mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
drivers/input/touchscreen: remove unused gt801/gt8110/gt811/gt818/gt819 drivers
Change-Id: Ib3f78cb12fe43203dbc5d5d4c2bac9258991c41e Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
@@ -1,671 +0,0 @@
|
||||
/*
|
||||
* drivers/input/touchscreen/gt801_ts.c
|
||||
*
|
||||
* Copyright (C) 2010 ROCKCHIP, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "gt801_ts.h"
|
||||
|
||||
#define GT801_DEBUG 0
|
||||
#if GT801_DEBUG
|
||||
#define gt801printk(msg...) printk(msg);
|
||||
#else
|
||||
#define gt801printk(msg...)
|
||||
#endif
|
||||
|
||||
#define SINGLTOUCH_MODE 0
|
||||
#define GT801_REGS_NUM 53
|
||||
|
||||
#if SINGLTOUCH_MODE
|
||||
#define TOUCH_NUMBER 1
|
||||
#else
|
||||
#define TOUCH_NUMBER 2
|
||||
#endif
|
||||
|
||||
#define TOUCH_REG_NUM 5 //ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ļĴ<C4BC><C4B4><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
|
||||
const unsigned char GT801_RegData[GT801_REGS_NUM]={
|
||||
0x19,0x05,0x06,0x28,0x02,0x14,0x14,0x10,0x40,0xB0,0x01,0xE0,0x03,0x4C,0x78,
|
||||
0x9A,0xBC,0xDE,0x65,0x43,0x20,0x11,0x00,0x00,0x00,0x00,0x05,0xCF,0x20,0x0B,
|
||||
0x0D,0x8D,0x32,0x3C,0x1E,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
|
||||
};
|
||||
|
||||
struct gt801_ts_data {
|
||||
u16 model; /* 801. */
|
||||
bool swap_xy; /* swap x and y axes */
|
||||
u16 x_min, x_max;
|
||||
u16 y_min, y_max;
|
||||
uint16_t addr;
|
||||
int use_irq;
|
||||
int gpio_pendown;
|
||||
int gpio_reset;
|
||||
int gpio_reset_active_low;
|
||||
int pendown_iomux_mode;
|
||||
int resetpin_iomux_mode;
|
||||
char pendown_iomux_name[IOMUX_NAME_SIZE];
|
||||
char resetpin_iomux_name[IOMUX_NAME_SIZE];
|
||||
char phys[32];
|
||||
char name[32];
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
struct hrtimer timer;
|
||||
struct work_struct work;
|
||||
struct early_suspend early_suspend;
|
||||
};
|
||||
/*tochscreen private data*/
|
||||
static int touch_state[TOUCH_NUMBER] = {TOUCH_UP,TOUCH_UP};
|
||||
static struct workqueue_struct *gt801_wq;
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void gt801_ts_early_suspend(struct early_suspend *h);
|
||||
static void gt801_ts_late_resume(struct early_suspend *h);
|
||||
#endif
|
||||
|
||||
static int verify_coord(struct gt801_ts_data *ts,unsigned short *x,unsigned short *y)
|
||||
{
|
||||
|
||||
gt801printk("%s:(%d/%d)\n",__FUNCTION__,*x, *y);
|
||||
if((*x< ts->x_min) || (*x > ts->x_max))
|
||||
return -1;
|
||||
|
||||
if((*y< ts->y_min) || (*y > ts->y_max))
|
||||
return -1;
|
||||
// *x = ts->x_max - *x;
|
||||
//if(*y <780)
|
||||
*y = ts->y_max -*y;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*read the gt801 register ,used i2c bus*/
|
||||
static int gt801_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
|
||||
{
|
||||
int ret;
|
||||
ret =i2c_master_reg8_recv(client, reg, buf, len, 200*1000);
|
||||
if(ret < 0)
|
||||
printk("gt801_ts_work_func:i2c_transfer fail =%d\n",ret);
|
||||
return ret;
|
||||
}
|
||||
/* set the gt801 registe,used i2c bus*/
|
||||
static int gt801_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_send(client,reg, buf, len, 200*1000);
|
||||
if (ret < 0) {
|
||||
printk("gt801_ts_work_func:i2c_transfer fail =%d\n",ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static int gt801_init_panel(struct gt801_ts_data *ts)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gt801_ts_work_func(struct work_struct *work)
|
||||
{
|
||||
#if SINGLTOUCH_MODE
|
||||
|
||||
#else
|
||||
int touch_state_index = 0;
|
||||
#endif
|
||||
|
||||
unsigned char start_reg = 0x02;
|
||||
unsigned char buf[TOUCH_NUMBER*TOUCH_REG_NUM];
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
int i,ret;
|
||||
int syn_flag = 0;
|
||||
int bufLen = TOUCH_NUMBER*TOUCH_REG_NUM;
|
||||
|
||||
struct gt801_ts_data *ts = container_of(work, struct gt801_ts_data, work);
|
||||
|
||||
gt801printk("%s\n",__FUNCTION__);
|
||||
|
||||
ret=gt801_read_regs(ts->client, start_reg, buf,bufLen);
|
||||
if (ret < 0) {
|
||||
printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,ret);
|
||||
if (ts->use_irq)
|
||||
enable_irq(ts->client->irq);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if SINGLTOUCH_MODE
|
||||
i = 0;
|
||||
if(buf[i+ptpressure] == 0)
|
||||
{
|
||||
gt801printk(" realse ts_dev->point.x=%d ,ts_dev->point.y=%d \n",ts->point.x,ts->point.y);
|
||||
|
||||
if (touch_state[i] == TOUCH_DOWN)
|
||||
{
|
||||
input_report_key(ts->input_dev,BTN_TOUCH,0);
|
||||
syn_flag = 1;
|
||||
touch_state[i] = TOUCH_UP;
|
||||
gt801printk("SINGLTOUCH_MODE up\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]);
|
||||
y= (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]);
|
||||
|
||||
if (ts->swap_xy)
|
||||
swap(x, y);
|
||||
|
||||
if (verify_coord(ts,&x,&y))
|
||||
goto out;
|
||||
|
||||
if (touch_state[i] == TOUCH_UP)
|
||||
{
|
||||
gt801printk("SINGLTOUCH_MODE down\n");
|
||||
input_report_key(ts->input_dev,BTN_TOUCH,1);
|
||||
touch_state[i] = TOUCH_DOWN;
|
||||
}
|
||||
|
||||
gt801printk("input_report_abs(%d/%d)\n",x,y);
|
||||
input_report_abs(ts->input_dev,ABS_X,x );
|
||||
input_report_abs(ts->input_dev,ABS_Y,y );
|
||||
syn_flag = 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for(i=0; i<bufLen; i+=TOUCH_REG_NUM)
|
||||
{
|
||||
if(buf[i+ptpressure] == 0){
|
||||
gt801printk("%s:buf=%d touch up\n",__FUNCTION__,buf[i+ptpressure]);
|
||||
if (touch_state[touch_state_index] == TOUCH_DOWN)
|
||||
{
|
||||
gt801printk("%s:%d touch up\n",__FUNCTION__,i);
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); //Finger Size
|
||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //Touch Size
|
||||
input_mt_sync(ts->input_dev);
|
||||
syn_flag =1;
|
||||
touch_state[touch_state_index] = TOUCH_UP;
|
||||
}
|
||||
}
|
||||
else{
|
||||
x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]);
|
||||
y = (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]);
|
||||
/* adjust the x and y to proper value added by hhb@rock-chips.com*/
|
||||
if(x < 480){
|
||||
x = 480-x;
|
||||
}
|
||||
|
||||
if(y < 800){
|
||||
y = 800-y;
|
||||
}
|
||||
|
||||
if (ts->swap_xy){
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
if (verify_coord(ts,&x,&y));//goto out;
|
||||
|
||||
gt801printk("input_report_abs--%d-%d-(%d/%d)\n", i,touch_state_index, x, y);
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //Finger Size
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
|
||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5); //Touch Size
|
||||
input_mt_sync(ts->input_dev);
|
||||
syn_flag = 1;
|
||||
touch_state[touch_state_index] = TOUCH_DOWN;
|
||||
}
|
||||
|
||||
touch_state_index++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(syn_flag){
|
||||
input_sync(ts->input_dev);
|
||||
}
|
||||
|
||||
out:
|
||||
if (ts->use_irq) {
|
||||
enable_irq(ts->client->irq);
|
||||
}
|
||||
return;
|
||||
}
|
||||
static enum hrtimer_restart gt801_ts_timer_func(struct hrtimer *timer)
|
||||
{
|
||||
struct gt801_ts_data *ts = container_of(timer, struct gt801_ts_data, timer);
|
||||
gt801printk("%s\n",__FUNCTION__);
|
||||
|
||||
queue_work(gt801_wq, &ts->work);
|
||||
|
||||
hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static irqreturn_t gt801_ts_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gt801_ts_data *ts = dev_id;
|
||||
gt801printk("%s=%d,%d\n",__FUNCTION__,ts->client->irq,ts->use_irq);
|
||||
|
||||
if(ts->use_irq){
|
||||
disable_irq_nosync(ts->client->irq);
|
||||
}
|
||||
queue_work(gt801_wq, &ts->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
static int __devinit setup_resetPin(struct i2c_client *client, struct gt801_ts_data *ts)
|
||||
{
|
||||
struct gt801_platform_data *pdata = client->dev.platform_data;
|
||||
int err;
|
||||
|
||||
ts->gpio_reset = pdata->gpio_reset;
|
||||
ts->gpio_reset_active_low = pdata->gpio_reset_active_low;
|
||||
ts->resetpin_iomux_mode = pdata->resetpin_iomux_mode;
|
||||
|
||||
if(pdata->resetpin_iomux_name != NULL)
|
||||
strcpy(ts->resetpin_iomux_name,pdata->resetpin_iomux_name);
|
||||
|
||||
gt801printk("%s=%d,%s,%d,%d\n",__FUNCTION__,ts->gpio_reset,ts->resetpin_iomux_name,ts->resetpin_iomux_mode,ts->gpio_reset_active_low);
|
||||
if (!gpio_is_valid(ts->gpio_reset)) {
|
||||
dev_err(&client->dev, "no gpio_reset?\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rk29_mux_api_set(ts->resetpin_iomux_name,ts->resetpin_iomux_mode);
|
||||
|
||||
err = gpio_request(ts->gpio_reset, "gt801_resetPin");
|
||||
if (err) {
|
||||
dev_err(&client->dev, "failed to request resetPin GPIO%d\n",
|
||||
ts->gpio_reset);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = gpio_direction_output(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
|
||||
if (err) {
|
||||
dev_err(&client->dev, "failed to pulldown resetPin GPIO%d,err%d\n",
|
||||
ts->gpio_reset,err);
|
||||
gpio_free(ts->gpio_reset);
|
||||
return err;
|
||||
}
|
||||
mdelay(100);
|
||||
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
|
||||
mdelay(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit setup_pendown(struct i2c_client *client, struct gt801_ts_data *ts)
|
||||
{
|
||||
int err;
|
||||
struct gt801_platform_data *pdata = client->dev.platform_data;
|
||||
|
||||
if (!client->irq) {
|
||||
dev_dbg(&client->dev, "no IRQ?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!gpio_is_valid(pdata->gpio_pendown)) {
|
||||
dev_err(&client->dev, "no gpio_pendown?\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ts->gpio_pendown = pdata->gpio_pendown;
|
||||
strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name);
|
||||
ts->pendown_iomux_mode = pdata->pendown_iomux_mode;
|
||||
|
||||
gt801printk("%s=%d,%s,%d\n",__FUNCTION__,ts->gpio_pendown,ts->pendown_iomux_name,ts->pendown_iomux_mode);
|
||||
|
||||
if (!gpio_is_valid(ts->gpio_pendown)) {
|
||||
dev_err(&client->dev, "no gpio_pendown?\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rk29_mux_api_set(ts->pendown_iomux_name,ts->pendown_iomux_mode);
|
||||
err = gpio_request(ts->gpio_pendown, "gt801_pendown");
|
||||
if (err) {
|
||||
dev_err(&client->dev, "failed to request pendown GPIO%d\n",
|
||||
ts->gpio_pendown);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = gpio_pull_updown(ts->gpio_pendown, GPIOPullUp);
|
||||
if (err) {
|
||||
dev_err(&client->dev, "failed to pullup pendown GPIO%d\n",
|
||||
ts->gpio_pendown);
|
||||
gpio_free(ts->gpio_pendown);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gt801_chip_Init(struct i2c_client *client)
|
||||
{
|
||||
u8 i,j;
|
||||
int ret=0;
|
||||
u8 start_reg=0x30;
|
||||
u8 buf[GT801_REGS_NUM];
|
||||
|
||||
gt801printk("enter gt801_chip_Init!!!!\n");
|
||||
|
||||
for(j=0;j<2;j++)
|
||||
{
|
||||
ret=gt801_write_regs(client,start_reg, GT801_RegData,GT801_REGS_NUM);
|
||||
if(ret<0)
|
||||
{
|
||||
printk("\n--%s--Set Register values error !!!\n",__FUNCTION__);
|
||||
}
|
||||
|
||||
ret=gt801_read_regs(client, start_reg, buf,GT801_REGS_NUM);
|
||||
if(ret<0)
|
||||
{
|
||||
printk("\n--%s--Read Register values error !!!\n",__FUNCTION__);
|
||||
}
|
||||
|
||||
for(i=0;i<GT801_REGS_NUM-1;i++)
|
||||
{
|
||||
if(buf[i]!=GT801_RegData[i])
|
||||
{
|
||||
printk("!!!!!!!!gt801_chip_Init err may be i2c errorat adress=%x var=%x i=%x\n",0x30+i, buf[i],i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i==GT801_REGS_NUM-1)
|
||||
break;
|
||||
else if(j==1)
|
||||
return -1;
|
||||
|
||||
mdelay(500);
|
||||
}
|
||||
mdelay(100);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gt801_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
struct gt801_ts_data *ts;
|
||||
struct gt801_platform_data *pdata = client->dev.platform_data;
|
||||
int ret = 0;
|
||||
|
||||
gt801printk("%s \n",__FUNCTION__);
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&client->dev, "empty platform_data\n");
|
||||
goto err_check_functionality_failed;
|
||||
}
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
printk(KERN_ERR "gt801_ts_probe: need I2C_FUNC_I2C\n");
|
||||
ret = -ENODEV;
|
||||
goto err_check_functionality_failed;
|
||||
}
|
||||
|
||||
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
|
||||
if (ts == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc_data_failed;
|
||||
}
|
||||
INIT_WORK(&ts->work, gt801_ts_work_func);
|
||||
ts->client = client;
|
||||
i2c_set_clientdata(client, ts);
|
||||
|
||||
ret = setup_resetPin(client,ts);
|
||||
if(ret)
|
||||
{
|
||||
printk("%s:setup_resetPin fail\n",__FUNCTION__);
|
||||
goto err_input_dev_alloc_failed;
|
||||
}
|
||||
|
||||
ret=gt801_chip_Init(ts->client);
|
||||
if(ret<0)
|
||||
{
|
||||
printk("%s:chips init failed\n",__FUNCTION__);
|
||||
goto err_resetpin_failed;
|
||||
}
|
||||
|
||||
/* allocate input device */
|
||||
ts->input_dev = input_allocate_device();
|
||||
if (ts->input_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
printk(KERN_ERR "%s: Failed to allocate input device\n",__FUNCTION__);
|
||||
goto err_input_dev_alloc_failed;
|
||||
}
|
||||
|
||||
ts->model = pdata->model ? : 801;
|
||||
ts->swap_xy = pdata->swap_xy;
|
||||
ts->x_min = pdata->x_min;
|
||||
ts->x_max = pdata->x_max;
|
||||
ts->y_min = pdata->y_min;
|
||||
ts->y_max = pdata->y_max;
|
||||
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev));
|
||||
snprintf(ts->name, sizeof(ts->name), "gt%d-touchscreen", ts->model);
|
||||
ts->input_dev->phys = ts->phys;
|
||||
ts->input_dev->name = ts->name;
|
||||
ts->input_dev->dev.parent = &client->dev;
|
||||
|
||||
#if SINGLTOUCH_MODE
|
||||
ts->input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY);
|
||||
ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
input_set_abs_params(ts->input_dev,ABS_X,
|
||||
ts->x_min ? : 0,
|
||||
ts->x_max ? : 480,
|
||||
0, 0);
|
||||
input_set_abs_params(ts->input_dev,ABS_Y,
|
||||
ts->y_min ? : 0,
|
||||
ts->y_max ? : 800,
|
||||
0, 0);
|
||||
|
||||
#else
|
||||
ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS);
|
||||
// ts->input_dev->absbit[0] =
|
||||
// BIT(ABS_MT_POSITION_X) | BIT(ABS_MT_POSITION_Y) |
|
||||
// BIT(ABS_MT_TOUCH_MAJOR) | BIT(ABS_MT_WIDTH_MAJOR); // for android
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
|
||||
ts->x_min ? : 0,
|
||||
ts->x_max ? : 480,
|
||||
0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
|
||||
ts->y_min ? : 0,
|
||||
ts->y_max ? : 800,
|
||||
0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0); //Finger Size
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 10, 0, 0); //Touch Size
|
||||
#endif
|
||||
ret = input_register_device(ts->input_dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: Unable to register %s input device\n", __FUNCTION__,ts->input_dev->name);
|
||||
goto err_input_register_device_failed;
|
||||
}
|
||||
|
||||
client->irq = gpio_to_irq(client->irq);
|
||||
if (client->irq) {
|
||||
ret = setup_pendown(client,ts);
|
||||
if(ret)
|
||||
{
|
||||
printk("%s:setup_pendown fail\n",__FUNCTION__);
|
||||
goto err_input_register_device_failed;
|
||||
}
|
||||
|
||||
ret = request_irq(client->irq, gt801_ts_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, client->name, ts);
|
||||
if (ret == 0) {
|
||||
gt801printk("%s:register ISR (irq=%d)\n", __FUNCTION__,client->irq);
|
||||
ts->use_irq = 1;
|
||||
}
|
||||
else
|
||||
dev_err(&client->dev, "request_irq failed\n");
|
||||
}
|
||||
|
||||
if (!ts->use_irq) {
|
||||
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
ts->timer.function = gt801_ts_timer_func;
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
}
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
||||
ts->early_suspend.suspend = gt801_ts_early_suspend;
|
||||
ts->early_suspend.resume = gt801_ts_late_resume;
|
||||
register_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO "%s: Start touchscreen %s in %s mode\n", __FUNCTION__,ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
|
||||
|
||||
return 0;
|
||||
|
||||
err_input_register_device_failed:
|
||||
input_free_device(ts->input_dev);
|
||||
err_resetpin_failed:
|
||||
gpio_free(ts->gpio_reset);
|
||||
err_input_dev_alloc_failed:
|
||||
kfree(ts);
|
||||
err_alloc_data_failed:
|
||||
err_check_functionality_failed:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gt801_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
struct gt801_ts_data *ts = i2c_get_clientdata(client);
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
if (ts->use_irq)
|
||||
free_irq(client->irq, ts);
|
||||
else
|
||||
hrtimer_cancel(&ts->timer);
|
||||
input_unregister_device(ts->input_dev);
|
||||
gpio_free(ts->gpio_pendown);
|
||||
gpio_free(ts->gpio_reset);
|
||||
kfree(ts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gt801_ts_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
int ret;
|
||||
struct gt801_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
printk("gt801 TS Suspend\n");
|
||||
|
||||
if (ts->use_irq)
|
||||
disable_irq(client->irq);
|
||||
else
|
||||
hrtimer_cancel(&ts->timer);
|
||||
|
||||
ret = cancel_work_sync(&ts->work);
|
||||
if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
|
||||
enable_irq(client->irq);
|
||||
|
||||
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void gt801_ts_resume_work_func(struct work_struct *work)
|
||||
{
|
||||
struct gt801_ts_data *ts = container_of(work, struct gt801_ts_data, work);
|
||||
msleep(50); //touch panel will generate an interrupt when it sleeps out,so as to avoid tihs by delaying 50ms
|
||||
enable_irq(ts->client->irq);
|
||||
PREPARE_WORK(&ts->work, gt801_ts_work_func);
|
||||
printk("enabling gt801_ts IRQ %d\n", ts->client->irq);
|
||||
}
|
||||
|
||||
|
||||
static int gt801_ts_resume(struct i2c_client *client)
|
||||
{
|
||||
struct gt801_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
gt801_init_panel(ts);
|
||||
|
||||
printk("gt801 TS Resume\n");
|
||||
|
||||
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
|
||||
|
||||
if (ts->use_irq) {
|
||||
if(!work_pending(&ts->work)){
|
||||
PREPARE_WORK(&ts->work, gt801_ts_resume_work_func);
|
||||
queue_work(gt801_wq, &ts->work);
|
||||
}
|
||||
}
|
||||
else {
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void gt801_ts_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct gt801_ts_data *ts;
|
||||
ts = container_of(h, struct gt801_ts_data, early_suspend);
|
||||
gt801_ts_suspend(ts->client, PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
static void gt801_ts_late_resume(struct early_suspend *h)
|
||||
{
|
||||
struct gt801_ts_data *ts;
|
||||
ts = container_of(h, struct gt801_ts_data, early_suspend);
|
||||
gt801_ts_resume(ts->client);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define gt801_TS_NAME "gt801_ts"
|
||||
|
||||
static const struct i2c_device_id gt801_ts_id[] = {
|
||||
{ gt801_TS_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver gt801_ts_driver = {
|
||||
.probe = gt801_ts_probe,
|
||||
.remove = gt801_ts_remove,
|
||||
#ifndef CONFIG_HAS_EARLYSUSPEND
|
||||
.suspend = gt801_ts_suspend,
|
||||
.resume = gt801_ts_resume,
|
||||
#endif
|
||||
.id_table = gt801_ts_id,
|
||||
.driver = {
|
||||
.name = gt801_TS_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit gt801_ts_init(void)
|
||||
{
|
||||
printk("%s\n",__FUNCTION__);
|
||||
gt801_wq = create_singlethread_workqueue("gt801_wq");
|
||||
if (!gt801_wq)
|
||||
return -ENOMEM;
|
||||
return i2c_add_driver(>801_ts_driver);
|
||||
}
|
||||
|
||||
static void __exit gt801_ts_exit(void)
|
||||
{
|
||||
printk("%s\n",__FUNCTION__);
|
||||
i2c_del_driver(>801_ts_driver);
|
||||
if (gt801_wq)
|
||||
destroy_workqueue(gt801_wq);
|
||||
}
|
||||
|
||||
module_init(gt801_ts_init);
|
||||
module_exit(gt801_ts_exit);
|
||||
|
||||
MODULE_DESCRIPTION("gt801 Touchscreen Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* drivers/input/touchscreen/gt801_ts.h
|
||||
*
|
||||
* Copyright (C) 2010 ROCKCHIP, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_TOUCHSCREEN_GT801_TS_H
|
||||
#define __DRIVERS_TOUCHSCREEN_GT801_TS_H
|
||||
|
||||
#define IOMUX_NAME_SIZE 48
|
||||
|
||||
enum regadd {
|
||||
ptxh = 0, ptxl = 1, ptyh = 2, ptyl = 3, ptpressure = 4,
|
||||
};
|
||||
enum touchstate {
|
||||
TOUCH_UP = 0, TOUCH_DOWN = 1,
|
||||
};
|
||||
|
||||
struct gt801_platform_data {
|
||||
|
||||
u16 model; /* 801. */
|
||||
bool swap_xy; /* swap x and y axes */
|
||||
u16 x_min, x_max;
|
||||
u16 y_min, y_max;
|
||||
int gpio_reset;
|
||||
int gpio_reset_active_low;
|
||||
int gpio_pendown; /* the GPIO used to decide the pendown */
|
||||
|
||||
char pendown_iomux_name[IOMUX_NAME_SIZE];
|
||||
char resetpin_iomux_name[IOMUX_NAME_SIZE];
|
||||
int pendown_iomux_mode;
|
||||
int resetpin_iomux_mode;
|
||||
|
||||
int (*get_pendown_state)(void);
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,274 +0,0 @@
|
||||
/* drivers/input/touchscreen/gt811_update.h
|
||||
*
|
||||
* Copyright (C) 2010 - 2011 Goodix, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*Any problem,please contact andrew@goodix.com,+86 755-33338828
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_GT811_UPDATE_H
|
||||
#define _LINUX_GT811_UPDATE_H
|
||||
static unsigned char goodix_gt811_firmware[] = {
|
||||
0x11,
|
||||
0x10,0x10,
|
||||
0x45,
|
||||
0x00,0x00,0x00,
|
||||
0x41,0x00,
|
||||
0x0e,0xf0,
|
||||
0x06,0x24,0xad,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/*'G','O','O','D','I','X',*/
|
||||
|
||||
0x4f,0xce,0x01,0x00,0x20,0x03,0xa7,0x00,0x08,0x8c,0x05,0xdf,
|
||||
0x26,0xf8,0x8e,0x05,0xdf,0xbd,0x41,0x16,0x20,0xfe,0x0e,0xbd,0xc2,0xd4,0xbd,0x4d,
|
||||
0x8c,0xbd,0x4d,0xc2,0xbd,0x41,0xb0,0xbd,0x47,0x61,0xbd,0x46,0x59,0xbd,0xf7,0x38,
|
||||
0x20,0x10,0x01,0x01,0x01,0x01,0x13,0xe6,0x01,0x08,0xd6,0xeb,0x26,0x04,0x01,0xcf,
|
||||
0x01,0x01,0xd6,0xeb,0x27,0xec,0xd6,0xe7,0x5c,0x26,0xe7,0xd7,0xeb,0xbd,0x46,0xf4,
|
||||
0xbd,0xc4,0x73,0xf6,0x07,0x0b,0x27,0x0f,0xbd,0x46,0xf8,0xbd,0x46,0x59,0xc6,0x80,
|
||||
0xd7,0xea,0xbd,0xf7,0x38,0x20,0xdb,0xbd,0xd4,0xb8,0xd6,0xea,0x5a,0x27,0x08,0xbd,
|
||||
0xf5,0x3c,0xbd,0xf7,0x38,0x20,0xcb,0x8d,0x64,0xbd,0x4c,0x90,0xbd,0xe9,0xd4,0xbd,
|
||||
0x4b,0xd7,0xbd,0x49,0x4c,0xbd,0xeb,0xe8,0xbd,0xf7,0x38,0xbd,0x42,0xa9,0xbd,0x47,
|
||||
0x87,0xbd,0x48,0xde,0xbd,0xd7,0xa2,0xbd,0x4b,0x41,0xbd,0xdb,0x6a,0xbd,0xef,0x1c,
|
||||
0xbd,0xdf,0x8d,0xbd,0xe3,0x51,0xbd,0xe3,0x71,0xbd,0xd5,0xa8,0xbd,0x4e,0x29,0xbd,
|
||||
0xef,0x95,0x20,0x8e,0x3c,0x34,0x30,0xbd,0xc7,0x1c,0xc6,0x5d,0x18,0xce,0x14,0x01,
|
||||
0x18,0xe7,0x00,0xbd,0x46,0x27,0xf7,0x07,0x10,0x56,0x56,0x56,0xc4,0xc0,0xe7,0x00,
|
||||
0xf6,0x07,0x21,0xc4,0x3f,0xea,0x00,0xf7,0x07,0x21,0x31,0x38,0x39,0xd6,0xef,0x26,
|
||||
0x1a,0xc6,0x01,0xd7,0xef,0xfe,0x01,0x28,0x3c,0xcc,0x0b,0x00,0xfd,0x01,0x28,0xbd,
|
||||
0x48,0x38,0xdd,0xf2,0xfd,0x02,0xf7,0x38,0xff,0x01,0x28,0x39,0x3c,0xd6,0xf5,0x26,
|
||||
0x03,0x7e,0x42,0x86,0xd6,0xac,0x5a,0x26,0x6e,0xfc,0x02,0x89,0x83,0x0d,0x80,0xce,
|
||||
0x00,0x14,0x02,0x8f,0x37,0xce,0x0b,0xa0,0x18,0xfe,0x01,0x28,0x32,0x81,0x08,0x23,
|
||||
0x0a,0x80,0x08,0xc6,0xa0,0x3a,0x3a,0x18,0x3a,0x18,0x3a,0xc6,0x14,0x3d,0x3a,0x18,
|
||||
0x3a,0x5f,0xd7,0x69,0xec,0x00,0x18,0xa3,0x00,0x7d,0x00,0x69,0x26,0x06,0xfd,0x02,
|
||||
0xfc,0xfd,0x02,0xfe,0x1a,0xb3,0x02,0xfc,0x2f,0x03,0xfd,0x02,0xfc,0x1a,0xb3,0x02,
|
||||
0xfe,0x2c,0x03,0xfd,0x02,0xfe,0x08,0x08,0x18,0x08,0x18,0x08,0x7c,0x00,0x69,0xd6,
|
||||
0x69,0xd1,0xc2,0x25,0xcf,0xd6,0xca,0x4f,0xf3,0x02,0xfe,0xb3,0x02,0xfc,0x2d,0x07,
|
||||
0xf6,0x02,0xf1,0xcb,0x02,0x20,0x06,0xf6,0x02,0xf1,0x27,0x01,0x5a,0xf7,0x02,0xf1,
|
||||
0xc1,0xfa,0x25,0x06,0xbd,0x49,0x43,0x7f,0x00,0xf5,0x38,0x39,0x3c,0xce,0x07,0x12,
|
||||
0xc6,0xa0,0xe7,0x00,0x5f,0xce,0x07,0x1d,0xe7,0x00,0x08,0x8c,0x07,0x48,0x23,0xf8,
|
||||
0xce,0x02,0xc4,0xe7,0x00,0x08,0x8c,0x02,0xec,0x25,0xf8,0x38,0x39,0x7f,0x03,0x33,
|
||||
0xbd,0xc5,0x25,0x13,0xe6,0x04,0x02,0x8d,0x49,0xbd,0x44,0x46,0xcc,0x01,0xc2,0xd0,
|
||||
0xda,0x82,0x00,0xd0,0xda,0x82,0x00,0xf3,0x02,0x90,0xfd,0x02,0x90,0x39,0x3c,0x18,
|
||||
0x3c,0x86,0x14,0xf6,0x03,0x33,0x3d,0xc3,0x0d,0x80,0x18,0x8f,0xce,0x02,0x2c,0xd6,
|
||||
0xc2,0xd7,0x6a,0xec,0x00,0x13,0xe6,0x40,0x02,0x47,0x56,0x18,0xed,0x00,0xc6,0x02,
|
||||
0x3a,0x18,0x3a,0x7a,0x00,0x6a,0x26,0xeb,0x4f,0x97,0xd1,0x7c,0x03,0x33,0x18,0x38,
|
||||
0x38,0x39,0x3c,0x18,0x3c,0xce,0x03,0x34,0x4f,0xc6,0xa0,0xa7,0x00,0x08,0x5a,0x26,
|
||||
0xfa,0x96,0xc1,0xb7,0x02,0x6f,0x18,0xce,0x0d,0x80,0xce,0x03,0x34,0xd6,0xc2,0xf7,
|
||||
0x02,0x6e,0x18,0x3c,0x4f,0x5f,0x18,0xe3,0x00,0x18,0x08,0x18,0x08,0x7a,0x02,0x6e,
|
||||
0x26,0xf4,0xfd,0x03,0x31,0x18,0x38,0x3c,0x4f,0xd6,0xc2,0x8f,0xfc,0x03,0x31,0x2a,
|
||||
0x0c,0x40,0x50,0x82,0x00,0x02,0x8f,0x40,0x50,0x82,0x00,0x20,0x02,0x02,0x8f,0xfd,
|
||||
0x03,0x31,0x38,0x96,0xc2,0xb7,0x02,0x6e,0x18,0x3c,0x18,0xec,0x00,0xb3,0x03,0x31,
|
||||
0x18,0xed,0x00,0x2d,0x04,0x2e,0x0d,0x20,0x18,0x6c,0x01,0x1a,0xa3,0x06,0x2c,0x11,
|
||||
0xed,0x06,0x20,0x0d,0x6c,0x00,0x1a,0xa3,0x04,0x2f,0x02,0xed,0x04,0xe3,0x02,0xed,
|
||||
0x02,0x18,0x08,0x18,0x08,0x7a,0x02,0x6e,0x26,0xd0,0x18,0x38,0xc6,0x0a,0x3a,0x58,
|
||||
0x18,0x3a,0x7a,0x02,0x6f,0x26,0x86,0xce,0x03,0x34,0x96,0xc1,0xb7,0x02,0x6f,0x4a,
|
||||
0xb7,0x03,0x29,0xb7,0x03,0x2a,0x4f,0xd6,0xc9,0xc0,0x0a,0xa3,0x04,0xe3,0x06,0x2b,
|
||||
0x15,0xd6,0xc1,0xf0,0x02,0x6f,0xb6,0x03,0x29,0xb1,0x03,0x2a,0x27,0x05,0xf7,0x03,
|
||||
0x29,0x20,0x03,0xf7,0x03,0x2a,0xc6,0x0a,0x3a,0x7a,0x02,0x6f,0x26,0xd8,0x8d,0x11,
|
||||
0xf6,0x03,0x29,0xf7,0x03,0x2a,0x8d,0x09,0xbd,0x45,0xff,0x8d,0x3a,0x18,0x38,0x38,
|
||||
0x39,0x7f,0x03,0x2c,0xf6,0x03,0x2a,0xf7,0x02,0x6f,0xd6,0xc2,0xd7,0x68,0xbd,0x45,
|
||||
0x1a,0xbd,0x45,0xc2,0x7c,0x02,0x6f,0xf6,0x02,0x6f,0xd1,0xc1,0x26,0xf0,0x7f,0x03,
|
||||
0x2c,0xf6,0x03,0x2a,0xf7,0x02,0x6f,0xd6,0xc2,0xd7,0x68,0xbd,0x45,0x1a,0xbd,0x45,
|
||||
0xc2,0x7a,0x02,0x6f,0x2a,0xf5,0x39,0x18,0xce,0x03,0x34,0xce,0x0d,0x80,0x96,0xc1,
|
||||
0xb7,0x02,0x6f,0x18,0x67,0x08,0x18,0x66,0x09,0x96,0xc2,0xb7,0x02,0x6e,0x3c,0xec,
|
||||
0x00,0x18,0xe3,0x08,0xed,0x00,0x08,0x08,0x7a,0x02,0x6e,0x26,0xf2,0x38,0xc6,0x0a,
|
||||
0x18,0x3a,0x58,0x3a,0x7a,0x02,0x6f,0x26,0xda,0x39,0x3c,0x4f,0x5f,0xb7,0x02,0x81,
|
||||
0xb7,0x02,0x80,0x97,0xe2,0x97,0xe1,0x97,0x68,0x97,0x67,0x18,0xce,0x0d,0x80,0xce,
|
||||
0x0d,0x80,0xff,0x02,0x89,0xff,0x02,0x87,0xd6,0xc1,0xd7,0x6a,0x3c,0x18,0x3c,0xd6,
|
||||
0xc2,0xd7,0x69,0x18,0xec,0x00,0x18,0x6f,0x00,0x18,0x6f,0x01,0x4d,0x2a,0x28,0x40,
|
||||
0x50,0x82,0x00,0x4d,0x27,0x02,0xc6,0xff,0xd1,0xc9,0x23,0x03,0x7c,0x00,0xe1,0xf1,
|
||||
0x02,0x7f,0x23,0x03,0x7c,0x02,0x80,0x4f,0xa7,0x00,0xf3,0x02,0x90,0xfd,0x02,0x90,
|
||||
0x86,0x02,0xb7,0x03,0x25,0x20,0x4d,0xd0,0xfb,0x82,0x00,0x2a,0x02,0x4f,0x5f,0x4d,
|
||||
0x27,0x02,0xc6,0xff,0xd1,0xc9,0x22,0x04,0x86,0x02,0x20,0x04,0x7c,0x00,0xe2,0x4f,
|
||||
0xb7,0x03,0x25,0xf1,0x02,0x7f,0x23,0x03,0x7c,0x02,0x81,0xe7,0x00,0x4f,0xf3,0x02,
|
||||
0x90,0xfd,0x02,0x90,0xe6,0x00,0xd1,0x68,0x23,0x11,0x96,0x68,0x97,0x67,0xd7,0x68,
|
||||
0xfc,0x02,0x89,0xfd,0x02,0x87,0xff,0x02,0x89,0x20,0x09,0xd1,0x67,0x23,0x05,0xd7,
|
||||
0x67,0xff,0x02,0x87,0x3c,0xc6,0xa0,0x3a,0x3a,0xf6,0x03,0x25,0xe7,0x00,0x38,0x08,
|
||||
0xc6,0x02,0x18,0x3a,0x7a,0x00,0x69,0x27,0x03,0x7e,0x44,0x6f,0x18,0x38,0x38,0xc6,
|
||||
0x14,0x3a,0x18,0x3a,0x7a,0x00,0x6a,0x27,0x03,0x7e,0x44,0x68,0x38,0x39,0xce,0x03,
|
||||
0x34,0xf6,0x02,0x6f,0x86,0x0a,0x3d,0x3a,0xec,0x00,0x3d,0x5d,0xfd,0x03,0x26,0x27,
|
||||
0x6e,0x86,0x01,0xf6,0x03,0x2c,0x27,0x10,0x5a,0x27,0x18,0x5a,0x27,0x26,0xf6,0x03,
|
||||
0x2b,0x27,0x05,0x5a,0x27,0x28,0x20,0x08,0xe6,0x00,0xe1,0x01,0x22,0x02,0x20,0x1e,
|
||||
0x4f,0x20,0x1b,0xf6,0x03,0x2b,0xc1,0x02,0x27,0x14,0xe6,0x00,0xd0,0x68,0xc1,0x04,
|
||||
0x2e,0xe6,0x20,0x1a,0x4f,0xf6,0x03,0x2b,0xc1,0x01,0x27,0x02,0x20,0x08,0xb7,0x03,
|
||||
0x28,0x4f,0xd6,0xc2,0x20,0x0e,0xb7,0x03,0x28,0x4f,0xe6,0x00,0x20,0x06,0xb7,0x03,
|
||||
0x28,0x4f,0xe6,0x01,0xfd,0x03,0x31,0xec,0x02,0x3c,0xfe,0x03,0x31,0x02,0x8f,0x38,
|
||||
0xfd,0x03,0x26,0x4f,0xf6,0x03,0x28,0x26,0x06,0xb3,0x03,0x26,0xfd,0x03,0x26,0xec,
|
||||
0x04,0xf3,0x03,0x26,0xfd,0x03,0x2f,0xec,0x06,0xf3,0x03,0x26,0xfd,0x03,0x2d,0xec,
|
||||
0x08,0xf3,0x03,0x26,0xed,0x08,0xfc,0x03,0x2d,0x47,0x56,0x47,0x56,0xe3,0x08,0xed,
|
||||
0x08,0xe6,0x00,0xd7,0x68,0x39,0xf6,0x03,0x2c,0xc1,0x03,0x2c,0x03,0xf7,0x03,0x2b,
|
||||
0x7f,0x03,0x2c,0x4f,0xd6,0xc9,0xc0,0x0a,0x1a,0xb3,0x03,0x2f,0x2c,0x03,0x7c,0x03,
|
||||
0x2c,0x40,0x50,0x82,0x00,0x1a,0xb3,0x03,0x2d,0x2f,0x06,0x7c,0x03,0x2c,0x7c,0x03,
|
||||
0x2c,0xf6,0x03,0x2c,0xc1,0x03,0x26,0x0a,0xf6,0x03,0x2b,0x26,0x05,0xc6,0x01,0xf7,
|
||||
0x03,0x2c,0x39,0x3c,0x18,0x3c,0xce,0x03,0x34,0x18,0xce,0x03,0x05,0xd6,0xc1,0x37,
|
||||
0xec,0x08,0x18,0xe3,0x00,0x47,0x56,0xed,0x08,0x18,0xed,0x00,0xc6,0x08,0x3a,0x18,
|
||||
0x08,0x18,0x08,0x33,0x5a,0x26,0xe8,0x18,0x38,0x38,0x39,0x3c,0xce,0x16,0x00,0x1d,
|
||||
0x00,0x02,0x1c,0x06,0x02,0x1d,0x07,0x02,0xbd,0xef,0x0d,0x1e,0x02,0x02,0x07,0x1d,
|
||||
0x06,0x02,0xc6,0x02,0x20,0x15,0x1d,0x06,0x02,0x1c,0x07,0x02,0xbd,0xef,0x0d,0x1f,
|
||||
0x02,0x02,0x07,0x1d,0x07,0x02,0xc6,0x01,0x20,0x01,0x5f,0x38,0x39,0x3c,0x34,0x30,
|
||||
0xbd,0xc8,0x97,0xd6,0x6a,0x4f,0xc3,0x07,0x92,0x18,0x8f,0xcc,0x42,0xca,0x18,0xed,
|
||||
0x01,0xbd,0x42,0x88,0x8d,0xb5,0xf7,0x07,0x10,0x56,0x56,0x56,0xc4,0xc0,0xe7,0x00,
|
||||
0xf6,0x07,0x21,0xc4,0x3f,0xea,0x00,0xf7,0x07,0x21,0x7f,0x02,0xc2,0xcc,0x80,0x00,
|
||||
0xfd,0x01,0x2e,0xf6,0x06,0xec,0xc4,0x0f,0xd7,0xfb,0x5f,0xd7,0xf5,0xd7,0xf4,0xf7,
|
||||
0x02,0xfb,0xd7,0xef,0xd7,0xc8,0xd7,0x6a,0x86,0x03,0x3d,0x4f,0xc3,0x03,0xd8,0xfd,
|
||||
0x03,0xd6,0xbd,0x4d,0x69,0xd6,0x6a,0x86,0x05,0x3d,0x4f,0xc3,0x03,0xe7,0x18,0x8f,
|
||||
0x18,0x6f,0x04,0x7c,0x00,0x6a,0xd6,0x6a,0xc1,0x05,0x25,0xdc,0xbd,0x48,0x20,0xd6,
|
||||
0xe6,0xc4,0x30,0xd7,0x68,0x26,0x0d,0xc6,0x0c,0xf7,0x02,0xed,0x5c,0xf7,0x02,0xee,
|
||||
0xc6,0x0f,0x20,0x09,0xc6,0x0c,0xf7,0x02,0xed,0x5c,0xf7,0x02,0xee,0xf7,0x02,0xef,
|
||||
0xc6,0x0a,0xf7,0x02,0xf0,0x31,0x38,0x39,0x7f,0x13,0x01,0x39,0xf6,0x07,0x21,0xc4,
|
||||
0xc0,0xca,0x20,0xf7,0x07,0x21,0xc6,0xf0,0xf7,0x07,0x22,0x5f,0xd7,0xfa,0x8d,0xe8,
|
||||
0xf6,0x07,0x0b,0x27,0x24,0x7f,0x07,0x0b,0xbd,0xf1,0x9e,0xf6,0x01,0x32,0x5a,0x26,
|
||||
0x18,0xf6,0x07,0x21,0xc4,0xc0,0xf7,0x07,0x21,0x7f,0x07,0x22,0xbd,0xf1,0x4e,0xfc,
|
||||
0x01,0x30,0xf7,0x07,0x0c,0xb7,0x07,0x0d,0x39,0x4f,0x5f,0xdd,0x75,0x8d,0xb9,0xbd,
|
||||
0xef,0x0d,0xf6,0x07,0x0b,0x26,0xce,0xdc,0x75,0xc3,0x00,0x01,0xdd,0x75,0x83,0x07,
|
||||
0xd0,0x25,0xea,0xd6,0xfa,0x26,0x05,0xbd,0xf7,0xd6,0x20,0x03,0xbd,0xf7,0xed,0xd6,
|
||||
0xfa,0xc8,0x01,0x20,0xa7,0x7f,0x07,0x11,0xc6,0x02,0xf7,0x06,0x92,0xbd,0xf3,0x11,
|
||||
0x39,0x39,0xd6,0xf5,0x26,0x0b,0x12,0xec,0x08,0x07,0xc6,0x01,0xd7,0xf5,0xbd,0x48,
|
||||
0xbc,0x7f,0x02,0xf1,0xbd,0xd2,0x22,0x7f,0x02,0x84,0x39,0xd6,0xcb,0xc5,0x80,0x26,
|
||||
0x01,0x39,0xbd,0x48,0x38,0x1a,0xb3,0x02,0xf7,0x24,0x03,0xfd,0x02,0xf7,0x37,0xf6,
|
||||
0x02,0xf9,0x33,0x26,0x03,0xfd,0x02,0xf3,0x1a,0xb3,0x02,0xf3,0x23,0x05,0xb3,0x02,
|
||||
0xf3,0x20,0x05,0xfc,0x02,0xf3,0x93,0xf0,0x1a,0x83,0x00,0xc8,0x25,0x03,0x8d,0x64,
|
||||
0x39,0xdc,0xf0,0xd3,0xed,0x24,0x03,0x7c,0x02,0xfa,0xdd,0xed,0xd6,0xac,0xc1,0x02,
|
||||
0x24,0x04,0x13,0xec,0x02,0x05,0xc6,0x01,0xf7,0x02,0xf2,0x7c,0x02,0xf9,0xf6,0x02,
|
||||
0xf9,0xc1,0x10,0x26,0x3e,0xc6,0x04,0xd7,0x6a,0xdc,0xed,0x74,0x02,0xfa,0x46,0x56,
|
||||
0x7a,0x00,0x6a,0x26,0xf6,0xfd,0x02,0xf5,0x93,0xf2,0x24,0x0c,0xdc,0xf2,0xb3,0x02,
|
||||
0xf5,0x83,0x01,0xf4,0x23,0x02,0x8d,0x2a,0xfc,0x02,0xf7,0x37,0x36,0xfc,0x02,0xf5,
|
||||
0xbd,0xf7,0xbb,0x31,0x31,0x83,0x00,0xc8,0x24,0x07,0xf6,0x02,0xf2,0x27,0x02,0x8d,
|
||||
0x11,0x8d,0x01,0x39,0x5f,0xf7,0x02,0xf9,0xf7,0x02,0xfa,0x4f,0xb7,0x02,0xf2,0xdd,
|
||||
0xed,0x39,0x7f,0x02,0x95,0x7f,0x02,0x94,0xbd,0x49,0x43,0x39,0x3c,0x18,0xfe,0x01,
|
||||
0x28,0xfe,0x01,0x28,0xc6,0x14,0x3a,0x4f,0x5f,0xdd,0xf0,0xd7,0xbe,0x20,0x66,0xd6,
|
||||
0xbe,0xc1,0x07,0x26,0x05,0xc6,0xa0,0x3a,0x20,0x08,0xc1,0x08,0x26,0x04,0xc6,0xa0,
|
||||
0x18,0x3a,0x5f,0xd7,0xbf,0x20,0x3f,0x3c,0x18,0x3c,0x3c,0x18,0x3c,0x3c,0xce,0x06,
|
||||
0xa2,0xd6,0xbf,0x3a,0xec,0x00,0x38,0x36,0x3a,0x18,0x3a,0xec,0x00,0x18,0xa3,0x00,
|
||||
0xdd,0xcf,0x33,0x18,0x38,0x38,0x3a,0x18,0x3a,0x18,0xec,0x00,0xa3,0x00,0xd3,0xcf,
|
||||
0x2a,0x05,0x43,0x53,0xc3,0x00,0x01,0xd3,0xf0,0x24,0x03,0xcc,0xff,0xff,0xdd,0xf0,
|
||||
0x18,0x38,0x38,0x7c,0x00,0xbf,0xd6,0xc2,0x5a,0xd1,0xbf,0x22,0xba,0xc6,0x14,0x3a,
|
||||
0x18,0x3a,0x7c,0x00,0xbe,0xd6,0xc0,0x5a,0xd1,0xbe,0x22,0x93,0xdc,0xf0,0x38,0x39,
|
||||
0x3c,0x18,0x3c,0xce,0x0b,0x00,0x18,0xce,0x0c,0x40,0xec,0x00,0xed,0xa0,0x18,0xec,
|
||||
0x00,0x18,0xed,0xa0,0xc6,0x02,0x3a,0x18,0x3a,0x8c,0x0b,0xa0,0x25,0xec,0x18,0x38,
|
||||
0x38,0x39,0x13,0xcb,0x80,0x2a,0xd6,0xe2,0xd1,0xe1,0x22,0x02,0xd6,0xe1,0x86,0x0a,
|
||||
0x3d,0xdd,0xf0,0xd6,0xda,0x86,0x07,0x3d,0x93,0xf0,0x24,0x05,0xbd,0x47,0x6e,0x20,
|
||||
0x0f,0xbd,0xce,0x22,0x13,0xec,0x08,0x05,0xbd,0x41,0xf8,0x20,0x03,0x5f,0xd7,0xf5,
|
||||
0x39,0x3c,0x3c,0x7e,0xce,0x98,0x3c,0x3c,0xbd,0xd0,0x9b,0x13,0xe6,0x02,0x06,0x7c,
|
||||
0x02,0x8c,0x7c,0x02,0x8b,0xfe,0x02,0x6c,0xe6,0x00,0xd1,0xca,0x25,0x16,0xf6,0x02,
|
||||
0x8b,0xc1,0x02,0x24,0x07,0xf6,0x02,0x8c,0xc1,0x02,0x25,0x08,0xc6,0x03,0xf7,0x02,
|
||||
0x8c,0xf7,0x02,0x8b,0x38,0x38,0x39,0xbd,0x48,0x38,0xdd,0xf2,0xbd,0xd1,0x6b,0x39,
|
||||
0xf6,0x07,0x11,0xf7,0x02,0x75,0xc1,0xc3,0x26,0x06,0x7f,0x07,0x11,0x7e,0xc0,0x00,
|
||||
0x15,0xe9,0xc0,0xf6,0x06,0x92,0x56,0x56,0x56,0xc4,0xc0,0xda,0xe9,0xd7,0xe9,0xf6,
|
||||
0x06,0x92,0xc5,0x03,0x26,0x05,0xca,0x02,0xf7,0x06,0x92,0xbd,0xec,0xc3,0xd6,0xb7,
|
||||
0x27,0x08,0xf6,0x02,0x16,0xca,0x20,0xf7,0x02,0x16,0x8d,0x0a,0xbd,0x4b,0x05,0xbd,
|
||||
0x4b,0x23,0xbd,0xe8,0xf5,0x39,0x3c,0x3c,0x34,0x30,0x6f,0x02,0xf6,0x01,0xb4,0x5a,
|
||||
0x27,0x03,0x7e,0x4a,0xbf,0xd6,0xb7,0xf7,0x07,0x22,0x5f,0xd7,0x6a,0x18,0xce,0x02,
|
||||
0xc4,0x58,0x58,0x58,0x18,0x3a,0x18,0xe6,0x00,0xd7,0x68,0x27,0x48,0x4f,0x05,0xc3,
|
||||
0x00,0xa0,0x37,0x36,0xd6,0x6a,0x58,0x58,0x58,0x4f,0xc3,0x02,0xc4,0x18,0x8f,0x18,
|
||||
0xa6,0x02,0x5f,0xed,0x00,0x18,0xe6,0x01,0x4f,0xe3,0x00,0x18,0x38,0x18,0xed,0x00,
|
||||
0xd6,0x68,0x4f,0x05,0xc3,0x00,0x96,0x37,0x36,0xd6,0x6a,0x58,0x58,0x58,0x4f,0xc3,
|
||||
0x02,0xc4,0x18,0x8f,0x18,0xa6,0x04,0x5f,0xed,0x00,0x18,0xe6,0x03,0x4f,0xe3,0x00,
|
||||
0x18,0x38,0x18,0xed,0x00,0x7c,0x00,0x6a,0xd6,0x6a,0xc1,0x05,0x25,0x9f,0x5f,0xd7,
|
||||
0x6a,0xc6,0x91,0xd7,0x68,0xbd,0x4a,0xc3,0xbd,0x4a,0xc3,0xbd,0x4a,0xc3,0xd6,0x6a,
|
||||
0x4f,0x05,0x18,0x8f,0x18,0xec,0xa2,0xdd,0x91,0x18,0xec,0x98,0xdd,0x8f,0xd6,0x91,
|
||||
0xf7,0x07,0x32,0xd6,0x92,0xf7,0x07,0x39,0xd6,0x8f,0xf7,0x07,0x3a,0xd6,0x90,0xf7,
|
||||
0x07,0x3b,0xd6,0x6a,0x4f,0x18,0x8f,0x18,0xe6,0x93,0xf7,0x07,0x3c,0xc6,0xab,0xd7,
|
||||
0x68,0x7c,0x00,0x6a,0x8d,0x71,0x5f,0xd7,0x68,0xd7,0x6a,0x74,0x00,0x68,0x4f,0x18,
|
||||
0x8f,0x18,0xe6,0x93,0x27,0x03,0x14,0x68,0x10,0x7c,0x00,0x6a,0xd6,0x6a,0xc1,0x05,
|
||||
0x25,0xe9,0xd6,0xb7,0x27,0x03,0x14,0x68,0x20,0xf6,0x07,0x21,0xc4,0xc0,0xda,0x68,
|
||||
0xf7,0x07,0x21,0xd6,0x68,0xd7,0x6a,0xc6,0x07,0xd7,0x68,0x13,0x6a,0x02,0x04,0xc6,
|
||||
0x0c,0xd7,0x68,0x13,0x6a,0x1c,0x04,0xc6,0x21,0xd7,0x68,0x5f,0xd7,0x6a,0x20,0x12,
|
||||
0x4f,0xc3,0x06,0x92,0x18,0x8f,0xe6,0x02,0x18,0xeb,0x8f,0xe7,0x02,0x7c,0x00,0x6a,
|
||||
0xd6,0x6a,0xd1,0x68,0x25,0xea,0xd6,0x68,0x4f,0xc3,0x06,0x92,0x18,0x8f,0xe6,0x02,
|
||||
0x18,0xe7,0x8f,0x31,0x38,0x38,0x39,0x3c,0x3c,0xd6,0x6a,0x4f,0x05,0x8f,0xec,0xa2,
|
||||
0xdd,0x91,0xec,0x98,0xdd,0x8f,0xce,0x06,0x92,0xd6,0x68,0x3a,0xd6,0x91,0xe7,0x00,
|
||||
0xd6,0x68,0x4f,0xc3,0x06,0x92,0x8f,0xd6,0x92,0xe7,0x01,0xd6,0x8f,0xe7,0x02,0xd6,
|
||||
0x90,0xe7,0x03,0x3c,0xd6,0x6a,0x4f,0x8f,0xe6,0x93,0x38,0xe7,0x04,0x7c,0x00,0x6a,
|
||||
0xd6,0x68,0xcb,0x05,0xd7,0x68,0x38,0x38,0x39,0x7f,0x01,0xb4,0xd6,0xc6,0xc5,0x3f,
|
||||
0x26,0x04,0x13,0xbd,0x3f,0x05,0xc6,0x01,0xf7,0x01,0xb4,0xf6,0x02,0x75,0x5a,0x26,
|
||||
0x05,0xc6,0x01,0xf7,0x01,0xb4,0x39,0xf6,0x01,0xb4,0x5a,0x26,0x17,0x13,0xe6,0x08,
|
||||
0x0a,0xbd,0xf7,0xed,0xbd,0xef,0x0d,0xbd,0xf7,0xd6,0x39,0xbd,0xf7,0xd6,0xbd,0xef,
|
||||
0x0d,0xbd,0xf7,0xed,0x39,0x3c,0x3c,0x5f,0xd7,0x6a,0x7e,0x4b,0xcd,0x4f,0x05,0x05,
|
||||
0xc3,0x00,0x29,0xfd,0x03,0xd4,0x8f,0xe6,0x00,0x5a,0x27,0x09,0xe6,0x01,0xd1,0xc2,
|
||||
0x26,0x31,0xfe,0x03,0xd4,0xe6,0x01,0xe1,0x00,0x26,0x0e,0xe6,0x00,0x5a,0x26,0x04,
|
||||
0x6c,0x01,0x20,0x05,0xfe,0x03,0xd4,0x6a,0x00,0xe6,0x03,0xe1,0x02,0x26,0x14,0xd1,
|
||||
0xc0,0x24,0x05,0x6c,0x03,0xfe,0x03,0xd4,0xe6,0x02,0xc1,0x01,0x23,0x05,0x6a,0x02,
|
||||
0xfe,0x03,0xd4,0xe6,0x02,0x5a,0x27,0x09,0xe6,0x03,0xd1,0xc0,0x26,0x2e,0xfe,0x03,
|
||||
0xd4,0xe6,0x03,0xe1,0x02,0x26,0x0e,0xe6,0x02,0x5a,0x26,0x04,0x6c,0x03,0x20,0x05,
|
||||
0xfe,0x03,0xd4,0x6a,0x02,0xe6,0x01,0xe1,0x00,0x26,0x11,0xd1,0xc2,0x24,0x05,0x6c,
|
||||
0x01,0xfe,0x03,0xd4,0xe6,0x00,0xc1,0x01,0x23,0x02,0x6a,0x00,0x7c,0x00,0x6a,0xd6,
|
||||
0x6a,0xd1,0xc8,0x24,0x03,0x7e,0x4b,0x49,0x38,0x38,0x39,0x3c,0x3c,0x5f,0xd7,0x6a,
|
||||
0x7e,0x4c,0x86,0x4f,0x8f,0xe6,0x93,0x26,0x05,0xce,0x03,0x00,0x20,0x18,0xce,0x03,
|
||||
0x00,0xd6,0x6a,0x3a,0x6c,0x00,0xe6,0x00,0xc1,0x05,0x23,0x04,0xc6,0x05,0xe7,0x00,
|
||||
0x5a,0x26,0x0a,0xce,0x01,0x3e,0xd6,0x6a,0x3a,0x6f,0x00,0x20,0x38,0xe6,0x00,0xc1,
|
||||
0x02,0x26,0x32,0xd6,0x6a,0x58,0x58,0x4f,0xc3,0x01,0x5c,0x37,0x36,0xd6,0x6a,0x58,
|
||||
0x58,0x58,0x4f,0xc3,0x01,0xc2,0x8f,0xec,0x02,0x38,0xed,0x02,0xd6,0x6a,0x58,0x58,
|
||||
0x4f,0xc3,0x01,0x48,0x37,0x36,0xd6,0x6a,0x58,0x58,0x58,0x4f,0xc3,0x01,0xea,0x8f,
|
||||
0xec,0x02,0x38,0xed,0x02,0xce,0x01,0x39,0xd6,0x6a,0x3a,0xa6,0x00,0x27,0x36,0x4f,
|
||||
0x05,0x37,0x36,0xce,0x01,0x5c,0xd6,0x6a,0x58,0x58,0x3a,0xec,0x00,0x38,0xed,0xa2,
|
||||
0xd6,0x6a,0x4f,0x05,0x37,0x36,0xce,0x01,0x48,0xd6,0x6a,0x58,0x58,0x3a,0xec,0x00,
|
||||
0x38,0xed,0x98,0xd6,0x6a,0x4f,0x8f,0xc6,0x01,0xe7,0x93,0xce,0x01,0x43,0xd6,0x6a,
|
||||
0x3a,0xc6,0x1f,0xe7,0x00,0x7c,0x00,0x6a,0xd6,0x6a,0xd1,0xc5,0x24,0x03,0x7e,0x4b,
|
||||
0xdf,0x38,0x38,0x39,0x12,0xcb,0x20,0x03,0x7e,0x4d,0x68,0x5f,0xd7,0x6a,0x18,0xce,
|
||||
0x03,0xe7,0x7e,0x4d,0x61,0x4f,0x97,0x67,0x05,0x8f,0xec,0xa2,0xdd,0x91,0xec,0x98,
|
||||
0xdd,0x8f,0xd6,0x6a,0x86,0x03,0x3d,0xc3,0x03,0xd8,0xfd,0x03,0xd6,0x4f,0xd6,0x6a,
|
||||
0x8f,0xe6,0x93,0x26,0x09,0xbd,0x4d,0x69,0x18,0x6f,0x04,0x7e,0x4d,0x58,0x18,0x6d,
|
||||
0x04,0x26,0x0f,0x18,0xe7,0x04,0xdc,0x91,0x18,0xed,0x00,0xdc,0x8f,0x18,0xed,0x02,
|
||||
0x20,0x7a,0xfe,0x03,0xd6,0xe6,0x00,0xc1,0x01,0x26,0x0a,0xce,0x01,0x3e,0xd6,0x6a,
|
||||
0x3a,0x6f,0x00,0x20,0x67,0xdc,0x91,0x18,0xa3,0x00,0x2f,0x0a,0x05,0xb3,0x01,0x78,
|
||||
0x23,0x13,0x86,0x02,0x20,0x0d,0x43,0x53,0xc3,0x00,0x01,0x05,0xb3,0x01,0x78,0x23,
|
||||
0x04,0x86,0x01,0x97,0x67,0x96,0x67,0xfe,0x03,0xd6,0xe6,0x01,0x27,0x07,0x11,0x26,
|
||||
0x04,0xc6,0x01,0xe7,0x00,0xa7,0x01,0x7f,0x00,0x67,0xdc,0x8f,0x18,0xa3,0x02,0x2f,
|
||||
0x0a,0x05,0xb3,0x01,0x76,0x23,0x13,0x86,0x02,0x20,0x0d,0x43,0x53,0xc3,0x00,0x01,
|
||||
0x05,0xb3,0x01,0x76,0x23,0x04,0x86,0x01,0x97,0x67,0x96,0x67,0xfe,0x03,0xd6,0xe6,
|
||||
0x02,0x27,0x07,0x11,0x26,0x04,0xc6,0x01,0xe7,0x00,0xa7,0x02,0xc6,0x05,0x18,0x3a,
|
||||
0x7c,0x00,0x6a,0xd6,0x6a,0xd1,0xc5,0x24,0x03,0x7e,0x4c,0xa1,0x39,0x3c,0xfe,0x03,
|
||||
0xd6,0x6f,0x00,0x6f,0x01,0x6f,0x02,0x38,0x39,0xbd,0xd6,0x07,0xd6,0xb9,0x27,0x03,
|
||||
0x14,0xb9,0x80,0x39,0xd6,0x81,0x26,0x04,0xd6,0x68,0xd7,0x80,0xbd,0xd9,0x29,0x39,
|
||||
0xce,0x05,0xe0,0xcc,0x4d,0x80,0xed,0x68,0xcc,0x4d,0x75,0xed,0x5e,0xcc,0x49,0x12,
|
||||
0xed,0x48,0xcc,0x46,0xf8,0xed,0x06,0xcc,0x49,0x43,0xed,0x58,0xcc,0x47,0x6d,0xed,
|
||||
0x56,0xcc,0x47,0x6e,0xed,0x4e,0xcc,0x4d,0xd8,0xed,0x60,0xcc,0x49,0x0d,0xed,0x50,
|
||||
0xcc,0x4e,0x33,0xed,0x6e,0x39,0xbd,0xc4,0x92,0xce,0x06,0x92,0xcc,0x00,0x00,0xed,
|
||||
0x81,0xcc,0xe8,0x11,0xed,0x83,0xcc,0x10,0x10,0xed,0x85,0x39,0x3c,0x3c,0xd6,0xc8,
|
||||
0xd1,0xac,0x26,0x20,0xf6,0x02,0xfb,0xd1,0xac,0x27,0x08,0xd6,0xac,0xf7,0x02,0xfb,
|
||||
0x5f,0xd7,0xf4,0xd6,0xac,0x27,0x0b,0xd6,0xf4,0xc1,0xff,0x24,0x07,0x7c,0x00,0xf4,
|
||||
0x20,0x02,0xd7,0xf4,0xd6,0xc8,0x27,0x10,0xd6,0xac,0x27,0x0c,0xd6,0xc8,0xd1,0xac,
|
||||
0x27,0x06,0xd6,0xf4,0xc1,0x04,0x22,0x03,0x7e,0xf4,0x76,0xd6,0xad,0x27,0x04,0xd1,
|
||||
0xc8,0x27,0x07,0xd6,0xc8,0xd7,0xad,0x5f,0xd7,0xae,0x7e,0xf4,0xae,0xd6,0xac,0x37,
|
||||
0xbd,0xd6,0x93,0x33,0xd7,0xac,0x39,0xbd,0xf8,0xdb,0x10,0x4f,0x5f,0xfd,0x01,0x7e,
|
||||
0xd6,0x68,0x26,0x04,0xdc,0x7d,0x20,0x02,0xdc,0x7b,0xfd,0x01,0x80,0x86,0x09,0x27,
|
||||
0x0f,0x78,0x01,0xbc,0x79,0x01,0xbb,0x79,0x01,0xba,0x79,0x01,0xb9,0x4a,0x26,0xf1,
|
||||
0xdc,0x8d,0x6f,0x02,0x6f,0x03,0xed,0x0a,0xec,0x02,0xed,0x08,0xfc,0x01,0xb9,0xed,
|
||||
0x02,0xec,0x00,0xc3,0xff,0xf9,0x18,0x8f,0xfc,0x01,0xbb,0xbd,0xf9,0x9d,0x18,0xce,
|
||||
0x4f,0xb5,0xbd,0xfb,0xa9,0xdd,0x91,0x83,0x04,0x00,0x25,0x03,0x7e,0x4f,0x27,0xcc,
|
||||
0x04,0x00,0xed,0x0e,0x93,0x91,0xed,0x0c,0x83,0x01,0x00,0x22,0x1f,0xf6,0x02,0xf0,
|
||||
0x4f,0xed,0x0a,0xf6,0x02,0xed,0x18,0x8f,0xec,0x0c,0xbd,0xf9,0x08,0x3c,0xee,0x0a,
|
||||
0x02,0x8f,0x38,0xed,0x08,0xcc,0x04,0x00,0xa3,0x08,0x20,0x60,0xec,0x0c,0x83,0x02,
|
||||
0x00,0x22,0x2a,0xf6,0x02,0xf0,0x4f,0xed,0x0a,0xf6,0x02,0xee,0x18,0x8f,0xec,0x0c,
|
||||
0x83,0x01,0x00,0xbd,0xf9,0x08,0xed,0x08,0xb6,0x02,0xed,0x5f,0xe3,0x08,0x3c,0xee,
|
||||
0x0a,0x02,0x8f,0x38,0xed,0x06,0xcc,0x04,0x00,0xa3,0x06,0x20,0x2f,0xf6,0x02,0xf0,
|
||||
0x4f,0xed,0x0a,0xf6,0x02,0xef,0x18,0x8f,0xec,0x0c,0x83,0x02,0x00,0xbd,0xf9,0x08,
|
||||
0xed,0x08,0xb6,0x02,0xee,0x5f,0xed,0x06,0xb6,0x02,0xed,0xe3,0x06,0xe3,0x08,0x3c,
|
||||
0xee,0x0a,0x02,0x8f,0x38,0xed,0x04,0xcc,0x04,0x00,0xa3,0x04,0xdd,0x91,0xb3,0x01,
|
||||
0x80,0x22,0x03,0x7e,0x4f,0xb1,0x4f,0x5f,0x7e,0x4f,0xaf,0xfc,0x01,0x80,0x83,0x04,
|
||||
0x00,0x93,0x91,0x24,0xee,0xfc,0x01,0x80,0x83,0x04,0x00,0xed,0x0e,0xdc,0x91,0xa3,
|
||||
0x0e,0xed,0x0c,0x83,0x01,0x00,0x22,0x12,0xf6,0x02,0xf0,0x4f,0xed,0x0a,0xf6,0x02,
|
||||
0xed,0x18,0x8f,0xec,0x0c,0xbd,0xf9,0x08,0x20,0x44,0xec,0x0c,0x83,0x02,0x00,0x22,
|
||||
0x1b,0xf6,0x02,0xf0,0x4f,0xed,0x0a,0xf6,0x02,0xee,0x18,0x8f,0xec,0x0c,0x83,0x01,
|
||||
0x00,0xbd,0xf9,0x08,0xed,0x08,0xb6,0x02,0xed,0x5f,0x20,0x20,0xf6,0x02,0xf0,0x4f,
|
||||
0xed,0x0a,0xf6,0x02,0xef,0x18,0x8f,0xec,0x0c,0x83,0x02,0x00,0xbd,0xf9,0x08,0xed,
|
||||
0x08,0xb6,0x02,0xee,0x5f,0xed,0x06,0xb6,0x02,0xed,0xe3,0x06,0xe3,0x08,0x3c,0xee,
|
||||
0x0a,0x02,0x8f,0x38,0xe3,0x0e,0xdd,0x91,0xb3,0x01,0x80,0x25,0x08,0xfc,0x01,0x80,
|
||||
0x83,0x00,0x01,0xdd,0x91,0xae,0x00,0x38,0x39,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,281 +0,0 @@
|
||||
/* drivers/input/touchscreen/gt811.h
|
||||
*
|
||||
* Copyright (C) 2010 - 2011 Goodix, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*Any problem,please contact andrew@goodix.com,+86 755-33338828
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_GT811_H
|
||||
#define _LINUX_GT811_H
|
||||
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
//*************************TouchScreen Work Part*****************************
|
||||
#define GOODIX_I2C_NAME "gt811_ts"
|
||||
#define GT801_PLUS
|
||||
#define GT801_NUVOTON
|
||||
#define GUITAR_UPDATE_STATE 0x02
|
||||
|
||||
//define resolution of the touchscreen
|
||||
#define TOUCH_MAX_HEIGHT 800
|
||||
#define TOUCH_MAX_WIDTH 480
|
||||
//#define STOP_IRQ_TYPE // if define then no stop irq in irq_handle kuuga add 1202S
|
||||
#define REFRESH 0 //0~0x64 Scan rate = 10000/(100+REFRESH)//define resolution of the LCD
|
||||
|
||||
#if 0
|
||||
#define SHUTDOWN_PORT RK2928_PIN3_PC3
|
||||
#endif
|
||||
|
||||
#define INT_PORT
|
||||
|
||||
#if 0
|
||||
#ifdef INT_PORT
|
||||
#define TS_INT gpio_to_irq(INT_PORT) //Interrupt Number,EINT18(119)
|
||||
// #define INT_CFG S3C_GPIO_SFN(3) //IO configer as EINT
|
||||
#else
|
||||
#define TS_INT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////// UPDATE STEP 5 START /////////////////////////////////////////////////////////////////
|
||||
#define TPD_CHIP_VERSION_C_FIRMWARE_BASE 0x5A
|
||||
#define TPD_CHIP_VERSION_D1_FIRMWARE_BASE 0x7A
|
||||
#define TPD_CHIP_VERSION_E_FIRMWARE_BASE 0x9A
|
||||
#define TPD_CHIP_VERSION_D2_FIRMWARE_BASE 0xBA
|
||||
|
||||
|
||||
/////////////////////////////// UPDATE STEP 5 END /////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FLAG_UP 0
|
||||
#define FLAG_DOWN 1
|
||||
//set GT801 PLUS trigger mode,ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>1
|
||||
//#define INT_TRIGGER 1 // 1=rising 0=falling
|
||||
#define POLL_TIME 10 //actual query spacing interval:POLL_TIME+6
|
||||
|
||||
#define GOODIX_MULTI_TOUCH
|
||||
#ifdef GOODIX_MULTI_TOUCH
|
||||
#define MAX_FINGER_NUM 5
|
||||
#else
|
||||
#define MAX_FINGER_NUM 1
|
||||
#endif
|
||||
|
||||
#if defined(INT_PORT)
|
||||
#if MAX_FINGER_NUM <= 3
|
||||
#define READ_BYTES_NUM 2+2+MAX_FINGER_NUM*5
|
||||
#elif MAX_FINGER_NUM == 4
|
||||
#define READ_BYTES_NUM 2+28
|
||||
#elif MAX_FINGER_NUM == 5
|
||||
#define READ_BYTES_NUM 2+34
|
||||
#endif
|
||||
#else
|
||||
#define READ_BYTES_NUM 2+34
|
||||
#endif
|
||||
|
||||
#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
|
||||
|
||||
#define READ_TOUCH_ADDR_H 0x07
|
||||
#define READ_TOUCH_ADDR_L 0x21 //GT811 0x721
|
||||
#define READ_KEY_ADDR_H 0x07
|
||||
#define READ_KEY_ADDR_L 0x21
|
||||
#define READ_COOR_ADDR_H 0x07
|
||||
#define READ_COOR_ADDR_L 0x22
|
||||
#define READ_ID_ADDR_H 0x00
|
||||
#define READ_ID_ADDR_L 0xff
|
||||
//****************************<2A><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>******************************************
|
||||
|
||||
//******************************************************************************
|
||||
struct gt811_ts_data {
|
||||
uint16_t addr;
|
||||
uint8_t bad_data;
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
int use_reset; //use RESET flag
|
||||
int use_irq; //use EINT flag
|
||||
int read_mode; //read moudle mode,20110221 by andrew
|
||||
struct hrtimer timer;
|
||||
struct work_struct work;
|
||||
char phys[32];
|
||||
int retry;
|
||||
int irq;
|
||||
spinlock_t irq_lock; //add by kuuga
|
||||
int irq_is_disable; /* 0: irq enable */ //add by kuuga
|
||||
uint16_t abs_x_max;
|
||||
uint16_t abs_y_max;
|
||||
uint8_t max_touch_num;
|
||||
uint8_t int_trigger_type;
|
||||
uint8_t btn_state; // key states
|
||||
/////////////////////////////// UPDATE STEP 6 START /////////////////////////////////////////////////////////////////
|
||||
unsigned int version;
|
||||
/////////////////////////////// UPDATE STEP 6 END /////////////////////////////////////////////////////////////////
|
||||
|
||||
struct early_suspend early_suspend;
|
||||
int (*power)(struct gt811_ts_data * ts, int on);
|
||||
};
|
||||
|
||||
//*****************************End of Part I *********************************
|
||||
|
||||
//*************************Touchkey Surpport Part*****************************
|
||||
/*#define HAVE_TOUCH_KEY
|
||||
//#define READ_KEY_VALUE
|
||||
//#define READ_KEY_COOR
|
||||
|
||||
#ifdef HAVE_TOUCH_KEY
|
||||
const uint16_t toucher_key_array[]={
|
||||
KEY_MENU, //MENU
|
||||
KEY_HOME,
|
||||
KEY_BACK,
|
||||
KEY_SEARCH
|
||||
};
|
||||
#define MAX_KEY_NUM (sizeof(toucher_key_array)/sizeof(toucher_key_array[0]))
|
||||
#endif
|
||||
*/
|
||||
//#define COOR_TO_KEY
|
||||
#ifdef COOR_TO_KEY
|
||||
|
||||
#define KEY_X 40
|
||||
#define KEY_Y 20
|
||||
#if 0
|
||||
#define AREA_X 0
|
||||
#else
|
||||
#define AREA_Y 800
|
||||
#endif
|
||||
|
||||
enum {x, y};
|
||||
s32 key_center[MAX_KEY_NUM][2] = {
|
||||
|
||||
{48,840},{124,840},{208,840},{282,840}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//*****************************End of Part II*********************************
|
||||
|
||||
/////////////////////////////// UPDATE STEP 7 START /////////////////////////////////////////////////////////////////
|
||||
//*************************Firmware Update part*******************************
|
||||
//#define AUTO_UPDATE_GT811
|
||||
|
||||
#define CONFIG_TOUCHSCREEN_GOODIX_IAP
|
||||
#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
|
||||
static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data);
|
||||
static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data );
|
||||
|
||||
#define PACK_SIZE 64 //update file package size
|
||||
//#define MAX_TIMEOUT 30000 //update time out conut
|
||||
//#define MAX_I2C_RETRIES 10 //i2c retry times
|
||||
|
||||
//write cmd
|
||||
#define APK_UPDATE_TP 1
|
||||
#define APK_READ_FUN 10
|
||||
#define APK_WRITE_CFG 11
|
||||
|
||||
//fun cmd
|
||||
//#define CMD_DISABLE_TP 0
|
||||
//#define CMD_ENABLE_TP 1
|
||||
#define CMD_READ_VER 2
|
||||
#define CMD_READ_RAW 3
|
||||
#define CMD_READ_DIF 4
|
||||
#define CMD_READ_CFG 5
|
||||
#define CMD_READ_CHIP_TYPE 6
|
||||
//#define CMD_SYS_REBOOT 101
|
||||
|
||||
//read mode
|
||||
#define MODE_RD_VER 1
|
||||
#define MODE_RD_RAW 2
|
||||
#define MODE_RD_DIF 3
|
||||
#define MODE_RD_CFG 4
|
||||
#define MODE_RD_CHIP_TYPE 5
|
||||
|
||||
#if 0
|
||||
struct tpd_firmware_info_t
|
||||
{
|
||||
int magic_number_1;
|
||||
int magic_number_2;
|
||||
unsigned short version;
|
||||
unsigned short length;
|
||||
unsigned short checksum;
|
||||
unsigned char data;
|
||||
};
|
||||
#else
|
||||
#pragma pack(1)
|
||||
struct tpd_firmware_info_t
|
||||
{
|
||||
unsigned char chip_type;
|
||||
unsigned short version;
|
||||
unsigned char rom_version;
|
||||
unsigned char reserved[3];
|
||||
unsigned short start_addr;
|
||||
unsigned short length;
|
||||
unsigned char checksum[3];
|
||||
unsigned char mandatory_flag[6];
|
||||
unsigned char data;
|
||||
};
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#define NVRAM_LEN 0x0FF0 // nvram total space
|
||||
#define NVRAM_BOOT_SECTOR_LEN 0x0100 // boot sector
|
||||
#define NVRAM_UPDATE_START_ADDR 0x4100
|
||||
|
||||
#define BIT_NVRAM_STROE 0
|
||||
#define BIT_NVRAM_RECALL 1
|
||||
#define BIT_NVRAM_LOCK 2
|
||||
#define REG_NVRCS_H 0X12
|
||||
#define REG_NVRCS_L 0X01
|
||||
#define GT811_SET_INT_PIN( gpio, level ) gpio_direction_output(gpio, level) //null macro now
|
||||
#endif
|
||||
//*****************************End of Part III********************************
|
||||
/////////////////////////////// UPDATE STEP 7 END /////////////////////////////////////////////////////////////////
|
||||
|
||||
struct gt811_platform_data {
|
||||
uint32_t version; /* Use this entry for panels with */
|
||||
u16 model; /* 801. */
|
||||
bool swap_xy; /* swap x and y axes */
|
||||
u16 x_min, x_max;
|
||||
u16 y_min, y_max;
|
||||
bool x_reverse, y_reverse;
|
||||
int (*get_pendown_state)(void);
|
||||
int (*init_platform_hw)(void);
|
||||
int (*platform_sleep)(void);
|
||||
int (*platform_wakeup)(void);
|
||||
void (*exit_platform_hw)(void);
|
||||
int gpio_reset;
|
||||
bool gpio_reset_active_low;
|
||||
|
||||
|
||||
//reservation
|
||||
};
|
||||
|
||||
#define RAW_DATA_READY 1
|
||||
#define RAW_DATA_NON_ACTIVE 0xffffffff
|
||||
#define RAW_DATA_ACTIVE 0
|
||||
|
||||
|
||||
enum CHIP_TYPE
|
||||
{
|
||||
GT800 = 1,
|
||||
GT800PLUS,
|
||||
GT800PLUS3,
|
||||
GT816,
|
||||
GT811,
|
||||
GT8105,
|
||||
GT8110,
|
||||
GT818PLUS
|
||||
};
|
||||
|
||||
|
||||
#endif /* _LINUX_GOODIX_TOUCH_H */
|
||||
@@ -1,856 +0,0 @@
|
||||
/* drivers/input/touchscreen/gt818_ts.c
|
||||
*
|
||||
* Copyright (C) 2011 Rockcip, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Author: hhb@rock-chips.com
|
||||
* Date: 2011.06.20
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#include <linux/irq.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/completion.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/input/mt.h>
|
||||
|
||||
#include "gt818_ts.h"
|
||||
|
||||
|
||||
|
||||
#if !defined(GT801_PLUS) && !defined(GT801_NUVOTON)
|
||||
#error The code does not match this touchscreen.
|
||||
#endif
|
||||
|
||||
static struct workqueue_struct *goodix_wq;
|
||||
|
||||
static const char *gt818_ts_name = "Goodix Capacitive TouchScreen";
|
||||
|
||||
//static struct point_queue finger_list;
|
||||
|
||||
struct i2c_client * i2c_connect_client = NULL;
|
||||
|
||||
//EXPORT_SYMBOL(i2c_connect_client);
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void goodix_ts_early_suspend(struct early_suspend *h);
|
||||
static void goodix_ts_late_resume(struct early_suspend *h);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TOUCH_KEY
|
||||
const uint16_t gt818_key_array[]={
|
||||
KEY_MENU,
|
||||
KEY_HOME,
|
||||
KEY_BACK,
|
||||
KEY_SEARCH
|
||||
};
|
||||
#define MAX_KEY_NUM (sizeof(gt818_key_array)/sizeof(gt818_key_array[0]))
|
||||
#endif
|
||||
|
||||
unsigned int last_x[MAX_FINGER_NUM + 1]= {0};
|
||||
unsigned int last_y[MAX_FINGER_NUM + 1]= {0};
|
||||
|
||||
|
||||
/*Function as i2c_master_send */
|
||||
static int i2c_read_bytes(struct i2c_client *client, u8 *buf, int len)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
int ret = -1;
|
||||
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].flags = client->flags;
|
||||
msgs[0].len = 2;
|
||||
msgs[0].buf = &buf[0];
|
||||
msgs[0].scl_rate = GT818_I2C_SCL;
|
||||
msgs[0].udelay = client->udelay;
|
||||
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].flags = client->flags | I2C_M_RD;
|
||||
msgs[1].len = len-2;
|
||||
msgs[1].buf = &buf[2];
|
||||
msgs[1].scl_rate = GT818_I2C_SCL;
|
||||
msgs[1].udelay = client->udelay;
|
||||
|
||||
ret = i2c_transfer(client->adapter, msgs, 2);
|
||||
if(ret < 0)
|
||||
printk("%s:i2c_transfer fail =%d\n",__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Function as i2c_master_send */
|
||||
static int i2c_write_bytes(struct i2c_client *client,u8 *data,int len)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
int ret = -1;
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = client->flags;
|
||||
msg.len = len;
|
||||
msg.buf = data;
|
||||
msg.scl_rate = GT818_I2C_SCL;
|
||||
msg.udelay = client->udelay;
|
||||
|
||||
ret = i2c_transfer(client->adapter, &msg, 1);
|
||||
if(ret < 0)
|
||||
printk("%s:i2c_transfer fail =%d\n",__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int i2c_pre_cmd(struct gt818_ts_data *ts)
|
||||
{
|
||||
int ret;
|
||||
u8 pre_cmd_data[2] = {0};
|
||||
pre_cmd_data[0] = 0x0f;
|
||||
pre_cmd_data[1] = 0xff;
|
||||
ret = i2c_write_bytes(ts->client,pre_cmd_data,2);
|
||||
udelay(20);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int i2c_end_cmd(struct gt818_ts_data *ts)
|
||||
{
|
||||
int ret;
|
||||
u8 end_cmd_data[2] = {0};
|
||||
end_cmd_data[0] = 0x80;
|
||||
end_cmd_data[1] = 0x00;
|
||||
ret = i2c_write_bytes(ts->client,end_cmd_data,2);
|
||||
udelay(20);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int goodix_init_panel(struct gt818_ts_data *ts)
|
||||
{
|
||||
int ret = -1;
|
||||
int i = 0;
|
||||
#if 1
|
||||
u8 config_info[] = {
|
||||
0x06,0xA2,
|
||||
0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
|
||||
0x10,0x12,0x00,0x00,0x10,0x00,0x20,0x00,
|
||||
0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,
|
||||
0xE0,0x00,0xD0,0x00,0xC0,0x00,0xB0,0x00,
|
||||
0xA0,0x00,0x90,0x00,0x80,0x00,0x70,0x00,
|
||||
0xF0,0x00,0x13,0x13,0x90,0x90,0x90,0x27,
|
||||
0x27,0x27,0x0F,0x0E,0x0A,0x40,0x30,0x01,
|
||||
0x03,0x00,MAX_FINGER_NUM,0x00,0x14,0xFA,0x1B,0x00,
|
||||
0x00,0x66,0x5A,0x6A,0x5E,0x00,0x00,0x05,
|
||||
0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x14,0x10,0xEF,0x03,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x20,0x40,0x70,0x90,0x0F,0x40,
|
||||
0x30,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x01
|
||||
};
|
||||
#endif
|
||||
u8 read_config_info[sizeof(config_info)] = {0};
|
||||
read_config_info[0] = 0x06;
|
||||
read_config_info[1] = 0xa2;
|
||||
|
||||
ret = i2c_write_bytes(ts->client, config_info, (sizeof(config_info)/sizeof(config_info[0])));
|
||||
if (ret < 0) {
|
||||
printk("config gt818 fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_read_bytes(ts->client, read_config_info, (sizeof(config_info)/sizeof(config_info[0])));
|
||||
if (ret < 0){
|
||||
printk("read gt818 config fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(i = 2; i < 106; i++){
|
||||
if(read_config_info[i] != config_info[i]){
|
||||
printk("write gt818 config error\n");
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
msleep(10);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int goodix_read_version(struct gt818_ts_data *ts)
|
||||
{
|
||||
int ret;
|
||||
u8 version_data[5] = {0}; //store touchscreen version infomation
|
||||
memset(version_data, 0, 5);
|
||||
version_data[0] = 0x07;
|
||||
version_data[1] = 0x17;
|
||||
msleep(2);
|
||||
ret = i2c_read_bytes(ts->client, version_data, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
dev_info(&ts->client->dev," Guitar Version: %d.%d\n",version_data[3],version_data[2]);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void goodix_ts_work_func(struct work_struct *work)
|
||||
{
|
||||
u8 touch_status[8*MAX_FINGER_NUM + 18] = {READ_TOUCH_ADDR_H, READ_TOUCH_ADDR_L, 0};
|
||||
u8 *key_value = NULL;
|
||||
u8 *point_data = NULL;
|
||||
static u8 finger_last[MAX_FINGER_NUM + 1]={0};
|
||||
u8 finger_current[MAX_FINGER_NUM + 1] = {0};
|
||||
u8 coor_data[6*MAX_FINGER_NUM] = {0};
|
||||
static u8 last_key = 0;
|
||||
|
||||
u8 finger = 0;
|
||||
u8 key = 0;
|
||||
unsigned int count = 0;
|
||||
unsigned int position = 0;
|
||||
int temp = 0;
|
||||
int x = 0, y = 0 , pressure;
|
||||
|
||||
u16 *coor_point;
|
||||
|
||||
int syn_flag = 0;
|
||||
|
||||
struct gt818_ts_data *ts = container_of(work, struct gt818_ts_data, work);
|
||||
|
||||
i2c_pre_cmd(ts);
|
||||
i2c_read_bytes(ts->client, touch_status, sizeof(touch_status)/sizeof(touch_status[0]));
|
||||
i2c_end_cmd(ts);
|
||||
|
||||
//judge whether the data is ready
|
||||
if((touch_status[2] & 0x30) != 0x20)
|
||||
{
|
||||
printk("%s:DATA_NO_READY\n", __func__);
|
||||
goto DATA_NO_READY;
|
||||
}
|
||||
//judge whether it is large area touch
|
||||
if(touch_status[13] & 0x0f)
|
||||
{
|
||||
goto DATA_NO_READY;
|
||||
}
|
||||
|
||||
ts->bad_data = 0;
|
||||
finger = touch_status[2] & 0x07;
|
||||
key_value = touch_status + 15;
|
||||
key = key_value[2] & 0x0f;
|
||||
|
||||
if(finger > 0)
|
||||
{
|
||||
point_data = key_value + 3;
|
||||
|
||||
for(position = 0; position < (finger*8); position += 8)
|
||||
{
|
||||
temp = point_data[position];
|
||||
//printk("track:%d\n", temp);
|
||||
if(temp < (MAX_FINGER_NUM + 1))
|
||||
{
|
||||
finger_current[temp] = 1;
|
||||
for(count = 0; count < 6; count++)
|
||||
{
|
||||
coor_data[(temp - 1) * 6 + count] = point_data[position+1+count];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//dev_err(&(ts->client->dev),"Track Id error:%d\n ",);
|
||||
ts->bad_data = 1;
|
||||
ts->retry++;
|
||||
goto XFER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
for(position = 1; position < MAX_FINGER_NUM+1; position++)
|
||||
{
|
||||
finger_current[position] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
coor_point = (u16 *)coor_data;
|
||||
|
||||
for(position = 1; position < MAX_FINGER_NUM + 1; position++)
|
||||
{
|
||||
if((finger_current[position] == 0) && (finger_last[position] != 0))
|
||||
{
|
||||
//printk("<<<<<<<<<<<<<<<<<<<%s:positon:%d (%d,%d)\n", __func__, position,last_x,last_y);
|
||||
//printk("<<<%d , %d ",finger_current[position],finger_last[position]);
|
||||
//input_mt_slot(ts->input_dev, position);
|
||||
//input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
|
||||
//input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
||||
//input_report_abs(ts->input_dev, ABS_MT_POSITION_X, last_x[position]);
|
||||
//input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, last_y[position]);
|
||||
//input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100);
|
||||
//input_mt_sync(ts->input_dev);
|
||||
input_mt_slot(ts->input_dev, position);
|
||||
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
|
||||
syn_flag = 1;
|
||||
}
|
||||
else if(finger_current[position])
|
||||
{
|
||||
x = (*(coor_point+3*(position-1)))*SCREEN_MAX_WIDTH/(TOUCH_MAX_WIDTH);
|
||||
y = (*(coor_point+3*(position-1)+1))*SCREEN_MAX_HEIGHT/(TOUCH_MAX_HEIGHT);
|
||||
pressure = (*(coor_point+3*(position-1)+2));
|
||||
if(x < SCREEN_MAX_WIDTH){
|
||||
x = SCREEN_MAX_WIDTH - x;
|
||||
}
|
||||
|
||||
if(y < SCREEN_MAX_HEIGHT){
|
||||
// y = SCREEN_MAX_HEIGHT-y;
|
||||
}
|
||||
|
||||
//printk(">>>>>>>>>>>>>>>>>%s:positon:%d (%d,%d)\n", __func__, position,x,y);
|
||||
input_mt_slot(ts->input_dev, position);
|
||||
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
|
||||
input_report_abs(ts->input_dev, ABS_MT_PRESSURE, pressure);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
|
||||
|
||||
last_x[position] = x;
|
||||
last_y[position] = y;
|
||||
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure);
|
||||
//input_mt_sync(ts->input_dev);
|
||||
syn_flag = 1;
|
||||
}
|
||||
|
||||
}
|
||||
input_sync(ts->input_dev);
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_TOUCH_KEY
|
||||
if((last_key == 0) && (key == 0)){
|
||||
goto NO_KEY_PRESS;
|
||||
}
|
||||
else{
|
||||
syn_flag = 1;
|
||||
switch(key){
|
||||
case 1:
|
||||
key = 4;
|
||||
break;
|
||||
case 2:
|
||||
key = 3;
|
||||
break;
|
||||
case 4:
|
||||
key = 2;
|
||||
break;
|
||||
case 8:
|
||||
key = 1;
|
||||
break;
|
||||
default:
|
||||
key = 0;
|
||||
break;
|
||||
}
|
||||
if(key != 0){
|
||||
input_report_key(ts->input_dev, gt818_key_array[key - 1], 1);
|
||||
}
|
||||
else{
|
||||
input_report_key(ts->input_dev, gt818_key_array[last_key - 1], 0);
|
||||
}
|
||||
last_key = key;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
NO_KEY_PRESS:
|
||||
if(syn_flag){
|
||||
input_sync(ts->input_dev);
|
||||
}
|
||||
|
||||
for(position = 1; position < MAX_FINGER_NUM + 1; position++)
|
||||
{
|
||||
finger_last[position] = finger_current[position];
|
||||
}
|
||||
|
||||
DATA_NO_READY:
|
||||
XFER_ERROR:
|
||||
// i2c_end_cmd(ts);
|
||||
if(ts->use_irq)
|
||||
enable_irq(ts->client->irq);
|
||||
|
||||
}
|
||||
#if 0
|
||||
static int test_suspend_resume(struct gt818_ts_data *ts){
|
||||
while(1){
|
||||
ts->power(ts, 0);
|
||||
msleep(5000);
|
||||
ts->power(ts, 1);
|
||||
msleep(5000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer)
|
||||
{
|
||||
struct gt818_ts_data *ts = container_of(timer, struct gt818_ts_data, timer);
|
||||
queue_work(goodix_wq, &ts->work);
|
||||
hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gt818_ts_data *ts = dev_id;
|
||||
disable_irq_nosync(ts->client->irq);
|
||||
queue_work(goodix_wq, &ts->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int goodix_ts_power(struct gt818_ts_data * ts, int on)
|
||||
{
|
||||
int ret = -1;
|
||||
struct gt818_platform_data *pdata = ts->client->dev.platform_data;
|
||||
unsigned char i2c_control_buf[3] = {0x06,0x92,0x01}; //suspend cmd
|
||||
if(ts != NULL && !ts->use_irq)
|
||||
return -2;
|
||||
switch(on)
|
||||
{
|
||||
case 0:
|
||||
i2c_pre_cmd(ts);
|
||||
// set the io port high level to avoid level change which might stop gt818 from sleeping
|
||||
gpio_direction_output(pdata->gpio_reset, 1);
|
||||
gpio_direction_output(pdata->gpio_pendown, 1);
|
||||
msleep(5);
|
||||
ret = i2c_write_bytes(ts->client, i2c_control_buf, 3);
|
||||
if(ret < 0)
|
||||
{
|
||||
printk(KERN_INFO"**gt818 suspend fail**\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//printk(KERN_INFO"**gt818 suspend**\n");
|
||||
ret = 0;
|
||||
}
|
||||
// i2c_end_cmd(ts);
|
||||
return ret;
|
||||
|
||||
case 1:
|
||||
|
||||
gpio_pull_updown(pdata->gpio_pendown, 1);
|
||||
gpio_direction_output(pdata->gpio_pendown, 0);
|
||||
msleep(1);
|
||||
gpio_direction_output(pdata->gpio_pendown, 1);
|
||||
msleep(1);
|
||||
gpio_direction_input(pdata->gpio_pendown);
|
||||
gpio_pull_updown(pdata->gpio_pendown, 0);
|
||||
|
||||
/*
|
||||
msleep(2);
|
||||
gpio_pull_updown(pdata->gpio_reset, 1);
|
||||
gpio_direction_output(pdata->gpio_reset, 0);
|
||||
msleep(2);
|
||||
gpio_direction_input(pdata->gpio_reset);
|
||||
gpio_pull_updown(pdata->gpio_reset, 0);
|
||||
msleep(30);
|
||||
*/
|
||||
msleep(1);
|
||||
ret = i2c_pre_cmd(ts);
|
||||
//printk(KERN_INFO"**gt818 reusme**\n");
|
||||
ret = i2c_end_cmd(ts);
|
||||
|
||||
return ret;
|
||||
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: Cant't support this command.", gt818_ts_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
int retry=0;
|
||||
struct gt818_ts_data *ts;
|
||||
|
||||
struct gt818_platform_data *pdata;
|
||||
dev_info(&client->dev,"Install touch driver.\n");
|
||||
printk("gt818: Install touch driver.\n");
|
||||
//Check I2C function
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
{
|
||||
dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
|
||||
ret = -ENODEV;
|
||||
goto err_check_functionality_failed;
|
||||
}
|
||||
|
||||
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
|
||||
if (ts == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc_data_failed;
|
||||
}
|
||||
|
||||
i2c_connect_client = client; //used by Guitar_Update
|
||||
pdata = client->dev.platform_data;
|
||||
ts->client = client;
|
||||
i2c_set_clientdata(client, ts);
|
||||
|
||||
//init int and reset ports
|
||||
ret = gpio_request(pdata->gpio_pendown, "TS_INT"); //Request IO
|
||||
if (ret){
|
||||
dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)pdata->gpio_pendown, ret);
|
||||
goto err_gpio_request_failed;
|
||||
}
|
||||
rk29_mux_api_set(pdata->pendown_iomux_name, pdata->pendown_iomux_mode);
|
||||
gpio_direction_input(pdata->gpio_pendown);
|
||||
gpio_pull_updown(pdata->gpio_pendown, 0);
|
||||
|
||||
ret = gpio_request(pdata->gpio_reset, "gt818_resetPin");
|
||||
if(ret){
|
||||
dev_err(&client->dev, "failed to request resetPin GPIO%d\n", pdata->gpio_reset);
|
||||
goto err_gpio_request_failed;
|
||||
}
|
||||
rk29_mux_api_set(pdata->resetpin_iomux_name, pdata->resetpin_iomux_mode);
|
||||
|
||||
#if 1
|
||||
for(retry = 0; retry < 4; retry++)
|
||||
{
|
||||
gpio_pull_updown(pdata->gpio_reset, 1);
|
||||
gpio_direction_output(pdata->gpio_reset, 0);
|
||||
msleep(1); //delay at least 1ms
|
||||
gpio_direction_input(pdata->gpio_reset);
|
||||
gpio_pull_updown(pdata->gpio_reset, 0);
|
||||
msleep(25); //delay at least 20ms
|
||||
ret = i2c_pre_cmd(ts);
|
||||
if (ret > 0)
|
||||
break;
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
if(ret <= 0)
|
||||
{
|
||||
dev_err(&client->dev, "Warnning: I2C communication might be ERROR!\n");
|
||||
goto err_i2c_failed;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
for(retry = 0; retry < 3; retry++)
|
||||
{
|
||||
ret = goodix_init_panel(ts);
|
||||
|
||||
dev_info(&client->dev,"the config ret is :%d\n", ret);
|
||||
msleep(20);
|
||||
if(ret < 0) //Initiall failed
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret < 0) {
|
||||
ts->bad_data = 1;
|
||||
goto err_init_godix_ts;
|
||||
}
|
||||
|
||||
goodix_read_version(ts);
|
||||
|
||||
|
||||
INIT_WORK(&ts->work, goodix_ts_work_func); //init work_struct
|
||||
ts->input_dev = input_allocate_device();
|
||||
if (ts->input_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
dev_dbg(&client->dev,"goodix_ts_probe: Failed to allocate input device\n");
|
||||
goto err_input_dev_alloc_failed;
|
||||
}
|
||||
|
||||
//ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;
|
||||
//ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
//ts->input_dev->absbit[0] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) |
|
||||
// BIT_MASK(ABS_MT_TOUCH_MAJOR) | BIT_MASK(ABS_MT_WIDTH_MAJOR); // for android
|
||||
|
||||
|
||||
#ifdef HAVE_TOUCH_KEY
|
||||
for(retry = 0; retry < MAX_KEY_NUM; retry++)
|
||||
{
|
||||
input_set_capability(ts->input_dev, EV_KEY, gt818_key_array[retry]);
|
||||
}
|
||||
#endif
|
||||
|
||||
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev));
|
||||
snprintf(ts->name, sizeof(ts->name), "gt818-touchscreen");
|
||||
|
||||
ts->input_dev->name = "gt818_ts";//ts->name;
|
||||
ts->input_dev->phys = ts->phys;
|
||||
ts->input_dev->dev.parent = &client->dev;
|
||||
ts->input_dev->id.bustype = BUS_I2C;
|
||||
ts->input_dev->id.vendor = 0xDEAD;
|
||||
ts->input_dev->id.product = 0xBEEF;
|
||||
ts->input_dev->id.version = 10427; //screen firmware version
|
||||
|
||||
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
|
||||
__set_bit(EV_ABS, ts->input_dev->evbit);
|
||||
#ifdef GOODIX_MULTI_TOUCH
|
||||
input_mt_init_slots(ts->input_dev, MAX_FINGER_NUM);
|
||||
//input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_WIDTH, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_HEIGHT, 0, 0);
|
||||
//input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, MAX_FINGER_NUM, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
|
||||
#else
|
||||
input_set_abs_params(ts->input_dev, ABS_X, 0, SCREEN_MAX_HEIGHT, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_Y, 0, SCREEN_MAX_WIDTH, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
|
||||
#endif
|
||||
|
||||
ret = input_register_device(ts->input_dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name);
|
||||
goto err_input_register_device_failed;
|
||||
}
|
||||
ts->bad_data = 0;
|
||||
// 16finger_list.length = 0;
|
||||
|
||||
client->irq = gpio_to_irq(pdata->gpio_pendown); //If not defined in client
|
||||
if (client->irq)
|
||||
{
|
||||
|
||||
#if INT_TRIGGER==0
|
||||
#define GT801_PLUS_IRQ_TYPE IRQ_TYPE_EDGE_RISING
|
||||
#elif INT_TRIGGER==1
|
||||
#define GT801_PLUS_IRQ_TYPE IRQ_TYPE_EDGE_FALLING
|
||||
#elif INT_TRIGGER==2
|
||||
#define GT801_PLUS_IRQ_TYPE IRQ_TYPE_LEVEL_LOW
|
||||
#elif INT_TRIGGER==3
|
||||
#define GT801_PLUS_IRQ_TYPE IRQ_TYPE_LEVEL_HIGH
|
||||
#endif
|
||||
|
||||
ret = request_irq(client->irq, goodix_ts_irq_handler, GT801_PLUS_IRQ_TYPE,
|
||||
client->name, ts);
|
||||
if (ret != 0) {
|
||||
dev_err(&client->dev,"Cannot allocate ts INT!ERRNO:%d\n", ret);
|
||||
gpio_direction_input(pdata->gpio_pendown);
|
||||
gpio_free(pdata->gpio_pendown);
|
||||
goto err_gpio_request_failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
disable_irq(client->irq);
|
||||
ts->use_irq = 1;
|
||||
dev_dbg(&client->dev,"Reques EIRQ %d succesd on GPIO:%d\n", client->irq, pdata->gpio_pendown);
|
||||
}
|
||||
}
|
||||
|
||||
err_gpio_request_failed:
|
||||
ts->power = goodix_ts_power;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
||||
ts->early_suspend.suspend = goodix_ts_early_suspend;
|
||||
ts->early_suspend.resume = goodix_ts_late_resume;
|
||||
register_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
dev_info(&client->dev,"Start %s in %s mode\n",
|
||||
ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
|
||||
|
||||
if (ts->use_irq)
|
||||
{
|
||||
enable_irq(client->irq);
|
||||
}
|
||||
else
|
||||
{
|
||||
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
ts->timer.function = goodix_ts_timer_func;
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
i2c_end_cmd(ts);
|
||||
return 0;
|
||||
|
||||
err_init_godix_ts:
|
||||
i2c_end_cmd(ts);
|
||||
if(ts->use_irq)
|
||||
{
|
||||
ts->use_irq = 0;
|
||||
free_irq(client->irq,ts);
|
||||
gpio_direction_input(pdata->gpio_pendown);
|
||||
gpio_free(pdata->gpio_pendown);
|
||||
}
|
||||
else
|
||||
hrtimer_cancel(&ts->timer);
|
||||
|
||||
err_input_register_device_failed:
|
||||
input_free_device(ts->input_dev);
|
||||
|
||||
err_input_dev_alloc_failed:
|
||||
i2c_set_clientdata(client, NULL);
|
||||
err_i2c_failed:
|
||||
kfree(ts);
|
||||
err_alloc_data_failed:
|
||||
err_check_functionality_failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int goodix_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
struct gt818_ts_data *ts = i2c_get_clientdata(client);
|
||||
struct gt818_platform_data *pdata = client->dev.platform_data;
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
|
||||
remove_proc_entry("goodix-update", NULL);
|
||||
#endif
|
||||
if (ts && ts->use_irq)
|
||||
{
|
||||
gpio_direction_input(pdata->gpio_pendown);
|
||||
gpio_free(pdata->gpio_pendown);
|
||||
free_irq(client->irq, ts);
|
||||
}
|
||||
else if(ts)
|
||||
hrtimer_cancel(&ts->timer);
|
||||
|
||||
dev_notice(&client->dev,"The driver is removing...\n");
|
||||
i2c_set_clientdata(client, NULL);
|
||||
input_unregister_device(ts->input_dev);
|
||||
kfree(ts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int goodix_ts_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
int ret;
|
||||
struct gt818_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
if (ts->use_irq)
|
||||
disable_irq(client->irq);
|
||||
else
|
||||
hrtimer_cancel(&ts->timer);
|
||||
//ret = cancel_work_sync(&ts->work);
|
||||
//if(ret && ts->use_irq)
|
||||
//enable_irq(client->irq);
|
||||
if (ts->power) {
|
||||
ret = ts->power(ts, 0);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "goodix_ts_resume power off failed\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int goodix_ts_resume(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct gt818_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
if (ts->power) {
|
||||
ret = ts->power(ts, 1);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "goodix_ts_resume power on failed\n");
|
||||
}
|
||||
|
||||
if (ts->use_irq)
|
||||
enable_irq(client->irq);
|
||||
else
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void goodix_ts_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct gt818_ts_data *ts;
|
||||
ts = container_of(h, struct gt818_ts_data, early_suspend);
|
||||
goodix_ts_suspend(ts->client, PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
static void goodix_ts_late_resume(struct early_suspend *h)
|
||||
{
|
||||
struct gt818_ts_data *ts;
|
||||
ts = container_of(h, struct gt818_ts_data, early_suspend);
|
||||
goodix_ts_resume(ts->client);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//only one client
|
||||
static const struct i2c_device_id goodix_ts_id[] = {
|
||||
{ GOODIX_I2C_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
static struct i2c_driver goodix_ts_driver = {
|
||||
.probe = goodix_ts_probe,
|
||||
.remove = goodix_ts_remove,
|
||||
#ifndef CONFIG_HAS_EARLYSUSPEND
|
||||
.suspend = goodix_ts_suspend,
|
||||
.resume = goodix_ts_resume,
|
||||
#endif
|
||||
.id_table = goodix_ts_id,
|
||||
.driver = {
|
||||
.name = GOODIX_I2C_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static int __devinit goodix_ts_init(void)
|
||||
{
|
||||
int ret;
|
||||
goodix_wq = create_singlethread_workqueue("goodix_wq"); //create a work queue and worker thread
|
||||
if (!goodix_wq) {
|
||||
printk(KERN_ALERT "creat workqueue faiked\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ret = i2c_add_driver(&goodix_ts_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void __exit goodix_ts_exit(void)
|
||||
{
|
||||
printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");
|
||||
i2c_del_driver(&goodix_ts_driver);
|
||||
if (goodix_wq)
|
||||
destroy_workqueue(goodix_wq); //release our work queue
|
||||
}
|
||||
|
||||
late_initcall(goodix_ts_init);
|
||||
module_exit(goodix_ts_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Goodix Touchscreen Driver");
|
||||
MODULE_AUTHOR("hhb@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/* drivers/input/touchscreen/gt818_ts.h
|
||||
*
|
||||
* Copyright (C) 2011 Rockcip, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Author: hhb@rock-chips.com
|
||||
* Date: 2011.06.20
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_GOODIX_TOUCH_H
|
||||
#define _LINUX_GOODIX_TOUCH_H
|
||||
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
|
||||
//*************************TouchScreen Work Part*****************************
|
||||
#define GOODIX_I2C_NAME "gt818_ts"
|
||||
#define GT801_PLUS
|
||||
#define GT801_NUVOTON
|
||||
#define GUITAR_UPDATE_STATE 0x02
|
||||
#define GT818_I2C_SCL 400*1000
|
||||
|
||||
//define resolution of the touchscreen
|
||||
#define TOUCH_MAX_HEIGHT 7168
|
||||
#define TOUCH_MAX_WIDTH 5120
|
||||
|
||||
//define resolution of the LCD
|
||||
#define SCREEN_MAX_HEIGHT 800
|
||||
#define SCREEN_MAX_WIDTH 480
|
||||
|
||||
|
||||
|
||||
#define SHUTDOWN_PORT pdata->gpio_reset //SHUTDOWN<57>ܽź<DCBD>
|
||||
#define INT_PORT pdata->gpio_pendown
|
||||
|
||||
#ifdef INT_PORT
|
||||
#define TS_INT gpio_to_irq(INT_PORT) //Interrupt Number
|
||||
#else
|
||||
#define TS_INT 0
|
||||
#endif
|
||||
|
||||
#define HAVE_TOUCH_KEY
|
||||
|
||||
|
||||
#define FLAG_UP 0
|
||||
#define FLAG_DOWN 1
|
||||
//set GT801 PLUS trigger mode,ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>1
|
||||
#define INT_TRIGGER 1
|
||||
#define POLL_TIME 10 //actual query spacing interval:POLL_TIME+6
|
||||
|
||||
#define GOODIX_MULTI_TOUCH
|
||||
#ifdef GOODIX_MULTI_TOUCH
|
||||
#define MAX_FINGER_NUM 2
|
||||
#else
|
||||
#define MAX_FINGER_NUM 1
|
||||
#endif
|
||||
|
||||
#define READ_TOUCH_ADDR_H 0x07
|
||||
#define READ_TOUCH_ADDR_L 0x12
|
||||
#define READ_KEY_ADDR_H 0x07
|
||||
#define READ_KEY_ADDR_L 0x21
|
||||
#define READ_COOR_ADDR_H 0x07
|
||||
#define READ_COOR_ADDR_L 0x22
|
||||
#define READ_ID_ADDR_H 0x00
|
||||
#define READ_ID_ADDR_L 0xff
|
||||
|
||||
|
||||
#define IOMUX_NAME_SIZE 48
|
||||
struct gt818_platform_data {
|
||||
|
||||
u16 model; /* 818. */
|
||||
bool swap_xy; /* swap x and y axes */
|
||||
u16 x_min, x_max;
|
||||
u16 y_min, y_max;
|
||||
int gpio_reset;
|
||||
int gpio_reset_active_low;
|
||||
int gpio_pendown; /* the GPIO used to decide the pendown */
|
||||
|
||||
char pendown_iomux_name[IOMUX_NAME_SIZE];
|
||||
char resetpin_iomux_name[IOMUX_NAME_SIZE];
|
||||
int pendown_iomux_mode;
|
||||
int resetpin_iomux_mode;
|
||||
|
||||
int (*get_pendown_state)(void);
|
||||
};
|
||||
|
||||
|
||||
struct gt818_ts_data {
|
||||
|
||||
|
||||
u16 addr;
|
||||
u8 bad_data;
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
int use_reset; //use RESET flag
|
||||
int use_irq; //use EINT flag
|
||||
int read_mode; //read moudle mode,20110221 by andrew
|
||||
struct hrtimer timer;
|
||||
struct work_struct work;
|
||||
char phys[32];
|
||||
char name[32];
|
||||
int retry;
|
||||
struct early_suspend early_suspend;
|
||||
int (*power)(struct gt818_ts_data * ts, int on);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* _LINUX_GOODIX_TOUCH_H */
|
||||
@@ -1,827 +0,0 @@
|
||||
/* drivers/input/touchscreen/goodix_touch.c
|
||||
*
|
||||
* Copyright (C) 2010 - 2011 Goodix, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/completion.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#define GOODIX_I2C_NAME "Goodix-TS"
|
||||
//define default resolution of the touchscreen
|
||||
#define GOODIX_MULTI_TOUCH
|
||||
#define GT819_IIC_SPEED 400*1000 //400*1000
|
||||
#define TOUCH_MAX_WIDTH 800
|
||||
#define TOUCH_MAX_HEIGHT 480
|
||||
#define TOUCH_MAJOR_MAX 200
|
||||
#define WIDTH_MAJOR_MAX 200
|
||||
#define MAX_POINT 5
|
||||
#define INT_TRIGGER_EDGE_RISING 0
|
||||
#define INT_TRIGGER_EDGE_FALLING 1
|
||||
#define INT_TRIGGER_EDGE_LOW 2
|
||||
#define INT_TRIGGER_EDGE_HIGH 3
|
||||
#define INT_TRIGGER INT_TRIGGER_EDGE_FALLING
|
||||
#define I2C_DELAY 0x0f
|
||||
|
||||
#define PACK_SIZE 64 //update file package size
|
||||
#define MAX_TIMEOUT 60000 //update time out conut
|
||||
#define MAX_I2C_RETRIES 20 //i2c retry times
|
||||
|
||||
//I2C buf address
|
||||
#define ADDR_CMD 80
|
||||
#define ADDR_STA 81
|
||||
#define ADDR_DAT 0
|
||||
//moudle state
|
||||
#define NEW_UPDATE_START 0x01
|
||||
#define UPDATE_START 0x02
|
||||
#define SLAVE_READY 0x08
|
||||
#define UNKNOWN_ERROR 0x00
|
||||
#define FRAME_ERROR 0x10
|
||||
#define CHECKSUM_ERROR 0x20
|
||||
#define TRANSLATE_ERROR 0x40
|
||||
#define FLASH_ERROR 0X80
|
||||
//error no
|
||||
#define ERROR_NO_FILE 2 //ENOENT
|
||||
#define ERROR_FILE_READ 23 //ENFILE
|
||||
#define ERROR_FILE_TYPE 21 //EISDIR
|
||||
#define ERROR_GPIO_REQUEST 4 //EINTR
|
||||
#define ERROR_I2C_TRANSFER 5 //EIO
|
||||
#define ERROR_NO_RESPONSE 16 //EBUSY
|
||||
#define ERROR_TIMEOUT 110 //ETIMEDOUT
|
||||
|
||||
struct goodix_ts_data {
|
||||
struct workqueue_struct *goodix_wq;
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
struct work_struct work;
|
||||
int irq;
|
||||
int irq_gpio;
|
||||
uint16_t abs_x_max;
|
||||
uint16_t abs_y_max;
|
||||
uint8_t max_touch_num;
|
||||
uint8_t int_trigger_type;
|
||||
};
|
||||
|
||||
static const char *goodix_ts_name = "Goodix Capacitive TouchScreen";
|
||||
unsigned int crc32_table[256];
|
||||
unsigned int oldcrc32 = 0xFFFFFFFF;
|
||||
unsigned int ulPolynomial = 0x04c11db7;
|
||||
struct i2c_client * i2c_connect_client = NULL;
|
||||
static struct early_suspend gt819_power;
|
||||
static u8 gt819_fw[]=
|
||||
{
|
||||
#include "gt819_fw.i"
|
||||
};
|
||||
#if 0
|
||||
uint8_t config_info[] = {
|
||||
0x02,(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_WIDTH&0xff),
|
||||
(TOUCH_MAX_HEIGHT>>8),(TOUCH_MAX_HEIGHT&0xff),MAX_POINT,(0xa0 | INT_TRIGGER),
|
||||
0x20,0x00,0x00,0x0f,0x20,0x08,0x14,0x00,
|
||||
0x00,0x20,0x00,0x00,0x88,0x88,0x88,0x00,0x37,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
|
||||
0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0xff,0xff,0x00,0x01,0x02,0x03,0x04,
|
||||
0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0xff,0xff,0xff,0x00,0x00,0x3c,0x64,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40
|
||||
};
|
||||
#else
|
||||
static u8 config_info[]=
|
||||
{
|
||||
#include "gt819.cfg"
|
||||
};
|
||||
#endif
|
||||
static int gt819_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int gt819_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
|
||||
if(ret>0)
|
||||
return ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gt819_printf(char *buf, int len)
|
||||
{
|
||||
int x, y, row = len/8,mod = len%8;
|
||||
for (y=0; y<row; y++) {
|
||||
for (x=0; x<8; x++) {
|
||||
printk("0x%02x, ",buf[y*8+x]);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
for (x=0; x<mod; x++) {
|
||||
printk("0x%02x, ",buf[row*8+x]);
|
||||
}
|
||||
printk("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gt189_wait_for_slave(struct i2c_client *client, u8 status)
|
||||
{
|
||||
unsigned char i2c_state_buf[2];
|
||||
int ret,i = 0;
|
||||
while(i < MAX_I2C_RETRIES)
|
||||
{
|
||||
ret = gt819_read_regs(client,ADDR_STA, i2c_state_buf, 1);
|
||||
printk("i2c read state byte:0x%x\n",i2c_state_buf[0]);
|
||||
if(ret < 0)
|
||||
return ERROR_I2C_TRANSFER;
|
||||
if(i2c_state_buf[0]==0xff)continue;
|
||||
if(i2c_state_buf[0] & status)
|
||||
return i2c_state_buf[0];
|
||||
msleep(10);
|
||||
i++;
|
||||
}
|
||||
return -ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
int gt819_update_write_config(struct i2c_client *client)
|
||||
{
|
||||
int ret,len = sizeof(config_info)-1; //byte[0] is the reg addr in the gt819.cfg
|
||||
u8 cfg_rd_buf[len];
|
||||
u8 cfg_cmd_buf = 0x03;
|
||||
u8 retries = 0;
|
||||
|
||||
reconfig:
|
||||
ret = gt819_set_regs(client, 101, &config_info[1], len);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
gt819_printf(config_info, len);
|
||||
ret = gt819_read_regs(client, 101, cfg_rd_buf, len);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(memcmp(cfg_rd_buf, &config_info[1], len))
|
||||
{
|
||||
dev_info(&client->dev, "config info check error!\n");
|
||||
if(retries < 5)
|
||||
{
|
||||
retries++;
|
||||
ret = gt819_set_regs(client, ADDR_CMD, &cfg_cmd_buf, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
goto reconfig;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
cfg_cmd_buf = 0x04;
|
||||
ret = gt819_set_regs(client, ADDR_CMD, &cfg_cmd_buf, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int gt819_read_version(struct i2c_client *client,char *version)
|
||||
{
|
||||
int ret, count = 0;
|
||||
char *p;
|
||||
|
||||
ret = gt819_read_regs(client,240, version, 16);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
version[16]='\0';
|
||||
p = version;
|
||||
do
|
||||
{
|
||||
if((*p > 122) || (*p < 48 && *p != 32) || (*p >57 && *p < 65)
|
||||
||(*p > 90 && *p < 97 && *p != '_')) //check illeqal character
|
||||
count++;
|
||||
}while(*++p != '\0' );
|
||||
if(count > 2)
|
||||
return -1;
|
||||
dev_info(&client->dev, "fw version is %s\n",version);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gt819_update_write_fw(struct i2c_client *client, char *fw_buf, int len)
|
||||
{
|
||||
int ret,data_len,i,check_len,frame_checksum,frame_number = 0;
|
||||
unsigned char *p,i2c_data_buf[PACK_SIZE+8];
|
||||
u8 i2c_rd_buf[PACK_SIZE+8];
|
||||
|
||||
u8 retries = 0;
|
||||
u8 check_state = 0;
|
||||
|
||||
if(!client || !fw_buf)
|
||||
return -1;
|
||||
|
||||
while(len){
|
||||
frame_checksum = 0;
|
||||
retries = 0;
|
||||
check_len = (len >= PACK_SIZE) ? PACK_SIZE : len;
|
||||
data_len = check_len+8;
|
||||
dev_info(&client->dev, "PACK[%d]:prepare data,remained len = %d\n",frame_number,len);
|
||||
p = &fw_buf[frame_number*PACK_SIZE];
|
||||
for(i=0; i<check_len; i++)
|
||||
frame_checksum += *p++;
|
||||
frame_checksum = 0 - frame_checksum;
|
||||
p = i2c_data_buf;
|
||||
*p++ = (frame_number>>24)&0xff;
|
||||
*p++ = (frame_number>>16)&0xff;
|
||||
*p++ = (frame_number>>8)&0xff;
|
||||
*p++ = frame_number&0xff;
|
||||
memcpy(p, &fw_buf[frame_number*PACK_SIZE],check_len);
|
||||
p += check_len;
|
||||
*p++ = frame_checksum&0xff;
|
||||
*p++ = (frame_checksum>>8)&0xff;
|
||||
*p++ = (frame_checksum>>16)&0xff;
|
||||
*p++ = (frame_checksum>>24)&0xff;
|
||||
//gt819_printf(i2c_data_buf, data_len);
|
||||
dev_info(&client->dev, "PACK[%d]:write to slave\n",frame_number);
|
||||
resend:
|
||||
ret = gt819_set_regs(client,ADDR_DAT, i2c_data_buf, data_len);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
//gt819_printf(i2c_data_buf, data_len);
|
||||
msleep(10);
|
||||
dev_info(&client->dev, "PACK[%d]:read data\n",frame_number);
|
||||
memset(i2c_rd_buf, 0, sizeof(i2c_rd_buf));
|
||||
ret = gt819_read_regs(client,ADDR_DAT, i2c_rd_buf, data_len);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
//gt819_printf(i2c_data_buf, data_len);
|
||||
msleep(10);
|
||||
dev_info(&client->dev, "PACK[%d]:check data\n",frame_number);
|
||||
if(memcmp(&i2c_rd_buf[4],&fw_buf[frame_number*PACK_SIZE],check_len))
|
||||
{
|
||||
dev_info(&client->dev, "PACK[%d]:File Data Frame readback check Error!\n",frame_number);
|
||||
i2c_rd_buf[0] = 0x03;
|
||||
ret = gt819_set_regs(client, ADDR_CMD, i2c_rd_buf, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
check_state = 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_info(&client->dev, "PACK[%d]:tell slave check data pass\n",frame_number);
|
||||
i2c_rd_buf[0] = 0x04;
|
||||
ret = gt819_set_regs(client,ADDR_CMD, i2c_rd_buf, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "PACK[%d]:wait for slave to start next frame\n",frame_number);
|
||||
}
|
||||
|
||||
ret = gt189_wait_for_slave(client, SLAVE_READY);
|
||||
if((ret & CHECKSUM_ERROR) || (ret & FRAME_ERROR) || (ret == ERROR_I2C_TRANSFER) || (ret < 0) || (check_state == 0x01))
|
||||
{
|
||||
|
||||
if(((ret & CHECKSUM_ERROR) || (ret & FRAME_ERROR) || (check_state == 0x01))&&(retries < 5))
|
||||
{
|
||||
if(check_state != 0x01)
|
||||
{
|
||||
printk("checksum error or miss frame error!\n");
|
||||
}
|
||||
check_state = 0x00;
|
||||
retries++;
|
||||
msleep(20);
|
||||
goto resend;
|
||||
}
|
||||
printk("wait slave return state:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
dev_info(&client->dev, "PACK[%d]:frame transfer finished\n",frame_number);
|
||||
if(len < PACK_SIZE)
|
||||
return 0;
|
||||
frame_number++;
|
||||
len -= check_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gt819_update_fw(struct i2c_client *client)
|
||||
{
|
||||
int ret,file_len,update_need_config;
|
||||
unsigned char i2c_control_buf[10];
|
||||
char version[17];
|
||||
const char version_base[17]={"GT81XNI"};
|
||||
|
||||
dev_info(&client->dev, "gt819 firmware update start...\n");
|
||||
dev_info(&client->dev, "step 1:read version...\n");
|
||||
ret = gt819_read_version(client,version);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 2:disable irq...\n");
|
||||
disable_irq(client->irq);
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 3:set update start...\n");
|
||||
i2c_control_buf[0] = UPDATE_START;
|
||||
ret = gt819_set_regs(client,ADDR_CMD, i2c_control_buf, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
//the time include time(APROM -> LDROM) and time(LDROM init)
|
||||
msleep(1000);
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 4:wait for slave start...\n");
|
||||
ret = gt189_wait_for_slave(client, UPDATE_START);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(!(ret & UPDATE_START))
|
||||
return -1;
|
||||
if(!(ret & NEW_UPDATE_START))
|
||||
update_need_config = 1;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 5:write the fw length...\n");
|
||||
file_len = sizeof(gt819_fw) + 4;
|
||||
dev_info(&client->dev, "file length is:%d\n", file_len);
|
||||
i2c_control_buf[0] = (file_len>>24) & 0xff;
|
||||
i2c_control_buf[1] = (file_len>>16) & 0xff;
|
||||
i2c_control_buf[2] = (file_len>>8) & 0xff;
|
||||
i2c_control_buf[3] = file_len & 0xff;
|
||||
ret = gt819_set_regs(client,ADDR_DAT, i2c_control_buf, 4);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 6:wait for slave ready\n");
|
||||
ret = gt189_wait_for_slave(client, SLAVE_READY);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 7:write data\n");
|
||||
ret = gt819_update_write_fw(client, gt819_fw, sizeof(gt819_fw));
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 8:write config\n");
|
||||
ret = gt819_update_write_config(client);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
dev_info(&client->dev, "step 9:wait for slave ready\n");
|
||||
ret = gt189_wait_for_slave(client,SLAVE_READY);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(ret & SLAVE_READY)
|
||||
dev_info(&client->dev, "The firmware updating succeed!update state:0x%x\n",ret);
|
||||
dev_info(&client->dev, "step 10:enable irq...\n");
|
||||
enable_irq(client->irq);
|
||||
dev_info(&client->dev, "done!\n");
|
||||
msleep(1000); //wait slave reset
|
||||
dev_info(&client->dev, "step 11:read version...\n");
|
||||
ret = gt819_read_version(client,version);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
dev_info(&client->dev, "done!\n");
|
||||
version[7] = '\0';
|
||||
if(strcmp(version ,version_base)==0)
|
||||
{
|
||||
sys_sync();
|
||||
msleep(200);
|
||||
kernel_restart(NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void gt819_queue_work(struct work_struct *work)
|
||||
{
|
||||
struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data, work);
|
||||
uint8_t point_data[53]={ 0 };
|
||||
int ret,i,offset,points;
|
||||
int points_chect;
|
||||
int x,y,w;
|
||||
unsigned int count = 0;
|
||||
uint8_t check_sum = 0;
|
||||
|
||||
ret = gt819_read_regs(ts->client,1, point_data, 2);
|
||||
if (ret < 0) {
|
||||
dev_err(&ts->client->dev, "i2c_read_bytes fail:%d!\n",ret);
|
||||
enable_irq(ts->irq);
|
||||
return;
|
||||
}
|
||||
check_sum =point_data[0]+point_data[1];
|
||||
|
||||
points = point_data[0] & 0x1f;
|
||||
//dev_info(&ts->client->dev, "points = %d\n",points);
|
||||
if (points == 0) {
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
||||
//input_mt_sync(data->input_dev);
|
||||
input_sync(ts->input_dev);
|
||||
enable_irq(ts->irq);
|
||||
dev_info(&ts->client->dev, "touch release\n");
|
||||
return;
|
||||
}
|
||||
for(i=0;0!=points;)
|
||||
{
|
||||
if(points&0x01)
|
||||
i++;
|
||||
points>>=1;
|
||||
}
|
||||
|
||||
points = i;
|
||||
points_chect = points;
|
||||
ret = gt819_read_regs(ts->client,3, point_data, points*5+1);
|
||||
if (ret < 0) {
|
||||
dev_err(&ts->client->dev, "i2c_read_bytes fail:%d!\n",ret);
|
||||
enable_irq(ts->irq);
|
||||
return;
|
||||
}
|
||||
//add by Nitiion
|
||||
for(points_chect *= 5; points_chect > 0; points_chect--)
|
||||
{
|
||||
check_sum += point_data[count++];
|
||||
}
|
||||
check_sum += point_data[count];
|
||||
if(check_sum != 0) //checksum verify error
|
||||
{
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
||||
//input_mt_sync(data->input_dev);
|
||||
input_sync(ts->input_dev);
|
||||
enable_irq(ts->irq);
|
||||
dev_info(&ts->client->dev, "coor checksum error!touch release\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0;i<points;i++){
|
||||
offset = i*5;
|
||||
x = (((s16)(point_data[offset+0]))<<8) | ((s16)point_data[offset+1]);
|
||||
y = (((s16)(point_data[offset+2]))<<8) | ((s16)point_data[offset+3]);
|
||||
w = point_data[offset+4];
|
||||
//dev_info(&ts->client->dev, "goodix multiple report event[%d]:x = %d,y = %d,w = %d\n",i,x,y,w);
|
||||
if(x<=TOUCH_MAX_WIDTH && y<=TOUCH_MAX_HEIGHT){
|
||||
//dev_info(&ts->client->dev, "goodix multiple report event[%d]:x = %d,y = %d,w = %d\n",i,x,y,w);
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
|
||||
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i);
|
||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
|
||||
input_mt_sync(ts->input_dev);
|
||||
}
|
||||
}
|
||||
input_sync(ts->input_dev);
|
||||
enable_irq(ts->irq);
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
Description:
|
||||
External interrupt service routine.
|
||||
|
||||
Parameter:
|
||||
irq: interrupt number.
|
||||
dev_id: private data pointer.
|
||||
|
||||
return:
|
||||
irq execute status.
|
||||
*******************************************************/
|
||||
static irqreturn_t gt819_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct goodix_ts_data *ts = dev_id;
|
||||
|
||||
disable_irq_nosync(ts->client->irq);
|
||||
queue_work(ts->goodix_wq, &ts->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int gt819_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
struct goodix_platform_data *pdata = client->dev.platform_data;
|
||||
dev_info(&client->dev,"gt819_suspend\n");
|
||||
|
||||
if (pdata->platform_sleep)
|
||||
pdata->platform_sleep();
|
||||
disable_irq(client->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gt819_resume(struct i2c_client *client)
|
||||
{
|
||||
struct goodix_platform_data *pdata = client->dev.platform_data;
|
||||
dev_info(&client->dev,"gt819_resume\n");
|
||||
|
||||
enable_irq(client->irq);
|
||||
if (pdata->platform_wakeup)
|
||||
pdata->platform_wakeup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gt819_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
dev_info(&i2c_connect_client->dev, "gt819_early_suspend!\n");
|
||||
gt819_suspend(i2c_connect_client,PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
static void gt819_early_resume(struct early_suspend *h)
|
||||
{
|
||||
dev_info(&i2c_connect_client->dev, "gt819_resume_early!\n");
|
||||
gt819_resume(i2c_connect_client);
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
Description:
|
||||
Goodix touchscreen driver release function.
|
||||
|
||||
Parameter:
|
||||
client: i2c device struct.
|
||||
|
||||
return:
|
||||
Executive outcomes. 0---succeed.
|
||||
*******************************************************/
|
||||
static int gt819_remove(struct i2c_client *client)
|
||||
{
|
||||
struct goodix_ts_data *ts = i2c_get_clientdata(client);
|
||||
#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
|
||||
remove_proc_entry("goodix-update", NULL);
|
||||
#endif
|
||||
//goodix_debug_sysfs_deinit();
|
||||
gpio_direction_input(ts->irq_gpio);
|
||||
gpio_free(ts->irq_gpio);
|
||||
free_irq(client->irq, ts);
|
||||
if(ts->goodix_wq)
|
||||
destroy_workqueue(ts->goodix_wq);
|
||||
dev_notice(&client->dev,"The driver is removing...\n");
|
||||
i2c_set_clientdata(client, NULL);
|
||||
input_unregister_device(ts->input_dev);
|
||||
unregister_early_suspend(>819_power);
|
||||
i2c_connect_client = 0;
|
||||
kfree(ts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gt819_init_panel(struct goodix_ts_data *ts)
|
||||
{
|
||||
int ret,I2cDelay;
|
||||
int len = sizeof(config_info)-1;
|
||||
uint8_t rd_cfg_buf[10];
|
||||
struct goodix_platform_data *pdata = ts->client->dev.platform_data;
|
||||
|
||||
ret = gt819_set_regs(ts->client, 101, &config_info[1], len);
|
||||
if(ret < 0)
|
||||
{
|
||||
pdata->platform_sleep();
|
||||
msleep(10);
|
||||
pdata->platform_wakeup();
|
||||
msleep(100);
|
||||
printk("First IIC request failed,retry!\n");
|
||||
ret = gt819_set_regs(ts->client, 101, &config_info[1], len);
|
||||
if(ret<0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gt819_read_regs(ts->client, 101, rd_cfg_buf, 10);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ts->abs_x_max = ((((uint16_t)rd_cfg_buf[1])<<8)|rd_cfg_buf[2]);
|
||||
ts->abs_y_max = ((((uint16_t)rd_cfg_buf[3])<<8)|rd_cfg_buf[4]);
|
||||
ts->max_touch_num = rd_cfg_buf[5];
|
||||
ts->int_trigger_type = rd_cfg_buf[6]&0x03;
|
||||
I2cDelay = rd_cfg_buf[9]&0x0f;
|
||||
dev_info(&ts->client->dev,"X_MAX = %d,Y_MAX = %d,MAX_TOUCH_NUM = %d,INT_TRIGGER = %d,I2cDelay = %x\n",
|
||||
ts->abs_x_max,ts->abs_y_max,ts->max_touch_num,ts->int_trigger_type,I2cDelay);
|
||||
if((ts->abs_x_max!=TOUCH_MAX_WIDTH)||(ts->abs_y_max!=TOUCH_MAX_HEIGHT)||
|
||||
(MAX_POINT!=ts->max_touch_num)||INT_TRIGGER!=ts->int_trigger_type || I2C_DELAY!=I2cDelay){
|
||||
ts->abs_x_max = TOUCH_MAX_WIDTH;
|
||||
ts->abs_y_max = TOUCH_MAX_HEIGHT;
|
||||
ts->max_touch_num = MAX_POINT;
|
||||
ts->int_trigger_type = INT_TRIGGER;
|
||||
rd_cfg_buf[1] = ts->abs_x_max>>8;
|
||||
rd_cfg_buf[2] = ts->abs_x_max&0xff;
|
||||
rd_cfg_buf[3] = ts->abs_y_max>>8;
|
||||
rd_cfg_buf[4] = ts->abs_y_max&0xff;
|
||||
rd_cfg_buf[5] = ts->max_touch_num;
|
||||
rd_cfg_buf[6] = ((rd_cfg_buf[6]&0xfc) | INT_TRIGGER);
|
||||
rd_cfg_buf[9] = ((rd_cfg_buf[9]&0xf0) | I2C_DELAY);
|
||||
ret = gt819_set_regs(ts->client, 101, rd_cfg_buf, 10);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
dev_info(&ts->client->dev,"set config\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
Description:
|
||||
Goodix touchscreen probe function.
|
||||
|
||||
Parameter:
|
||||
client: i2c device struct.
|
||||
id:device id.
|
||||
|
||||
return:
|
||||
Executive outcomes. 0---succeed.
|
||||
*******************************************************/
|
||||
static int gt819_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
char version[17];
|
||||
char version_base[17]={"GT81XNI_1R05_18Q"};
|
||||
struct goodix_ts_data *ts;
|
||||
struct goodix_platform_data *pdata = client->dev.platform_data;
|
||||
const char irq_table[4] = {IRQ_TYPE_EDGE_RISING,
|
||||
IRQ_TYPE_EDGE_FALLING,
|
||||
IRQ_TYPE_LEVEL_LOW,
|
||||
IRQ_TYPE_LEVEL_HIGH};
|
||||
|
||||
dev_info(&client->dev,"Install goodix touch driver\n");
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&client->dev, "platform data is required!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pdata->init_platform_hw)
|
||||
pdata->init_platform_hw();
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
|
||||
if (ts == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ts->client = i2c_connect_client = client;
|
||||
|
||||
ret = gt819_init_panel(ts);
|
||||
if(ret != 0){
|
||||
dev_err(&client->dev,"init panel fail,ret = %d\n",ret);
|
||||
goto err_init_panel_fail;
|
||||
}
|
||||
|
||||
ret = gt819_read_version(client,version);
|
||||
if((ret>=0) && (strcmp(version ,version_base)!=0)){
|
||||
gt819_update_fw(client);
|
||||
}
|
||||
|
||||
if (!client->irq){
|
||||
dev_err(&client->dev,"no irq fail\n");
|
||||
ret = -ENODEV;
|
||||
goto err_no_irq_fail;
|
||||
}
|
||||
ts->irq_gpio = client->irq;
|
||||
ts->irq = client->irq = gpio_to_irq(client->irq);
|
||||
ret = request_irq(client->irq, gt819_irq_handler, irq_table[ts->int_trigger_type],client->name, ts);
|
||||
if (ret != 0) {
|
||||
dev_err(&client->dev,"request_irq fail:%d\n", ret);
|
||||
goto err_irq_request_fail;
|
||||
}
|
||||
|
||||
ts->goodix_wq = create_workqueue("goodix_wq");
|
||||
if (!ts->goodix_wq) {
|
||||
printk(KERN_ALERT "creat workqueue failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_create_work_queue_fail;
|
||||
}
|
||||
|
||||
INIT_WORK(&ts->work, gt819_queue_work);
|
||||
|
||||
ts->input_dev = input_allocate_device();
|
||||
if (ts->input_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
dev_err(&client->dev,"Failed to allocate input device\n");
|
||||
goto err_input_dev_alloc_failed;
|
||||
}
|
||||
|
||||
set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit);
|
||||
set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit);
|
||||
set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit);
|
||||
set_bit(ABS_MT_TRACKING_ID, ts->input_dev->absbit);
|
||||
set_bit(ABS_MT_WIDTH_MAJOR, ts->input_dev->absbit);
|
||||
set_bit(EV_ABS, ts->input_dev->evbit);
|
||||
set_bit(EV_KEY, ts->input_dev->evbit);
|
||||
input_set_abs_params(ts->input_dev,ABS_MT_POSITION_X, 0, TOUCH_MAX_WIDTH, 0, 0);
|
||||
input_set_abs_params(ts->input_dev,ABS_MT_POSITION_Y, 0, TOUCH_MAX_HEIGHT, 0, 0);
|
||||
input_set_abs_params(ts->input_dev,ABS_MT_TOUCH_MAJOR, 0, TOUCH_MAJOR_MAX, 0, 0);
|
||||
input_set_abs_params(ts->input_dev,ABS_MT_TRACKING_ID, 0, MAX_POINT, 0, 0);
|
||||
input_set_abs_params(ts->input_dev,ABS_MT_WIDTH_MAJOR, 0, WIDTH_MAJOR_MAX, 0, 0);
|
||||
|
||||
ts->input_dev->name = goodix_ts_name;
|
||||
ret = input_register_device(ts->input_dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name);
|
||||
goto err_input_register_device_failed;
|
||||
}
|
||||
i2c_set_clientdata(client, ts);
|
||||
|
||||
gt819_power.suspend = gt819_early_suspend;
|
||||
gt819_power.resume = gt819_early_resume;
|
||||
gt819_power.level = 0x2;
|
||||
register_early_suspend(>819_power);
|
||||
return 0;
|
||||
i2c_set_clientdata(client, NULL);
|
||||
input_unregister_device(ts->input_dev);
|
||||
err_input_register_device_failed:
|
||||
input_free_device(ts->input_dev);
|
||||
err_input_dev_alloc_failed:
|
||||
destroy_workqueue(ts->goodix_wq);
|
||||
err_create_work_queue_fail:
|
||||
free_irq(client->irq,ts);
|
||||
err_irq_request_fail:
|
||||
err_no_irq_fail:
|
||||
err_init_panel_fail:
|
||||
if (pdata->exit_platform_hw)
|
||||
pdata->exit_platform_hw();
|
||||
kfree(ts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const struct i2c_device_id gt819_id[] = {
|
||||
{ GOODIX_I2C_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver gt819_driver = {
|
||||
.probe = gt819_probe,
|
||||
.remove = gt819_remove,
|
||||
.id_table = gt819_id,
|
||||
.driver = {
|
||||
.name = GOODIX_I2C_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/*******************************************************
|
||||
Description:
|
||||
Driver Install function.
|
||||
return:
|
||||
Executive Outcomes. 0---succeed.
|
||||
********************************************************/
|
||||
static int __devinit gt819_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret=i2c_add_driver(>819_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
Description:
|
||||
Driver uninstall function.
|
||||
return:
|
||||
Executive Outcomes. 0---succeed.
|
||||
********************************************************/
|
||||
static void __exit gt819_exit(void)
|
||||
{
|
||||
printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");
|
||||
i2c_del_driver(>819_driver);
|
||||
}
|
||||
|
||||
late_initcall(gt819_init);
|
||||
module_exit(gt819_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Goodix Touchscreen Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1 +0,0 @@
|
||||
0x65,0x02,0x03,0x20,0x01,0xE0,0x05,0xA1,0x21,0x00,0x0F,0x0F,0x20,0x10,0x10,0x00,0x00,0x20,0x00,0x00,0x10,0x10,0x10,0x00,0x37,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,0x00,0x46,0x78,0x2E,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x02,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2011 Goodix, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_GOODIX_GT8110_TOUCH_H
|
||||
#define _LINUX_GOODIX_GT8110_TOUCH_H
|
||||
|
||||
struct goodix_8110_platform_data {
|
||||
uint32_t version; /* Use this entry for panels with */
|
||||
int reset;
|
||||
int irq_pin;
|
||||
int power_control;
|
||||
int mode_check_pin;
|
||||
int (*hw_init) (void);
|
||||
int (*hw_exit) (void);
|
||||
};
|
||||
|
||||
#endif /* _LINUX_GOODIX_TOUCH_H */
|
||||
|
||||
Reference in New Issue
Block a user