aosp gpio driver 和 dts 以及键值上报
配置和定义
gpio_power_detect {
compatible = "quectel,gpio_power_detect";
pinctrl-names = "default";
pinctrl-0 = <&gpio_power_detect_active>;
gpio_power_gpio = <&tlmm 95 0x00>;
//otg-power-gpios = <&tlmm 18 0>;
usb-sel-gpios = <&tlmm 66 0>;
debounce = <15>;
linux,code = <172>;
};
struct gpio_power_detect {
struct device *dev;
struct input_dev *p_inputdev;
unsigned int gpio_power_gpio;
unsigned int gpio_power_irq_num;
// struct work_struct power_detect;
struct workqueue_struct *gpio_power_detect_wq;
struct work_struct work;
unsigned int gpio_usb_sel_gpio;
atomic_t state;
unsigned int code;
};
driver 和 dts 块之间的绑定
driver 中的 struct of_device_id
中的 compatible
会和 dts 中的 compatible
进行匹配,吻合的情况下, driver 就能从这个 dts 块中读取相应的数据了。 本文的 dts 是 qm215-qrd.dtsi
static struct of_device_id of_device_sc20_gpio_match_table[] =
{
{.compatible = "quectel,gpio_power_detect"},
{},
};
gpio_power_detect {
compatible = "quectel,gpio_power_detect";
...
};
driver 配置输入引脚
输入引脚一般需要配置: 引脚方向,中断,上下拉。
- 获取 gpio, driver 中通过 dts 中的相同名称,获取到 gpio,然后申请相应的结构体
dev_struct->gpio_power_gpio = of_get_named_gpio(dev_struct->dev->of_node, "gpio_power_gpio", 0);
gpio_request(dev_struct->gpio_power_gpio, "gpio_power_gpio");
gpio_power_detect {
...
gpio_power_gpio = <&tlmm 95 0x00>;
...
};
-
获取中断
dev_struct->gpio_power_irq_num = gpio_to_irq(dev_struct->gpio_power_gpio);
-
设置方向
gpio_direction_input(dev_struct->gpio_power_gpio);
- 设置上下拉,是通过 dts 来配置的,本文实在
msm8917-pinctrl.dtsi
中配置的,然后在qm215-qrd.dtsi
中进行引用。tlmm_gpio_power_detect { gpio_power_detect_active: gpio_power_detect_active { mux { pins = "gpio95"; drive-strength = <2>; bias-pull-up; }; }; };
gpio_power_detect {
...
pinctrl-names = "default";
pinctrl-0 = <&gpio_power_detect_active>;
...
};
···
# 配置输出引脚
输出引脚配置比较简单,只要获取 gpio 后,配置方向和初始值即可。
1. 获取 gpio
dev_struct->gpio_usb_sel_gpio = of_get_named_gpio(dev_struct->dev->of_node, "usb-sel-gpios", 0);
if (dev_struct->gpio_usb_sel_gpio < 0){
pr_err("%s: get usb_sel_gpio failed\n", __func__);
return -EINVAL;
}
ret = gpio_request(dev_struct->gpio_usb_sel_gpio, "usb-sel-gpios");
if (ret) {
pr_err("%s: Unable to request usb_sel_spio [%d]\n", __func__, dev_struct->gpio_usb_sel_gpio);
return ret;
}
gpio_power_detect {
...
usb-sel-gpios = <&tlmm 66 0>;
...
};
2. 配置位输出
ret = gpio_direction_output(dev_struct->gpio_usb_sel_gpio, 1);
if (ret) {
pr_err("%s: Unable to set direction for usb-sel-gpios [%d]\n", __func__, dev_struct->gpio_usb_sel_gpio);
gpio_free(dev_struct->gpio_usb_sel_gpio);
}
# 配置按键值上报
1. 获取按键值
if(of_property_read_u32(dev_struct->dev->of_node, "linux,code", &dev_struct->code)) {
dev_err(dev_struct->dev, "fail to get linux code\n");
return (-EINVAL);
}
printk("gpio_power_detect probe get key code %d\n", dev_struct->code);
state = gpio_get_value(dev_struct->gpio_power_gpio);
if(state < 0) {
dev_err(dev_struct->dev, "fail to init base_detect state %d\n", state);
return (-EINVAL);
}
atomic_set(&dev_struct->state, state);
gpio_power_detect {
...
linux,code = <172>;
};
2. 工作时上报键值
old_state = atomic_read(&dev_struct->state);
new_state = gpio_get_value(dev_struct->gpio_power_gpio);
if (new_state < 0) {
dev_err(dev_struct->dev,
"failed to get bd-gpio state: %d\n", new_state);
return;
}
if(new_state != old_state){
dev_err(dev_struct->dev, "base_detect update state %d", new_state);
atomic_set(&dev_struct->state, new_state);
gpio_set_value(dev_struct->gpio_usb_sel_gpio, new_state);
input_report_key(dev_struct->p_inputdev, dev_struct->code, new_state);
input_sync(dev_struct->p_inputdev);
}
# 注意
本文中使用的 `gpio_request` 属于老的 api,新的 api 一般是 `gpiod` 开头,比如:`gpiod_direction_output`.
如果是按键,为了消抖,dts 中需要考虑 `debounce`,driver 中需要考虑 延迟工作 `struct delayed_work` 。
`DEVICE_ATTR` 可以在 `sys fs` 中添加文件,相关可以参考: https://blog.csdn.net/njuitjf/article/details/16849333
# 参考:
设备树详解
https://blog.csdn.net/qq_28992301/article/details/53321610
在Linux驱动中使用gpio子系统
https://www.jianshu.com/p/f160209bd64b
Linux内核中的GPIO驱动
https://blog.csdn.net/vincent1995x/article/details/51581711
1.1. GPIO设置
http://developer.rokid.com/docs/7-bspguide/pinmuxji_gpio_she_zhi/gpioshe_zhi.html
LinuxGPIO中文文档
https://www.cnblogs.com/bforever/p/10528395.html
一、初识linux输入子系统
https://www.cnblogs.com/zhaobinyouth/p/6257662.html
pm_stay_awake()和pm_relax()的意义
https://blog.csdn.net/chizhang7815/article/details/100800761
linux gpio_to_irq()源码分析
https://blog.csdn.net/MACMACip/article/details/105549516
of_property_read_u32
https://biscuitos.github.io/blog/DTS-of_property_read_u32/
如何在一份驱动中上报键值之理解input子系统设备
https://blog.csdn.net/weixin_44158983/article/details/106872084?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.no_search_link&spm=1001.2101.3001.4242.1&utm_relevant_index=3
INPUT子系统学习 evdev
https://blog.csdn.net/xiaochuan110/article/details/82424237
高通 gpio控制方式
https://blog.csdn.net/qq_36781842/article/details/102625088?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.no_search_link
Android 5.1高通方案增加GPIO按键
https://blog.csdn.net/tdstds/article/details/50920443?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.no_search_link
Qualcomm MSM GPIO-KEY device tree
https://blog.csdn.net/bolanlst/article/details/51385808?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link
android7.1 msm8953通过寄存器拉高gpio电平
https://blog.csdn.net/zjy764219923/article/details/106243794?spm=1001.2101.3001.6650.15&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-15.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-15.no_search_link
msm8996的gpio和irq
https://blog.csdn.net/lintwins/article/details/50203173?spm=1001.2101.3001.6650.11&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-11.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-11.no_search_link
Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)
https://radia.blog.csdn.net/article/details/70800076?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.no_search_link
高通msm8916 gpio笔记(基于设备树)
https://blog.csdn.net/hm131415/article/details/54377549?spm=1001.2101.3001.6650.18&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.no_search_link
msm8953 申请gpio失败,查看所有的gpio 申请情况。
https://blog.csdn.net/jlgcumt/article/details/106614870?spm=1001.2101.3001.6650.14&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-14.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-14.no_search_link
高通 gpio控制方式
https://blog.csdn.net/qq_36781842/article/details/102625088?spm=1001.2101.3001.6650.9&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-9.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-9.no_search_link
高通msm8916 gpio笔记(基于设备树)
https://blog.csdn.net/hm131415/article/details/54377549?spm=1001.2101.3001.6650.16&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-16.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-16.no_search_link
高通 msm平台GPIO相关的device tree设置
https://blog.csdn.net/viewsky11/article/details/53402536?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link
配置学习总结高通平台GPIO
https://blog.csdn.net/Joymine/article/details/48161895?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link
GPIO中断唤醒系统调试方法
https://blog.csdn.net/jlgcumt/article/details/110480062?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-4.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-4.no_search_link
Linux休眠后开启中断的方法及中断唤醒过程
https://blog.csdn.net/mike8825/article/details/98473014
Android系统下如何通过外设实现GPIO中断触发调用Android程序执行
https://blog.csdn.net/a499957739/article/details/104425753
配置学习总结高通平台GPIO
https://blog.csdn.net/Joymine/article/details/48161895
Android GPIO 控制方案
https://blog.csdn.net/WXXGoodJob/article/details/90599925
android 上层如何控制GPIO
https://blog.csdn.net/prike/article/details/53216954
[RK3288]LED亮灯GPIO驱动编写及dts文件架构介绍(基于android8.1使用android studio3.6开发)
https://blog.csdn.net/a812417530/article/details/107004198
Android(Linux)控制GPIO的方法及实时性分析
https://www.cnblogs.com/we-hjb/p/5859479.html
Android(Linux)控制GPIO方法二
https://www.cnblogs.com/we-hjb/p/5903366.html
Android 驱动 (一) GPIO
https://www.cnblogs.com/tlnshuju/p/7028985.html