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代码片段如下:

[cpp] view plaincopy

  1. gpio_keypad: gpio_keyad@0{  
  2.     compatible = "gpio-keys";  
  3.     #address-cells = <1>;  
  4.     #size-cells = <0>;  
  5.     autorepeat;  
  6.   
  7.     switch@1 {  
  8.         label = "up";  
  9.         linux,code = <103>;  
  10.         gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;  
  11.         gpio-key,wakeup;  
  12.     };  
  13.   
  14.     switch@2 {  
  15.         label = "down";  
  16.         linux,code = <108>;  
  17.         gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;  
  18.         gpio-key,wakeup;  
  19.     };  
  20.   
  21.     switch@3 {  
  22.         label = "left";  
  23.         linux,code = <105>;  
  24.         gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;  
  25.         gpio-key,wakeup;  
  26.     };  
  27.   
  28.     switch@4 {  
  29.         label = "right";  
  30.         linux,code = <106>;  
  31.         gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;  
  32.         gpio-key,wakeup;  
  33.     };  
  34.   
  35.     switch@5 {  
  36.         label = "enter";  
  37.         linux,code = <28>;  
  38.         gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;  
  39.         gpio-key,wakeup;  
  40.     };  
  41.   
  42.     switch@6 {  
  43.         label = "esc";  
  44.         linux,code = <1>;  
  45.         gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;  
  46.         gpio-key,wakeup;  
  47.     };  
  48. };  

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

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

