Demon 发表于 2019-5-9 11:08:17

AIO-3288C的TP驱动详解

本帖最后由 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()函数太长,就不在贴子中解析,请下载附件查阅


文章参考百度文库:https://wenku.baidu.com/u/%E4%BC ... E9%B9%85?from=wenku
如有不足之处,敬请指出。
页: [1]
查看完整版本: AIO-3288C的TP驱动详解