全志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 固件

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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu 硬盘安装图解

    ubuntu 硬盘安装图解br MaverickMeer 10 启用了全新的安装程序 使得整个安装过程不但焕然一新 对那些不太熟悉 Linux 环境的用户来说也更容易使用了 br 在安装过程中 用户可以下载软件更新 安装无线网卡官方驱动 并完成对 MP3 音频文件 AdobeFlashPl 播放器 Java DVD 播放的支持 br 下面说说在 WindowsXP 系统下硬盘安装 Ubuntu10 10 双系统的全程图解 安装很快 30 分钟不到就能安装好 br 1 首先下

    2025年11月8日
    2
  • 【NOIP2011提高组】选择客栈

    【NOIP2011提高组】选择客栈题目背景NOIP2011提高组 DAY1 试题。题目描述丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们…

    2025年12月7日
    7
  • RGB-D(深度图像) & 图像深度「建议收藏」

    RGB-D(深度图像) & 图像深度「建议收藏」RGB-D(深度图像)  深度图像=普通的RGB三通道彩色图像+DepthMap  在3D计算机图形中,DepthMap(深度图)是包含与视点的场景对象的表面的距离有关的信息的图像或图像通道。其中,DepthMap类似于灰度图像,只是它的每个像素值是传感器距离物体的实际距离。通常RGB图像和Depth图像是配准的,因而像素点之间具有一对一的对应关系

    2022年5月28日
    32
  • 图片切割工具—产生多个div切割图片 采用for和一的二维阵列设置背景位置

    图片切割工具—产生多个div切割图片 采用for和一的二维阵列设置背景位置

    2022年1月12日
    40
  • 近距离接触品牌与终端

    近距离接触品牌与终端

    2021年8月12日
    51
  • MATLAB矩阵生成

    MATLAB矩阵生成MATLAB矩阵生成

    2022年6月25日
    21

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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