input_dev & battery temperature

本文介绍了作者在调试触摸屏过程中遇到的问题及解决方案,包括如何在驱动中支持按键功能及长按操作,并添加了电池温度检测功能。

昨天感冒了,不舒服,所以没有写日志。晚上回来的时候就一直脑袋迷糊,不清醒,也没有写东西的心情了。病这个玩意,真不是个好东西。回来随便看了几封LKML的邮件就睡了。也记不得昨天一天干了啥了,反正状态也不是很好。

上午弄好了sx8651的一个触摸屏,这个是挂上i2c上的。调一个触摸屏其实挺简单的,以前好像也写过,设置一个x,y的最大值最小值,让应用知道后可以写lcd对应起来,这样一校准就OK了,驱动通过上报x,y坐标,就可以确定触摸的是个啥地方了。现在有很多触摸屏都是支持按键的,这样的屏我见过有一种是物理按键的,也就是在下面做几个gpio式的,跟普通的物理按键基本没有区别。大多数都是在屏上划分一个区域,然后画几个按键,说,这个地方应该是啥键。这样其实比较麻烦。我觉得这样实现按键,一种是不用修改驱动,在应用里面做处理,就是在驱动上报一个坐标后,应用做判断,如果这个区域是按键区,就按照按键的方式来处理,驱动就比较单纯了。具体应用里面怎么处理,我也不太明白,反正现在公司都是要实现在驱动里面,于是上午就在驱动里面加上了支持按键的代码,而且还要支持长按操作。具体是这样做的:

在Kconfig里加了一个CONFIG,可以在配置内核的时候配置是不是支持按键,因为项目比较多,所以这样做有必要。然后根据这个macro定义了一个key_pos的数组,数组里面是那几个按键x轴位置的中心值,定义了一个key_map数组,数组成员的值keycode与pos相对应起来,当然keycode是用input.h中的key macro。然后定义了一个key_sensitivity,也就是这相区域的灵敏度。定义了三个函数,第一个是设置input_dev capacity的,一个for()来set input_dev的capatity。把key_map中的那几个keycode都设置上,这个函数是在probe里面用到的。接着一个函数是把key_map中的key都上报为抬起,也是一个for(),都是input_report_key(input, keycode, 0);这个是用在timer里的,因为probe里面会设一个timer,这个跟屏的其它地方上报ABS相符合。再有一个函数就是上报按键的,具体就是如果Y大于一个值,就说明是在按键区域,x如果在这个键的中心值加减灵敏度的范围内,就input_report_key这个值,然后再input_sync。为什么要设一个灵敏度的值呢,因为触摸屏按一下就会上报好多值,可以通过调整sensitivity的值来调整按键被击中的灵敏度,我觉得这样做比较合适,不知道有没有更好的方法,这个函数是用在send_event里面的,用在最开始处进行处理,如果在按键区,下面的上报ABS的代码就不用再去执行了。

然后如果不定义支持按键的macro,就不定义那几个数组,并且把这几个函数定义成空操作,这样代码比较整洁,这是linus建议的,比较靠谱。

按键这个问题告一个段落,不知道有没有说清楚。。。。。

下午的时候有一个严重的pm不供电的bug,怀疑到我头上了,因为从好的版本到不好的版本,我改的最多,而且是与pm有关的,这就是一个悲剧啊,查了一下午问题,最后不知情况,回退了一句我的代码,就是一句不知作用的写寄存器的代码。。。。。。

晚上把电池温度检测的功能添加上了,基本是这样的一个过程:(可能说起来还是有点乱,可能我表达的能力有问题,但是思路绝对清晰)

温度检测角上接地了,然后连了一个GPADC1和GPADC3,搞了两个功能,检测电池有没有和电池温度的,由于打开电池检测的功能会影响温度检测的电流值,于是在init_battery的时候检测完电池存在后,就把这个功能给关掉了。让它只有温度检测的功能。使能gpadc功能在pm-core里就做过了,我只需要打开gp_bias的ou1和en1。让gp_bias1工作,设置gp_bias的电流。然后再根据热敏电阻的规格,不同温度下的电阻的大小不同,乘上电流,算出来电压,设置触发温度中断的最高电压和最低电压值。其它的就完全自己发挥了,看看想要个啥温度。大概就是这个样子吧。

写得有点多了,感冒没有好,得早点睡了。。。。。。。。。。。。。。。。。。。。。。。。。

转载于:https://www.cnblogs.com/linuxkernel/archive/2011/03/29/1999296.html

