OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9815|回复: 11

Linux下GT9147/GT9271多点触摸驱动

[复制链接]

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2179
金钱
2179
注册时间
2018-8-27
在线时间
258 小时
发表于 2020-8-6 10:59:27 | 显示全部楼层 |阅读模式
本帖最后由 xiaotaotao 于 2020-8-6 11:01 编辑

正点原子10寸LCD触摸屏使用了GT9271作为触摸IC、而4.3寸LCD触摸(分为800*480、480*272两款)屏则使用了GT9147作为触摸IC。
这两款触摸IC在Linux下实现多点触摸不太好处理,主要原因在于GT9147/GT9271没有硬件检测每个触摸点的按下和抬起状态,
因此在上报数据的时候不好处理;像FT5426这类触摸IC,它能够检测到触摸点的按下与松开等状态,通过读取寄存器就可以知道。
虽然说GT9147/GT9271没有硬件检测每个触摸点的按下和抬起状态,但也不是不能实现多点触摸,只是比较麻烦一点,现给出笔者
的一份驱动代码,大家可以参考一下:
  1. /***************************************************************
  2. Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
  3. 文件名    : gt9xx.c
  4. 作者      : 邓涛
  5. 版本      : V1.0
  6. 描述      : GOODiX GT9147/GT9271触摸屏驱动程序
  7. 其他      : 无
  8. 论坛      : www.openedv.com
  9. 日志      : 初版V1.0 2020/7/26 邓涛创建
  10. ***************************************************************/

  11. #include <linux/module.h>
  12. #include <linux/i2c.h>
  13. #include <linux/input/mt.h>
  14. #include <linux/of_gpio.h>
  15. #include <linux/delay.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/of_device.h>

  18. /* 寄存器定义 */
  19. #define GOODIX_REG_COMMAND                0x8040
  20. #define GOODIX_REG_CFG_DATA                0x8047
  21. #define GOODIX_REG_CFG_CSM                0x80FF
  22. #define GOODIX_REG_ID                        0x8140
  23. #define GOODIX_READ_COOR_ADDR        0x814E

  24. /*
  25. *GT9271配置参数表
  26. *第一个字节为版本号,必须保证新的版本号大于等于GT9147内部
  27. *flash原有版本号,才会更新配置.
  28. */
  29. static u8 gt9271_cfg_data[]=
  30. {
  31.         0x41,0x00,0x05,0x20,0x03,0x0A,0x3d,0x20,0x01,0x0A,
  32.         0x28,0x0F,0x6E,0x5A,0x03,0x05,0x00,0x00,0x00,0x00,
  33.         0x00,0x00,0x00,0x18,0x1A,0x1E,0x14,0x8F,0x2F,0xAA,
  34.         0x26,0x24,0x0C,0x08,0x00,0x00,0x00,0x81,0x03,0x2D,
  35.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  36.         0x00,0x1A,0x3C,0x94,0xC5,0x02,0x07,0x00,0x00,0x04,
  37.         0x9E,0x1C,0x00,0x89,0x21,0x00,0x77,0x27,0x00,0x68,
  38.         0x2E,0x00,0x5B,0x37,0x00,0x5B,0x00,0x00,0x00,0x00,
  39.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  40.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  41.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  42.         0x00,0x00,0x19,0x18,0x17,0x16,0x15,0x14,0x11,0x10,
  43.         0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,
  44.         0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  45.         0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,
  46.         0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,
  47.         0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
  48.         0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
  49.         0x00,0x00,0x00,0x00,0x5D,0x01,
  50. };

  51. /*
  52. *GT9147配置参数表
  53. *第一个字节为版本号,必须保证新的版本号大于等于GT9147内部
  54. *flash原有版本号,才会更新配置.
  55. */
  56. static u8 gt9147_cfg_data[]=
  57. {
  58.         0x41,0x20,0x03,0xE0,0x01,0x05,0x0d,0x00,0x01,0x08,
  59.         0x28,0x05,0x50,0x32,0x03,0x05,0x00,0x00,0xff,0xff,
  60.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x28,0x0a,
  61.         0x17,0x15,0x31,0x0d,0x00,0x00,0x02,0x9b,0x03,0x25,
  62.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,
  63.         0x00,0x0f,0x94,0x94,0xc5,0x02,0x07,0x00,0x00,0x04,
  64.         0x8d,0x13,0x00,0x5c,0x1e,0x00,0x3c,0x30,0x00,0x29,
  65.         0x4c,0x00,0x1e,0x78,0x00,0x1e,0x00,0x00,0x00,0x00,
  66.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  67.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  68.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  69.         0x00,0x00,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,
  70.         0x18,0x1a,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,
  71.         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  72.         0xff,0xff,0x00,0x02,0x04,0x05,0x06,0x08,0x0a,0x0c,
  73.         0x0e,0x1d,0x1e,0x1f,0x20,0x22,0x24,0x28,0x29,0xff,
  74.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
  75.         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  76.         0xff,0xff,0xff,0xff,
  77. };

  78. /* 自定义结构体,用于描述goodix触摸屏设备 */
  79. struct goodix_gt9xx_dev {
  80.         struct i2c_client *client;
  81.         struct input_dev *input;
  82.         int max_support_points;                //支持的最大触摸点数
  83.         int abs_x_max;                                //X轴最大值
  84.         int abs_y_max;                                //Y轴最大值
  85.         int reset_gpio;
  86.         int irq_gpio;
  87. };

  88. /* goodix触摸IC信息 */
  89. struct goodix_i2c_chip_data {
  90.         int max_support_points;                //支持的最大触摸点数
  91.         int abs_x_max;                                //X轴最大值
  92.         int abs_y_max;                                //Y轴最大值
  93.         int (*chip_cfg)(struct goodix_gt9xx_dev *);        //配置函数
  94. };

  95. static int goodix_gt9xx_ts_write(struct goodix_gt9xx_dev *gt9xx,
  96.                         u16 addr, u8 *buf, u16 len)
  97. {
  98.         struct i2c_client *client = gt9xx->client;
  99.         struct i2c_msg msg;
  100.         u8 send_buf[190] = {0};                //gt9147/gt9271最大配置长度+4
  101.         int ret;

  102.         send_buf[0] = addr >> 8;
  103.         send_buf[1] = addr & 0xFF;
  104.         memcpy(&send_buf[2], buf, len);

  105.         msg.flags = 0;                        //i2c写
  106.         msg.addr = client->addr;
  107.         msg.buf = send_buf;
  108.         msg.len = len + 2;

  109.         ret = i2c_transfer(client->adapter, &msg, 1);
  110.         if (1 == ret)
  111.                 return 0;
  112.         else {
  113.                 dev_err(&client->dev, "%s: write error, addr=0x%x len=%d.\n",
  114.                                         __func__, addr, len);
  115.                 return -1;
  116.         }
  117. }

  118. static int goodix_gt9xx_ts_read(struct goodix_gt9xx_dev *gt9xx,
  119.                         u16 addr, u8 *buf, u16 len)
  120. {
  121.         struct i2c_client *client = gt9xx->client;
  122.         struct i2c_msg msg[2];
  123.         u8 send_buf[2];
  124.         int ret;

  125.         send_buf[0] = addr >> 8;
  126.         send_buf[1] = addr & 0xFF;

  127.         msg[0].flags = 0;                        // i2c写
  128.         msg[0].addr = client->addr;
  129.         msg[0].buf = send_buf;
  130.         msg[0].len = 2;                                // 2个字节

  131.         msg[1].flags = I2C_M_RD;        //i2c读
  132.         msg[1].addr = client->addr;
  133.         msg[1].buf = buf;
  134.         msg[1].len = len;

  135.         ret = i2c_transfer(client->adapter, msg, 2);
  136.         if (2 == ret)
  137.                 return 0;
  138.         else {
  139.                 dev_err(&client->dev, "%s: read error, addr=0x%x len=%d.\n",
  140.                                         __func__, addr, len);
  141.                 return -1;
  142.         }
  143. }

  144. static int goodix_gt9147_cfg(struct goodix_gt9xx_dev *gt9xx)
  145. {
  146.         struct i2c_client *client = gt9xx->client;
  147.         u8 buf[5] = {0};
  148.         int i;

  149.         /* 读取Chip ID */
  150.         goodix_gt9xx_ts_read(gt9xx, GOODIX_REG_ID, buf, 4);
  151.         dev_info(&client->dev, "Chip ID: %s\n",  buf);

  152.         /* 软件复位 */
  153.         buf[0] = 0x2;
  154.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_COMMAND, buf, 1);

  155.         /* 设置写入版本号以及分辨率 */
  156.         goodix_gt9xx_ts_read(gt9xx, GOODIX_REG_CFG_DATA, buf, 1);
  157.         gt9147_cfg_data[0] = buf[0];        //写入版本号等于IC原有版本号
  158.         gt9147_cfg_data[1] = gt9xx->abs_x_max & 0xFF;
  159.         gt9147_cfg_data[2] = (gt9xx->abs_x_max & 0xFF00) >> 8;
  160.         gt9147_cfg_data[3] = gt9xx->abs_y_max & 0xFF;
  161.         gt9147_cfg_data[4] = (gt9xx->abs_y_max & 0xFF00) >> 8;

  162.         /* 计算校验和 */
  163.         buf[0] = 0;
  164.         buf[1] = 1;
  165.         for(i = 0; i < sizeof(gt9147_cfg_data); i++)
  166.                 buf[0] += gt9147_cfg_data[i];
  167.         buf[0] = (~buf[0]) + 1;

  168.         /* 配置寄存器 */
  169.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_CFG_DATA,
  170.                                 gt9147_cfg_data, sizeof(gt9147_cfg_data));
  171.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_CFG_CSM, buf, 2);        // 写入校验和,更新配置

  172.         /* 结束软件复位,回到读坐标模式 */
  173.         msleep(1);
  174.         buf[0] = 0x0;
  175.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_COMMAND, buf, 1);
  176.         goodix_gt9xx_ts_write(gt9xx, GOODIX_READ_COOR_ADDR, buf, 1);

  177.         return 0;
  178. }

  179. static int goodix_gt9271_cfg(struct goodix_gt9xx_dev *gt9xx)
  180. {
  181.         struct i2c_client *client = gt9xx->client;
  182.         u8 buf[5] = {0};
  183.         int i;

  184.         /* 读取Chip ID */
  185.         goodix_gt9xx_ts_read(gt9xx, GOODIX_REG_ID, buf, 4);
  186.         dev_info(&client->dev, "Chip ID: %s\n",  buf);

  187.         /* 软件复位 */
  188.         buf[0] = 0x2;
  189.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_COMMAND, buf, 1);

  190.         /* 读取配置文件版本号 */
  191.         goodix_gt9xx_ts_read(gt9xx, GOODIX_REG_CFG_DATA, buf, 1);
  192.         gt9271_cfg_data[0] = buf[0];        //写入版本号等于IC原有版本号
  193.         gt9271_cfg_data[1] = gt9xx->abs_x_max & 0xFF;
  194.         gt9271_cfg_data[2] = (gt9xx->abs_x_max & 0xFF00) >> 8;
  195.         gt9271_cfg_data[3] = gt9xx->abs_y_max & 0xFF;
  196.         gt9271_cfg_data[4] = (gt9xx->abs_y_max & 0xFF00) >> 8;

  197.         /* 计算校验和 */
  198.         buf[0] = 0;
  199.         buf[1] = 1;
  200.         for(i = 0; i < sizeof(gt9271_cfg_data) - 2; i++)
  201.                 buf[0] += gt9271_cfg_data[i];
  202.         buf[0] = (~buf[0]) + 1;

  203.         /* 配置寄存器 */
  204.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_CFG_DATA,
  205.                                 gt9271_cfg_data, sizeof(gt9271_cfg_data));
  206.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_CFG_CSM, buf, 2);        // 写入校验和,更新配置

  207.         /* 结束软件复位,回到读坐标模式 */
  208.         msleep(1);
  209.         buf[0] = 0x0;
  210.         goodix_gt9xx_ts_write(gt9xx, GOODIX_REG_COMMAND, buf, 1);
  211.         goodix_gt9xx_ts_write(gt9xx, GOODIX_READ_COOR_ADDR, buf, 1);

  212.         return 0;
  213. }

  214. static int goodix_gt9xx_ts_reset(struct goodix_gt9xx_dev *gt9xx)
  215. {
  216.         struct i2c_client *client = gt9xx->client;
  217.         int ret;

  218.         /* 从设备树中获取复位管脚和中断管脚 */
  219.         gt9xx->reset_gpio = of_get_named_gpio(client->dev.of_node, "reset-gpio", 0);
  220.         if (!gpio_is_valid(gt9xx->reset_gpio)) {
  221.                 dev_err(&client->dev, "Failed to get ts reset gpio\n");
  222.                 return gt9xx->reset_gpio;
  223.         }

  224.         gt9xx->irq_gpio = of_get_named_gpio(client->dev.of_node, "interrupt-gpio", 0);
  225.         if (!gpio_is_valid(gt9xx->irq_gpio)) {
  226.                 dev_err(&client->dev, "Failed to get ts interrupt gpio\n");
  227.                 return gt9xx->irq_gpio;
  228.         }

  229.         /* 申请使用管脚 */
  230.         ret = devm_gpio_request_one(&client->dev, gt9xx->reset_gpio,
  231.                                 GPIOF_OUT_INIT_HIGH, "gt9xx reset PIN");
  232.         if (ret < 0)
  233.                 return ret;

  234.         ret = devm_gpio_request_one(&client->dev, gt9xx->irq_gpio,
  235.                                 GPIOF_OUT_INIT_HIGH, "gt9xx interrupt PIN");
  236.         if (ret < 0)
  237.                 return ret;

  238.         /*
  239.          *硬件复位开始
  240.          *这里严格按照官方参考手册提供的复位时序
  241.          */
  242.         msleep(5);

  243.         /* begin select I2C slave addr */
  244.         gpio_set_value_cansleep(gt9xx->reset_gpio, 0);
  245.         msleep(20);                                        /* T2: > 10ms */

  246.         /* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
  247.         gpio_set_value_cansleep(gt9xx->irq_gpio, client->addr == 0x14);
  248.         usleep_range(200, 1000);        /* T3: > 100us */
  249.         gpio_set_value_cansleep(gt9xx->reset_gpio, 1);
  250.         msleep(10);                                        /* T4: > 5ms */

  251.         /* end select I2C slave addr */
  252.         gpio_direction_input(gt9xx->reset_gpio);

  253.         /* 中断管脚拉低 */
  254.         gpio_set_value_cansleep(gt9xx->irq_gpio, 0);
  255.         msleep(50);                                        /* T5: 50ms */

  256.         /* 将中断引脚设置为输入模式 */
  257.         gpio_direction_input(gt9xx->irq_gpio);
  258.         return 0;
  259. }

  260. static int goodix_gt9xx_ts_get_points(struct goodix_gt9xx_dev *gt9xx, u8 *buf)
  261. {
  262.         u8 state = 0;
  263.         int touch_num = 0;
  264.         int ret;

  265.         ret = goodix_gt9xx_ts_read(gt9xx, GOODIX_READ_COOR_ADDR, &state, 1);
  266.         if (ret)
  267.                 return ret;

  268.         if ((state & 0x80) == 0)                // 判断数据是否准备好
  269.                 return -1;

  270.         touch_num = state & 0x0F;                // 获取触摸点数
  271.         if (touch_num > gt9xx->max_support_points) {
  272.                 touch_num = -1;
  273.                 goto out;
  274.         }

  275.         if (touch_num) {
  276.                 /* 读取触摸点坐标数据,从0x814F寄存器开始读取
  277.                  * 其中每一个触摸点使用8个寄存器来描述
  278.                  * 以第一个触摸点为例,各寄存器描述信息如下:
  279.                  * 0x814F: 触摸点id
  280.                  * 0x8150: 触摸点X轴坐标低位字节
  281.                  * 0x8151: 触摸点X轴坐标高位字节
  282.                  * 0x8152: 触摸点Y轴坐标低位字节
  283.                  * 0x8153: 触摸点Y轴坐标高位字节
  284.                  * 0x8154~0x8155: 触摸点的大小信息,我们不需要
  285.                  * 0x8156: 保留
  286.                  */
  287.                 ret = goodix_gt9xx_ts_read(gt9xx, GOODIX_READ_COOR_ADDR + 1,
  288.                                         buf, 8 * touch_num);
  289.                 if (ret)
  290.                         touch_num = -1;
  291.         }

  292. out:
  293.         state = 0x0;
  294.         goodix_gt9xx_ts_write(gt9xx, GOODIX_READ_COOR_ADDR, &state, 1);        //清buffer
  295.         return touch_num;
  296. }

  297. static irqreturn_t goodix_gt9xx_ts_isr(int irq, void *dev_id)
  298. {
  299.         struct goodix_gt9xx_dev *gt9xx = dev_id;
  300.         static int pre_touch = 0;                //上一次触摸点数
  301.         static int pre_ids[10] = {0};        //上一次触摸点的id
  302.         int cur_touch = 0;                                //当前触摸点数
  303.         int cur_ids[10] = {0};                        //当前触摸点的id
  304.         u8 rdbuf[8 * 10] = {0};                        //gt9147最大支持10点触摸
  305.         int i, x, y, id;

  306.         /* 读取触摸点坐标信息 */
  307.         cur_touch = goodix_gt9xx_ts_get_points(gt9xx, rdbuf);
  308.         if (cur_touch < 0)
  309.                 goto out;

  310.         /* 上报触摸屏按下相关事件 */
  311.         for (i = 0; i < cur_touch; i++) {

  312.                 u8 *buf = &rdbuf[i * 8];
  313.                 id = buf[0];
  314.                 x = (buf[2] << 8) | buf[1];
  315.                 y = (buf[4] << 8) | buf[3];

  316.                 input_mt_slot(gt9xx->input, id);
  317.                 input_mt_report_slot_state(gt9xx->input, MT_TOOL_FINGER, true);
  318.                 input_report_abs(gt9xx->input, ABS_MT_POSITION_X, x);
  319.                 input_report_abs(gt9xx->input, ABS_MT_POSITION_Y, y);
  320.                 cur_ids[i] = id;
  321.         }

  322.         /* 上报触摸屏松开相关事件 */
  323.         for (i = 0; i < pre_touch; i++) {

  324.                 int j;
  325.                 for (j = 0; j < cur_touch; j++) {

  326.                         if (pre_ids[i] == cur_ids[j])
  327.                                 break;
  328.                 }

  329.                 if (j == cur_touch) {        //表示当前触摸点中不存在这个pre_ids[i]id,表示它已经松开了
  330.                         input_mt_slot(gt9xx->input, pre_ids[i]);
  331.                         input_mt_report_slot_state(gt9xx->input, MT_TOOL_FINGER, false);
  332.                 }
  333.         }

  334.         input_mt_report_pointer_emulation(gt9xx->input, true);
  335.         input_sync(gt9xx->input);

  336.         for (i = 0; i < cur_touch; i++)
  337.                 pre_ids[i] = cur_ids[i];
  338.         pre_touch = cur_touch;

  339. out:
  340.         return IRQ_HANDLED;
  341. }

  342. static int goodix_gt9xx_ts_irq(struct goodix_gt9xx_dev *gt9xx)
  343. {
  344.         struct i2c_client *client = gt9xx->client;
  345.         int ret;

  346.         /* 注册中断服务函数 */
  347.         ret = devm_request_threaded_irq(&client->dev, client->irq,
  348.                                 NULL, goodix_gt9xx_ts_isr, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  349.                                 client->name, gt9xx);
  350.         if (ret) {
  351.                 dev_err(&client->dev, "Failed to request touchscreen IRQ.\n");
  352.                 return ret;
  353.         }

  354.         return 0;
  355. }

  356. static int goodix_gt9xx_ts_probe(struct i2c_client *client,
  357.                         const struct i2c_device_id *id)
  358. {
  359.         struct goodix_gt9xx_dev *gt9xx;
  360.         const struct goodix_i2c_chip_data *chip_data;
  361.         struct input_dev *input;
  362.         int ret;

  363.         /* 实例化一个struct goodix_gt9xx_dev对象 */
  364.         gt9xx = devm_kzalloc(&client->dev, sizeof(struct goodix_gt9xx_dev), GFP_KERNEL);
  365.         if (!gt9xx) {
  366.                 dev_err(&client->dev, "Failed to allocate ts driver data.\n");
  367.                 return -ENOMEM;
  368.         }

  369.         gt9xx->client = client;

  370.         /* 获取gt9147、gt9271不同IC对应的信息 */
  371.         chip_data = of_device_get_match_data(&client->dev);
  372.         gt9xx->max_support_points = chip_data->max_support_points;
  373.         gt9xx->abs_x_max = chip_data->abs_x_max;
  374.         gt9xx->abs_y_max = chip_data->abs_y_max;

  375.         /* 复位GT9xx触摸芯片 */
  376.         ret = goodix_gt9xx_ts_reset(gt9xx);
  377.         if (ret)
  378.                 return ret;

  379.         msleep(5);

  380.         /* 初始化GT9xx */
  381.         ret = chip_data->chip_cfg(gt9xx);
  382.         if (ret)
  383.                 return ret;

  384.         /* 申请、注册中断服务函数 */
  385.         ret = goodix_gt9xx_ts_irq(gt9xx);
  386.         if (ret)
  387.                 return ret;

  388.         /* 注册input设备 */
  389.         input = devm_input_allocate_device(&client->dev);
  390.         if (!input) {
  391.                 dev_err(&client->dev, "Failed to allocate input device.\n");
  392.                 return -ENOMEM;
  393.         }

  394.         gt9xx->input = input;
  395.         input->name = "Goodix GT9xx TouchScreen";
  396.         input->id.bustype = BUS_I2C;

  397.         input_set_abs_params(input, ABS_MT_POSITION_X,
  398.                                 0, gt9xx->abs_x_max, 0, 0);
  399.         input_set_abs_params(input, ABS_MT_POSITION_Y,
  400.                                 0, gt9xx->abs_y_max, 0, 0);

  401.         ret = input_mt_init_slots(input, gt9xx->max_support_points,
  402.                                 INPUT_MT_DIRECT);
  403.         if (ret) {
  404.                 dev_err(&client->dev, "Failed to init MT slots.\n");
  405.                 return ret;
  406.         }

  407.         ret = input_register_device(input);
  408.         if (ret)
  409.                 return ret;

  410.         i2c_set_clientdata(client, gt9xx);
  411.         return 0;
  412. }

  413. static int goodix_gt9xx_ts_remove(struct i2c_client *client)
  414. {
  415.         struct goodix_gt9xx_dev *gt9xx = i2c_get_clientdata(client);
  416.         input_unregister_device(gt9xx->input);
  417.         return 0;
  418. }

  419. static const struct goodix_i2c_chip_data goodix_gt9147_data = {
  420.         .max_support_points = 5,
  421.         .abs_x_max = 800,                //以4.3寸800*480屏幕为例
  422.         .abs_y_max = 480,                //如果是4.3寸480*272,这里要改
  423.         .chip_cfg = goodix_gt9147_cfg,
  424. };

  425. static const struct goodix_i2c_chip_data goodix_gt9271_data = {
  426.         .max_support_points = 10,
  427.         .abs_x_max = 1280,
  428.         .abs_y_max = 800,
  429.         .chip_cfg = goodix_gt9271_cfg,
  430. };

  431. static const struct of_device_id goodix_gt9xx_of_match[] = {
  432.         { .compatible = "goodix,gt9147", .data = &goodix_gt9147_data },
  433.         { .compatible = "goodix,gt9271", .data = &goodix_gt9271_data },
  434.         { /* sentinel */ }
  435. };
  436. MODULE_DEVICE_TABLE(of, goodix_gt9xx_of_match);

  437. static struct i2c_driver goodix_gt9xx_ts_driver = {
  438.         .driver = {
  439.                 .owner                        = THIS_MODULE,
  440.                 .name                        = "goodix-gt9xx",
  441.                 .of_match_table        = of_match_ptr(goodix_gt9xx_of_match),
  442.         },
  443.         .probe    = goodix_gt9xx_ts_probe,
  444.         .remove   = goodix_gt9xx_ts_remove,
  445. };

  446. module_i2c_driver(goodix_gt9xx_ts_driver);

  447. MODULE_AUTHOR("Deng Tao <773904075@qq.com>, ALIENTEK, Inc.");
  448. MODULE_DESCRIPTION("Goodix gt9147/gt9271 I2C Touchscreen Driver");
  449. MODULE_LICENSE("GPL");
