码迷,mamicode.com
首页 > 其他好文 > 详细

gt811 driver

时间:2015-04-10 06:37:39      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

    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.\n");  
    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.\n");  
    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.\n");  
    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)\n", 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.\n");  
    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...\n");  
    174.             status = -ENODEV;  
    175.         }  
    176.         else {  
    177.             dev_info(dev, "Gt811 detected, version(%04x)...\n", (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...\n");  
    191.             status = -EINVAL;  
    192.         }  
    193.         else {  
    194.             dev_info(dev, "Gt811 configue succeed\n");  
    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.\n");  
    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.\n");  
    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!\n");  
    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.\n");  
    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.\n");  
    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.\n");  
    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!\n");  
    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\n");  
    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.\n");  
    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!\n");  
    316.         goto input_free;  
    317.     }  
    318.   
    319.     if (gt811_ts_initilize(client)) {  
    320.         dev_err(dev, "Failed to initialize GT811.\n");  
    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)\n", 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"); 

gt811 driver

标签:

原文地址:http://www.cnblogs.com/zym0805/p/4413351.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!