本帖最后由 Demon 于 2019-5-9 11:08 编辑
本文描述在firefly AIO-3288C平台上添加一个新的TP驱动(gsl3680驱动)以及详细的驱动代码信息。如有不足之处,敬请指出。
1、修改DTS,添加i2c设备
在kernel/arch/arm/boot/dts/lcd-HSX101H40C-aio-3288c.dtsi中添加i2c设备的相关信息: - <font face="微软雅黑">/*==*/
- &i2c4 {
- status = "okay";
- mt@40 {
- status = "okay";
- compatible = "firefly,gsl3680";
- reg = <0x41>;
- touch-gpio = <&gpio5 GPIO_C3 IRQ_TYPE_EDGE_RISING>;
- reset-gpio = <&gpio7 GPIO_B1 GPIO_ACTIVE_LOW>;
- max-y = <1280>;
- max-x = <800>;
- flip-x = <1>;
- flip-y = <0>;
- swap-xy = <0>;
- };
- }; </font>
复制代码
表示i2c2总线上下挂在了多个i2c设备。 其中mt@40是表示此i2c设备的设备类型为触摸屏,设备地址为0x40(7位地址,注意:在i2c的传输函数中,会将此地址左移一位,因此实际上gsl3680的i2c设备地址为0x80)。该节点下有多个属性:
1、compatible= " firefly,gsl3680"; 属性用于驱动和设备的绑定。表示特定的设备名称,此处为gslX680; 2、reg= <0x40>;属性表示此设备的i2c地址为0x40,等同于@40; 3、touch-gpio= <&gpio5 GPIO_C3 IRQ_TYPE_EDGE_RISING>;表示复位引脚使用的是GPIO0中的GPIO_D3这个引脚,低电平有效。 reset-gpio= <&gpio7 GPIO_B1 GPIO_ACTIVE_LOW>;表示中断引脚使用的是GPIO0中的GPIO_A2这个引脚,高电平触发。 4、max-y= <1280>;max-x = <800>;表示屏幕的横轴跟纵轴的max像素。 5、flip-x= <1>; flip-y = <0>;标记x和y是否需要翻转。
在上述的信息中,可以通过of接口获取到属性对应的值。在后面的probe()函数中就会使用到。
2、修改Makefile、Kconfig (1)、修改Makefile添加gsl3680驱动 在drivers/input/touchscreen/Makefile中添加驱动: obj-$(CONFIG_TOUCHSCREEN_GSLX680)+= rockchip_gslX680_firefly.o 只要当配置了CONFIG_TOUCHSCREEN_GSLX680的选项才会去编译rockchip_gslX680_firefly.o的内容。在配置内核的时候会通过makemenuconfig来配置对应的选项。 注:如果不想要这么复杂,可以将该语句写成obj-y+= rockchip_gslX680_firefly.o 来强制编译该驱动。
(2)、修改Kconfig添加驱动配置描述 在drivers/input/touchscreen/Kconfig中添加驱动配置描述: - config TOUCHSCREEN_GSLX680
- tristate "gslX680 touchscreen driver"
- help
- gslX680 touchscreen driver
复制代码
3、添加i2c驱动
- #define GSLX680_I2C_NAME "gslX680"
- #define GSLX680_I2C_ADDR 0x40
-
- static const struct i2c_device_id gsl_ts_id[] = {
- {GSLX680_I2C_NAME, 0},
- {}
- };
- MODULE_DEVICE_TABLE(i2c, gsl_ts_id);
- static struct i2c_driver gsl_ts_driver = {
- .driver = {
- .name = GSLX680_I2C_NAME,
- .owner = THIS_MODULE,
- },
- #ifndef CONFIG_HAS_EARLYSUSPEND
- // .suspend = gsl_ts_suspend,
- // .resume = gsl_ts_resume,
- #endif
- .probe = gsl_ts_probe,
- .remove = gsl_ts_remove,
- .id_table = gsl_ts_id,
- };
- static int __init gsl_ts_init(void)
- {
- int ret;
- printk("==gsl_ts_init==\n");
- ret = i2c_add_driver(&gsl_ts_driver);
- printk("ret=%d\n",ret);
- return ret;
- }
- static void __exit gsl_ts_exit(void)
- {
- printk("==gsl_ts_exit==\n");
- i2c_del_driver(&gsl_ts_driver);
- return;
- }
复制代码 注册名字为GSLX680_I2C_NAME的i2c驱动,即gslx680,该驱动支持的设备名为字gsl_ts_id[]里的设备名称。因为我们在dts中已注册了一个名字为gslx680的i2c设备。因此,设备与驱动可以匹配成功并正确执行probe()函数。
后面的probe()函数太长,就不在贴子中解析,请下载附件查阅
RT.pdf
(367.47 KB, 下载次数: 0, 售价: 3 灯泡)
|