金牌会员
- 积分
- 1820
- 金钱
- 1820
- 注册时间
- 2019-7-23
- 在线时间
- 281 小时
|
- #include <linux/module.h>
- #include <linux/ratelimit.h>
- #include <linux/interrupt.h>
- #include <linux/input.h>
- #include <linux/i2c.h>
- #include <linux/uaccess.h>
- #include <linux/delay.h>
- #include <linux/debugfs.h>
- #include <linux/slab.h>
- #include <linux/gpio.h>
- #include <linux/of_gpio.h>
- #include <linux/input/mt.h>
- #include <linux/input/touchscreen.h>
- #define GT911_DEBUG 0
- #define GT911_DEBUG_PRINTK 0
- struct _gt911_pointsInfo //编译器默认4字节对齐
- {
- u8 reversed;
- u8 P1_trackId;
- u16 P1_x;
- u16 P1_y;
- u16 P1_size;
- u8 Reserved1;
- u8 P2_trackId;
- u16 P2_x;
- u16 P2_y;
- u16 P2_size;
- u8 Reserved2;
- u8 P3_trackId;
- u16 P3_x;
- u16 P3_y;
- u16 P3_size;
- u8 Reserved3;
- u8 P4_trackId;
- u16 P4_x;
- u16 P4_y;
- u16 P4_size;
- u8 Reserved4;
- u8 P5_trackId;
- u16 P5_x;
- u16 P5_y;
- u16 P5_size;
- u8 Reserved5;
- };
- union gt911_pointsInfo
- {
- struct _gt911_pointsInfo pInfo;
- u8 data[41];
- };
- struct gt911_ts_data
- {
- struct i2c_client *client;
- struct input_dev *input;
- int irq;
- int rst_pin;
- int irq_pin;
-
- int x_max; //x最大坐标值
- int y_max;
- u8 triger_type;
- u8 touch_number;
- u8 number_touchPoints;
-
- #pragma pack(4)
- union gt911_pointsInfo pointsInfo;
- #pragma pack()
- };
- const u8 triger_type[4] = {IRQF_TRIGGER_RISING,IRQF_TRIGGER_FALLING,IRQF_TRIGGER_LOW,IRQF_TRIGGER_HIGH};
- static int gt11_read_reg(struct i2c_client *client, u16 cmd, u8* data, u8 len)
- {
- int ret = 0;
- u8 buf[2];
- struct i2c_msg msg[2] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = buf,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = len,
- .buf = data,
- },
- };
- buf[0] = (u8)((cmd >> 8)&0xff);
- buf[1] = (u8)(cmd &0xff);
- ret = i2c_transfer(client->adapter, msg, 2);
- if(ret < 0)
- printk("read_reg:%d\n",ret);
- return ret < 0 ? ret : 0;
- }
- static int gt11_write_reg(struct i2c_client *client, u16 cmd, u8* data, u8 len)
- {
- int ret = 0;
- u8 buf[100];
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = len + 2,
- .buf = buf,
- };
- memset(buf, 0, 100);
- buf[0] = (u8)((cmd >> 8)&0xff);
- buf[1] = (u8)(cmd &0xff);
- memcpy(&buf[2],data,len);
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if(ret < 0)
- printk("write_reg:%d\n",ret);
- return ret < 0 ? ret : 0;
- }
- static int gt911_getInfo(struct i2c_client *client)
- {
- int ret = 0;
- struct gt911_ts_data *tsdata = i2c_get_clientdata(client);
- ret = gt11_read_reg(client, 0x8048, (u8 *)(&tsdata->x_max), 2);
- if(ret)
- {
- printk("gt11 read reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- ret = gt11_read_reg(client, 0x804A, (u8 *)(&tsdata->y_max), 2);
- if(ret)
- {
- printk("gt11 read reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- ret = gt11_read_reg(client, 0x804C, (u8 *)(&tsdata->touch_number), 1);
- if(ret)
- {
- printk("gt11 read reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- tsdata->touch_number &= 0x0f;
- ret = gt11_read_reg(client, 0x804D, (u8 *)(&tsdata->triger_type), 1);
- if(ret)
- {
- printk("gt11 read reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- tsdata->triger_type &= 0x03;
- tsdata->triger_type = triger_type[tsdata->triger_type];
-
- fail:
- return ret;
-
- }
- static int gt911_reset(struct i2c_client *client)
- {
- int error;
- struct gt911_ts_data *tsdata = i2c_get_clientdata(client);
- tsdata->rst_pin = of_get_named_gpio(client->dev.of_node, "goodix,rst-gpio", 0);
- if (gpio_is_valid(tsdata->rst_pin)) {
- error = devm_gpio_request_one(&client->dev,
- tsdata->rst_pin, GPIOF_OUT_INIT_LOW,
- "goodix,rst-gpio");
- if (error) {
- dev_err(&client->dev,
- "Failed to request GPIO %d as rst pin, error %d\n",
- tsdata->rst_pin, error);
- return error;
- }
-
- }
-
-
- tsdata->irq_pin = of_get_named_gpio(client->dev.of_node, "goodix,irq-gpio", 0);//default 0
- if (gpio_is_valid(tsdata->irq_pin)) {
- error = devm_gpio_request_one(&client->dev,
- tsdata->irq_pin, GPIOF_OUT_INIT_LOW,
- "goodix,irq-gpio");
- if (error) {
- dev_err(&client->dev,
- "Failed to request GPIO %d as irq pin, error %d\n",
- tsdata->irq_pin, error);
- return error;
- }
- msleep(5);
-
- }
- gpio_set_value(tsdata->rst_pin, 1);
- msleep(10);
- error = gpio_direction_input(tsdata->irq_pin);
- if (error) {
- dev_err(&client->dev,
- "Failed to set GPIO input %d as irq pin, error %d\n",
- tsdata->irq_pin, error);
- }
- msleep(10);
- client->addr = 0x5d;
-
- return error;
- }
- #if GT911_DEBUG
- static void gt911_debugInfo(struct gt911_ts_data *tsdata)
- {
-
- printk("touch num:%#x\n",tsdata->number_touchPoints);
- printk("P1 track id:%d\n",tsdata->pointsInfo.pInfo.P1_trackId);
- printk("P1 x:%d y:%d\n\n",tsdata->pointsInfo.pInfo.P1_x,tsdata->pointsInfo.pInfo.P1_y);
- printk("P2 track id:%d\n",tsdata->pointsInfo.pInfo.P2_trackId);
- printk("P2 x:%d y:%d\n\n",tsdata->pointsInfo.pInfo.P2_x,tsdata->pointsInfo.pInfo.P2_y);
- printk("P3 track id:%d\n",tsdata->pointsInfo.pInfo.P3_trackId);
- printk("P3 x:%d y:%d\n\n",tsdata->pointsInfo.pInfo.P3_x,tsdata->pointsInfo.pInfo.P3_y);
- printk("P4 track id:%d\n",tsdata->pointsInfo.pInfo.P4_trackId);
- printk("P4 x:%d y:%d\n\n",tsdata->pointsInfo.pInfo.P4_x,tsdata->pointsInfo.pInfo.P4_y);
- printk("P5 track id:%d\n",tsdata->pointsInfo.pInfo.P5_trackId);
- printk("P5 x:%d y:%d\n\n",tsdata->pointsInfo.pInfo.P5_x,tsdata->pointsInfo.pInfo.P5_y);
- }
- #endif
- static irqreturn_t gt911_ts_isr(int irq, void *dev_id)
- {
- struct gt911_ts_data *tsdata = dev_id;
- int ret = 0, i = 0,j = 0;
- u8 trackId = 0;
- u16 x,y,P_size;
- static u8 preTouchNum = 0;
- static u8 pretouchTrackID[5];
-
- ret = gt11_read_reg(tsdata->client, 0x814E, (u8 *)(&tsdata->number_touchPoints), 1);
- if(ret)
- {
- printk("gt11 read reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
-
- if(!(tsdata->number_touchPoints & 0x80))
- {
- #if GT911_DEBUG_PRINTK
- printk("buffer status error %s %d\n",__FUNCTION__,__LINE__);
- #endif
- goto fail;
- }
- if((tsdata->number_touchPoints & 0x0f) > tsdata->touch_number)
- goto fail;
- if(tsdata->number_touchPoints & 0x0f)
- ret = gt11_read_reg(tsdata->client, 0x814E, tsdata->pointsInfo.data, 41);
- else{
- #if GT911_DEBUG_PRINTK
- printk("finger up %s %d\n",__FUNCTION__,__LINE__);
- #endif
-
- if(preTouchNum)
- {
- for(i=0; i< preTouchNum; i++)
- {
- input_mt_slot(tsdata->input, pretouchTrackID[i]);
- input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, false);
- #if GT911_DEBUG_PRINTK
- printk("finger up ID %d %s %d\n",pretouchTrackID[i],__FUNCTION__,__LINE__);
- #endif
- }
-
- preTouchNum = 0;
- }
- input_mt_report_pointer_emulation(tsdata->input, true);
- input_sync(tsdata->input);
-
- goto fail;
- }
-
- if(ret)
- {
- printk("gt11 read reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- for(i=0; i< tsdata->touch_number; i++)
- {
- u8 *buf = &tsdata->pointsInfo.data[i * 8 + 1];
- trackId = buf[0];
- x = (buf[2] << 8) | buf[1];
- y = (buf[4] << 8) | buf[3];
- P_size = (buf[6] << 8) | buf[5];
- if(preTouchNum <= (tsdata->number_touchPoints & 0x0f)) //触摸点增加或者保持触摸点数量
- {
- if(!((tsdata->number_touchPoints & 0x0f) > i)) //上报所有的点
- break;
- input_mt_slot(tsdata->input, trackId);
- input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, true);
-
- input_report_abs(tsdata->input, ABS_MT_POSITION_X, x);
- input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
- input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, P_size);
- #if GT911_DEBUG_PRINTK
- printk("finger increase down ID:%d %s %d\n",trackId,__FUNCTION__,__LINE__);
- #endif
-
- }else { //触摸点减少
- if(!(preTouchNum > i)) //处理上报上次所有的点
- break;
- for(; j < preTouchNum;j++)
- {
- if(pretouchTrackID[j] != trackId)
- {
- input_mt_slot(tsdata->input, pretouchTrackID[j]);
- input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, false);
- #if GT911_DEBUG_PRINTK
- printk("finger decrease up ID:%d %s %d\n",pretouchTrackID[j],__FUNCTION__,__LINE__);
- #endif
-
- }else {
-
- input_mt_slot(tsdata->input, trackId);
- input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, true);
-
- input_report_abs(tsdata->input, ABS_MT_POSITION_X, x);
- input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
- input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, P_size);
- #if GT911_DEBUG_PRINTK
- printk("finger decrease down j:%d ID:%d %s %d\n",j,trackId,__FUNCTION__,__LINE__);
- #endif
-
- j++;
- break;
- }
- }
-
- }
-
- }
- input_mt_report_pointer_emulation(tsdata->input, true);
- input_sync(tsdata->input);
-
- preTouchNum = tsdata->number_touchPoints & 0x0f;
- for(i=0; i< tsdata->touch_number; i++)
- {
- u8 *buf = &tsdata->pointsInfo.data[i * 8 + 1];
- pretouchTrackID[i] = buf[0];
- }
-
- #if GT911_DEBUG
- gt911_debugInfo(tsdata);
- #endif
- fail:
- gt11_write_reg(tsdata->client, 0x814E, "\x00", 1);
- return IRQ_HANDLED;
- }
- static int gt911_ts_probe(struct i2c_client *client,const struct i2c_device_id *id)
- {
- int ret = 0;
- struct gt911_ts_data *tsdata;
- struct input_dev *input;
- tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
- if (!tsdata) {
- dev_err(&client->dev, "failed to allocate driver data.\n");
- return -ENOMEM;
- }
- tsdata->client = client;
- i2c_set_clientdata(client, tsdata);
- gt911_reset(client);
-
- ret = gt11_write_reg(tsdata->client, 0x814E, "\x00", 1);
- if(ret)
- {
- printk("gt11 write reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- ret = gt911_getInfo(client);
- if(ret)
- {
- printk("gt11 write reg fail %s %d\n",__FUNCTION__,__LINE__);
- goto fail;
- }
- input = devm_input_allocate_device(&client->dev);
- if (!input) {
- dev_err(&client->dev, "failed to allocate input data.\n");
- return -ENOMEM;
- }
- input_set_drvdata(input, tsdata);
- tsdata->input = input;
- input->name = client->name;
- input->id.bustype = BUS_I2C;
- input->dev.parent = &client->dev;
- input_set_capability(input, EV_KEY , BTN_TOUCH);
- __set_bit(EV_ABS, input->evbit);
- __set_bit(INPUT_PROP_DIRECT, input->propbit);
- input_set_abs_params(input, ABS_X, 0, tsdata->x_max , 0, 0);
- input_set_abs_params(input, ABS_Y, 0, tsdata->y_max, 0, 0);
- input_set_abs_params(input, ABS_MT_POSITION_X,
- 0, tsdata->x_max, 0, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y,
- 0, tsdata->y_max, 0, 0);
-
- input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
- 0, 255, 0, 0);
-
- ret = input_mt_init_slots(input, tsdata->touch_number, 0);
- if (ret) {
- dev_err(&client->dev, "Unable to init MT slots.\n");
- goto fail;
- }
- ret = input_register_device(input);
- if (ret)
- {
- dev_err(&client->dev, "Unable to register input device.\n");
- goto fail;
-
- }
-
- ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- gt911_ts_isr,
- tsdata->triger_type | IRQF_ONESHOT,
- client->name, tsdata);
-
- return 0;
- fail:
- return ret;
- }
- static int gt911_ts_remove(struct i2c_client *client)
- {
- struct gt911_ts_data *tsdata = i2c_get_clientdata(client);
- input_unregister_device(tsdata->input);
- return 0;
- }
- static const struct i2c_device_id gt911_ts_id[] = {
- { "goodix,gt9xx", 0, },
- { /* sentinel */ }
- };
- static const struct of_device_id gt911_of_match[] = {
- { .compatible = "goodix,gt9xx", },
- { /* sentinel */ }
- };
- static struct i2c_driver gt911_ts_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "gt911",
- .of_match_table = of_match_ptr(gt911_of_match),
- },
- .id_table = gt911_ts_id,
- .probe = gt911_ts_probe,
- .remove = gt911_ts_remove,
- };
- module_i2c_driver(gt911_ts_driver);
- MODULE_LICENSE("GPL");
复制代码 使用insmod加载这个驱动是没有问题的, 但是编译进内核经过调试发现初始化那部分有问题,也就是获取屏幕分辨率和触摸点数量获取的都是零。导致后续处理出问题。但是 i2c_transfer函数无错误返回。且i2c adapter在加载这个驱动之前就注册成功了。有哪位大师能解决此问题,请留言。
后来使用一个歪招,用脚本加载这个触摸屏触动,进而使用tslib。
|
|