复制代码


设备树配置:
  1. gt9xx: ts@5d {
  2.         compatible = "goodix,gt9147";
  3.         //compatible = "goodix,gt9271";
  4.         status = "okay";
  5.         reg = <0x5d>;
  6.         interrupt-parent = <&gpio0>;
  7.         interrupts = <64 0>;
  8.         reset-gpio = <&gpio0 63 GPIO_ACTIVE_LOW>;
  9.         interrupt-gpio = <&gpio0 64 GPIO_ACTIVE_LOW>;
  10. };
复制代码
如果你的触摸IC是GT9147那就将compatible属性设置为"goodix,gt9147",如果是GT9271就将其设置为"goodix,gt9271"。
复位管脚、中断管脚大家根据实际情况修改。
需要注意的是正点原子4.3寸屏有两款,它们的分辨率不同,分别为800*480以及480*272,代码默认支持的是800*480,
如果要改成480*272则需要对驱动代码进行修改,修改位置如下:

驱动源码见附件。

分辨率修改

分辨率修改

gt9xx.zip

4.57 KB, 下载次数: 108

驱动源码文件

森罗万象
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2022-1-12
在线时间
2 小时
发表于 2022-7-9 11:05:59 | 显示全部楼层
楼主,用您的驱动在make的时候报错:隐式声明函数‘of_device_get_match_data’查了一下没找到此函数的头文件
回复 支持 1 反对 0

