全志A33之添加电容触摸GT911驱动[通俗易懂]

全志A33之添加电容触摸GT911驱动[通俗易懂]全志A33之添加电容触摸GT911驱动基于锐尔威视的A33开发板及提供的开发包,仅供参考。开发板说是支持GT911,其实是不支持的,得修改驱动及配置,启动文件。一.     修改配置文件/home/yygyickl/A33/dragonboard/tools/pack/chips/sun8iw5p1/configs/vstar/sys_config.fex    这是我的目录。

大家好,又见面了,我是你们的朋友全栈君。

全志A33之添加电容触摸GT911驱动

基于锐尔威视的A33开发板及提供的开发包,仅供参考。

开发板说是支持GT911,其实是不支持的,得修改驱动及配置,启动文件。

一.      修改配置文件

/home/yygyickl/A33/dragonboard/tools/pack/chips/sun8iw5p1/configs/vstar/sys_config.fex     这是我的目录。

      触摸部分修改为下面的样子。

[ctp_para]

ctp_used            = 1

ctp_name            = “gt9xx_ts”

ctp_twi_id          = 0

ctp_twi_addr        = 0x5d

ctp_screen_max_x    = 1024

ctp_screen_max_y    = 600

ctp_revert_x_flag   = 0

ctp_revert_y_flag   = 0

ctp_exchange_x_y_flag= 0

 

ctp_int_port        =port:PB05<4><default><default><default>

ctp_wakeup          =port:PH01<1><default><default><1>

;ctp_power_ldo       = “axp22_eldo1”

;ctp_power_ldo_vol   = 3000

;ctp_power_io        =

 

;——————————————————————————–

; CTP automaticdetection configuration

;ctp_detect_used  — Whether startup automatic inspectionfunction. 1:used,0:unused

;Module namepostposition 1 said detection, 0 means no detection.

;——————————————————————————–

[ctp_list_para]

ctp_det_used              = 0

ft5x_ts                   = 0

gt82x                     = 0

gslX680                   = 0

gslX680new                = 0

gt9xx_ts                  = 1

gt9xxf_ts                 = 0

tu_ts                     = 0

gt818_ts                  = 0

zet622x                   = 0

aw5306_ts                 = 0

icn83xx_ts                = 0

仅支持GT911。

 

二.      修改启动文件

/home/yygyickl/A33/dragonboard/buildroot/target/dragonboard/extra/autorun.sh     这是我的目录。

将触摸部分的insmod”$tp_module_path” 修改为        

insmod     /system/vendor/modules/gt9xx_ts.ko

下面这部分中的ft5x_ts全部替换为gt9xx_ts

#tslib config

export TSLIB_CALIBFILE=/etc/pointercal

TS_INFO_FILE1=/sys/class/input/event3/device/name

TS_INFO_FILE2=/sys/class/input/event4/device/name

if grep -q ft5x_ts $TS_INFO_FILE1; then

export TSLIB_TSDEVICE=/dev/input/event3

export QWS_MOUSE_PROTO=”Tslib:/dev/input/event3MouseMan:/dev/input/mouse0″

       if [ ! -s “$TSLIB_CALIBFILE” ];then

            rm -f $TSLIB_CALIBFILE

       fi

elif grep -q ft5x_ts $TS_INFO_FILE2; then

  export TSLIB_TSDEVICE=/dev/input/event4

  export QWS_MOUSE_PROTO=”Tslib:/dev/input/event4MouseMan:/dev/input/mouse0″

  if [ ! -s “$TSLIB_CALIBFILE” ]; then

     rm -f $TSLIB_CALIBFILE

  fi

else

  export QWS_MOUSE_PROTO=MouseMan:/dev/input/mouse0 > $TSLIB_CALIBFILE

fi

unset TS_INFO_FILE1

unset TS_INFO_FILE2

三.      修改驱动

 /home/yygyickl/A33/dragonboard/Linux-3.4/Drivers/Input/Touchscreen/Gt9xx/    进入目录

修改Gt9xx_ts.h为:

#ifndef _LINUX_GOODIX_TOUCH_H

#define  _LINUX_GOODIX_TOUCH_H

 

#include <linux/kernel.h>

#include <linux/hrtimer.h>

#include <linux/i2c.h>

#include <linux/input.h>

#include <linux/module.h>

#include <linux/delay.h>

#include <linux/i2c.h>

#include <linux/proc_fs.h>

#include <linux/string.h>

#include <asm/uaccess.h>

#include <linux/vmalloc.h>

#include <linux/interrupt.h>

#include <linux/io.h>

 

#ifdef CONFIG_HAS_EARLYSUSPEND

#include <linux/earlysuspend.h>

#endif

 

 

#include <linux/device.h>

#include <linux/slab.h>

#include <linux/init.h>

#include <linux/errno.h>

#include <linux/platform_device.h>

#include <linux/async.h>

#include <linux/ioport.h>

#include <asm/irq.h>

#include <asm/delay.h>

#include <linux/irq.h>

#include <linux/gpio.h>

#include <mach/irqs.h>

#include <mach/hardware.h>

#include <mach/sys_config.h>

#include <linux/init-input.h>

 

#include <linux/pinctrl/consumer.h>

#include<linux/pinctrl/pinconf-sunxi.h>

 

struct gt9xx_event {

inttouch_point;

 

u16x[5];

u16y[5];

u16w[5];

};

 

 

struct goodix_ts_data {

   spinlock_t irq_lock;

   struct i2c_client *client;

   struct input_dev  *input_dev;

structgt9xx_event event;

   struct hrtimer timer;

   struct work_struct  work;

   

   #ifdef CONFIG_HAS_EARLYSUSPEND

   struct early_suspend early_suspend;

       #endif

 

   s32 irq_is_disable;

   s32 use_irq;

   u16 abs_x_max;

   u16 abs_y_max;

    u8  max_touch_num;

   u8  int_trigger_type;

   u8  green_wake_mode;

   u8  enter_update;

   u8  gtp_is_suspend;

   u8  gtp_rawdiff_mode;

   int  gtp_cfg_len;

   u8  fw_error;

   u8  pnl_init_error;

 

#if  defined(CONFIG_FB)

structnotifier_block notifier;

#elif defined(CONFIG_HAS_EARLYSUSPEND)

structearly_suspend early_suspend;

#endif

 

};

 

extern u16 show_len;

extern u16 total_len;

extern struct ctp_config_info config_info;

 

//***************************PART1:ON/OFFdefine*******************************

#define GTP_CUSTOM_CFG        1  

#define GTP_CHANGE_X2Y        0      //swap x y

#define GTP_DRIVER_SEND_CFG   1     //driver send config     此开关根据需要选择

#define GTP_CONFIG_MODE         0       //触摸屏本来是好的,没有厂家数据表的情况下:0=从GT911中读原来的配置参数,修改后再配置

                                              //有厂家数据表的情况 1:修改数据表后配置

#define GTP_HAVE_TOUCH_KEY    0

#define GTP_POWER_CTRL_SLEEP  0   //power off when suspend

#define GTP_ICS_SLOT_REPORT   0   // slot protocol

 

#define GTP_AUTO_UPDATE       0   // auto update fw by .bin file as default

#define GTP_HEADER_FW_UPDATE  0    //auto update fw by gtp_default_FW in gt9xx_firmware.h, function together withGTP_AUTO_UPDATE

#define GTP_AUTO_UPDATE_CFG   0   // auto update config by .cfg file, function together withGTP_AUTO_UPDATE

 

#define GTP_COMPATIBLE_MODE   0   // compatible with GT9XXF

 

#define GTP_CREATE_WR_NODE    0

#define GTP_ESD_PROTECT       0   // esd protection with a cycle of 2 seconds

 

#define GTP_WITH_PEN          0

#define GTP_PEN_HAVE_BUTTON   0   // active pen has buttons, function together with GTP_WITH_PEN

 

