打印

AM335x(TQ335x)学习笔记——GPIO按键驱动移植

[复制链接]
635|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Roses|  楼主 | 2017-10-3 11:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AM335x(TQ335x)学习笔记——GPIO按键驱动移植

还是按照S5PV210的学习顺序来,我们首先解决按键问题。TQ335x有六个用户按键,分别是上、下、左、右、Enter和ESC。开始我想到的是跟学习S5PV210时一样,编写输入子系统驱动解决按键问题,但是浏览driver/input/keyboard目录时意外的发现了gpio-keys.c,大体上看下该驱动程序,其功能是实现了通用的gpio按键。再去看了下DTS,发现DTS中有对gpio-keys的引用,于是猜到,新的内核不需要自己编写输入子系统驱动,可以通过配置DTS直接解决按键问题。本人最终通过实验证实了这个猜想,下面是实验笔记及本人的一些理解。

(1)确定GPIO管脚

通过查看TQ335x的原理图可以看到,TQ335x的6个按键分别接在GPIO1的20~25管脚上,原理图如下:


(2)查看原有的dts配置

进行DTS文件修改之前可以阅读下内核相关文档,在Documentation/devicetree/目录下有很多关于devicetree的记载,其实,这些第一手的资料才是最具参考价值的资料。我还没来得及系统的阅读这些文档,急于实现功能,仅阅读了gpio-key和pinmux相关的部分就开始了修改工作,这是浮躁的表现,大家不要养成这种恶习啊!

通过仔细阅读原dts文件可以发现am335x-evm开发板上有个gpio矩阵键盘和gpio的音量+、音量-键,且矩阵键盘和音量键与TQ335x的按键管脚有冲突,因此,删除这两组配置并重新添加适应TQ335x按键的配置。修改后的DTS代码片段如下:

  • gpio_keypad: gpio_keyad@0{  
  •     compatible = "gpio-keys";  
  •     #address-cells = <1>;  
  •     #size-cells = <0>;  
  •     autorepeat;  
  •   
  •     switch@1 {  
  •         label = "up";  
  •         linux,code = <103>;  
  •         gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;  
  •         gpio-key,wakeup;  
  •     };  
  •   
  •     switch@2 {  
  •         label = "down";  
  •         linux,code = <108>;  
  •         gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;  
  •         gpio-key,wakeup;  
  •     };  
  •   
  •     switch@3 {  
  •         label = "left";  
  •         linux,code = <105>;  
  •         gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;  
  •         gpio-key,wakeup;  
  •     };  
  •   
  •     switch@4 {  
  •         label = "right";  
  •         linux,code = <106>;  
  •         gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;  
  •         gpio-key,wakeup;  
  •     };  
  •   
  •     switch@5 {  
  •         label = "enter";  
  •         linux,code = <28>;  
  •         gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;  
  •         gpio-key,wakeup;  
  •     };  
  •   
  •     switch@6 {  
  •         label = "esc";  
  •         linux,code = <1>;  
  •         gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;  
  •         gpio-key,wakeup;  
  •     };  
  • };  

[color=rgb(51, 102, 153) !important]复制代码

其中,linux,code后面对应的是linux标准的键值,可以在linux系统中找到,路径是:/usr/include/linux/input.h。

