驱动的目录结构如下:
.../build.sh
.../driver
.../driver/gt818.h
.../driver/gt818_update.h
.../driver/gt818.mod.c //编译时自动生成
.../driver/gt818.c //主要驱动文件
.../driver/Makefile
.../firmware
.../firmware/update_0080.bin //固件
.../init.3rdparty.rc
备注:头文件(gt818.h) 请查看如下链接,这两份都是完整的代码。gt818_update.h 对于使用来说没有什么用处,可以不用。
http://blog.csdn.net/duanlove/article/details/7881043
头文件(gt818_update.h)请查看如下链接。 内容很简单,就是一个存储参数的数组。
http://blog.csdn.net/duanlove/article/details/11127833
--------------------------------------------- gt818.c -----------------------------------------------------------------------------
/* drivers/input/touchscreen/goodix_touch.c
*
* Copyright (C) 2011 Goodix, Inc.
*
* Author: Felix
* Date: 2011.04.28
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/earlysuspend.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <mach/gpio.h>
//#include <plat/gpio-cfg.h>
//#include <plat/gpio-bank-l.h>
//#include <plat/gpio-bank-f.h>
#include <linux/irq.h>
#include <linux/syscalls.h>
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include "gt818.h"//<linux/gt818.h>
#include "gt818_update.h"//<linux/gt818_50.h>
//#include <linux/goodix_queue.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <mach/ldo.h>
#include <mach/regs_ana.h>
#if !defined(GT801_PLUS) && !defined(GT801_NUVOTON)
#error The code does not match this touchscreen.
#endif
static struct workqueue_struct *goodix_wq;
static const char *s3c_ts_name = "pixcir_ts";
//static struct point_queue finger_list;
struct i2c_client * i2c_connect_client = NULL;
//EXPORT_SYMBOL(i2c_connect_client);
static struct proc_dir_entry *goodix_proc_entry;
static short goodix_read_version(struct goodix_ts_data *ts);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void goodix_ts_early_suspend(struct early_suspend *h);
static void goodix_ts_late_resume(struct early_suspend *h);
static int gt818_downloader( struct goodix_ts_data *ts, unsigned char * data,unsigned char * path );
#endif
//used by firmware update CRC
unsigned int oldcrc32 = 0xFFFFFFFF;
unsigned int crc32_table[256];
unsigned int ulPolynomial = 0x04c11db7;
//static int gt818_gpio_tp_irq=0;
//static int shout_down_num=0;
//static int int_cfg_num=0;
//static int ts_int=0;
static int gt818_gpio_tp_irq_int_num=0;
static int gt818_gpio_tp_rst = 59;
static int gt818_gpio_tp_irq = 60;
static int gt818_wrong_num =0;
#define TS_DEBUG_MSG 1
//#define I2C_BOARD_INFO_METHOD 0
//#define TS_DATA_THRESHOLD_CHECK 1
//#define TS_WIDTH_MAX 320
//#define TS_HEIGHT_MAX 480
//static int debug_level=0;
#if TS_DEBUG_MSG
#define TS_DBG(format, ...) \
printk(KERN_INFO "gt818 " format "\n", ## __VA_ARGS__)
#else
#define TS_DBG(format, ...)
#endif
static struct sprd_i2c_setup_data {
unsigned i2c_bus; //the same number as i2c->adap.nr in adapter probe function
unsigned short i2c_address;
int irq;
char type[I2C_NAME_SIZE];
};
static struct sprd_i2c_setup_data gt818_ts_setup={1, GT818_TS_ADDR, 0, GOODIX_I2C_NAME};
static int gt818_sprd_add_i2c_device(struct sprd_i2c_setup_data *i2c_set_data, struct i2c_driver *driver)
{
struct i2c_board_info info;
struct i2c_adapter *adapter;
struct i2c_client *client;
int ret,err;
TS_DBG("%s : i2c_bus=%d; slave_address=0x%x; i2c_name=%s",__func__,i2c_set_data->i2c_bus, \
i2c_set_data->i2c_address, i2c_set_data->type);
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = i2c_set_data->i2c_address;
strlcpy(info.type, i2c_set_data->type, I2C_NAME_SIZE);
if(i2c_set_data->irq > 0)
info.irq = i2c_set_data->irq;
adapter = i2c_get_adapter( i2c_set_data->i2c_bus);
if (!adapter) {
printk("%s: can't get i2c adapter %d\n",
__func__, i2c_set_data->i2c_bus);
err = -ENODEV;
goto err_driver;
}
client = i2c_new_device(adapter, &info);
if (!client) {
printk("%s: can't add i2c device at 0x%x\n",
__func__, (unsigned int)info.addr);
err = -ENODEV;
goto err_driver;
}
i2c_put_adapter(adapter);
ret = i2c_add_driver(driver);
if (ret != 0) {
printk("%s: can't add i2c driver\n", __func__);
err = -ENODEV;
goto err_driver;
}
return 0;
err_driver:
return err;
}
static void gt818_sprd_del_i2c_device(struct i2c_client *client, struct i2c_driver *driver)
{
TS_DBG("%s : slave_address=0x%x; i2c_name=%s",__func__, client->addr, client->name);
i2c_unregister_device(client);
i2c_del_driver(driver);
}
//static struct sprd_i2c_setup_data ft5x0x_ts_setup={0, FT5206_TS_ADDR_R, 0, FT5206_TS_NAME};
/*******************************************************************************
* Function : ft5x0x_ts_config_pins
* Description : config gpio pins and set relative TS pins
* Parameters : void
* Return : int irq_num;
*******************************************************************************/
static int gt818_config_pins(void)
{
int gt818irq;
gpio_direction_output(gt818_gpio_tp_rst, 1);
gpio_direction_input(gt818_gpio_tp_irq);
gpio_set_value(gt818_gpio_tp_rst, 1);
gt818irq=sprd_alloc_gpio_irq(gt818_gpio_tp_irq);
msleep(10); //wait for stable
return gt818irq;
}
/*******************************************************
鍔熻兘锛?
璇诲彇浠庢満鏁版嵁
姣忎釜璇绘搷浣滅敤涓ゆ潯i2c_msg缁勬垚锛岀1鏉℃秷鎭敤浜庡彂閫佷粠鏈哄湴鍧€锛? 绗?鏉$敤浜庡彂閫佽鍙栧湴鍧€鍜屽彇鍥炴暟鎹紱姣忔潯娑堟伅鍓嶅彂閫佽捣濮嬩俊鍙?鍙傛暟锛? client: i2c璁惧锛屽寘鍚澶囧湴鍧€
buf[0]锛?棣栧瓧鑺備负璇诲彇鍦板潃
buf[1]~buf[len]锛氭暟鎹紦鍐插尯
len锛?璇诲彇鏁版嵁闀垮害
return锛? 鎵ц娑堟伅鏁?*********************************************************/
/*Function as i2c_master_send */
static int i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len)
{
struct i2c_msg msgs[2];
int ret=-1;
//鍙戦€佸啓鍦板潃
msgs[0].flags=!I2C_M_RD;//鍐欐秷鎭? msgs[0].addr=client->addr;
msgs[0].len=2;
msgs[0].buf=&buf[0];
//鎺ユ敹鏁版嵁
msgs[1].flags=I2C_M_RD;//璇绘秷鎭? msgs[1].addr=client->addr;
msgs[1].len=len-2;
msgs[1].buf=&buf[2];
ret=i2c_transfer(client->adapter,msgs, 2);
return ret;
}
/*******************************************************
鍔熻兘锛? 鍚戜粠鏈哄啓鏁版嵁
鍙傛暟锛? client: i2c璁惧锛屽寘鍚澶囧湴鍧€
buf[0]锛?棣栧瓧鑺備负鍐欏湴鍧€
buf[1]~buf[len]锛氭暟鎹紦鍐插尯
len锛?鏁版嵁闀垮害
return锛? 鎵ц娑堟伅鏁?*******************************************************/
/*Function as i2c_master_send */
static int i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len)
{
struct i2c_msg msg;
int ret=-1;
//鍙戦€佽澶囧湴鍧€
msg.flags=!I2C_M_RD;//鍐欐秷鎭? msg.addr=client->addr;
msg.len=len;
msg.buf=data;
ret=i2c_transfer(client->adapter,&msg, 1);
return ret;
}
/*******************************************************
鍔熻兘锛? 鍙戦€佸墠缂€鍛戒护
ts: client绉佹湁鏁版嵁缁撴瀯浣?return锛?
鎵ц缁撴灉鐮侊紝0琛ㄧず姝e父鎵ц
*******************************************************/
static int i2c_pre_cmd(struct goodix_ts_data *ts)
{
int ret;
uint8_t pre_cmd_data[2]={0};
pre_cmd_data[0]=0x0f;
pre_cmd_data[1]=0xff;
ret=i2c_write_bytes(ts->client,pre_cmd_data,2);
//msleep(2);
return ret;
}
/*******************************************************
鍔熻兘锛? 鍙戦€佸悗缂€鍛戒护
ts: client绉佹湁鏁版嵁缁撴瀯浣?return锛?
鎵ц缁撴灉鐮侊紝0琛ㄧず姝e父鎵ц
*******************************************************/
static int i2c_end_cmd(struct goodix_ts_data *ts)
{
int ret;
uint8_t end_cmd_data[2]={0};
end_cmd_data[0]=0x80;
end_cmd_data[1]=0x00;
ret=i2c_write_bytes(ts->client,end_cmd_data,2);
//msleep(2);
return ret;
}
/*
*/
static short get_chip_version( unsigned int sw_ver )
{
if ( (sw_ver&0xff) < TPD_CHIP_VERSION_C_FIRMWARE_BASE )
return TPD_GT818_VERSION_B;
else if ( (sw_ver&0xff) < TPD_CHIP_VERSION_D_FIRMWARE_BASE )
return TPD_GT818_VERSION_C;
else
return TPD_GT818_VERSION_D;
}
/*******************************************************
鍔熻兘锛? Guitar鍒濆鍖栧嚱鏁帮紝鐢ㄤ簬鍙戦€侀厤缃俊鎭紝鑾峰彇鐗堟湰淇℃伅
鍙傛暟锛? ts: client绉佹湁鏁版嵁缁撴瀯浣?return锛? 鎵ц缁撴灉鐮侊紝0琛ㄧず姝e父鎵ц
*******************************************************/
static int goodix_init_panel(struct goodix_ts_data *ts)
{
short ret=-1;
// int ic_size = 0;
#if 1
uint8_t config_info_c[] = { //Touch key devlop board
0x06,0xA2,
0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
0x10,0x12,0xE0,0x00,0xD0,0x00,0xC0,0x00,
0xB0,0x00,0xA0,0x00,0x90,0x00,0x80,0x00,
0x70,0x00,0x00,0x00,0x10,0x00,0x20,0x00,
0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,
0x00,0x00,0x01,0x13,0x80,0x88,0x90,0x14,
0x15,0x40,0x0F,0x0F,0x0A,0x50,0x3C,0x0C,
0x00,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_HEIGHT&0xff),(TOUCH_MAX_HEIGHT>>8),0x00,
0x00,0x46,0x5A,0x00,0x00,0x00,0x00,0x03,
0x19,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
0x20,0x10,0x00,0x04,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,
0x00,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,
0x00,0x01
};
uint8_t config_info_d[] = { //Touch key devlop board
#if 0
0x06,0xA2,
0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
0x10,0x12,0xE0,0x00,0xD0,0x00,0xC0,0x00,
0xB0,0x00,0xA0,0x00,0x90,0x00,0x80,0x00,
0x70,0x00,0x00,0x00,0x10,0x00,0x20,0x00,
0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,
0x00,0x00,0x0B,0x13,0x90,0x90,0x90,0x27,
0x27,0x27,0x0F,0x0F,0x0A,0x50,0x3C,0x4B,
0x00,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_HEIGHT&0xff),(TOUCH_MAX_HEIGHT>>8),0x00,
0x00,0x46,0x5A,0x00,0x00,0x00,0x00,0x03,
0x19,0x05,0x05,0x00,0x00,0x00,0x00,0x00,
0x20,0x10,0x00,0x04,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,
0x00,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,
0x00,0x01
/*0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
0x10,0x12,0xE0,0x00,0xD0,0x00,0xC0,0x00,
0xB0,0x00,0xA0,0x00,0x90,0x00,0x80,0x00,
0x70,0x00,0x00,0x00,0x10,0x00,0x20,0x00,
0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,
0x00,0x00,0x01,0x13,0x80,0x88,0x90,0x14,
0x15,0x40,0x0F,0x0F,0x0A,0x50,0x3C,0x0C,
0x00,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_HEIGHT&0xff),(TOUCH_MAX_HEIGHT>>8),0x00,
0x00,0x46,0x5A,0x00,0x00,0x00,0x00,0x03,
0x19,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
0x20,0x10,0x00,0x04,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,
0x00,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,
0x00,0x01
*/
#endif
#if 1 //defined(CONFIG_S9_IPhone) //s9 hua fei jeed
/*0x06,0xA2,
0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,
0x02,0x00,0x02,0x22,0x12,0x22,0x22,0x22,
0x32,0x22,0x42,0x22,0x52,0x22,0x62,0x22,
0xE2,0x22,0xD2,0x22,0xC2,0x22,0xB2,0x22,
0xA2,0x22,0x92,0x22,0x82,0x22,0x72,0x22,
0xF2,0x22,0x37,0x03,0xA8,0xA8,0xA8,0x1A,
0x1A,0x1A,0x0F,0x0E,0x0A,0x48,0x38,0x09,
//0x03,0x00,0x05,0x40,0x01,0xE0,0x01,0x00,
0x03,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_HEIGHT&0xff),(TOUCH_MAX_HEIGHT>>8),0x00,
0x00,0x5C,0x57,0x60,0x5A,0x00,0x00,0x23,
0x14,0x05,0x05,0x00,0x00,0x00,0x00,0x00,
0x14,0x10,0xCE,0x03,0x00,0x40,0x37,0x10,
0x31,0x00,0x40,0x50,0x60,0x70,0x0D,0x40,
0x30,0x25,0x20,0x00,0x00,0x00,0x00,0x00,
0x00,0x01*/
/*0x06,0xA2,
0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
0x10,0x12,0x60,0x00,0x50,0x00,0x40,0x00,
0x30,0x00,0x20,0x00,0x10,0x00,0x00,0x00,
0xF0,0x00,0xE0,0x00,0xD0,0x00,0xC0,0x00,
0xB0,0x00,0xA0,0x00,0x90,0x00,0x80,0x00,
0x70,0x00,0x1B,0x03,0x70,0x70,0x70,0x26,
0x26,0x26,0x10,0x0F,0x0A,0x50,0x30,0x45,
//0x03,0x16,0x05,0xE0,0x01,0x20,0x03,0x00,
0x03,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_HEIGHT&0xff),(TOUCH_MAX_HEIGHT>>8),0x00,
0x00,0x55,0x4F,0x58,0x52,0x00,0x00,0x03,
0x14,0x05,0x06,0x00,0x00,0x00,0x00,0x00,
0x14,0x10,0x74,0x03,0x00,0x40,0x37,0x50,
0x26,0x00,0x10,0x20,0x00,0x00,0x0D,0x40,
0x30,0x3C,0x14,0x00,0x00,0x00,0x00,0x00,
0x00,0x01*/
/*
0x06,0xA2,
0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,
0x02,0x00,0x70,0x00,0x60,0x00,0x50,0x00,
0x40,0x00,0x30,0x00,0x20,0x00,0x10,0x00,
0x00,0x00,0xF0,0x00,0xE0,0x00,0xD0,0x00,
0xC0,0x00,0xB0,0x00,0xA0,0x00,0x90,0x00,
0x80,0x00,0x1B,0x03,0x70,0x70,0x70,0x27,
0x27,0x27,0x10,0x0F,0x0A,0x50,0x30,0x0D,
//0x03,0x16,0x05,0xE0,0x01,0x20,0x03,0x00,
0x03,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_HEIGHT&0xff)