#define GTP_GESTURE_WAKEUP    0   // gesture wakeup

 

#define GTP_DEBUG_ON          1

#define GTP_DEBUG_ARRAY_ON    0

#define GTP_DEBUG_FUNC_ON     0

 

//***************************PART2:TODOdefine**********************************

//STEP_1(REQUIRED):Change config table.

/*TODO: puts the config info correspondedto your TP here, the following is just

a sample config, send this config shouldcause the chip cannot work normally*/

//default or float

// sochip,ma805d5 ,768*1024,gt911,COB

#define CTP_CFG_GROUP0    {\

0x42,0x00,0x04,0x58,0x02,0x05,0x3D,0x00,0x01,0x08,\

0x28,0x08,0x50,0x3C,0x03,0x05,0x00,0x00,0x00,0x00,\

0x00,0x00,0x00,0x18,0x1A,0x1E,0x14,0x89,0x2A,0x0B,\

0x40,0x42,0xB5,0x06,0x00,0x00,0x00,0x02,0x02,0x1D,\

0x00,0x01,0x00,0x00,0x00,0x03,0x64,0x00,0x00,0x00,\

0x00,0x32,0x5A,0x94,0xC5,0x02,0x08,0x00,0x00,0x00,\

0x98,0x35,0x00,0x8A,0x3B,0x00,0x7A,0x43,0x00,0x6E,\

0x4B,0x00,0x62,0x55,0x00,0x62,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,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,\

0x12,0x14,0x16,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,\

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\

0x00,0x00,0x00,0x02,0x04,0x06,0x08,0x0A,0x0F,0x10,\

0x12,0x16,0x18,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,\

0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,\

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\

0x00,0x00,0x00,0x00,0x60,0x01}

  

//#define GTP_RST_PORT    S5PV210_GPJ3(6)

//#define GTP_INT_PORT    S5PV210_GPH1(3)

//#define GTP_INT_IRQ     SW_INT_IRQNO_PIO

//#define GTP_INT_CFG     S3C_GPIO_SFN(0xF)

//#ifdef CONFIG_ARCH_SUN4I

//#define CTP_IRQ_NO               (IRQ_EINT21)

//#elif defined CONFIG_ARCH_SUN5I

//#define CTP_IRQ_NO               (IRQ_EINT9)

//#endif

//#define CTP_IRQ_MODE                (TRIG_EDGE_NEGATIVE)

 

#define GTP_GPIO_AS_INPUT(pin)          do{\

                                           gpio_direction_input(pin);\

                                           s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);\

                                       }while(0)

#define GTP_GPIO_AS_INT(pin)            do{\

                                           GTP_GPIO_AS_INPUT(pin);\

                                            s3c_gpio_cfgpin(pin,GTP_INT_CFG);\

                                       }while(0)

#define GTP_GPIO_GET_VALUE(pin)         gpio_get_value(pin)

#define GTP_GPIO_OUTPUT(pin,level)      gpio_direction_output(pin,level)

#define GTP_GPIO_REQUEST(pin, label)    gpio_request(pin, label)

#define GTP_GPIO_FREE(pin)              gpio_free(pin)

#define GTP_IRQ_TAB                     {IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH}

 

//STEP_3(optional):Custom set some configby themself,if need.

#if GTP_CUSTOM_CFG

 #define GTP_MAX_HEIGHT   600

 #define GTP_MAX_WIDTH    1024

 #define GTP_INT_TRIGGER  1    //0:Rising 1:Falling

#else

 #define GTP_MAX_HEIGHT   4096

 #define GTP_MAX_WIDTH    4096

 #define GTP_INT_TRIGGER  1

#endif

#define GTP_MAX_TOUCH         5

#define GTP_ESD_CHECK_CIRCLE  2000

 

//STEP_4(optional):If this project havetouch key,Set touch key config.                                   

#if GTP_HAVE_TOUCH_KEY

   #define GTP_KEY_TAB     {KEY_MENU,KEY_HOME, KEY_BACK, KEY_SEND}

#endif

 

//***************************PART3:OTHERdefine*********************************

#define GTP_DRIVER_VERSION    “V2.4<2014/11/28>”

#define GTP_I2C_NAME          “gt9xx_ts”

#define GTP_POLL_TIME         10

#define GTP_ADDR_LENGTH       2

#define GTP_CONFIG_MIN_LENGTH 186

#define GTP_CONFIG_MAX_LENGTH 240

#define FAIL                  0

#define SUCCESS               1

 

//Register define

#define GTP_READ_COOR_ADDR    0x814E

#define GTP_REG_SLEEP         0x8040

#define GTP_REG_SENSOR_ID     0x814A

#define GTP_REG_CONFIG_DATA   0x8047

#define GTP_REG_VERSION       0x8140

#define GTP_REG_COMMAND       0x8040

 

#define GTP_COMMAND_READSTATUS            0

#define GTP_COMMAND_DIFFERENCE         1

#define GTP_COMMAND_SOFTRESET              2

#define GTP_COMMAND_UPDATE                    3

#define GTP_COMMAND_CALCULATE           4

#define GTP_COMMAND_TURNOFF                    5

 

#define RESOLUTION_LOC        3

#define TRIGGER_LOC           8

 

//Log define

#define GTP_INFO(fmt,arg…)          printk(“<<-GTP-INFO->> “fmt”\n”,##arg)

#define GTP_ERROR(fmt,arg…)         printk(“<<-GTP-ERROR->> “fmt”\n”,##arg)

#define GTP_DEBUG(fmt,arg…)          do{\

                                        if(GTP_DEBUG_ON)\

                                        printk(“<<-GTP-DEBUG->>[%d]”fmt”\n”,__LINE__, ##arg);\

                                      }while(0)

#define GTP_DEBUG_ARRAY(array, num)    do{\

                                         s32i;\

                                         u8* a = array;\

                                        if(GTP_DEBUG_ARRAY_ON)\

                                         {\

                                           printk(“<<-GTP-DEBUG-ARRAY->>\n”);\

                                            for (i = 0; i < (num); i++)\

                                            {\

                                               printk(“%02x   “,(a)[i]);\

                                               if ((i + 1 ) %10 == 0)\

                                                {\

                                                   printk(“\n”);\

                                               }\

                                            }\

                                           printk(“\n”);\

                                        }\

                                      }while(0)

#define GTP_DEBUG_FUNC()               do{\

                                        if(GTP_DEBUG_FUNC_ON)\

                                        printk(“<<-GTP-FUNC->>Func:%s@Line:%d\n”,__func__,__LINE__);\

                                      }while(0)

#define GTP_SWAP(x, y)                 do{\

                                        typeof(x) z = x;\

                                         x =y;\

                                        y = z;\

                                       }while(0)

 

//****************************PART4:UPDATEdefine*******************************

//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

 

//*****************************End of PartIII********************************

 

#endif /* _LINUX_GOODIX_TOUCH_H */

 

修改gt9xx.c为:

#include <linux/irq.h>

#include “gt9xx_ts.h”

#include <linux/pm.h>

 

#if GTP_ICS_SLOT_REPORT

   #include <linux/input/mt.h>

#endif

 

static const char *goodix_ts_name =”gt9xx”;

static struct workqueue_struct *goodix_wq;

struct i2c_client * i2c_connect_client =NULL;

static u8 config[GTP_CONFIG_MAX_LENGTH +GTP_ADDR_LENGTH]

                = {GTP_REG_CONFIG_DATA >>8, GTP_REG_CONFIG_DATA & 0xff};

 

#if GTP_HAVE_TOUCH_KEY

staticconst u16 touch_key_array[] = GTP_KEY_TAB;

#defineGTP_MAX_KEY_NUM      (sizeof(touch_key_array)/sizeof(touch_key_array[0]))

#endif

 

static s8 gtp_i2c_test(struct i2c_client*client);

void gtp_reset_guitar(struct i2c_client*client, s32 ms);

void gtp_int_sync(s32 ms);

 

