rk3288 gpio按键驱动分析
dts配置GPIO
164 gpio_keys { // rk3036-echo.dts
165 compatible = "gpio-keys";
166 #address-cells = <1>;
167 #size-cells = <0>;
168
169 pinctrl-names = "default";
170 pinctrl-0 = <&pwr_key>;
171
172 power_key: power-key {
173 label = "GPIO Key Power";
174 gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; // [gpio2 25] to GPIO0_A1
175 linux,code = ; //207
176 debounce-interval = <100>;
177 wakeup-source;
178 };
179 };
832 &pinctrl {
833 keys {
834 pwr_key: pwr-key {
835 rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_pull_none>; // pcfg_pull_default
836 };
837 };
838 };
驱动文件:./drivers/input/keyboard/gpio_keys.c
以下是GPIO按键驱动的简单代码调用流程跟踪:
gpio_keys_probe
-->pdata = gpio_keys_get_devtree_pdata(dev); //获取dts的资源配置
-->
-->input = devm_input_allocate_device(dev); //分配输入子设备
-->error = gpio_keys_setup_key(pdev, input, bdata, button); //设置GPIO按键属性,在这个接口判断GPIO是否合法有效能用,申请GPIO,申请gpio中断号
-->gpio_is_valid(button->gpio)
-->gpio_set_debounce
-->irq = gpio_to_irq(button->gpio); //设置GPIO中断号
-->INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func); //初始化工作队列gpio_keys_gpio_work_func
-->isr = gpio_keys_gpio_isr; //注册中断子函数,按键按下,触发中断,然后调用中断子函数
-->mod_delayed_work//调用工作队列
-->gpio_keys_gpio_work_func //调用gpio按键工作队列
-->gpio_keys_gpio_report_event(bdata); //调用gpio按键上报处理函数
-->state = gpio_get_value_cansleep(button->gpio); //获取gpio的状态
-->state = (state ? 1 : 0) ^ button->active_low; //这里得出判断按键的状态,为1就是按下,为0就是抬起
-->input_event(input, type, button->code, !!state); //上报GPIO按键键值和状态
-->input_sync(input); //sync一下,表示此次上报完成
-->irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; //设置上升沿或者下降沿触发中断
rk3288 gpio按键驱动分析
dts配置GPIO
164 gpio_keys { // rk3036-echo.dts
165 compatible = "gpio-keys";
166 #address-cells = <1>;
167 #size-cells = <0>;
168
169 pinctrl-names = "default";
170 pinctrl-0 = <&pwr_key>;
171
172 power_key: power-key {
173 label = "GPIO Key Power";
174 gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; // [gpio2 25] to GPIO0_A1
175 linux,code = ; //207
176 debounce-interval = <100>;
177 wakeup-source;
178 };
179 };
832 &pinctrl {
833 keys {
834 pwr_key: pwr-key {
835 rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_pull_none>; // pcfg_pull_default
836 };
837 };
838 };
驱动文件:./drivers/input/keyboard/gpio_keys.c
以下是GPIO按键驱动的简单代码调用流程跟踪:
gpio_keys_probe
-->pdata = gpio_keys_get_devtree_pdata(dev); //获取dts的资源配置
-->
-->input = devm_input_allocate_device(dev); //分配输入子设备
-->error = gpio_keys_setup_key(pdev, input, bdata, button); //设置GPIO按键属性,在这个接口判断GPIO是否合法有效能用,申请GPIO,申请gpio中断号
-->gpio_is_valid(button->gpio)
-->gpio_set_debounce
-->irq = gpio_to_irq(button->gpio); //设置GPIO中断号
-->INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func); //初始化工作队列gpio_keys_gpio_work_func
-->isr = gpio_keys_gpio_isr; //注册中断子函数,按键按下,触发中断,然后调用中断子函数
-->mod_delayed_work//调用工作队列
-->gpio_keys_gpio_work_func //调用gpio按键工作队列
-->gpio_keys_gpio_report_event(bdata); //调用gpio按键上报处理函数
-->state = gpio_get_value_cansleep(button->gpio); //获取gpio的状态
-->state = (state ? 1 : 0) ^ button->active_low; //这里得出判断按键的状态,为1就是按下,为0就是抬起
-->input_event(input, type, button->code, !!state); //上报GPIO按键键值和状态
-->input_sync(input); //sync一下,表示此次上报完成
-->irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; //设置上升沿或者下降沿触发中断
举报