由于这六个按键使用的是gpio管脚,还需要通过后面的pinmux配置下gpio相关寄存器。同样的,删除gpio矩阵键盘和音量键相关的配置,添加使用TQ335x的配置,修改后的代码片段如下:

  • &am33xx_pinmux {  
  • pinctrl-names = "default";  
  • pinctrl-0 = <&clkout2_pin>;  
  •   
  • gpio_key_pins: gpio_keys_s0 {  
  •     pinctrl-single,pins = <  
  •         0x50 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a3.gpio1_20 */  
  •         0x54 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a5.gpio1_21 */  
  •         0x58 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */  
  •         0x5C (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a7.gpio1_23 */  
  •         0x60 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */  
  •         0x64 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a9.gpio1_25 */  
  •     >;  
  • };  
  •   
  • i2c0_pins: pinmux_i2c0_pins {  
  •     pinctrl-single,pins = <  
  •         0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */  
  •         0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */  
  •     >;  
  • };  

[color=rgb(51, 102, 153) !important]复制代码

需要注意的是,pinctrl-0后与矩阵键盘和音量键相关的配置项名称也要删除,对于phandler,目前还没有看懂什么意思,这里先让按键功能正常,之后再去详细的研究dts。学习dts的时候也会来写笔记的。

(3)重新编译dts

与之前编译dts的方法一样:

  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- tq335x.dtb  

[color=rgb(51, 102, 153) !important]复制代码

(4)用新的dtb启动内核


将新的tq335x.dtb拷贝到SD卡的boot目录下(可以直接覆盖掉原来的)并给开发板上电,同时按任意键使u-boot进入命令行模式,使用命令启动内核:

  • load mmc 0 ${fdtaddr} /boot/tq335x.dtb  
  • load mmc 0 ${loadaddr} /boot/zImage  
  • load mmc 0 ${rdaddr} /boot/ramdisk.img  
  • bootz ${loadaddr} ${rdaddr} ${fdtaddr}  

[color=rgb(51, 102, 153) !important]复制代码

(5)测试按键


从终端上无法直接看到按键效果,不过可以同hexdump命令来测试按键功能是否正常,使用方法如下:

  • hexdump /dev/input/event0  

[color=rgb(51, 102, 153) !important]复制代码

由于gpio-keys驱动将按键事件映射到了/dev/input/event0设备节点上,因此,对该设备节点使用hexdump工具可以读取到按键事件。执行上述指令后按键,可以从终端上看到输出。我按照上、下、左、右、Enter和ESC的顺序短按这六个键,可以看到如下Log:

  • @tq335x #hexdump /dev/input/event0   
  • 0000000 4b7c 386d f9b4 0005 0001 0067 0001 0000  
  • 0000010 4b7c 386d f9b4 0005 0000 0000 0000 0000  
  • 0000020 4b7c 386d 80c4 0008 0001 0067 0000 0000  
  • 0000030 4b7c 386d 80c4 0008 0000 0000 0000 0000  
  • 0000040 4b7d 386d 09f8 0008 0001 006c 0001 0000  
  • 0000050 4b7d 386d 09f8 0008 0000 0000 0000 0000  
  • 0000060 4b7d 386d 1005 000a 0001 006c 0000 0000  
  • 0000070 4b7d 386d 1005 000a 0000 0000 0000 0000  
  • 0000080 4b7f 386d 1304 000d 0001 0069 0001 0000  
  • 0000090 4b7f 386d 1304 000d 0000 0000 0000 0000  
  • 00000a0 4b80 386d 48e6 0000 0001 0069 0000 0000  
  • 00000b0 4b80 386d 48e6 0000 0000 0000 0000 0000  
  • 00000c0 4b80 386d f340 000a 0001 006a 0001 0000  
  • 00000d0 4b80 386d f340 000a 0000 0000 0000 0000  
  • 00000e0 4b80 386d cd6f 000c 0001 006a 0000 0000  
  • 00000f0 4b80 386d cd6f 000c 0000 0000 0000 0000  
  • 0000100 4b81 386d a2d7 0007 0001 001c 0001 0000  
  • 0000110 4b81 386d a2d7 0007 0000 0000 0000 0000  
  • 0000120 4b81 386d b39d 0009 0001 001c 0000 0000  
  • 0000130 4b81 386d b39d 0009 0000 0000 0000 0000  
  • 0000140 4b82 386d 5aa3 0002 0001 0001 0001 0000  
  • 0000150 4b82 386d 5aa3 0002 0000 0000 0000 0000  
  • 0000160 4b82 386d 4bf3 0004 0001 0001 0000 0000  
  • 0000170 4b82 386d 4bf3 0004 0000 0000 0000 0000  

[color=rgb(51, 102, 153) !important]复制代码

通过hexdump工具看到的数字是16进制的。由于linux的input_event事件定义如下:

  • struct input_event {  
  •     struct timeval time;  
  •     __u16 type;  
  •     __u16 code;  
  •     __s32 value;  
  • };  

[color=rgb(51, 102, 153) !important]复制代码

结合之前设置的linux,code分析可知,hexdump打印的各列数据含义如下:


第一列:行号

第2~5列:输入事件时间戳,即结构体中的time。

第6列:输入事件类型,即结构体中的type。

第7列:按键的键值,即结构体中的code。

第8列:按键的状态,即结构体中的value,1表示按下,0表示松开。

细心的朋友会发现,按下并松开一个按键后能看到四行数据,这是由于每个input_event后会接一个linux同步事件,从上述log可以看到,同步事件的type,code,value都为0。

到这里,就完成了TQ335x的按键驱动移植。虽然过程很简单,但已经体会到了DTS的好处。对于一些通用的功能,可以不修改内核源码、不重新编译内核,仅修改dts配置就能实现所需的功能,如这里的gpio按键功能。dts方式启动内核有着巨大的优势,必须弄清DTS的编写规则,以后会记录DTS相关的笔记的。







相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

709

主题

1023

帖子

7

粉丝