#ifdef CONFIG_HAS_EARLYSUSPEND

static void goodix_ts_early_suspend(structearly_suspend *h);

static void goodix_ts_late_resume(structearly_suspend *h);

#endif

 

#if GTP_CREATE_WR_NODE

extern s32 init_wr_node(structi2c_client*);

extern void uninit_wr_node(void);

#endif

 

#if GTP_AUTO_UPDATE

extern u8 gup_init_update_proc(structgoodix_ts_data *);

#endif

 

#if GTP_ESD_PROTECT

static struct delayed_workgtp_esd_check_work;

static struct workqueue_struct *gtp_esd_check_workqueue = NULL;

static void gtp_esd_check_func(structwork_struct *);

s32 gtp_init_ext_watchdog(structi2c_client *client);

#endif

 

///

//specific tp related macro: need beconfigured for specific tp

 

#define CTP_IRQ_NUMBER          (config_info.int_number)

#define CTP_IRQ_MODE        (IRQF_TRIGGER_FALLING)

#define CTP_NAME         (“gt9xx_ts”)

#define SCREEN_MAX_X  (screen_max_x)

#define SCREEN_MAX_Y  (screen_max_y)

#define PRESS_MAX        (255)

 

 

static int screen_max_x = 0;

static int screen_max_y = 0;

static int revert_x_flag = 0;

static int revert_y_flag = 0;

static int exchange_x_y_flag = 0;

static __u32 twi_id = 0;

static char irq_pin_name[8];

 

static u32 debug_mask = 0;

 

enum{   

DEBUG_INIT= 1U << 0,    

DEBUG_SUSPEND= 1U << 1,

DEBUG_INT_INFO= 1U << 2,

DEBUG_X_Y_INFO= 1U << 3,

DEBUG_KEY_INFO= 1U << 4,

DEBUG_WAKEUP_INFO= 1U << 5,

DEBUG_OTHERS_INFO= 1U << 6,

};

 

#definedprintk(level_mask,fmt,arg…)   if(unlikely(debug_mask & level_mask)) \

       printk(“***CTP***”fmt, ## arg)

module_param_named(debug_mask,debug_mask,int,S_IRUGO| S_IWUSR | S_IWGRP);

 

static const unsigned short normal_i2c[2]= {0x5d, I2C_CLIENT_END};

//static const int chip_id_value[3] ={57};

//static uint8_t read_chip_value[3] ={GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff,0};

struct ctp_config_info config_info = {

.input_type= CTP_TYPE,

.name= NULL,

.int_number= 0,

};

 

//static void goodix_init_events(structwork_struct *work);

static void goodix_resume_events(structwork_struct *work);

static struct workqueue_struct *goodix_wq;

//static struct workqueue_struct*goodix_init_wq;

static struct workqueue_struct*goodix_resume_wq;

//static DECLARE_WORK(goodix_init_work,goodix_init_events);

static DECLARE_WORK(goodix_resume_work,goodix_resume_events);

 

/**

 *ctp_detect – Device detection callback for automatic device creation

 *return value: 

 *                    = 0; success;

 *                    < 0; err

 */

static int ctp_detect(struct i2c_client*client, struct i2c_board_info *info)

{

structi2c_adapter *adapter = client->adapter;

   int  ret = -1;

     

   if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)){

        printk(“======return=====\n”);

                return -ENODEV;

   }

        

   if(twi_id == adapter->nr){

           dprintk(DEBUG_INIT,”%s: addr = %x\n”, __func__,client->addr);

           ret = gtp_i2c_test(client);

             printk(“detectret %d\n”,ret);

           if(!ret){

              printk(“%s:I2Cconnection might be something wrong \n”, __func__);

              return -ENODEV;

        }else{                    

            strlcpy(info->type, CTP_NAME,I2C_NAME_SIZE);

                  printk(“======detectok !=====\n”);

                  return0;    

        }

}else{

        return -ENODEV;

}

}

 

/**

 *ctp_print_info – sysconfig print function

 *return value:

 *

 */

void ctp_print_info(struct ctp_config_infoinfo,int debug_level)

{

if(debug_level== DEBUG_INIT)

{

       dprintk(DEBUG_INIT,”info.ctp_used:%d\n”,info.ctp_used);

       dprintk(DEBUG_INIT,”info.twi_id:%d\n”,info.twi_id);

       dprintk(DEBUG_INIT,”info.screen_max_x:%d\n”,info.screen_max_x);

       dprintk(DEBUG_INIT,”info.screen_max_y:%d\n”,info.screen_max_y);

       dprintk(DEBUG_INIT,”info.revert_x_flag:%d\n”,info.revert_x_flag);

       dprintk(DEBUG_INIT,”info.revert_y_flag:%d\n”,info.revert_y_flag);

       dprintk(DEBUG_INIT,”info.exchange_x_y_flag:%d\n”,info.exchange_x_y_flag);

       dprintk(DEBUG_INIT,”info.irq_gpio_number:%d\n”,info.irq_gpio.gpio);

       dprintk(DEBUG_INIT,”info.wakeup_gpio_number:%d\n”,info.wakeup_gpio.gpio);

}

}

 

/**

 *ctp_wakeup – function

 *

 */

int ctp_wakeup(int status,int ms)

{

dprintk(DEBUG_INIT,”***CTP***%s:status:%d,ms = %d\n”,__func__,status,ms);

 

if(status == 0) {

 

       if(ms== 0) {

             __gpio_set_value(config_info.wakeup_gpio.gpio,0);

       }else{

             __gpio_set_value(config_info.wakeup_gpio.gpio,0);

             msleep(ms);

             __gpio_set_value(config_info.wakeup_gpio.gpio,1);

       }

}

if(status == 1) {

       if(ms== 0) {

             __gpio_set_value(config_info.wakeup_gpio.gpio,1);

       }else{

             __gpio_set_value(config_info.wakeup_gpio.gpio,1);

             msleep(ms);

             __gpio_set_value(config_info.wakeup_gpio.gpio,0);

       }

}

msleep(5);

 

return0;

}

 

void gtp_set_int_value(int status)

{

       long unsigned int config;

      

       config= SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF);

   pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config);

 

       if(1 != SUNXI_PINCFG_UNPACK_VALUE(config)){

             config =SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,1);

               pin_config_set(SUNXI_PINCTRL,irq_pin_name,config);;

    }

 

       __gpio_set_value(CTP_IRQ_NUMBER, status);  

}

 

void gtp_set_io_int(void)

{

       long unsigned int config;

       config= SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF);

   pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config);

 

       if(4 != SUNXI_PINCFG_UNPACK_VALUE(config)){          

             config =SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,4);      

              pin_config_set(SUNXI_PINCTRL,irq_pin_name,config);

    }

       

}

 

/*******************************************************

Function:

   Synchronization.

Input:

   ms: synchronization time in millisecond.

Output:

   None.

*******************************************************/

void gtp_int_sync(s32 ms)

{

   gtp_set_int_value(0);

   msleep(ms);

   gtp_set_io_int();

}

 

/*******************************************************

Function:

   Reset chip.

Input:

   ms: reset time in millisecond

Output:

   None.

*******************************************************/

void gtp_reset_guitar(struct i2c_client*client, s32 ms)

{

#if GTP_COMPATIBLE_MODE

   struct goodix_ts_data *ts = i2c_get_clientdata(client);

#endif   

 

   GTP_DEBUG_FUNC();

   GTP_INFO(“Guitar reset”);

   ctp_wakeup(0, 0);   // beginselect I2C slave addr

   msleep(ms);                        // T2: > 10ms

   // HIGH: 0x28/0x29, LOW: 0xBA/0xBB

   gtp_set_int_value(0);

 

   msleep(2);                         // T3: > 100us

   ctp_wakeup(1, 0);

   

   msleep(6);                         // T4: > 5ms

 

 // GTP_GPIO_AS_INPUT(gtp_rst_gpio);   // end select I2C slave addr

 

#if GTP_COMPATIBLE_MODE

   if (CHIP_TYPE_GT9F == ts->chip_type)

   {

       return;

   }

#endif

 

   gtp_int_sync(50); 

#if GTP_ESD_PROTECT

   gtp_init_ext_watchdog(client);

#endif

}

 

 

