设备树学习 您所在的位置:网站首页 触摸电脑屏幕是电容屏吗 设备树学习

设备树学习

2024-06-29 19:37| 来源: 网络整理| 查看: 265

首先,分析下 FT5406 的基本电路接口: 基本都是通用的接口,如 I2C 接口,INT,WAKE,RST。如图:

以上可知,我们在驱动中必须定义一个中断口,来启动接收触摸数据,一个gpio脚来复位FT5406。wake:主要靠cpu发送一个唤醒指令给FT5406。 查看tiny4412原理图

再次,需确认FT5406的从地址,以便于I2C访问得到。这个可以根据FT5406数据手册查找到.

可知从地址高位必须为:3,低位必须根据 i2ccon 设定的值来确定,这点很奇怪。 我这边找到的从地址为:0x38 i2ccon 暂时未找到出处,可以用 i2c tools 探测一下

/mnt # ./i2cdetect -y 1                                                  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f                 00:          -- -- -- -- -- -- -- -- -- -- -- -- --                 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                 30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --                 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                 70: -- -- -- -- -- -- -- --  基本的东西确认好后,剩下的就是根据FT5406数据手册上的指令,开始写驱动了。 在此之前,我们先了解下驱动如何实现电容屏的多点触摸,其实很简单,主要需要 触摸屏IC FT5406 能够捕获多点数据,这点电容屏基本多能支持到捕获2点以上,而FT5406 可以捕获5个触摸点,编写驱动时,只要去获取这几个点的数据,然后上报就行。格式如图:

解释:

02h : 捕获的触摸点个数 03h- 1eh :对应每个点的x,y坐标数值。 touch id 表示触点编号,对应于typeB的slot

驱动参考:Ft6236.c (drivers\input\touchscreen)

touch_demo{     compatible = "tiny4412,touch_demo";     interrupts = ;         interrupt-parent = ;         status = "okay"; }; &i2c_1{         status = "okay";         touch@38{                 compatible = "tiny4412,touch";                 reg = ;         }; }; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

#define uchar unsigned char

static void touch_read_handler(struct work_struct *work); DECLARE_WORK(touch_read_work, touch_read_handler);

static struct i2c_client *touch_client; static struct input_dev *touch_dev; static int irq;

static void touch_read(unsigned char sAddr, unsigned char *buf, unsigned int len) {     struct i2c_msg msg[2];     int i, ret;     unsigned char address;     for (i = 0; i < len; i++)     {         /* 先写入要读取的寄存器地址 */         address = sAddr + i;         msg[0].addr  = touch_client->addr;    /* 目的 */         msg[0].buf   = &address;              /* 源 */         msg[0].len   = 1;                     /* 地址=1 byte */         msg[0].flags = 0;                     /* 表示写 */

        /* 然后启动读操作 */         msg[1].addr  = touch_client->addr;    /* 源 */         msg[1].buf   = &buf[i];               /* 目的 */         msg[1].len   = 1;                     /* 数据=1 byte */         msg[1].flags = I2C_M_RD;              /* 表示读 */         ret = i2c_transfer(touch_client->adapter, msg, 2);         if (ret < 0)         {             printk("i2c_transfer eror\n");         }         mdelay(10);     }

}