使用道具 举报

9

主题

776

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5304
金钱
5304
注册时间
2019-9-25
在线时间
438 小时
发表于 2020-8-6 15:14:45 | 显示全部楼层
牛逼!
回复 支持 反对

使用道具 举报

3

主题

187

帖子

0

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
558
金钱
558
注册时间
2019-5-22
在线时间
267 小时
发表于 2020-8-6 19:31:55 | 显示全部楼层
这个要学习一下
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2017-9-13
在线时间
6 小时
发表于 2020-8-12 17:31:28 | 显示全部楼层
刚好学到这个,学习了
回复 支持 反对

使用道具 举报

1

主题

31

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
231
金钱
231
注册时间
2016-2-11
在线时间
68 小时
发表于 2020-10-6 06:27:39 来自手机 | 显示全部楼层
我使用10.1寸液晶屏的触摸屏,用手指控制光标的移动。当光标移动到需要的位置时,手指就松开。由于无法立即检测到手指的动作,光标还会再移动2格。我想了许多办法,都没有解决这个问题。请问大神,手指松开的时刻,该芯片就没有反应吗?此芯片的应用手册似乎没有公开,也找不到。求大神赐教!!
回复 支持 反对

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2179
金钱
2179
注册时间
2018-8-27
在线时间
258 小时
 楼主| 发表于 2020-10-9 09:33:33 | 显示全部楼层