void gtp_io_init(int ms)

{      

       ctp_wakeup(0, 0);

       msleep(ms);

       

       gtp_set_int_value(0);

       msleep(2);

       ctp_wakeup(1, 0);

       

       msleep(6);

 

       gtp_int_sync(50);

#if GTP_ESD_PROTECT

    //  gtp_init_ext_watchdog(client);

#endif

        

}

 

/******************************************************* 

Function:

Readdata from the i2c slave device.

 

Input:

client:   i2c device.

buf[0]:operateaddress.

buf[1]~buf[len]:readdata buffer.

len:operatelength.

Output:

numbersof i2c_msgs to transfer

*********************************************************/

s32 gtp_i2c_read(struct i2c_client*client, u8 *buf, s32 len)

{

       struct i2c_msg msgs[2];

       s32 ret = -1;

       s32 retries = 0;

              

       msgs[0].flags = !I2C_M_RD;

       msgs[0].addr  = client->addr;

       msgs[0].len   = GTP_ADDR_LENGTH;

       msgs[0].buf   = &buf[0];

       

       msgs[1].flags = I2C_M_RD;

       msgs[1].addr  = client->addr;

       msgs[1].len   = len -GTP_ADDR_LENGTH;

       msgs[1].buf   = &buf[GTP_ADDR_LENGTH];

 

       while(retries < 5) {

                ret =i2c_transfer(client->adapter, msgs, 2);

                if(ret == 2)

                        break;

                retries++;

       }

 

       if(retries >= 5) {

                printk(“%s:I2C retrytimeout, reset chip.”, __func__);

                gtp_reset_guitar(client,10); 

       }

       return ret;

}

 

/******************************************************* 

Function:

writedata to the i2c slave device.

 

Input:

client:   i2c device.

buf[0]:operateaddress.

buf[1]~buf[len]:writedata buffer.

len:operatelength.

Output:

numbersof i2c_msgs to transfer.

*********************************************************/

s32 gtp_i2c_write(struct i2c_client*client,u8 *buf,s32 len)

{

       struct i2c_msg msg;

       s32 ret = -1;

       s32 retries = 0;

       

       msg.flags = !I2C_M_RD;

       msg.addr  = client->addr;

       msg.len   = len;

       msg.buf   = buf;

       

       while(retries < 5) {

                ret =i2c_transfer(client->adapter, &msg, 1);

                if (ret == 1)

                        break;

                retries++;

       }

 

       if(retries >= 5) {

                printk(“%s:I2C retry timeout,reset chip.”, __func__);

                gtp_reset_guitar(client,10); 

       }

       return ret;

}

/*******************************************************

Function:

   i2c read twice, compare the results

Input:

   client:  i2c device

   addr:    operate address

   rxbuf:   read data to store, ifcompare successful

   len:     bytes to read

Output:

   FAIL:    read failed

   SUCCESS: read successful

*********************************************************/

s32 gtp_i2c_read_dbl_check(structi2c_client *client, u16 addr, u8 *rxbuf, int len)

{

   u8 buf[16] = {0};

   u8 confirm_buf[16] = {0};

   u8 retry = 0;

   

   while (retry++ < 3)

   {

       memset(buf, 0xAA, 16);

       buf[0] = (u8)(addr >> 8);

        buf[1] = (u8)(addr & 0xFF);

       gtp_i2c_read(client, buf, len + 2);

       

       memset(confirm_buf, 0xAB, 16);

       confirm_buf[0] = (u8)(addr >> 8);

       confirm_buf[1] = (u8)(addr & 0xFF);

       gtp_i2c_read(client, confirm_buf, len + 2);

       

       if (!memcmp(buf, confirm_buf, len+2))

       {

           memcpy(rxbuf, confirm_buf+2, len);

           return SUCCESS;

       }

   }   

   GTP_ERROR(“I2C read 0x%04X, %d bytes, double check failed!”,addr, len);

   return FAIL;

}

 

/*******************************************************

Function:

   i2c read config data check it

Input:

   client:  i2c device

Output:

   FAIL:    read failed

   SUCCESS: read successful

*********************************************************/

void gtp_i2c_read_cfg_check(structi2c_client *client)

{

structgoodix_ts_data *ts = i2c_get_clientdata(client);

u8buf[GTP_CONFIG_MIN_LENGTH + GTP_ADDR_LENGTH];

 

u8retry = 0;

memset(buf,0, ts->gtp_cfg_len + GTP_ADDR_LENGTH);

buf[0]= config[0];

buf[1]= config[1];

gtp_i2c_read(client,buf, ts->gtp_cfg_len + GTP_ADDR_LENGTH);

GTP_DEBUG_ARRAY(buf+GTP_ADDR_LENGTH,ts->gtp_cfg_len);

if(memcmp(buf+GTP_ADDR_LENGTH,config+GTP_ADDR_LENGTH, ts->gtp_cfg_len-1) == 0)

{

       GTP_INFO(“cfgcheck ok!\r\n”);

       returnSUCCESS;

}

else

{

       GTP_INFO(“cfgcheck failed!\r\n”);

       returnFAIL;

}

}

 

/*******************************************************

Function:

Sendconfig Function.

 

Input:

client:   i2c client.

 

Output:

Executiveoutcomes.0–success,non-0–fail.

*******************************************************/

s32 gtp_send_cfg(struct i2c_client*client)

{

   s32 ret = 0;

   

#if GTP_DRIVER_SEND_CFG

   s32 retry = 0;

 

   for (retry = 0; retry < 5; retry++)

   {

       ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH +GTP_ADDR_LENGTH);

       if (ret > 0)

       {

           break;

       }

   }

#endif

 

   return ret;

}

 

/*******************************************************

Function:

DisableIRQ Function.

 

Input:

ts:  i2c client private struct.

Output:

None.

*******************************************************/

void gtp_irq_disable(struct goodix_ts_data*ts)

{

       unsigned long irqflags;

       intret;

 

       dprintk(DEBUG_INT_INFO, “%s —start!—\n”, __func__);

       spin_lock_irqsave(&ts->irq_lock, irqflags);

       if (!ts->irq_is_disable) {

               ts->irq_is_disable = 1;

               ret =input_set_int_enable(&(config_info.input_type), 0);

                if (ret < 0)                  

                  dprintk(DEBUG_OTHERS_INFO,”%s irqdisable failed\n”, goodix_ts_name);

       }

       spin_unlock_irqrestore(&ts->irq_lock, irqflags);

}

 

/*******************************************************

Function:

DisableIRQ Function.

 

Input:

ts:  i2c client private struct.

Output:

None.

*******************************************************/

void gtp_irq_enable(struct goodix_ts_data*ts)

{

       unsigned long irqflags = 0;

       intret;

 

       dprintk(DEBUG_INT_INFO, “%s —start!—\n”, __func__);

   

       spin_lock_irqsave(&ts->irq_lock, irqflags);

       if (ts->irq_is_disable) {

                ts->irq_is_disable = 0;

                ret =input_set_int_enable(&(config_info.input_type), 1);  

                  if(ret < 0)                   

                        dprintk(DEBUG_OTHERS_INFO,”%sirq enable failed\n”, goodix_ts_name);

       }

       spin_unlock_irqrestore(&ts->irq_lock, irqflags);

}

 

/*******************************************************

Function:

Touchdown report function.

 

Input:

ts:privatedata.

id:trackingid.

x:inputx.

y:inputy.

w:inputweight.

Output:

None.

*******************************************************/

static void gtp_touch_down(structgoodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w)

