gt811 driver
- #include <linux/module.h>
- #include <linux/i2c.h>
- #include <linux/platform_device.h>
- #include <linux/gpio.h>
- #include <linux/of.h>
- #include <linux/of_platform.h>
- #include <linux/of_gpio.h>
- #include <linux/input.h>
- #include <linux/input/mt.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- struct gt811_ts_platdata
- {
- u32 size_x;
- u32 size_y;
- u32 size_p;
- u32 swap;
- u32 revert_x;
- u32 revert_y;
- u32 reset_pin;
- u32 interrupt_pin;
- u32 ponits_max;
- struct i2c_client *client;
- struct input_dev *input;
- struct work_struct work;
- };
- static const struct of_device_id gt811_ts_of_match[] = {
- { .compatible = "gt811,gt811_ts", .data = NULL },
- { }
- };
- static int i2c_write_bytes(struct i2c_client *client, uint8_t *data, int len){
- struct i2c_msg msg;
- msg.flags=!I2C_M_RD;
- msg.addr=client->addr;
- msg.len=len;
- msg.buf=data;
- return i2c_transfer(client->adapter,&msg, 1);
- }
- static int i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len){
- struct i2c_msg msgs[2];
- msgs[0].flags=!I2C_M_RD;
- msgs[0].addr=client->addr;
- msgs[0].len=2;
- msgs[0].buf=&buf[0];
- msgs[1].flags=I2C_M_RD;
- msgs[1].addr=client->addr;
- msgs[1].len=len-2;
- msgs[1].buf=&buf[2];
- return i2c_transfer(client->adapter,msgs, 2);
- }
- static void gt811_ts_handler(struct work_struct *work)
- {
- struct gt811_ts_platdata *pdata = container_of(work, struct gt811_ts_platdata, work);
- struct device *dev = &pdata->client->dev;
- uint8_t buffer[36] = {0x07, 0x21, 0};
- uint8_t count, index, flags, position;
- int x, y;
- buffer[0] = 0x0f;
- buffer[1] = 0xff;
- if (i2c_write_bytes(pdata->client,buffer,2) < 0) {
- dev_err(dev, "Failed to write wakeup message.\n");
- goto reenable_irq;
- }
- buffer[0] = 0x07;
- buffer[1] = 0x21;
- if (i2c_read_bytes(pdata->client, buffer, sizeof(buffer)) < 0) {
- dev_err(dev, "Failed to read touch message.\n");
- goto reenable_irq;
- }
- buffer[0] = 0x80;
- buffer[1] = 0x00;
- if (i2c_write_bytes(pdata->client, buffer, 2) < 0) {
- dev_err(dev, "Failed to write sleep message.\n");
- goto reenable_irq;
- }
- buffer[25] = buffer[19];
- buffer[19] = 0;
- flags = buffer[2]&0x1f;
- while (flags) {
- if (!(flags&0x1)) {
- continue;
- }
- if (index < 3) {
- position = 4 + index * 5;
- }
- else{
- position = 25 + (index - 3) * 5;
- }
- x = (buffer[position] << 8) | buffer[position + 1];
- y = (buffer[position + 2] << 8) | buffer[position + 3];
- if(pdata->swap) {
- swap(x, y);
- }
- if(pdata->revert_x){
- x = pdata->size_x - x;
- }
- if(pdata->revert_y){
- y = pdata->size_y - y;
- }
- printk("point:(x:%03d, y:%03d)\n", x, y);
- }
- // 组织检测出来的触摸点信息上报到输入子系统节点即可
- reenable_irq:
- enable_irq(pdata->client->irq);
- }
- static irqreturn_t gt811_ts_isr(int irq, void *dev_id)
- {
- struct gt811_ts_platdata* pdata = (struct gt811_ts_platdata*)dev_id;
- disable_irq_nosync(pdata->client->irq);
- schedule_work(&pdata->work);
- return IRQ_HANDLED;
- }
- static int gt811_ts_initilize(struct i2c_client *client)
- {
- struct device *dev = &client->dev;
- struct gt811_ts_platdata *pdata = (struct gt811_ts_platdata*)i2c_get_clientdata(client);
- int status = 0, count = 0;
- uint8_t version[4] = {0x7, 0x17, 0};
- uint8_t config[] = {
- 0x06,0xA2,
- 0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0xE2,0x53,0xD2,0x53,0xC2,0x53,
- 0xB2,0x53,0xA2,0x53,0x92,0x53,0x82,0x53,0x72,0x53,0x62,0x53,0x52,0x53,0x42,0x53,
- 0x32,0x53,0x22,0x53,0x12,0x53,0x02,0x53,0xF2,0x53,0x0F,0x13,0x40,0x40,0x40,0x10,
- 0x10,0x10,0x0F,0x0F,0x0A,0x35,0x25,0x0C,0x03,0x00,0x05,0x20,0x03,0xE0,0x01,0x00,
- 0x00,0x34,0x2C,0x36,0x2E,0x00,0x00,0x03,0x19,0x03,0x08,0x00,0x00,0x00,0x00,0x00,
- 0x14,0x10,0xEC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x40,
- 0x30,0x3C,0x28,0x00,0x00,0x00,0x00,0xC0,0x12,0x01
- };
- config[62] = 480 >> 8;
- config[61] = 480 & 0xff;
- config[64] = 800 >> 8;
- config[63] = 800 & 0xff;
- if (!gpio_is_valid(pdata->reset_pin)) {
- dev_err(dev, "The reset pin number is invalid.\n");
- return -EINVAL;
- }
- count = 3;
- while (count--) {
- gpio_direction_output(pdata->reset_pin, 0);
- msleep(10);
- gpio_direction_output(pdata->reset_pin, 1);
- msleep(100);
- if (i2c_read_bytes(client, version, sizeof(version)) < 0) {
- dev_err(dev, "Failed to get the version of GT811, try again...\n");
- status = -ENODEV;
- }
- else {
- dev_info(dev, "Gt811 detected, version(%04x)...\n", (version[2]<<8)|version[3]);
- status = 0;
- break;
- }
- }
- if (status) {
- return status;
- }
- count = 3;
- while (count--) {
- if (i2c_write_bytes(client, config, sizeof(config)) < 0) {
- dev_err(dev, "Failed to configure the GT811, try again...\n");
- status = -EINVAL;
- }
- else {
- dev_info(dev, "Gt811 configue succeed\n");
- status = 0;
- break;
- }
- }
- return status;
- }
- static struct gt811_ts_platdata *gt811_ts_parse_devtree(struct i2c_client *client)
- {
- struct device *dev = &client->dev;
- struct device_node *node;
- struct gt811_ts_platdata *pdata;
- enum of_gpio_flags flags;
- node = dev->of_node;
- if (!node) {
- dev_err(dev, "The of_node is NULL.\n");
- return ERR_PTR(-ENODEV);
- }
- pdata = devm_kzalloc(dev, sizeof(struct device_node), GFP_KERNEL);
- if (!pdata) {
- dev_err(dev, "No enough memory left.\n");
- return ERR_PTR(-ENOMEM);
- }
- pdata->reset_pin = of_get_gpio_flags(node, 0, &flags);
- if (pdata->reset_pin < 0) {
- dev_err(dev, "Get RST pin failed!\n");
- return ERR_PTR(-EINVAL);
- }
- if (of_property_read_u32(node, "touchscreen-size-x", &pdata->size_x )) {
- dev_err(dev, "Failed to get the touch screen x size.\n");
- return ERR_PTR(-EINVAL);
- }
- if (of_property_read_u32(node, "touchscreen-size-y", &pdata->size_y)) {
- dev_err(dev, "Failed to get the touch screen y size.\n");
- return ERR_PTR(-EINVAL);
- }
- if (of_property_read_u32(node, "touchscreen-size-p", &pdata->size_p)) {
- pdata->size_p = 255;
- }
- if (of_property_read_u32(node, "touchscreen-swap", &pdata->swap)) {
- pdata->swap = 1;
- }
- if (of_property_read_u32(node, "touchscreen-revert-x", &pdata->revert_x)) {
- pdata->revert_x = 1;
- }
- if (of_property_read_u32(node, "touchscreen-revert-x", &pdata->revert_y)) {
- pdata->revert_y = 1;
- }
- return pdata;
- }
- static int gt811_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
- {
- struct device *dev = &client->dev;
- struct gt811_ts_platdata *pdata = dev_get_platdata(dev);
- struct input_dev *input;
- int error = 0;
- if (!of_match_device(of_match_ptr(gt811_ts_of_match), dev)) {
- dev_err(dev, "Failed to match.\n");
- return -EINVAL;
- }
- if (!pdata) {
- pdata = gt811_ts_parse_devtree(client);
- if (IS_ERR(pdata)) {
- dev_err(dev, "Get device data from device tree failed!\n");
- error = -EINVAL;
- goto failed_exit;
- }
- }
- pdata->client = client;
- i2c_set_clientdata(client, pdata);
- input = devm_input_allocate_device(dev);
- if (!input) {
- dev_err(dev, "Failed to allocate input device\n");
- error = -ENOMEM;
- goto pdata_free;
- }
- pdata->input = input;
- input->name = client->name;
- input->id.bustype = BUS_I2C;
- input->id.product = 0xBEEF;
- input->id.vendor =0xDEAD;
- input->dev.parent = &client->dev;
- __set_bit(EV_KEY, input->evbit);
- __set_bit(EV_ABS, input->evbit);
- __set_bit(BTN_TOUCH, input->keybit);
- input_set_abs_params(input, ABS_X, 0, pdata->size_x, 0, 0);
- input_set_abs_params(input, ABS_Y, 0, pdata->size_y, 0, 0);
- input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->size_x, 0, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->size_y, 0, 0);
- error = input_mt_init_slots(input, 5, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
- if (error) {
- dev_err(dev, "Failed to initialize the multi-touch slots.\n");
- goto input_free;
- }
- input_set_drvdata(input, pdata);
- error = input_register_device(input);
- if (error) {
- dev_err(dev, "Register input device failed!\n");
- goto input_free;
- }
- if (gt811_ts_initilize(client)) {
- dev_err(dev, "Failed to initialize GT811.\n");
- }
- INIT_WORK(&pdata->work, gt811_ts_handler);
- error = devm_request_any_context_irq(dev, client->irq, gt811_ts_isr,
- IRQF_TRIGGER_FALLING, client->name, pdata);
- if (error) {
- dev_err(dev, "Failed to request irq(number:%d)\n", client->irq);
- goto input_free;
- }
- return 0;
- input_free:
- devm_kfree(dev, input);
- pdata_free:
- devm_kfree(dev, pdata);
- failed_exit:
- return error;
- }
- static int gt811_ts_remove(struct i2c_client *client)
- {
- struct gt811_ts_platdata *pdata = (struct gt811_ts_platdata*)i2c_get_clientdata(client);
- devm_free_irq(&client->dev, client->irq, i2c_get_clientdata(client));
- input_unregister_device(pdata->input);
- devm_kfree(&client->dev, pdata);
- return 0;
- }
- static const struct i2c_device_id gt811_ts_id[] = {
- { "gt811_ts", 0 },
- { }
- };
- static struct i2c_driver gt811_ts_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "gt811_ts",
- .of_match_table = of_match_ptr(gt811_ts_of_match),
- },
- .probe = gt811_ts_probe,
- .remove = gt811_ts_remove,
- .id_table = gt811_ts_id,
- };
- module_i2c_driver(gt811_ts_driver);
- MODULE_AUTHOR("girlkoo <nightmeng@gmail.com>");
- MODULE_DESCRIPTION("Gt811 I2C Touchscreen Driver");
- MODULE_LICENSE("GPL");
gt811 driver的更多相关文章
- 深入linux kernel内核配置选项
============================================================================== 深入linux kernel内核配置选项 ...
- MongoDB Java Driver操作指南
MongoDB为Java提供了非常丰富的API操作,相比关系型数据库,这种NoSQL本身的数据也有点面向对象的意思,所以对于Java来说,Mongo的数据结构更加友好. MongoDB在今年做了一次重 ...
- c#操作MangoDB 之MangoDB CSharp Driver驱动详解
序言 MangoDB CSharp Driver是c#操作mongodb的官方驱动. 官方Api文档:http://api.mongodb.org/csharp/2.2/html/R_Project_ ...
- Java JDBC Thin Driver 连接 Oracle 三种方法说明(转载)
一.JDBC 连接Oracle 说明 JDBC 的应用连接Oracle 遇到问题,错误如下: ORA-12505,TNS:listener does not currently know of SID ...
- 设备模型(device-model)之平台总线(bus),驱动(driver),设备(device)
关于关于驱动设备模型相关概念请参考<Linux Device Drivers>等相关书籍,和内核源码目录...\Documentation\driver-model 简单来说总线(bus) ...
- AM335x tscadc platform driver 相关代码跟踪
TI AM335x ti am335x_tsc.c 代码跟踪 在kernel 首层目录: 先运行make ARCH=arm tags 这个作用是建立tags文件,只含有arm架构的,利用ctag即可进 ...
- selenium web driver 实现截图功能
在验证某些关键步骤时,需要截个图来记录一下当时的情况 Webdriver截图时,需要引入 import java.io.File; import java.io.IOException; import ...
- selenium web driver 使用JS修改input属性
selenium获取input时候,发现type=”hidden” 的input无法修改value,经牛人指点,可以使用js修改 首先html源文件如下,设置为text .hidden.submit ...
- 转载:安装ie driver和chrome driver
很多同学在使用webdriver的时候总是忘了安装ie driver和chrome driver, 因此在这里简单介绍一下这2个driver的安装方式. IE driver 在新版本的webdrive ...
随机推荐
- [NPM] Avoid Duplicate Commands by Calling one NPM Script from Another
We can get a lot of utility through CLI tools invoked via npm scripts. Many of these tools have APIs ...
- haproxy综合
常见问题:haproxy启动报错Starting proxy : cannot bind socket?答:查看haproxy.conf配置文件发现其监听80跟apache冲突,而apache没在使用 ...
- android中可以使用bitmap的平铺,镜像平铺等减小图片带来的apk过大的问题
bitmap的平铺.镜像drawable文件夹中新建bitmap,其中的tileMode属性 tileMode 属性就是用于定义背景的显示模式: disabled 默认值,表示不使用平铺 cla ...
- ionic的加载功能
下面是代码(黄色背景的是加载功能的代码): <html ng-app="ionicApp"> <head> <meta charset="u ...
- OFBiz:配置过程
OFBiz使用了大量的配置文件,整个过程有点复杂.这里将配置过程大略整理了一下,方便后面查阅. 第一层:org.ofbiz.base.start.Start启动类.该类载入org/ofbiz/base ...
- android中checkbox的padding引发的问题
自己定义checkbox中的勾选框图标.这次由于想偷懒.图标弄的大了些.然后一系列的问题就都引出来了. 1.图标比checkbox的layout_height高.看不见了. 非常吐血吧,Compoun ...
- 【CentOS6.5】安装之DNS配置错误,yum install 软件报错:ERROR 6或者56错误提示”could not retrieve mirrorlist http://mirrorlist.centos.org ***”
刚安装完CentOS,使用yum命令安装一些常用的软件,使用如下命令:yum grouplist | more. 提示如下错误信息: Loaded plugins: fastestmirror Set ...
- sms_queue 短信队列
git地址:https://github.com/Filix/sms_queue 简介 通过队列的方式发送短信,暂时实现了redis作为队列. 以实现的第三方短信服务: 百悟.漫道. 发送短信方,只需 ...
- Linux命令-网络命令:ping
ping 192.168.67.1 ping windows网卡地址,默认会一直ping下去,区别于windows的ping命令ping4次 ping -c 次192. 友情提示:如果您(阅读者)是从 ...
- Linux命令-权限管理命令:chown
选项:-R 处理指定目录以及其子目录下的所有文件 useradd wangyunpeng 创建一个用户名为wangyunpeng的用户 passwd wangyunpeng 给wangyunpeng这 ...