我现在要实现VBUS唤醒系统,(即系统休眠后插入usb可以实现唤醒系统,并且有adb口,目前是休眠之后插入usb无法唤醒) 目前抓到的唤醒log如下: [ 282.641013] PM: pm_system_irq_wakeup: 175 triggered c263000.thermal-sensor [ 282.641764] PM: PM: Pending Wakeup Sources: [timerfd] [ 282.669925] usb_extcon_detect_cable : id = 1, vbus = 0 [ 282.709202] [drm] [msm-dsi-warn]: secondary default panel not found 我的预期是id = 1, vbus = 1 这是log打印相关的代码: static void usb_extcon_detect_cable(struct work_struct *work) { int id, vbus; struct usb_extcon_info *info = container_of(to_delayed_work(work), struct usb_extcon_info, wq_detcable); /* check ID and VBUS and update cable state */ id = info->id_gpiod ? gpiod_get_value_cansleep(info->id_gpiod) : 1; vbus = info->vbus_gpiod ? gpiod_get_value_cansleep(info->vbus_gpiod) : id; printk("ct %s : id = %d, vbus = %d\n", __func__, id, vbus); /* at first we clean states which are no longer active */ if (id) { if (info->vbus_out_gpiod) gpiod_set_value_cansleep(info->vbus_out_gpiod, 0); extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false); } if (!vbus) extcon_set_state_sync(info->edev, EXTCON_USB, false); if (!id) { if (info->vbus_out_gpiod) gpiod_set_value_cansleep(info->vbus_out_gpiod, 1); extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true); } else { if (vbus) extcon_set_state_sync(info->edev, EXTCON_USB, true); } } 这是我在devicetree/qcom/neo-pmic-overlay.dtsi的配置:你检查下哪些地方可能配置的不对: #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include <dt-bindings/iio/qcom,spmi-vadc.h> #include <dt-bindings/interrupt-controller/irq.h> #include "pm8150.dtsi" &pm8150_gpios { usb0_vbus_det { usb0_vbus_det_default: usb0_vbus_det_default { pins = "gpio5"; function = "normal"; input-enable; bias-disable; //power-source = <0>; /* 1.8V input supply */ }; }; }; &soc { reboot_reason { compatible = "qcom,reboot-reason"; nvmem-cells = <&restart_reason>; nvmem-cell-names = "restart_reason"; }; gpio_keys { compatible = "gpio-keys"; label = "gpio-keys"; pinctrl-names = "default"; pinctrl-0 = <&gpio_vol_up>, <&gpio_camera_shot>; vol_up { label = "vol_up"; gpios = <&tlmm 122 GPIO_ACTIVE_LOW>; linux,input-type = <1>; linux,code = <KEY_VOLUMEUP>; debounce-interval = <15>; linux,can-disable; }; camera_shot { label = "camera_shot"; gpios = <&tlmm 64 GPIO_ACTIVE_LOW>; linux,input-type = <1>; linux,code = <KEY_CAMERA>; debounce-interval = <15>; linux,can-disable; }; }; extcon_usb0: extcon_usb0 { compatible = "linux,extcon-usb-gpio"; vbus-gpio = <&pm8150_gpios 5 GPIO_ACTIVE_HIGH>; interrupt-parent = <&spmi_bus>; interrupts = <0x0 0xc9 0 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "pm8150_gpio5"; wakeup-source; pinctrl-names = "default"; pinctrl-0 = <&usb0_vbus_det_default>; }; }; &pm8150_vadc { pm8150_skin_therm { reg = <ADC5_AMUX_THM1_100K_PU>; label = "pm8150_skin_temp"; qcom,hw-settle-time = <200>; qcom,ratiometric; qcom,pre-scaling = <1 1>; }; /* * This thermistor has 100k pullup already connected, * modify config following HW recommendation, for all * platforms other than SG. */ pm8150_wlan_therm { reg = <ADC5_AMUX_THM2>; label = "pm8150_wlan_temp"; qcom,hw-settle-time = <200>; qcom,pre-scaling = <1 1>; qcom,scale-fn-type = <ADC_SCALE_HW_CALIB_THERM_100K_PULLUP>; }; pm8150_xo_therm { reg = <ADC5_XO_THERM_100K_PU>; label = "pm8150_xo_therm"; qcom,hw-settle-time = <600>; qcom,ratiometric; qcom,pre-scaling = <1 1>; }; }; &pm8150_adc_tm { io-channels = <&pm8150_vadc ADC5_AMUX_THM1_100K_PU>, <&pm8150_vadc ADC5_AMUX_THM2>, <&pm8150_vadc ADC5_XO_THERM_100K_PU>; pm8150_skin_therm { reg = <ADC5_AMUX_THM1_100K_PU>; qcom,hw-settle-time = <200>; qcom,ratiometric; }; /* * This thermistor has 100k pullup already connected, * modify config following HW recommendation, for all * platforms other than SG. */ pm8150_wlan_therm { reg = <ADC5_AMUX_THM2>; qcom,hw-settle-time = <200>; }; pm8150_xo_therm { reg = <ADC5_XO_THERM_100K_PU>; qcom,hw-settle-time = <600>; qcom,ratiometric; }; }; &thermal_zones { sys-therm-0 { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&pm8150_adc_tm ADC5_AMUX_THM1_100K_PU>; trips { active-config0 { temperature = <125000>; hysteresis = <1000>; type = "passive"; }; active-config1 { temperature = <125000>; hysteresis = <1000>; type = "passive"; }; }; }; sys-therm-1 { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&pm8150_adc_tm ADC5_AMUX_THM2>; trips { active-config0 { temperature = <125000>; hysteresis = <1000>; type = "passive"; }; active-config1 { temperature = <125000>; hysteresis = <1000>; type = "passive"; }; sys_therm1_config0: sys-therm1-config0 { temperature = <54000>; hysteresis = <2000>; type = "passive"; }; sys_therm1_config1: sys-therm1-config1 { temperature = <56000>; hysteresis = <2000>; type = "passive"; }; sys_therm1_config2: sys-therm1-config2 { temperature = <58000>; hysteresis = <2000>; type = "passive"; }; }; }; xo-therm { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&pm8150_adc_tm ADC5_XO_THERM_100K_PU>; trips { active-config0 { temperature = <125000>; hysteresis = <1000>; type = "passive"; }; active-config1 { temperature = <125000>; hysteresis = <1000>; type = "passive"; }; }; }; }; &qupv3_se10_i2c { clock-frequency = <400000>; #address-cells = <1>; #size-cells = <0>; status = "ok"; battery: battery { compatible = "simple-battery"; voltage-min-design-microvolt = <3100000>; energy-full-design-microwatt-hours = <2520000>; charge-full-design-microamp-hours = <645000>; over-voltage-threshold-microvolt = <4500000>; re-charge-voltage-microvolt = <250000>; /* bq256xx's termination current setting has a min limit of 60mA */ charge-term-current-microamp = <60000>; constant-charge-current-max-microamp = <500000>; constant-charge-voltage-max-microvolt = <4480000>; voltage-max-design-microvolt = <4480000>; precharge-current-microamp = <128000>; factory-internal-resistance-micro-ohms = <120000>; }; charger: charger@6b { compatible = "ti,bq25600"; reg = <0x6b>; interrupt-parent = <&tlmm>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; debugboard-detect-gpio = <&tlmm 54 GPIO_ACTIVE_HIGH>; ti,watchdog-timeout-ms = <0>; pinctrl-names = "default"; pinctrl-0 = <&bq256xx_intr_default>; input-voltage-limit-microvolt = <4480000>; input-current-limit-microamp = <500000>; monitored-battery = <&battery>; status = "ok"; }; battery_645mAh: battery_645mAh { qmax-cell0 = <16384>; resist-table = <34 31 29 33 39 26 31 28 28 29 31 31 46 83 221>; }; battery_630mAh: battery_630mAh { qmax-cell0 = <15656>; resist-table = <16 16 17 20 22 13 17 18 18 18 17 23 28 44 62>; }; bq27421: fuel-gauge@55 { compatible = "ti,bq27421"; reg = <0x55>; interrupt-parent = <&tlmm>; interrupts = <7 IRQ_TYPE_EDGE_FALLING>; pinctrl-names = "default"; pinctrl-0 = <&bq27421_intr_default>; bat-resist-table = <&battery_645mAh>; monitored-battery = <&battery>; status = "ok"; }; }; &usb0 { extcon = <&extcon_usb0>, <&eud>; }; &pm8150_pon { qcom,log-kpd-event; };补充一下,gpio5注册的中断号是cat /proc/interrupts | grep spmi 304: 0 0 0 0 spmi-gpio 4 Edge soc:extcon_usb0我 cat /proc/interrupts | grep spmi 304: 0 0 0 0 spmi-gpio 4 Edge soc:extcon_usb0 而代码里interrupt-parent = <&spmi_bus>;这两者需要对应吗
最新发布
08-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值