{

       dprintk(DEBUG_X_Y_INFO, “source data:ID:%d, X:%d, Y:%d,W:%d\n”, id, x, y, w);

       

       if(1 == exchange_x_y_flag){

                swap(x, y);

       }

       

       if(1 == revert_x_flag){

                x = SCREEN_MAX_X – x;

       }

       

       if(1 == revert_y_flag){

                y = SCREEN_MAX_Y – y;

       }

       

       dprintk(DEBUG_X_Y_INFO,”report data:ID:%d, X:%d, Y:%d,W:%d\n”, id, x, y, w);

 

#if GTP_ICS_SLOT_REPORT

       input_mt_slot(ts->input_dev, id);

       input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id);

       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_TOUCH_MAJOR, w);

       input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);

#else

       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_TOUCH_MAJOR, w);

       input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);

       input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id);

       input_mt_sync(ts->input_dev);

#endif

 

}

 

/*******************************************************

Function:

Touchup report function.

 

Input:

ts:privatedata.

Output:

None.

*******************************************************/

static void gtp_touch_up(structgoodix_ts_data* ts, s32 id)

{

#if GTP_ICS_SLOT_REPORT

       input_mt_slot(ts->input_dev, id);

       input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);

       dprintk(DEBUG_X_Y_INFO, “Touch id[%2d] release!”, id);

#else

       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(ts->input_dev);

#endif

}

 

/*******************************************************

Function:

Goodixtouchscreen work function.

 

Input:

work:    work_struct of goodix_wq.

Output:

None.

*******************************************************/

static void goodix_ts_work_func(structwork_struct *work)

{

       u8  end_cmd[3] ={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0};

       u8  point_data[2 + 1 + 8 *GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR &0xFF};

       u8  touch_num = 0;

       u8  finger = 0;

       static u16 pre_touch = 0;

       static u8 pre_key = 0;

       u8  key_value = 0;

       u8* coor_data = NULL;

       s32 input_x = 0;

       s32 input_y = 0;

       s32 input_w = 0;

       s32 id = 0;

       s32 i  = 0;

       s32 ret = -1;

       struct goodix_ts_data *ts = NULL;

 

       dprintk(DEBUG_X_Y_INFO,”===enter %s===\n”,__func__);

 

       ts = container_of(work, struct goodix_ts_data, work);

       if (ts->enter_update){

                return;

       }

 

       ret = gtp_i2c_read(ts->client, point_data, 12);

       if (ret < 0){

                printk(“I2C transfererror. errno:%d\n “, ret);

                goto exit_work_func;

       }

 

       finger = point_data[GTP_ADDR_LENGTH];   

       if((finger & 0x80) == 0) {

                goto exit_work_func;

       }

 

       touch_num = finger & 0x0f;

       if (touch_num > GTP_MAX_TOUCH) {

                goto exit_work_func;

       }

 

       if (touch_num > 1) {

                u8 buf[8 * GTP_MAX_TOUCH] ={(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff};

 

                ret =gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num – 1));

                memcpy(&point_data[12],&buf[2], 8 * (touch_num – 1));

       }

 

#if GTP_HAVE_TOUCH_KEY

       key_value = point_data[3 + 8 * touch_num];

   

       if(key_value || pre_key) {

                for (i = 0; i <GTP_MAX_KEY_NUM; i++) {

                       input_report_key(ts->input_dev, touch_key_array[i], key_value &(0x01<<i));  

                }

                touch_num = 0;

                pre_touch = 0;

       }

#endif

       pre_key = key_value;

 

       dprintk(DEBUG_X_Y_INFO, “pre_touch:%02x, finger:%02x.”,pre_touch, finger);

 

#if GTP_ICS_SLOT_REPORT

       if (pre_touch || touch_num) {

                s32 pos = 0;

                u16 touch_index = 0;

                coor_data = &point_data[3];

               

                if(touch_num) {

                        id = coor_data[pos]& 0x0F;

                        touch_index |=(0x01<<id);

                }

 

                dprintk(DEBUG_X_Y_INFO,

                       “id=%d,touch_index=0x%x, pre_touch=0x%x\n”, id, touch_index, pre_touch);

               

                for (i = 0; i <GTP_MAX_TOUCH; i++) {

                        if (touch_index &(0x01<<i)) {

                                input_x  = coor_data[pos + 1] | coor_data[pos + 2]<< 8;

                                input_y  = coor_data[pos + 3] | coor_data[pos + 4]<< 8;

                                input_w  = coor_data[pos + 5] | coor_data[pos + 6]<< 8;

 

                               gtp_touch_down(ts, id, input_x, input_y, input_w);

                                pre_touch |=0x01 << i;

 

                                pos += 8;

                                id =coor_data[pos] & 0x0F;

                                touch_index |=(0x01<<id);

                        }else {// if (pre_touch& (0x01 << i))

           

                               gtp_touch_up(ts, i);

                                pre_touch&= ~(0x01 << i);

                        }

                }

       }

 

#else

       if (touch_num ) {

                for (i = 0; i < touch_num;i++) {

                        coor_data =&point_data[i * 8 + 3];

 

                        id = coor_data[0] &0x0F;

                        input_x  = coor_data[1] | coor_data[2] << 8;

                        input_y  = coor_data[3] | coor_data[4] << 8;

                        input_w  = coor_data[5] | coor_data[6] << 8;

 

                        gtp_touch_down(ts, id,input_x, input_y, input_w);

                }

       }else if(pre_touch){

                dprintk(DEBUG_X_Y_INFO,”Touch Release!”);

                gtp_touch_up(ts, 0);

       }

       

       pre_touch = touch_num;

 

#endif

 

       input_sync(ts->input_dev);

 

exit_work_func:

       if(!ts->gtp_rawdiff_mode) {

                ret =gtp_i2c_write(ts->client, end_cmd, 3);

                if (ret < 0) {

                        printk(“I2C writeend_cmd  error!”);

                }

       }

       return ;

}

 

/*******************************************************

Function:

Externalinterrupt service routine.

 

Input:

irq: interrupt number.

dev_id:private data pointer.

Output:

irqexecute status.

*******************************************************/

 

irqreturn_t goodix_ts_irq_handler(int irq,void *dev_id)

{         

    struct goodix_ts_data *ts = (struct goodix_ts_data *)dev_id;

 dprintk(DEBUG_INT_INFO,”==========——TS Interrupt—–============\n”); 

 

 queue_work(goodix_wq, &ts->work);

 return 0;

}

 

 

 

 

/*******************************************************

Function:

Etersleep function.

 

Input:

ts:privatedata.

Output:

Executiveoutcomes.0–success,non-0–fail.

*******************************************************/

static s8 gtp_enter_sleep(structgoodix_ts_data * ts)

{

       s8 ret = -1;

       s8 retry = 0;

       u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8),(u8)GTP_REG_SLEEP, 5};

       

       dprintk(DEBUG_SUSPEND, “%s start!\n”, __func__);

       

       gtp_set_int_value(0);

                  msleep(5);

                 

       while(retry++ < 5) {

                ret =gtp_i2c_write(ts->client, i2c_control_buf, 3);

                if (ret > 0) {

                        dprintk(DEBUG_SUSPEND,”GTP enter sleep!”);

                        return ret;

                }

                msleep(10);

       }

       dprintk(DEBUG_SUSPEND, “GTP send sleep cmd failed.”);

       

       return ret;

}

 

/*******************************************************

Function:

Wakeupfrom sleep mode Function.

 

Input:

ts:  private data.

Output:

Executiveoutcomes.0–success,non-0–fail.

*******************************************************/

static s8 gtp_wakeup_sleep(structgoodix_ts_data * ts)