fuda 发表于 2020-10-6 06:27
我使用10.1寸液晶屏的触摸屏,用手指控制光标的移动。当光标移动到需要的位置时,手指就松开。由于无法立即 ...

单点触摸情况下,手指松开的时候,触摸点的数量会变成0,这个可以读取到的
森罗万象
回复 支持 反对

使用道具 举报

5

主题

27

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2020-5-30
在线时间
19 小时
发表于 2020-10-15 13:38:52 | 显示全部楼层
大佬牛逼
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2020-8-1
在线时间
5 小时
发表于 2021-9-7 16:48:32 | 显示全部楼层
楼主牛逼,加油
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2020-8-1
在线时间
5 小时
发表于 2021-9-7 16:49:30 | 显示全部楼层
请问,系统里面有自带gt9147的驱动吗
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2022-10-14
在线时间
9 小时
发表于 2022-11-3 10:03:22 | 显示全部楼层
hefengzxp 发表于 2022-7-9 11:05
楼主,用您的驱动在make的时候报错:隐式声明函数‘of_device_get_match_data’查了一下没找到此函数的头文 ...

我也是,请问你找到原因了没
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2022-10-14
在线时间
9 小时
发表于 2022-11-3 10:07:45 | 显示全部楼层
大佬,我把你的代码编译了一遍,发现of_device_get_match_data那里隐式声明错误,请问这个怎么解决??
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-23 14:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表