[cpp] view plaincopy

  1. &am33xx_pinmux {  
  2. pinctrl-names = "default";  
  3. pinctrl-0 = <&clkout2_pin>;  
  4.   
  5. gpio_key_pins: gpio_keys_s0 {  
  6.     pinctrl-single,pins = <  
  7.         0x50 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a3.gpio1_20 */  
  8.         0x54 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a5.gpio1_21 */  
  9.         0x58 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */  
  10.         0x5C (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a7.gpio1_23 */  
  11.         0x60 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */  
  12.         0x64 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a9.gpio1_25 */  
  13.     >;  
  14. };  
  15.   
  16. i2c0_pins: pinmux_i2c0_pins {  
  17.     pinctrl-single,pins = <  
  18.         0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */  
  19.         0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */  
  20.     >;  
  21. };  

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

(3)重新编译dts

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

[cpp] view plaincopy

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

(4)用新的dtb启动内核

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

[cpp] view plaincopy

  1. load mmc 0 ${fdtaddr} /boot/tq335x.dtb  
  2. load mmc 0 ${loadaddr} /boot/zImage  
  3. load mmc 0 ${rdaddr} /boot/ramdisk.img  
  4. bootz ${loadaddr} ${rdaddr} ${fdtaddr}  

(5)测试按键

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

[cpp] view plaincopy

  1. hexdump /dev/input/event0  

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

[cpp] view plaincopy

  1. @tq335x #hexdump /dev/input/event0   
  2. 0000000 4b7c 386d f9b4 0005 0001 0067 0001 0000  
  3. 0000010 4b7c 386d f9b4 0005 0000 0000 0000 0000  
  4. 0000020 4b7c 386d 80c4 0008 0001 0067 0000 0000  
  5. 0000030 4b7c 386d 80c4 0008 0000 0000 0000 0000  
  6. 0000040 4b7d 386d 09f8 0008 0001 006c 0001 0000  
  7. 0000050 4b7d 386d 09f8 0008 0000 0000 0000 0000  
  8. 0000060 4b7d 386d 1005 000a 0001 006c 0000 0000  
  9. 0000070 4b7d 386d 1005 000a 0000 0000 0000 0000  
  10. 0000080 4b7f 386d 1304 000d 0001 0069 0001 0000  
  11. 0000090 4b7f 386d 1304 000d 0000 0000 0000 0000  
  12. 00000a0 4b80 386d 48e6 0000 0001 0069 0000 0000  
  13. 00000b0 4b80 386d 48e6 0000 0000 0000 0000 0000  
  14. 00000c0 4b80 386d f340 000a 0001 006a 0001 0000  
  15. 00000d0 4b80 386d f340 000a 0000 0000 0000 0000  
  16. 00000e0 4b80 386d cd6f 000c 0001 006a 0000 0000  
  17. 00000f0 4b80 386d cd6f 000c 0000 0000 0000 0000  
  18. 0000100 4b81 386d a2d7 0007 0001 001c 0001 0000  
  19. 0000110 4b81 386d a2d7 0007 0000 0000 0000 0000  
  20. 0000120 4b81 386d b39d 0009 0001 001c 0000 0000  
  21. 0000130 4b81 386d b39d 0009 0000 0000 0000 0000  
  22. 0000140 4b82 386d 5aa3 0002 0001 0001 0001 0000  
  23. 0000150 4b82 386d 5aa3 0002 0000 0000 0000 0000  
  24. 0000160 4b82 386d 4bf3 0004 0001 0001 0000 0000  
  25. 0000170 4b82 386d 4bf3 0004 0000 0000 0000 0000  

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

[cpp] view plaincopy

  1. struct input_event {  
  2.     struct timeval time;  
  3.     __u16 type;  
  4.     __u16 code;  
  5.     __s32 value;  
  6. };  

结合之前设置的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相关的笔记的。

时间: 2024-10-21 14:05:59

AM335x(TQ335x)学习笔记——GPIO按键驱动移植的相关文章

AM335x(TQ335x)学习笔记——WM8960声卡驱动移植

经过一段时间的调试,终于调好了TQ335x的声卡驱动.TQ335x采用的Codec是WM8960,本文来总结下WM8960驱动在AM335x平台上的移植方法.Linux声卡驱动架构有OSS和ALSA两种架构,目前最常用的架构是ALSA,本文也使用ALSA架构对WM8960驱动进行移植. ASoC是对ALSA驱动架构的进一步封装.ASoC将ALSA驱动中的各模块抽象为三部分:Platform.Codec和Machine.Platform主要是平台硬件驱动,包括SoC的IIS模块.DMA等,在本文中

AM335x(TQ335x)学习笔记——Nand&amp;amp;&amp;amp;网卡驱动移植

移植完成声卡驱动之后本想再接再励,移植网卡驱动,但没想到的是TI维护的内核太健壮,移植网卡驱动跟之前移植按键驱动一样简单,Nand驱动也是如此,于是,本人将Nand和网卡放在同一篇文章中介绍.介绍之前先感慨一下:TI的维护的内核真的很健壮,DTS真的很强大. 1. Nand驱动移植 阅读TQ335x的原理图可知,TQ335x的Nand连接到了GPMC上,且与DTS中默认的配置吻合,此处不做任何修改,详情如下: [cpp] view plaincopy nandflash_pins_s0: nan

AM335x(TQ335x)学习笔记——LCD驱动移植

TI的LCD控制器驱动是非常完善的,共通的地方已经由驱动封装好了,与按键一样,我们可以通过DTS配置完成LCD的显示.下面,我们来讨论下使用DTS方式配置内核完成LCD驱动的思路. (1)初步分析 由于TQ335x使用的芯片是AM335x,故仍然可以参考am335x-evm.dts.当然,am335x-evmsk.dts.am335x-beagbone.dts都可以.本文以am335x-evm.dts为例.大体上浏览下DTS文件,可以发现两个醒目的节点:一个是panel,一个是backlight

AM335x(TQ335x)学习笔记——触摸屏驱动编写

前面几篇文章已经通过配置DTS的方式完成了多个驱动的移植,接下来我们解决TQ335x的触摸驱动问题.由于种种原因,TQ335x的触摸屏驱动是以模块方式提供的,且Linux官方内核中也没有带该触摸屏的驱动源码,单纯的配置DTS是无法完成TQ335x的触摸驱动移植工作的,因此,本文参考内核中原有的pixcir_i2c_ts驱动编写TQ335x的触摸屏(TN92)驱动. 在之前移植TQ210时,我已经编写过TQ210的触摸屏驱动,我的TQ335x还是使用的TQ210的屏,因此,难度不是很大.这里需要说

AM335x(TQ335x)学习笔记——挂载Ramdisk

上篇文章中我们已经能够通过u-boot启动内核了,但是没有能够启动成功,从内核的log中可以看出,内核启动失败的原因是没有挂载到root文件系统,本文将使用busybox制作根文件系统并打包成ramdisk供u-boot启动内核使用. (1)制作根文件系统 使用busybox构建根文件系统的步骤可以参考本博客的另外一篇文章,该文章链接如下: S5PV210(TQ210)学习笔记--内核移植与文件系统构建 需要补充的是,文章"S5PV210(TQ210)学习笔记--内核移植与文件系统构建"

AM335x(TQ335x)学习笔记——USB驱动移植

对于AM335x来讲,TI维护的USB驱动已经非常完善了,本文称之为移植,实际上仅仅是配置内核选项使能USB HOST/OTG功能.废话少说,直接动手开启AM335x的USB驱动配置项. Step1. 配置内核支持USB 默认的配置项没有配置USB相关的选项,但是DTS已经配置好了,我们不需要对DTS作任何修改,详细的内核配置项如下: [cpp] view plaincopy Device Drivers  --->       [*] USB support  --->           

AM335x(TQ335x)学习笔记——u-boot-2014.10移植

最近移植了下u-boot-2014.10到TQ335x,如果基于am335x evm进行移植,需要修改的地方并不多. 由于TI的am335x evm开发使用了一个eeprom保存了板载配置信息,用来区分不同板子的型号的,而TQ335x没有这个eeprom,因此,需要修改eeprom相关的部分,使u-boot适应TQ335x开发板. 使用source insight查看代码,很容易发现,所有获取板载配置的部分都是通过读取eeprom获得的,因此,首选修改read_eeprom(board/ti/a

AM335x(TQ335x)学习笔记——使用dtb方式启动内核

老式的u-boot使用ATAGS的方式启动linux内核,本文使用新式的dtb方式启动内核. 我使用的内核是linux-3.17.2版本,下面开始编译内核. (1) 解压内核 [php] view plaincopy tar jxf linux-3.17.2.tar.bz2   (2)配置linux内核,由于am335x在内核中都归为omap2系列,故可以使用如下命令: [cpp] view plaincopy make ARCH=arm omap2plus_defconfig   (3)编译内

Nodejs学习笔记之测试驱动_node.js

分享第二章,关于测试驱动.这里的测试主要针对Web后端的测试 -- 你为什么要写测试用例(即测试用例的完善是否是浪费时间),如何完善你的测试用例,代码设计如何简化测试用例的书写,以及一些后期的构想. 1. 你为什么要写测试用例 这个习惯通常会被认为是一种耽误开发进度的行为,你需要花费几乎和开发代码相同的时间来逐步完善你的测试用例.但是在开发过程中,在开发完成一段代码后如果负责任而不是说完全把问题交给测试人员去发现的话,这个时候通常都会去做一些手动的测试.例如: 在代码中执行某些方法,查看输出的值