{

       u8 retry = 0;

       s8 ret = -1;

       

       gtp_io_init(20);

       gtp_set_io_int();

      

#if GTP_POWER_CTRL_SLEEP

   while(retry++ < 5)

   {

       gtp_reset_guitar(ts->client, 20);

       

       GTP_INFO(“GTP wakeup sleep.”);

       return 1;

   }

#else

   while(retry++ < 10)

   {

   #if GTP_GESTURE_WAKEUP

       if (DOZE_WAKEUP != doze_status) 

       {

           GTP_INFO(“Powerkey wakeup.”);

       }

       else  

       {

           GTP_INFO(“Gesture wakeup.”);

       }

       doze_status = DOZE_DISABLED;

       gtp_irq_disable(ts);

       gtp_reset_guitar(ts->client, 10);

       gtp_irq_enable(ts);

       

   #else

       gtp_set_int_value(1);

       msleep(5);

   #endif

   

       ret = gtp_i2c_test(ts->client);

       if (ret > 0)

       {

            GTP_INFO(“GTP wakeupsleep.”);

           

       #if (!GTP_GESTURE_WAKEUP)

           {

                gtp_int_sync(25);

           #if GTP_ESD_PROTECT

               gtp_init_ext_watchdog(ts->client);

           #endif

           }

        #endif

           

           return ret;

       }

       gtp_reset_guitar(ts->client, 20);

   }

#endif

 

   GTP_ERROR(“GTP wakeup sleep failed.”);

   return ret;

 

}

 

 

/*******************************************************

Function:

GTP initializefunction.

 

Input:

ts:  i2c client private struct.

Output:

Executiveoutcomes.0—succeed.

*******************************************************/

static s32 gtp_init_panel(structgoodix_ts_data *ts)

{

   s32 ret = -1;

s32i = 0;

   u8 check_sum = 0;

   u8 opr_buf[16] = {0};

   u8 sensor_id = 0;

u8drv_cfg_version;

u8flash_cfg_version;

 

   u8 send_cfg_buf[] = CTP_CFG_GROUP0;

   u8 cfg_info_len = GTP_CONFIG_MIN_LENGTH;

ts->gtp_cfg_len= cfg_info_len;

gtp_int_sync(20);          //先同步一下INT脚才能读到正确的配置信息

memset(config+GTP_ADDR_LENGTH,0, GTP_CONFIG_MAX_LENGTH);

if(gtp_i2c_read(ts->client,config, GTP_CONFIG_MIN_LENGTH+GTP_ADDR_LENGTH) < 0)

{

       GTP_DEBUG(“readgt9xx config data failed! return.\r\n”);

       return-1;

}

GTP_DEBUG(“readconfig data ok!,as follows:\r\n”);

GTP_DEBUG_ARRAY(config+GTP_ADDR_LENGTH,GTP_CONFIG_MIN_LENGTH);                //读出原配置信息,以利恢复_记得将打印出来的配置信息保存

#if GTP_DRIVER_SEND_CFG

   

/*check firmware */

ret= gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);

if(SUCCESS == ret)

{

       if(opr_buf[0] != 0xBE)

       {

             ts->fw_error= 1;

             GTP_ERROR(“Firmwareerror, no config sent!”);

             return-1;

       }

}

#if GTP_CONFIG_MODE        //根据厂家数据表配罿                                                      

memcpy(config+GTP_ADDR_LENGTH,send_cfg_buf, ts->gtp_cfg_len);

 

ret= gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0],1);//读版本号

if(ret == SUCCESS)           

{

       GTP_DEBUG(“ConfigVersion: 0x%02X; IC Config Version: 0x%02X”, \

                                         config[GTP_ADDR_LENGTH],opr_buf[0]);

 

       flash_cfg_version= opr_buf[0];

       drv_cfg_version= config[GTP_ADDR_LENGTH];

      

       if(flash_cfg_version < 90 && flash_cfg_version > drv_cfg_version)

       {

             config[GTP_ADDR_LENGTH]= 0x00;       //版本写入0,强制更新版本为0X41 A版本

       }

}

else

{

       GTP_ERROR(“Failedto get ic config version!No config sent!”);

       return-1;

}

#endif//GTP_CONFIG_MODE

      

#if GTP_CUSTOM_CFG

   config[RESOLUTION_LOC]     =(u8)GTP_MAX_WIDTH;

   config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8);

   config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT;

   config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8);    

config[RESOLUTION_LOC+ 4] = (u8)GTP_MAX_TOUCH; 

   config[TRIGGER_LOC] &= 0xfc;        

config[TRIGGER_LOC]|= GTP_INT_TRIGGER;          

#endif // GTP_CUSTOM_CFG

   

   check_sum = 0;

   for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)

   {

       check_sum += config[i];

   }

   config[ts->gtp_cfg_len] = (~check_sum) + 1;

config[ts->gtp_cfg_len+1]= 1;

ret= gtp_send_cfg(ts->client);

if(ret < 0)

{

       GTP_ERROR(“Sendconfig error.”);

}

      

ts->abs_x_max= (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC];

ts->abs_y_max= (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2];

ts->int_trigger_type= (config[TRIGGER_LOC]) & 0x03;

#if GTP_CONFIG_MODE        //根据厂家数据表配罿

if(flash_cfg_version < 90 && flash_cfg_version > drv_cfg_version)

{

       config[GTP_ADDR_LENGTH]= 0x41;       //版本写入0x41 ,唤醒时不会强制更新版本

}

#endif//GTP_CONFIG_MODE

#else // driver not send config

 

   ts->abs_x_max = GTP_MAX_WIDTH;

ts->abs_y_max= GTP_MAX_HEIGHT;

ts->int_trigger_type= GTP_INT_TRIGGER;

  

#endif // GTP_DRIVER_SEND_CFG

 

   GTP_INFO(“X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x”,ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type);

   msleep(10);

   return 0;

 

}

 

/*******************************************************

Function:

Readgoodix touchscreen version function.

 

Input:

client:   i2c client struct.

version:addressto store version info

Output:

Executiveoutcomes.0—succeed.

*******************************************************/

s32 gtp_read_version(struct i2c_client*client, u16* version)

{

       s32 ret = -1;

       u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff};

 

       dprintk(DEBUG_INIT, “%s —start!.—\n”, __func__);

 

       ret = gtp_i2c_read(client, buf, sizeof(buf));

       if (ret < 0) {

                printk(“GTP read versionfailed”);

                return ret;

       }

 

       if (version) {

                *version = (buf[7] << 8)| buf[6];

       }

 

       if (buf[5] == 0x00) {

                printk(“IC Version:%c%c%c_%02x%02x”, buf[2], buf[3], buf[4], buf[7], buf[6]);

       }

       else {

                printk(“IC Version:%c%c%c%c_%02x%02x”, buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]);

       }

       return ret;

}

 

/*******************************************************

Function:

I2ctest Function.

 

Input:

client:i2cclient.

Output:

Executiveoutcomes.0–success,non-0–fail.

*******************************************************/

static s8 gtp_i2c_test(struct i2c_client*client)

{

       u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA &0xff};

       u8 retry = 0;

       s8 ret = -1;

 

       while(retry++ < 2) {

                ret = gtp_i2c_read(client,test, 3);

                if (ret > 0) {

                        return ret;

                }

                printk(“GTP i2c testfailed time %d.”,retry);

                msleep(10);

       }

       return ret;

}

 

 

/*******************************************************

Function:

Requestinput device Function.

 

Input:

ts:privatedata.

Output:

Executiveoutcomes.0–success,non-0–fail.

*******************************************************/

static s8 gtp_request_input_dev(structgoodix_ts_data *ts)

{

       s8 ret = -1;

#if GTP_HAVE_TOUCH_KEY

       u8 index = 0;

#endif

 

       ts->input_dev = input_allocate_device();

       if (ts->input_dev == NULL) {

                GTP_ERROR(“Failed toallocate input device.”);

                return -ENOMEM;

       }

 

       ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) |BIT_MASK(EV_ABS) ;

#if GTP_ICS_SLOT_REPORT

       __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);

       input_mt_init_slots(ts->input_dev, 255);

#else

       ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

#endif

 