static void touch_read_handler(struct work_struct *work) {     unsigned char buf[13];     unsigned char touches, i, event, id;     unsigned short x, y;     bool act;     /* read tp resister by i2c */     touch_read(0x00, buf, 13);

    /* number of touch points */     touches = buf[2] & 0x0f;     //printk("point num %d\n", touches);

    if (touches > 2) {         printk("%s touch read touches error\n",__func__);         touches = 2;     }

    for (i = 0; i < touches; i++) {         y = ((buf[5 + i * 6] & 0x0f) 6;    //event flags         id = buf[5 + i * 6] >> 4;       //touch id         //printk("event %d id %d\n", event, id);

        //down or contact         act = (event == 0x00 || event == 0x02);

        input_mt_slot(touch_dev, id);         input_mt_report_slot_state(touch_dev, MT_TOOL_FINGER, act);

        //if up return         if (!act)             continue;

        input_report_abs(touch_dev, ABS_MT_POSITION_X, x);         input_report_abs(touch_dev, ABS_MT_POSITION_Y, y);       }

    input_mt_sync_frame(touch_dev);     input_sync(touch_dev);

}

static irqreturn_t touch_isr(int irq, void *dev_id) {     schedule_work(&touch_read_work);

    return IRQ_HANDLED; }

static int touch_probe(struct i2c_client *client,                          const struct i2c_device_id *id) {     unsigned char buf;     int ret;

    touch_client = client;     printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

    touch_read(0xa3, &buf, 1);     printk("Chip vendor ID  %x\n", buf);

    touch_read(0xa6, &buf, 1);     printk("Firmware ID %x\n", buf);

    touch_read(0xa8, &buf, 1);     printk("CTPM Vendor ID %x\n", buf);

    touch_read(0x00, &buf, 1);     printk("DEVIDE_MODE %x\n", buf);

    touch_read(0x80, &buf, 1);     printk("ID_G_THGROUP. %x\n", buf);

    touch_read(0x88, &buf, 1);     printk("ID_G_PERIODACTIVE. %x\n", buf);

    touch_dev = input_allocate_device();     if (touch_dev == NULL)     {         printk("%s, allocate input device, error\n", __func__);         return -1;     }

    //告诉input能够支持哪些事件     input_set_abs_params(touch_dev, ABS_MT_POSITION_X, 0, 800, 0, 0);     input_set_abs_params(touch_dev, ABS_MT_POSITION_Y, 0, 480, 0, 0);     ret = input_mt_init_slots(touch_dev, 2, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);     if (ret)     {         printk("%s, input_mt_init_slots error\n", __func__);         return ret;     }     touch_dev->name = "touch";     touch_dev->id.bustype = BUS_I2C;     touch_dev->dev.parent = &(touch_client)->dev;     ret = input_register_device(touch_dev);     if (ret)     {         printk("%s, register input device, error\n", __func__);         return ret;     }

    printk("irq is %d\n", irq); 

    ret = devm_request_threaded_irq(&touch_client->dev, irq, touch_isr, NULL, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "touch1", NULL);

    if (ret < 0)     {         printk("failed to request_irq %d\n", ret);     }

    return 0; }

static int touch_remove(struct i2c_client *client) {

    return 0; }

static const struct i2c_device_id touch_id_table[] = {     { "touch", 0 },     {} };

/* 1. 分配/设置i2c_driver */ static struct i2c_driver touch_driver = {     .driver = {         .name   = "touch",         .owner  = THIS_MODULE,     },     .probe      = touch_probe,     .remove     = touch_remove,     .id_table   = touch_id_table, };

static int int_demo_remove(struct platform_device *pdev) {

    printk("%s enter.\n", __func__);

    return 0; }

static int int_demo_probe(struct platform_device *pdev) {     irq = platform_get_irq(pdev, 0);     printk("int_demo_probe %d\n", irq);     return 0; }

static const struct of_device_id touch_demo_dt_ids[] = {     { .compatible = "tiny4412,touch_demo", },     {}, }; MODULE_DEVICE_TABLE(of, touch_demo_dt_ids); static struct platform_driver touch_demo_driver = {     .driver        = {         .name      = "touch_demo",         .of_match_table    = of_match_ptr(touch_demo_dt_ids),     },     .probe         = int_demo_probe,     .remove        = int_demo_remove, };

static int touch_drv_init(void) {     int ret;     /* 1.注册平台设备驱动 */     ret = platform_driver_register(&touch_demo_driver);     if (ret)         printk(KERN_ERR "int demo: probe failed: %d\n", ret);     /* 2. 注册i2c_driver */     i2c_add_driver(&touch_driver);

    return 0; }

static void touch_drv_exit(void) {     i2c_del_driver(&touch_driver);     platform_driver_unregister(&touch_demo_driver); }

module_init(touch_drv_init); module_exit(touch_drv_exit); MODULE_LICENSE("GPL");  



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有