zoukankan      html  css  js  c++  java
  • gt811 driver

      1. #include <linux/module.h>  
      2. #include <linux/i2c.h>  
      3. #include <linux/platform_device.h>  
      4. #include <linux/gpio.h>  
      5. #include <linux/of.h>  
      6. #include <linux/of_platform.h>  
      7. #include <linux/of_gpio.h>  
      8. #include <linux/input.h>  
      9. #include <linux/input/mt.h>  
      10. #include <linux/interrupt.h>  
      11. #include <linux/delay.h>  
      12.   
      13. struct gt811_ts_platdata  
      14. {  
      15.     u32 size_x;  
      16.     u32 size_y;  
      17.     u32 size_p;  
      18.     u32 swap;  
      19.     u32 revert_x;  
      20.     u32 revert_y;  
      21.     u32 reset_pin;  
      22.     u32 interrupt_pin;  
      23.     u32 ponits_max;  
      24.     struct i2c_client *client;  
      25.     struct input_dev *input;  
      26.     struct work_struct work;  
      27. };  
      28.   
      29. static const struct of_device_id gt811_ts_of_match[] = {  
      30.     { .compatible = "gt811,gt811_ts", .data = NULL },  
      31.     { }  
      32. };  
      33.   
      34. static int i2c_write_bytes(struct i2c_client *client, uint8_t *data, int len){  
      35.     struct i2c_msg msg;  
      36.   
      37.     msg.flags=!I2C_M_RD;  
      38.     msg.addr=client->addr;  
      39.     msg.len=len;  
      40.     msg.buf=data;  
      41.   
      42.     return i2c_transfer(client->adapter,&msg, 1);  
      43. }  
      44.   
      45. static int i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len){  
      46.     struct i2c_msg msgs[2];  
      47.   
      48.     msgs[0].flags=!I2C_M_RD;  
      49.     msgs[0].addr=client->addr;  
      50.     msgs[0].len=2;  
      51.     msgs[0].buf=&buf[0];  
      52.   
      53.     msgs[1].flags=I2C_M_RD;  
      54.     msgs[1].addr=client->addr;  
      55.     msgs[1].len=len-2;  
      56.     msgs[1].buf=&buf[2];  
      57.   
      58.     return i2c_transfer(client->adapter,msgs, 2);  
      59. }  
      60. static void gt811_ts_handler(struct work_struct *work)  
      61. {  
      62.     struct gt811_ts_platdata *pdata = container_of(work, struct gt811_ts_platdata, work);  
      63.     struct device *dev = &pdata->client->dev;  
      64.     uint8_t buffer[36] = {0x07, 0x21, 0};  
      65.     uint8_t count, index, flags, position;  
      66.     int x, y;  
      67.   
      68.     buffer[0] = 0x0f;  
      69.     buffer[1] = 0xff;  
      70.     if (i2c_write_bytes(pdata->client,buffer,2) < 0) {  
      71.         dev_err(dev, "Failed to write wakeup message. ");  
      72.         goto reenable_irq;  
      73.     }  
      74.   
      75.     buffer[0] = 0x07;  
      76.     buffer[1] = 0x21;  
      77.     if (i2c_read_bytes(pdata->client, buffer, sizeof(buffer)) < 0) {  
      78.         dev_err(dev, "Failed to read touch message. ");  
      79.         goto reenable_irq;  
      80.     }  
      81.   
      82.     buffer[0] = 0x80;  
      83.     buffer[1] = 0x00;  
      84.     if (i2c_write_bytes(pdata->client, buffer, 2) < 0) {  
      85.         dev_err(dev, "Failed to write sleep message. ");  
      86.         goto reenable_irq;  
      87.     }  
      88.   
      89.     buffer[25] = buffer[19];  
      90.     buffer[19] = 0;  
      91.   
      92.     flags = buffer[2]&0x1f;  
      93.   
      94.     while (flags) {  
      95.         if (!(flags&0x1)) {  
      96.             continue;  
      97.         }  
      98.   
      99.         if (index < 3) {  
      100.             position = 4 + index * 5;  
      101.         }  
      102.         else{  
      103.             position = 25 + (index - 3) * 5;  
      104.         }  
      105.   
      106.         x = (buffer[position] << 8) | buffer[position + 1];  
      107.         y = (buffer[position + 2] << 8) | buffer[position + 3];  
      108.   
      109.         if(pdata->swap) {  
      110.             swap(x, y);  
      111.         }  
      112.         if(pdata->revert_x){  
      113.             x = pdata->size_x - x;  
      114.         }  
      115.         if(pdata->revert_y){  
      116.             y = pdata->size_y - y;  
      117.         }  
      118.   
      119.         printk("point:(x:%03d, y:%03d) ", x, y);  
      120.     }  
      121.   
      122.     // 组织检测出来的触摸点信息上报到输入子系统节点即可  
      123.   
      124. reenable_irq:  
      125.     enable_irq(pdata->client->irq);  
      126. }  
      127.   
      128. static irqreturn_t gt811_ts_isr(int irq, void *dev_id)  
      129. {  
      130.     struct gt811_ts_platdata* pdata = (struct gt811_ts_platdata*)dev_id;  
      131.   
      132.     disable_irq_nosync(pdata->client->irq);  
      133.     schedule_work(&pdata->work);  
      134.   
      135.     return IRQ_HANDLED;  
      136. }  
      137.   
      138. static int gt811_ts_initilize(struct i2c_client *client)  
      139. {  
      140.     struct device *dev = &client->dev;  
      141.     struct gt811_ts_platdata *pdata = (struct gt811_ts_platdata*)i2c_get_clientdata(client);  
      142.     int status = 0, count = 0;  
      143.     uint8_t version[4] = {0x7, 0x17, 0};  
      144.     uint8_t config[] = {  
      145.         0x06,0xA2,  
      146.         0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0xE2,0x53,0xD2,0x53,0xC2,0x53,  
      147.         0xB2,0x53,0xA2,0x53,0x92,0x53,0x82,0x53,0x72,0x53,0x62,0x53,0x52,0x53,0x42,0x53,  
      148.         0x32,0x53,0x22,0x53,0x12,0x53,0x02,0x53,0xF2,0x53,0x0F,0x13,0x40,0x40,0x40,0x10,  
      149.         0x10,0x10,0x0F,0x0F,0x0A,0x35,0x25,0x0C,0x03,0x00,0x05,0x20,0x03,0xE0,0x01,0x00,  
      150.         0x00,0x34,0x2C,0x36,0x2E,0x00,0x00,0x03,0x19,0x03,0x08,0x00,0x00,0x00,0x00,0x00,  
      151.         0x14,0x10,0xEC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x40,  
      152.         0x30,0x3C,0x28,0x00,0x00,0x00,0x00,0xC0,0x12,0x01  
      153.     };  
      154.   
      155.     config[62] = 480 >> 8;  
      156.     config[61] = 480 & 0xff;  
      157.     config[64] = 800 >> 8;  
      158.     config[63] = 800 & 0xff;  
      159.   
      160.     if (!gpio_is_valid(pdata->reset_pin)) {  
      161.         dev_err(dev, "The reset pin number is invalid. ");  
      162.         return -EINVAL;  
      163.     }  
      164.   
      165.     count = 3;  
      166.     while (count--) {  
      167.         gpio_direction_output(pdata->reset_pin, 0);  
      168.         msleep(10);  
      169.         gpio_direction_output(pdata->reset_pin, 1);  
      170.         msleep(100);  
      171.   
      172.         if (i2c_read_bytes(client, version, sizeof(version)) < 0) {  
      173.             dev_err(dev, "Failed to get the version of GT811, try again... ");  
      174.             status = -ENODEV;  
      175.         }  
      176.         else {  
      177.             dev_info(dev, "Gt811 detected, version(%04x)... ", (version[2]<<8)|version[3]);  
      178.             status = 0;  
      179.             break;  
      180.         }  
      181.     }  
      182.   
      183.     if (status) {  
      184.         return status;  
      185.     }  
      186.   
      187.     count = 3;  
      188.     while (count--) {  
      189.         if (i2c_write_bytes(client, config, sizeof(config)) < 0) {  
      190.             dev_err(dev, "Failed to configure the GT811, try again... ");  
      191.             status = -EINVAL;  
      192.         }  
      193.         else {  
      194.             dev_info(dev, "Gt811 configue succeed ");  
      195.             status = 0;  
      196.             break;  
      197.         }  
      198.     }  
      199.   
      200.     return status;  
      201. }  
      202.   
      203. static struct gt811_ts_platdata *gt811_ts_parse_devtree(struct i2c_client *client)  
      204. {  
      205.     struct device *dev = &client->dev;  
      206.     struct device_node *node;  
      207.     struct gt811_ts_platdata *pdata;  
      208.     enum of_gpio_flags flags;  
      209.   
      210.     node = dev->of_node;  
      211.     if (!node) {  
      212.         dev_err(dev, "The of_node is NULL. ");  
      213.         return ERR_PTR(-ENODEV);  
      214.     }  
      215.   
      216.     pdata = devm_kzalloc(dev, sizeof(struct device_node), GFP_KERNEL);  
      217.     if (!pdata) {  
      218.         dev_err(dev, "No enough memory left. ");  
      219.         return ERR_PTR(-ENOMEM);  
      220.     }  
      221.   
      222.     pdata->reset_pin = of_get_gpio_flags(node, 0, &flags);  
      223.     if (pdata->reset_pin < 0) {  
      224.         dev_err(dev, "Get RST pin failed! ");  
      225.         return ERR_PTR(-EINVAL);  
      226.     }  
      227.   
      228.     if (of_property_read_u32(node, "touchscreen-size-x", &pdata->size_x )) {  
      229.         dev_err(dev, "Failed to get the touch screen x size. ");  
      230.         return ERR_PTR(-EINVAL);  
      231.     }  
      232.   
      233.     if (of_property_read_u32(node, "touchscreen-size-y", &pdata->size_y)) {  
      234.         dev_err(dev, "Failed to get the touch screen y size. ");  
      235.         return ERR_PTR(-EINVAL);  
      236.     }  
      237.   
      238.     if (of_property_read_u32(node, "touchscreen-size-p", &pdata->size_p)) {  
      239.         pdata->size_p = 255;  
      240.     }  
      241.   
      242.     if (of_property_read_u32(node, "touchscreen-swap", &pdata->swap)) {  
      243.         pdata->swap = 1;  
      244.     }  
      245.   
      246.     if (of_property_read_u32(node, "touchscreen-revert-x", &pdata->revert_x)) {  
      247.         pdata->revert_x = 1;  
      248.     }  
      249.   
      250.     if (of_property_read_u32(node, "touchscreen-revert-x", &pdata->revert_y)) {  
      251.         pdata->revert_y = 1;  
      252.     }  
      253.   
      254.     return pdata;  
      255. }  
      256.   
      257. static int gt811_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)  
      258. {  
      259.     struct device *dev = &client->dev;  
      260.     struct gt811_ts_platdata *pdata = dev_get_platdata(dev);  
      261.     struct input_dev *input;  
      262.     int error = 0;  
      263.   
      264.     if (!of_match_device(of_match_ptr(gt811_ts_of_match), dev)) {  
      265.         dev_err(dev, "Failed to match. ");  
      266.         return -EINVAL;  
      267.     }  
      268.   
      269.     if (!pdata) {  
      270.         pdata = gt811_ts_parse_devtree(client);  
      271.         if (IS_ERR(pdata)) {  
      272.             dev_err(dev, "Get device data from device tree failed! ");  
      273.             error = -EINVAL;  
      274.             goto failed_exit;  
      275.         }  
      276.     }  
      277.   
      278.     pdata->client = client;  
      279.   
      280.     i2c_set_clientdata(client, pdata);  
      281.   
      282.     input = devm_input_allocate_device(dev);  
      283.     if (!input) {  
      284.         dev_err(dev, "Failed to allocate input device ");  
      285.         error = -ENOMEM;  
      286.         goto pdata_free;  
      287.     }  
      288.   
      289.     pdata->input = input;  
      290.   
      291.     input->name = client->name;  
      292.     input->id.bustype = BUS_I2C;  
      293.     input->id.product = 0xBEEF;  
      294.     input->id.vendor  =0xDEAD;  
      295.     input->dev.parent = &client->dev;  
      296.   
      297.     __set_bit(EV_KEY, input->evbit);  
      298.     __set_bit(EV_ABS, input->evbit);  
      299.     __set_bit(BTN_TOUCH, input->keybit);  
      300.     input_set_abs_params(input, ABS_X, 0, pdata->size_x, 0, 0);  
      301.     input_set_abs_params(input, ABS_Y, 0, pdata->size_y, 0, 0);  
      302.     input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->size_x, 0, 0);  
      303.     input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->size_y, 0, 0);  
      304.   
      305.     error = input_mt_init_slots(input, 5, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);  
      306.     if (error) {  
      307.         dev_err(dev, "Failed to initialize the multi-touch slots. ");  
      308.         goto input_free;  
      309.     }  
      310.   
      311.     input_set_drvdata(input, pdata);  
      312.   
      313.     error = input_register_device(input);  
      314.     if (error) {  
      315.         dev_err(dev, "Register input device failed! ");  
      316.         goto input_free;  
      317.     }  
      318.   
      319.     if (gt811_ts_initilize(client)) {  
      320.         dev_err(dev, "Failed to initialize GT811. ");  
      321.     }  
      322.   
      323.     INIT_WORK(&pdata->work, gt811_ts_handler);  
      324.   
      325.     error = devm_request_any_context_irq(dev, client->irq, gt811_ts_isr,  
      326.                       IRQF_TRIGGER_FALLING, client->name, pdata);  
      327.     if (error) {  
      328.         dev_err(dev, "Failed to request irq(number:%d) ", client->irq);  
      329.         goto input_free;  
      330.     }  
      331.   
      332.     return 0;  
      333.   
      334. input_free:  
      335.     devm_kfree(dev, input);  
      336. pdata_free:  
      337.     devm_kfree(dev, pdata);  
      338. failed_exit:  
      339.     return error;  
      340. }  
      341.   
      342. static int gt811_ts_remove(struct i2c_client *client)  
      343. {  
      344.     struct gt811_ts_platdata *pdata = (struct gt811_ts_platdata*)i2c_get_clientdata(client);  
      345.   
      346.     devm_free_irq(&client->dev, client->irq, i2c_get_clientdata(client));  
      347.   
      348.     input_unregister_device(pdata->input);  
      349.   
      350.     devm_kfree(&client->dev, pdata);  
      351.     return 0;  
      352. }  
      353.   
      354. static const struct i2c_device_id gt811_ts_id[] = {  
      355.     { "gt811_ts", 0 },  
      356.     { }  
      357. };  
      358.   
      359. static struct i2c_driver gt811_ts_driver = {  
      360.     .driver = {  
      361.         .owner  = THIS_MODULE,  
      362.         .name   = "gt811_ts",  
      363.         .of_match_table = of_match_ptr(gt811_ts_of_match),  
      364.     },  
      365.     .probe      = gt811_ts_probe,  
      366.     .remove     = gt811_ts_remove,  
      367.     .id_table   = gt811_ts_id,  
      368. };  
      369.   
      370. module_i2c_driver(gt811_ts_driver);  
      371.   
      372. MODULE_AUTHOR("girlkoo <nightmeng@gmail.com>");  
      373. MODULE_DESCRIPTION("Gt811 I2C Touchscreen Driver");  
      374. MODULE_LICENSE("GPL"); 
  • 相关阅读:
    后端架构师技术图谱
    互联网经典技术架构
    软件开发知识体系(二)
    软件开发知识体系(一)
    HSF源码剖析
    分库分表的几种常见形式以及可能遇到的难题
    iOS 关于MVC和MVVM设计模式的那些事
    MVC与MVP简单对比
    MVC、MVP、MVVM 模式
    Learning Android ActionBar
  • 原文地址:https://www.cnblogs.com/zym0805/p/4413351.html
Copyright © 2011-2022 走看看