#if GTP_HAVE_TOUCH_KEY

       for (index = 0; index < GTP_MAX_KEY_NUM; index++) {

               input_set_capability(ts->input_dev,EV_KEY,touch_key_array[index]);    

       }

#endif

 

//#if GTP_CHANGE_X2Y

//       GTP_SWAP(ts->abs_x_max, ts->abs_y_max);

//#endif

 

       input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0,SCREEN_MAX_X, 0, 0);

       input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0,SCREEN_MAX_Y, 0, 0);

       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_TRACKING_ID, 0, 255, 0,0);

       set_bit(INPUT_PROP_DIRECT,ts->input_dev->propbit);

   

       ts->input_dev->name = CTP_NAME;

       ts->input_dev->phys = “input/goodix-ts”;

       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;

       ret = input_register_device(ts->input_dev);

       if (ret) {

                printk(“Register %s inputdevice failed”, ts->input_dev->name);

                return -ENODEV;

       }

#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

       return 0;

}

 

 

/*******************************************************

Function:

Goodixtouchscreen probe function.

 

Input:

client:   i2c device struct.

id:deviceid.

Output:

Executiveoutcomes. 0—succeed.

*******************************************************/

static int goodix_ts_probe(structi2c_client *client, const struct i2c_device_id *id)

{

       s32 ret = -1;

       struct goodix_ts_data *ts;

       u16 version_info;  

   

       dprintk(DEBUG_INIT, “GTP DriverVersion:%s\n”,GTP_DRIVER_VERSION);

       dprintk(DEBUG_INIT, “GTP Driver build@%s,%s\n”,__TIME__,__DATE__);

       printk(“GTP I2C Address:0x%02x\n”, client->addr);

 

       i2c_connect_client = client;

       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {

                printk(“I2C checkfunctionality failed.\n”);

                return -ENODEV;

       }

       

       ts = kzalloc(sizeof(*ts), GFP_KERNEL);

       if (ts == NULL) {

                printk(“Alloc GFP_KERNELmemory failed.\n”);

                return -ENOMEM;

       }

  

       memset(ts, 0, sizeof(*ts));

       INIT_WORK(&ts->work, goodix_ts_work_func);

       ts->client = client;

       i2c_set_clientdata(client, ts);

       //ts->irq_lock = SPIN_LOCK_UNLOCKED;

       ts->gtp_rawdiff_mode = 0;

 

 

       ret = gtp_i2c_test(client);

       if (ret < 0){

                printk(“I2C communicationERROR!\n”);

               goto exit_device_detect;

       }

 

    goodix_resume_wq = create_singlethread_workqueue(“goodix_resume”);

    if (goodix_resume_wq == NULL) {

               printk(“create goodix_resume_wqfail!\n”);

               return -ENOMEM;

    }

 

    goodix_wq =create_singlethread_workqueue(“goodix_wq”);

    if (!goodix_wq) {

               printk(KERN_ALERT “Creat goodix_wqworkqueue failed.\n”);

                  return-ENOMEM;

    }

 

#if GTP_AUTO_UPDATE

       ret = gup_init_update_proc(ts);

       if (ret < 0) {

                printk(“Create updatethread error.”);

       }

#endif

 

       ret = gtp_init_panel(ts);

       if (ret < 0) {

                printk(“GTP init panelfailed.\n”);

       }

 

       

      

    ret = gtp_request_input_dev(ts);

       if (ret < 0) {

                printk(“GTP request inputdev failed\n”);

       gotoexit_device_detect;

       }

 

       ret= gtp_read_version(client, &version_info);

       if(ret < 0) {

                             printk(“Readversion failed.”);

       }

      

       config_info.dev= &(ts->input_dev->dev);

      

       ret = input_request_int(&(config_info.input_type), goodix_ts_irq_handler,CTP_IRQ_MODE,ts);     

       if (ret) {

                printk(“Request irqfail!.\n”);

       }

       

       

       spin_lock_init(&ts->irq_lock);

 

#if GTP_CREATE_WR_NODE

       init_wr_node(client);

#endif

 

#if GTP_ESD_PROTECT

       INIT_DELAYED_WORK(&gtp_esd_check_work, gtp_esd_check_func);

       gtp_esd_check_workqueue = create_workqueue(“gtp_esd_check”);

       queue_delayed_work(gtp_esd_check_workqueue, &gtp_esd_check_work,GTP_ESD_CHECK_CIRCLE);

#endif

dprintk(DEBUG_INIT,”gt9xx probe success!\n”);

       return 0;

exit_device_detect:

i2c_set_clientdata(client,NULL);

kfree(ts);

returnret;

}

 

 

/*******************************************************

Function:

Goodixtouchscreen driver release function.

 

Input:

client:   i2c device struct.

Output:

Executiveoutcomes. 0—succeed.

*******************************************************/

static int goodix_ts_remove(structi2c_client *client)

{

   struct goodix_ts_data *ts = i2c_get_clientdata(client);

dprintk(DEBUG_INIT,”%sstart!\n”, __func__);

#ifdef CONFIG_HAS_EARLYSUSPEND

       unregister_early_suspend(&ts->early_suspend);

#endif

 

#if GTP_CREATE_WR_NODE

       uninit_wr_node();

#endif

 

#if GTP_ESD_PROTECT

       flush_workqueue(gtp_esd_check_workqueue);

   if(gtp_esd_check_workqueue)

       destroy_workqueue(gtp_esd_check_workqueue);

#endif

   input_free_int(&(config_info.input_type), ts);

flush_workqueue(goodix_wq);

//cancel_work_sync(&goodix_init_work);

      cancel_work_sync(&goodix_resume_work);

if(goodix_wq)

       destroy_workqueue(goodix_wq);

      //destroy_workqueue(goodix_init_wq);

      if(goodix_resume_wq)

            destroy_workqueue(goodix_resume_wq);

      i2c_set_clientdata(ts->client, NULL);

input_unregister_device(ts->input_dev);

kfree(ts);

   return 0;

}

 

static void goodix_resume_events (structwork_struct *work)

{

intret;

       struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client);

       

       ret= gtp_wakeup_sleep(ts);

       if(ret < 0)

             printk(“resumepower on failed\n”);      

  gtp_irq_enable(ts);

}

 

/*******************************************************

Function:

Earlysuspend function.

 

Input:

h:early_suspendstruct.

Output:

None.

*******************************************************/

#ifdef CONFIG_HAS_EARLYSUSPEND

static void goodix_ts_early_suspend(structearly_suspend *h)

{

       struct goodix_ts_data *ts;

       s8 ret = -1;  

       ts = container_of(h, struct goodix_ts_data, early_suspend);

 

#if GTP_ESD_PROTECT

       ts->gtp_is_suspend = 1;

       cancel_delayed_work_sync(&gtp_esd_check_work);

#endif

 

       gtp_irq_disable(ts);

       

      

       cancel_work_sync(&goodix_resume_work);

         flush_workqueue(goodix_resume_wq);

       ret = cancel_work_sync(&ts->work);

       flush_workqueue(goodix_wq);

     

          ret = gtp_enter_sleep(ts);

       if (ret < 0) {

                printk(“GTP early suspendfailed.”);

       }

}

 

/*******************************************************

Function:

Lateresume function.

 

Input:

h:early_suspendstruct.

Output:

None.

*******************************************************/

static void goodix_ts_late_resume(structearly_suspend *h)

{

       struct goodix_ts_data *ts;

       ts = container_of(h, struct goodix_ts_data, early_suspend);

       queue_work(goodix_resume_wq, &goodix_resume_work);//gandy

 

#if GTP_ESD_PROTECT

       ts->gtp_is_suspend = 0;

       queue_delayed_work(gtp_esd_check_workqueue, &gtp_esd_check_work,GTP_ESD_CHECK_CIRCLE);

#endif

}

#else

#ifdef CONFIG_PM

static void goodix_ts_suspend(structi2c_client *client, pm_message_t mesg)

