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的电流。然后再根据热敏电阻的规格,不同温度下的电阻的大小不同,乘上电流,算出来电压,设置触发温度中断的最高电压和最低电压值。其它的就完全自己发挥了,看看想要个啥温度。大概就是这个样子吧。
写得有点多了,感冒没有好,得早点睡了。。。。。。。。。。。。。。。。。。。。。。。。。