{

       struct goodix_ts_data *ts;

       s8 ret = -1;  

       ts = i2c_get_clientdata(client);

       printk(“%s goodix_ts_suspend\n”, goodix_ts_name);

#if GTP_ESD_PROTECT

       ts->gtp_is_suspend = 1;

       cancel_delayed_work_sync(&gtp_esd_check_work);

#endif

 

       ret = input_set_int_enable(&(config_info.input_type), 0);

    if (ret < 0)

       dprintk(DEBUG_SUSPEND,”%sirq disable failed\n”, goodix_ts_name);

       cancel_work_sync(&goodix_resume_work);

    flush_workqueue(goodix_resume_wq);

       ret = cancel_work_sync(&ts->work);

       flush_workqueue(goodix_wq);

   

   ret = gtp_enter_sleep(ts);

       if (ret < 0) {

                printk(“GTP suspendfailed.”);

       }

}

 

static void goodix_ts_resume(structi2c_client *client)

{

       struct goodix_ts_data *ts;

       ts = i2c_get_clientdata(client);

    printk(“%s goodix_ts_resume\n”,goodix_ts_name);

       queue_work(goodix_resume_wq, &goodix_resume_work);//gandy

 

#if GTP_ESD_PROTECT

       ts->gtp_is_suspend = 0;

       queue_delayed_work(gtp_esd_check_workqueue, &gtp_esd_check_work,GTP_ESD_CHECK_CIRCLE);

#endif

}

#endif

#endif

 

#if GTP_ESD_PROTECT

/*******************************************************

Function:

   Initialize external watchdog for esd protect

Input:

   client:  i2c device.

Output:

   result of i2c write operation.

       1: succeed, otherwise: failed

*********************************************************/

s32 gtp_init_ext_watchdog(structi2c_client *client)

{

       u8 opr_buffer[4] = {0x80, 0x40, 0xAA, 0xAA};

       dprintk(DEBUG_INIT, “Init external watchdog…”);

       return gtp_i2c_write(client, opr_buffer, 4);

}

/*******************************************************

Function:

   Esd protect function.

   Added external watchdog by meta, 2013/03/07

Input:

   work: delayed work

Output:

   None.

*******************************************************/

static void gtp_esd_check_func(structwork_struct *work)

{

       s32 i;

       s32 ret = -1;

       struct goodix_ts_data *ts = NULL;

       u8 test[4] = {0x80, 0x40};

       

       dprintk(DEBUG_INIT, “enter %s work!\n”, __func__);

 

        ts = i2c_get_clientdata(i2c_connect_client);

 

       if (ts->gtp_is_suspend || ts->enter_update) {

                return;

       }

   

       for (i = 0; i < 3; i++) {

                ret =gtp_i2c_read(ts->client, test, 4);

       

                dprintk(DEBUG_INIT,”0x8040 = 0x%02X, 0x8041 = 0x%02X”, test[2], test[3]);

                if ((ret < 0)) {

                        // IC worksabnormally..

                        continue;

                }else {

                        if ((test[2] == 0xAA)|| (test[3] != 0xAA)) {

                                // IC works abnormally..

                                i = 3;

                                break; 

                        }else {

                                // IC worksnormally, Write 0x8040 0xAA

                                test[2] = 0xAA;

                               gtp_i2c_write(ts->client, test, 3);

                                break;

                        }

                }

       }

       

       if (i >= 3) {

               GTP_DEBUG(“IC WorkingABNORMALLY, Resetting Guitar…”);

              //  gtp_reset_guitar(ts->client, 50);

       }

 

       if(!ts->gtp_is_suspend) {

               queue_delayed_work(gtp_esd_check_workqueue, &gtp_esd_check_work,GTP_ESD_CHECK_CIRCLE);

       }

 

       return;

}

#endif

 

static const struct i2c_device_idgoodix_ts_id[] = {

       { CTP_NAME, 0 },

       { }

};

 

static struct i2c_driver goodix_ts_driver= {

       .class          = I2C_CLASS_HWMON,

       .probe          = goodix_ts_probe,

       .remove         = goodix_ts_remove,

#ifndef CONFIG_HAS_EARLYSUSPEND

#ifdef CONFIG_PM

       .suspend        =goodix_ts_suspend,

       .resume         =goodix_ts_resume,

#endif

#endif

       .id_table       = goodix_ts_id,

       .driver = {

                .name   = CTP_NAME,

                .owner  = THIS_MODULE,

       },

       .address_list  = normal_i2c,

};

 

static int ctp_get_system_config(void)

{  

       ctp_print_info(config_info,DEBUG_INIT);

       twi_id = config_info.twi_id;

        screen_max_x = config_info.screen_max_x;

       screen_max_y = config_info.screen_max_y;

       revert_x_flag = config_info.revert_x_flag;

       revert_y_flag = config_info.revert_y_flag;

       exchange_x_y_flag = config_info.exchange_x_y_flag;

       if((screen_max_x == 0) || (screen_max_y == 0)){

                printk(“%s:read configerror!\n”,__func__);

                return 0;

       }

       return 1;

}

 

/******************************************************* 

Function:

DriverInstall function.

Input:

 None.

Output:

ExecutiveOutcomes. 0—succeed.

********************************************************/

static int __devinit goodix_ts_init(void)

{

       s32 ret = -1;

       dprintk(DEBUG_INIT,”****************************************************************\n”);

       struct regulator *ldo = regulator_get(NULL, “axp22_ldoio1”);

       if (input_fetch_sysconfig_para(&(config_info.input_type))) {

             printk(“%s:ctp_fetch_sysconfig_para err.\n”, __func__);

             return0;

    } else {

             printk(“%s:gt9xx ctp_fetch_sysconfig_para ok.\n”, __func__);

             ret= input_init_platform_resource(&(config_info.input_type));

             if(0 != ret) {

                  printk(“%s:ctp_ops.init_platform_resourceerr. \n”, __func__);   

             }

       }

       

       if(config_info.ctp_used == 0){

        printk(“*** ctp_used set to 0!\n”);

        printk(“*** if use ctp,please putthe sys_config.fex ctp_used set to 1. \n”);

        return 0;

       }

//关于电压部分是关键

       if(IS_ERR(ldo)) {

       printk(“glsX680get regulator error!! \n”);

       return-1;

}else {

       regulator_set_voltage(ldo,3300000, 3300000);

       if(!regulator_is_enabled(ldo)){

             regulator_enable(ldo);   

       }

       regulator_put(ldo);

}

       if(!ctp_get_system_config()){

                printk(“%s:read configfail!\n”,__func__);

                return ret;

       }

       input_set_power_enable(&(config_info.input_type),1);

       msleep(10);

       sunxi_gpio_to_name(CTP_IRQ_NUMBER,irq_pin_name);

       gtp_io_init(20);

                 

       goodix_ts_driver.detect= ctp_detect;

       ret = i2c_add_driver(&goodix_ts_driver);

       printk(“%s: gt9xx init over!.\n”, __func__);

       dprintk(DEBUG_INIT,”****************************************************************\n”);

       return ret;

}

 

/******************************************************* 

Function:

Driveruninstall function.

Input:

 None.

Output:

ExecutiveOutcomes. 0—succeed.

********************************************************/

static void __exit goodix_ts_exit(void)

{

       printk(“GTP driver exited.\n”);

       i2c_del_driver(&goodix_ts_driver);

       input_free_platform_resource(&(config_info.input_type));      

}

 

late_initcall(goodix_ts_init);

module_exit(goodix_ts_exit);

 

MODULE_DESCRIPTION(“GTP SeriesDriver”);

MODULE_LICENSE(“GPL”);

 

四.      编译打包

回到目录:/home/yygyickl/A33/dragonboard

./build.sh  重新编译

./build.sh pack_debug      打包debug 固件

五.      烧到开发板,进入 校准程序后,触摸正常。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/148830.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号