mako: touch driver merge

- lge touch common driver
- synaptics touch driver integration with lge common driver

Change-Id: I72e53f8d16610155ab1a31a366e33910a41643be
This commit is contained in:
Jongrak Kwon 2012-06-15 22:06:54 -07:00 committed by Iliyan Malchev
parent 911aed249d
commit 000adcf065
11 changed files with 11392 additions and 141 deletions

View file

@ -271,6 +271,7 @@ CONFIG_KEYBOARD_PMIC8XXX=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_LGE_SYNAPTICS=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
CONFIG_INPUT_KEYCHORD=y

View file

@ -33,20 +33,9 @@
#include <linux/regulator/consumer.h>
#include <linux/i2c.h>
#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
#include <linux/input/touch_synaptics_rmi4_i2c.h>
#include <linux/earlysuspend.h>
#include <linux/input/lge_touch_core.h>
#endif
#include <mach/board_lge.h>
#ifdef CONFIG_TOUCHSCREEN_MMS136
#include <linux/i2c/melfas_ts.h>
#endif
#if defined(CONFIG_RMI4_I2C)
#include <linux/rmi.h>
#endif
#include "board-mako.h"
/* TOUCH GPIOS */
@ -60,7 +49,7 @@
/* touch screen device */
#define APQ8064_GSBI3_QUP_I2C_BUS_ID 3
#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)
#if defined(CONFIG_TOUCHSCREEN_LGE_SYNAPTICS)
int synaptics_t1320_power_on(int on)
{
int rc = -EINVAL;
@ -170,141 +159,14 @@ static struct i2c_board_info synaptics_ts_info[] = {
};
#endif
#if defined(CONFIG_RMI4_I2C)
struct syna_gpio_data {
u16 gpio_number;
char *gpio_name;
};
static int synaptics_touchpad_gpio_setup(void *gpio_data, bool configure)
{
int rc = -EINVAL;
static struct regulator *vreg_l15;
static struct regulator *vreg_l22;
struct syna_gpio_data *data = gpio_data;
pr_err("%s: [Touch D] S1 \n", __func__);
/* Touch IC Power On */
vreg_l15 = regulator_get(NULL, "8921_l15"); //3.3V_TOUCH_VDD, VREG_L15: 2.75 ~ 3.3
if (IS_ERR(vreg_l15)) {
pr_err("%s: regulator get of 8921_l15 failed (%ld)\n", __func__,
PTR_ERR(vreg_l15));
rc = PTR_ERR(vreg_l15);
return rc;
}
pr_err("%s: [Touch D] S2 \n", __func__);
vreg_l22 = regulator_get(NULL, "8921_l22"); //1.8V_TOUCH_IO, VREG_L22: 1.7 ~ 2.85
if (IS_ERR(vreg_l22)) {
pr_err("%s: regulator get of 8921_l22 failed (%ld)\n", __func__,
PTR_ERR(vreg_l22));
rc = PTR_ERR(vreg_l22);
return rc;
}
pr_err("%s: [Touch D] S3 \n", __func__);
rc = regulator_set_voltage(vreg_l15, 3300000, 3300000);
rc = regulator_set_voltage(vreg_l22, 1800000, 1800000);
regulator_enable(vreg_l15);
regulator_enable(vreg_l22);
if (configure) {
rc = gpio_request(data->gpio_number, "rmi4_attn");
if (rc) {
pr_err("%s: Failed to get attn gpio %d. Code: %d.",
__func__, data->gpio_number, rc);
return rc;
}
gpio_tlmm_config(GPIO_CFG(data->gpio_number, 0, GPIO_CFG_INPUT,
GPIO_CFG_PULL_UP, GPIO_CFG_6MA),
GPIO_CFG_ENABLE);
rc = gpio_direction_input(data->gpio_number);
if (rc) {
pr_err("%s: Failed to setup attn gpio %d. Code: %d.",
__func__, data->gpio_number, rc);
gpio_free(data->gpio_number);
}
} else {
pr_warn("%s: No way to deconfigure gpio %d.",
__func__, data->gpio_number);
}
if (rc < 0) {
printk(KERN_INFO "[Touch D] %s: cannot request GPIO\n",
__func__);
return rc;
}
printk("[Touch D]synaptics_touchpad_gpio_setup -- \n");
return rc;
}
#define AXIS_ALIGNMENT { \
.swap_axes = false, \
.flip_x = false, \
.flip_y = false, \
.clip_X_low = 0, \
.clip_Y_low = 0, \
.offset_X = 0, \
.offset_Y = 0, \
}
#define TM2144_ADDR 0x20
#define TM2144_ATTN 6
static unsigned char tm2144_button_codes[] = {
KEY_BACK, KEY_HOMEPAGE, KEY_MENU
};
static struct rmi_f1a_button_map tm2144_button_map = {
.nbuttons = ARRAY_SIZE(tm2144_button_codes),
.map = tm2144_button_codes,
};
static struct syna_gpio_data tm2144_gpiodata = {
.gpio_number = TM2144_ATTN,
.gpio_name = "ts_int.gpio_6",
};
static struct rmi_device_platform_data tm2144_platformdata = {
.driver_name = "rmi_generic",
.sensor_name = "TM2144",
.attn_gpio = TM2144_ATTN,
.attn_polarity = RMI_ATTN_ACTIVE_LOW,
.gpio_data = &tm2144_gpiodata,
.gpio_config = synaptics_touchpad_gpio_setup,
.axis_align = AXIS_ALIGNMENT,
.f1a_button_map = &tm2144_button_map,
.reset_delay_ms = 100,
};
static struct i2c_board_info synaptics_ds4_rmi_info[] = {
[0] = {
I2C_BOARD_INFO("rmi_i2c", TM2144_ADDR),
.platform_data = &tm2144_platformdata,
},
};
#endif
/* common function */
void __init apq8064_init_input(void)
{
#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)
#if defined(CONFIG_TOUCHSCREEN_LGE_SYNAPTICS)
printk(KERN_INFO "[Touch D] %s: NOT DCM KDDI, reg synaptics driver \n",
__func__);
i2c_register_board_info(APQ8064_GSBI3_QUP_I2C_BUS_ID,
&synaptics_ts_info[0], 1);
#endif
/* Wireless Debugging Porting */
#if defined(CONFIG_RMI4_I2C)
i2c_register_board_info(APQ8064_GSBI3_QUP_I2C_BUS_ID,
&synaptics_ds4_rmi_info[0], 1);
#endif
}

View file

@ -946,4 +946,24 @@ config TOUCHSCREEN_FT5X06
To compile this driver as a module, choose M here: the
module will be called ft5x06_ts.
config TOUCHSCREEN_LGE_COMMON
bool "LGE Touch common driver"
depends on I2C
help
Enable LGE Touch Common Driver which runs with lower driver.
config TOUCHSCREEN_LGE_SYNAPTICS
bool "Synaptics RMI4 driver for LG Touch Common Driver"
depends on I2C
select TOUCHSCREEN_LGE_COMMON
help
Enables Synaptics RMI4 protocol I2C Touch Screens
config TOUCH_REG_MAP_TM2000
tristate "synaptics TM2000 touchscreen"
depends on TOUCHSCREEN_LGE_SYNAPTICS
default y
help
Synaptics Register map TM2000.
endif

View file

@ -77,3 +77,6 @@ obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
obj-$(CONFIG_TOUCHSCREEN_MSM_LEGACY) += msm_touch.o
obj-$(CONFIG_TOUCHSCREEN_CY8C_TS) += cy8c_ts.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC) += cyttsp-i2c-qc.o
obj-$(CONFIG_TOUCHSCREEN_LGE_COMMON) += lge_touch_core.o
obj-$(CONFIG_TOUCHSCREEN_LGE_SYNAPTICS) += touch_synaptics.o
obj-$(CONFIG_TOUCHSCREEN_LGE_SYNAPTICS) += touch_synaptics_ds4_fw_upgrade.o

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,811 @@
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 2011 Synaptics, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <mach/gpio.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
//#include "SynaImage.h"
//#include "TM2000-E010-PR1084335-DS4_120211.h"
/////////////////////////////////////
//#ifdef CONFIG_TS_INFO_CLASS
//#include "ts_class.h"
//#endif
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/earlysuspend.h>
#include <linux/input/lge_touch_core.h>
#include <linux/input/touch_synaptics.h>
/* Variables for F34 functionality */
unsigned short SynaF34DataBase;
unsigned short SynaF34QueryBase;
unsigned short SynaF01DataBase;
unsigned short SynaF01CommandBase;
unsigned short SynaF01ControlBase;
unsigned short SynaF01QueryBase;
unsigned short SynaF34Reflash_BlockNum;
unsigned short SynaF34Reflash_BlockData;
unsigned short SynaF34ReflashQuery_BootID;
unsigned short SynaF34ReflashQuery_FlashPropertyQuery;
unsigned short SynaF34ReflashQuery_FirmwareBlockSize;
unsigned short SynaF34ReflashQuery_FirmwareBlockCount;
unsigned short SynaF34ReflashQuery_ConfigBlockSize;
unsigned short SynaF34ReflashQuery_ConfigBlockCount;
unsigned short SynaFirmwareBlockSize;
unsigned short SynaFirmwareBlockCount;
unsigned long SynaImageSize;
unsigned short SynaConfigBlockSize;
unsigned short SynaConfigBlockCount;
unsigned long SynaConfigImageSize;
unsigned short SynaBootloadID;
unsigned short SynaF34_FlashControl;
unsigned char *SynafirmwareImgData;
unsigned char *SynaconfigImgData;
unsigned char *SynalockImgData;
unsigned int SynafirmwareImgVersion;
//unsigned char ConfigBlock[];
//unsigned char FirmwareImage[16000]; // make smaller and dynamic
//unsigned char ConfigImage[16000]; // make smaller and dynamic
unsigned char *my_image_bin;
unsigned long my_image_size;
u8 fw_image_config_id[5];
void CompleteReflash(struct synaptics_ts_data *ts);
void ConfigBlockReflash(struct synaptics_ts_data *ts);
void CompleteReflash_Lockdown(struct synaptics_ts_data *ts);
void SynaInitialize(struct synaptics_ts_data *ts);
void SynaReadConfigInfo(struct synaptics_ts_data *ts);
void SynaReadFirmwareInfo(struct synaptics_ts_data *ts);
void SynaEnableFlashing(struct synaptics_ts_data *ts);
void SynaProgramFirmware(struct synaptics_ts_data *ts);
void SynaProgramConfiguration(struct synaptics_ts_data *ts);
void SynaFinalizeReflash(struct synaptics_ts_data *ts);
void SynaWaitForATTN(int time);
//void waitATTN(void);
//called from .c//////////////// start
//FIXME
/*int FirmwareUpgrade(struct synaptics_ts_data *ts){
CompleteReflash(ts);
return 0;
}*/
int FirmwareUpgrade(struct synaptics_ts_data *ts, const char* fw_path){
int ret = 0;
int fd = -1;
mm_segment_t old_fs = 0;
struct stat fw_bin_stat;
unsigned long read_bytes;
if (unlikely(fw_path[0] != 0)) {
old_fs = get_fs();
set_fs(get_ds());
if ((fd = sys_open((const char __user *) fw_path, O_RDONLY, 0)) < 0) {
TOUCH_ERR_MSG("Can not read FW binary from %s\n", fw_path);
ret = -EEXIST;
goto read_fail;
}
if ((ret = sys_newstat((char __user *) fw_path,
(struct stat *)&fw_bin_stat)) < 0) {
TOUCH_ERR_MSG("Can not read FW binary stat from %s\n", fw_path);
goto fw_mem_alloc_fail;
}
my_image_size = fw_bin_stat.st_size;
my_image_bin =
kzalloc(sizeof(char) * (my_image_size+1), GFP_KERNEL);
if (my_image_bin == NULL) {
TOUCH_ERR_MSG("Can not allocate memory\n");
ret = -ENOMEM;
goto fw_mem_alloc_fail;
}
//sys_lseek(fd, (off_t) pos, 0);
read_bytes = sys_read(fd,
(char __user *)my_image_bin, my_image_size);
/* for checksum */
*(my_image_bin+my_image_size) = 0xFF;
TOUCH_INFO_MSG("Touch FW image read %ld bytes from %s\n",
read_bytes, fw_path);
} else {
my_image_size = ts->fw_info->fw_size-1;
my_image_bin = (unsigned char *)(&ts->fw_info->fw_start[0]);
}
strncpy(fw_image_config_id, &my_image_bin[0xb100], 4);
TOUCH_INFO_MSG("fw_image_confid_id = %s\n", fw_image_config_id);
switch( ts->ic_panel_type ) {
case IC7020_G2_H_PTN:
if (fw_image_config_id[0] == 'E' && (int)simple_strtoul(&fw_image_config_id[1], NULL, 10) >= 27) {
TOUCH_INFO_MSG("Firmware Upgrade / IC is 7020, "
"H pattern, panel is G2.\n");
} else {
TOUCH_ERR_MSG("Firmware Version mismatch / "
"IC is 7020, H pattern, panel is G2.\n");
ret = -1;
goto fw_version_mismatch;
}
break;
case IC7020_GFF_H_PTN:
if (fw_image_config_id[0] == 'E' && (int)simple_strtoul(&fw_image_config_id[1], NULL, 10) >= 1) {
TOUCH_INFO_MSG("Firmware Upgrade / IC is 7020, "
"H pattern, panel is GFF.\n");
} else {
TOUCH_ERR_MSG("Firmware Version mismatch / "
"IC is 7020, H pattern, panel is GFF.\n");
ret = -1;
goto fw_version_mismatch;
}
break;
default:
TOUCH_ERR_MSG("DO NOT UPDATE EXCEPT 7020 G2 H pattern\n");
ret = -1;
goto fw_version_mismatch;
break;
}
//CompleteReflash(ts);
CompleteReflash_Lockdown(ts);
fw_version_mismatch:
if (unlikely(fw_path[0] != 0))
kfree(my_image_bin);
fw_mem_alloc_fail:
sys_close(fd);
read_fail:
set_fs(old_fs);
return ret;
//return 0;
}
///////////////////////////////// end
static int writeRMI(struct i2c_client *client, u8 uRmiAddress, u8 *data, unsigned int length)
{
//return synaptics_ts_write(client, uRmiAddress, data, length);
return touch_i2c_write(client, uRmiAddress, length, data);
}
static int readRMI(struct i2c_client *client, u8 uRmiAddress, u8 *data, unsigned int length)
{
//return synaptics_ts_read(client, uRmiAddress, length, data);
return touch_i2c_read(client, uRmiAddress, length, data);
}
/*void waitATTN(){//FIXME
//mdelay(300);
mdelay(10);
}*/
///////////////////////////////////////////////////
/* End: Variables for F34 functionality */
/* SynaSetup scans the Page Description Table (PDT) and sets up the necessary variables
* for the reflash process. This function is a "slim" version of the PDT scan function in
* in PDT.c, since only F34 and F01 are needed for reflash.
*/
void SynaSetup(struct synaptics_ts_data *ts)
{
unsigned char address;
unsigned char buffer[6];
TOUCH_INFO_MSG("%s", __FUNCTION__);
for (address = 0xe9; address > 0xd0; address = address - 6) {
readRMI(ts->client, address, &buffer[0], 6);
if (!buffer[5])
break;
switch (buffer[5]) {
case 0x34:
SynaF34DataBase = buffer[3];
SynaF34QueryBase = buffer[0];
break;
case 0x01:
SynaF01DataBase = buffer[3];
SynaF01CommandBase = buffer[1];
SynaF01ControlBase = buffer[2];
SynaF01QueryBase = buffer[0];
break;
}
}
SynaF34Reflash_BlockNum = SynaF34DataBase;
SynaF34Reflash_BlockData = SynaF34DataBase + 2;
SynaF34ReflashQuery_BootID = SynaF34QueryBase;
SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 2;
SynaF34ReflashQuery_FirmwareBlockSize = SynaF34QueryBase + 3;
SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase +5;
SynaF34ReflashQuery_ConfigBlockSize = SynaF34QueryBase + 3;
SynaF34ReflashQuery_ConfigBlockCount = SynaF34QueryBase + 7;
//SynafirmwareImgData = (unsigned char *)((&SynaFirmware[0])+0x100);
//SynafirmwareImgData = (unsigned char *)((&ts->fw_info->fw_start[0])+0x100);
SynafirmwareImgData = (unsigned char *)((&my_image_bin[0])+0x100);
SynaconfigImgData = (unsigned char *)(SynafirmwareImgData+SynaImageSize);
//SynafirmwareImgVersion = (unsigned int)(SynaFirmware[7]);
//SynafirmwareImgVersion = (unsigned int)(ts->fw_info->fw_start[7]);
SynafirmwareImgVersion = (unsigned int)(my_image_bin[7]);
switch (SynafirmwareImgVersion) {
case 2:
//SynalockImgData = (unsigned char *)((&SynaFirmware[0]) + 0xD0);
//SynalockImgData = (unsigned char *)((&ts->fw_info->fw_start[0]) + 0xD0);
SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xD0);
break;
case 3:
case 4:
//SynalockImgData = (unsigned char *)((&SynaFirmware[0]) + 0xC0);
//SynalockImgData = (unsigned char *)((&ts->fw_info->fw_start[0]) + 0xC0);
SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xC0);
break;
case 5:
//SynalockImgData = (unsigned char *)((&SynaFirmware[0]) + 0xB0);
//SynalockImgData = (unsigned char *)((&ts->fw_info->fw_start[0]) + 0xB0);
SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xB0);
break;
default: break;
}
}
/* SynaInitialize sets up the reflahs process
*/
void SynaInitialize(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
//unsigned char uStatus;
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nInitializing Reflash Process...");
uData[0] = 0x00;
writeRMI(ts->client, 0xff, &uData[0], 1);
SynaSetup(ts);
//Set all interrupt enable
uData[0] = 0x0f;
writeRMI(ts->client, SynaF01ControlBase+1, &uData[0], 1);
//SynafirmwareImgData = 0;
//SynaconfigImgData = 0 ;
//SynafirmwareImgData = &FirmwareImage[0]; // new unsigned char [GetFirmwareSize()];
//SynaconfigImgData = &ConfigImage[0]; // new unsigned char [GetConfigSize()];
readRMI(ts->client, SynaF34ReflashQuery_FirmwareBlockSize, &uData[0], 2);
SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);
}
/* SynaReadFirmwareInfo reads the F34 query registers and retrieves the block size and count
* of the firmware section of the image to be reflashed
*/
void SynaReadFirmwareInfo(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
uData[0] = 0;
uData[1] = 0;
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nRead Firmware Info");
readRMI(ts->client, SynaF34ReflashQuery_FirmwareBlockSize, &uData[0], 2);
SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);
readRMI(ts->client, SynaF34ReflashQuery_FirmwareBlockCount, &uData[0], 2);
SynaFirmwareBlockCount = uData[0] | (uData[1] << 8);
SynaImageSize = SynaFirmwareBlockCount * SynaFirmwareBlockSize;
}
/* SynaReadConfigInfo reads the F34 query registers and retrieves the block size and count
* of the configuration section of the image to be reflashed
*/
void SynaReadConfigInfo(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nRead Config Info");
readRMI(ts->client, SynaF34ReflashQuery_ConfigBlockSize, &uData[0], 2);
SynaConfigBlockSize = uData[0] | (uData[1] << 8);
readRMI(ts->client, SynaF34ReflashQuery_ConfigBlockCount, &uData[0], 2);
SynaConfigBlockCount = uData[0] | (uData[1] << 8);
SynaConfigImageSize = SynaConfigBlockCount * SynaConfigBlockSize;
}
/* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader ID of the firmware
*/
void SynaReadBootloadID(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
TOUCH_INFO_MSG("%s", __FUNCTION__);
readRMI(ts->client, SynaF34ReflashQuery_BootID, &uData[0], 2);
SynaBootloadID = uData[0] + uData[1] * 0x100;
}
/* SynaWriteBootloadID writes the bootloader ID to the F34 data register to unlock the reflash process
*/
void SynaWriteBootloadID(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
TOUCH_INFO_MSG("%s", __FUNCTION__);
uData[0] = SynaBootloadID % 0x100;
uData[1] = SynaBootloadID / 0x100;
writeRMI(ts->client, SynaF34Reflash_BlockData, &uData[0], 2);
}
/* SynaWaitForATTN waits for ATTN to be asserted within a certain time threshold.
*/
void SynaWaitForATTN(int time)
{
//unsigned int error;
//error = waitATTN(1, time);
//waitATTN(time);
mdelay(time);
}
/* SynaWaitATTN waits for ATTN to be asserted within a certain time threshold.
* The function also checks for the F34 "Program Enabled" bit and clear ATTN accordingly.
*/
void SynaWaitATTN(struct synaptics_ts_data *ts)
{
unsigned char uData;
unsigned char uStatus;
// unsigned char temp;
//wait ATTN line until it goes low by 300ms
// temp = SynaWaitForATTN(300);
SynaWaitForATTN(10);
do {
readRMI(ts->client, SynaF34_FlashControl, &uData, 1);
readRMI(ts->client, (SynaF01DataBase + 1), &uStatus, 1);
} while (uData!= 0x80);
}
/* SynaEnableFlashing kicks off the reflash process
*/
void SynaEnableFlashing(struct synaptics_ts_data *ts)
{
unsigned char uData;
unsigned char uStatus;
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nEnable Reflash...");
// Reflash is enabled by first reading the bootloader ID from the firmware and write it back
SynaReadBootloadID(ts);
SynaWriteBootloadID(ts);
// Make sure Reflash is not already enabled
do {
readRMI(ts->client, SynaF34_FlashControl, &uData, 1);
} while (((uData & 0x0f) != 0x00));
// Clear ATTN
readRMI (ts->client, SynaF01DataBase, &uStatus, 1);
if ((uStatus &0x40) == 0) {
// Write the "Enable Flash Programming command to F34 Control register
// Wait for ATTN and then clear the ATTN.
uData = 0x0f;
writeRMI(ts->client, SynaF34_FlashControl, &uData, 1);
SynaWaitForATTN(100);
readRMI(ts->client, (SynaF01DataBase + 1), &uStatus, 1);
// Scan the PDT again to ensure all register offsets are correct
SynaSetup(ts);
/* Read the "Program Enabled" bit of the F34 Control register,
and proceed only if the bit is set. */
do {
readRMI(ts->client, SynaF34_FlashControl, &uData, 1);
/* In practice, if uData!=0x80 happens for multiple counts,
it indicates reflash */
// is failed to be enabled, and program should quit
} while (uData != 0x80);
}
}
/* SynaProgramConfiguration writes the configuration section of the image block by block
*/
void SynaProgramConfiguration(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
//unsigned char *puData = ConfigBlockData;
//unsigned char *puData = (unsigned char *)&SynaFirmware[0xb100];
//unsigned char *puData = (unsigned char *)&ts->fw_info->fw_start[0xb100];
unsigned char *puData = (unsigned char *)&my_image_bin[0xb100];
unsigned short blockNum;
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nProgram Configuration Section...");
for (blockNum = 0; blockNum < SynaConfigBlockCount; blockNum++) {
uData[0] = blockNum & 0xff;
uData[1] = (blockNum & 0xff00) >> 8;
//Block by blcok, write the block number and data to the corresponding F34 data registers
writeRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);
writeRMI(ts->client, SynaF34Reflash_BlockData, puData, SynaConfigBlockSize);
puData += SynaConfigBlockSize;
// Issue the "Write Configuration Block" command
uData[0] = 0x06;
writeRMI(ts->client, SynaF34_FlashControl, &uData[0], 1);
SynaWaitATTN(ts);
TOUCH_INFO_MSG(".");
}
}
/* SynaFinalizeReflash finalizes the reflash process
*/
void SynaFinalizeReflash(struct synaptics_ts_data *ts)
{
unsigned char uData;
unsigned char uStatus;
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nFinalizing Reflash...");
// Issue the "Reset" command to F01 command register to reset the chip
// This command will also test the new firmware image and check if its is valid
uData = 1;
writeRMI(ts->client, SynaF01CommandBase, &uData, 1);
SynaWaitForATTN(100);
readRMI(ts->client, SynaF01DataBase, &uData, 1);
// Sanity check that the reflash process is still enabled
do {
readRMI(ts->client, SynaF34_FlashControl, &uStatus, 1);
} while ((uStatus & 0x0f) != 0x00);
readRMI(ts->client, (SynaF01DataBase + 1), &uStatus, 1);
SynaSetup(ts);
uData = 0;
// Check if the "Program Enabled" bit in F01 data register is cleared
// Reflash is completed, and the image passes testing when the bit is cleared
do {
readRMI(ts->client, SynaF01DataBase, &uData, 1);
} while ((uData & 0x40) != 0);
// Rescan PDT the update any changed register offsets
SynaSetup(ts);
TOUCH_INFO_MSG("\nReflash Completed. Please reboot.");
}
/* SynaFlashFirmwareWrite writes the firmware section of the image block by block
*/
void SynaFlashFirmwareWrite(struct synaptics_ts_data *ts)
{
//unsigned char *puFirmwareData = SynafirmwareImgData;
//unsigned char *puFirmwareData = (unsigned char *)&SynaFirmware[0x100];
//unsigned char *puFirmwareData = (unsigned char *)&ts->fw_info->fw_start[0x100];
unsigned char *puFirmwareData = (unsigned char *)&my_image_bin[0x100];
unsigned char uData[2];
unsigned short blockNum;
TOUCH_INFO_MSG("%s", __FUNCTION__);
for (blockNum = 0; blockNum < SynaFirmwareBlockCount; ++blockNum) {
if (blockNum%100 == 0)
TOUCH_INFO_MSG("blockNum = [%d], (SynaFirmwareBlockCount=%d)\n", blockNum, SynaFirmwareBlockCount);
//Block by blcok, write the block number and data to the corresponding F34 data registers
uData[0] = blockNum & 0xff;
uData[1] = (blockNum & 0xff00) >> 8;
writeRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);
writeRMI(ts->client, SynaF34Reflash_BlockData, puFirmwareData,
SynaFirmwareBlockSize);
puFirmwareData += SynaFirmwareBlockSize;
// Issue the "Write Firmware Block" command
uData[0] = 2;
writeRMI(ts->client, SynaF34_FlashControl, &uData[0], 1);
SynaWaitATTN(ts);
}
}
/* SynaProgramFirmware prepares the firmware writing process
*/
void SynaProgramFirmware(struct synaptics_ts_data *ts)
{
unsigned char uData;
TOUCH_INFO_MSG("%s", __FUNCTION__);
TOUCH_INFO_MSG("\nProgram Firmware Section...");
//SynaReadBootloadID(ts);
SynaWriteBootloadID(ts);
uData = 3;
writeRMI(ts->client, SynaF34_FlashControl, &uData, 1);
msleep(1000);
SynaWaitATTN(ts);
SynaFlashFirmwareWrite(ts);
}
/* eraseConfigBlock erases the config block
*/
void eraseConfigBlock(struct synaptics_ts_data *ts)
{
unsigned char uData;
TOUCH_INFO_MSG("%s", __FUNCTION__);
// Erase of config block is done by first entering into bootloader mode
SynaReadBootloadID(ts);
SynaWriteBootloadID(ts);
// Command 7 to erase config block
uData = 7;
writeRMI(ts->client, SynaF34_FlashControl, &uData, 1);
SynaWaitATTN(ts);
}
#if 0
// This function is intended to convert the config data struct output by DS4 (read DS4_config.h) into an array that
// the reflash code uses (read SynaFirmwareImage.h)
// DS4 will output the array format in the next release and this function will not be necessary
void convertConfigBlockData()
{
for (int i = 0; value[i]!=NULL; i++)
{
ConfigBlock[i] = value[i].Value;
}
}
#endif
// CRC_Calculate illustates how to calculate a checksum from the config block data.
// With DS4, the config block checksum is calculated and applies towards the end of
// the config block data automatically
// Variable data to this function represents the data only portion of the config block
// Varaible len represents the length of the variable data.
void CRC_Calculate(unsigned short * data, unsigned short len)
{
short i;
unsigned long Data_CRC = 0xffffffff;
unsigned long sum1 = (unsigned long)(Data_CRC & 0xFFFF);
unsigned long sum2 = (unsigned long)(Data_CRC >> 16);
TOUCH_INFO_MSG("%s", __FUNCTION__);
for (i = 0; i < len; i++) {
unsigned long temp = data[i];
sum1 += temp;
sum2 += sum1;
sum1 = (unsigned long)((sum1 & 0xffff) + (sum1 >> 16));
sum2 = (unsigned long)((sum2 & 0xffff) + (sum2 >> 16));
}
Data_CRC = (unsigned long)(sum2 << 16 | sum1);
//return Bootloader_incrementalCrc;
}
void SynaBootloaderLock(struct synaptics_ts_data *ts)
{
unsigned short lockBlockCount;
unsigned char *puFirmwareData = SynalockImgData;
unsigned char uData[2];
unsigned short uBlockNum;
// Check if device is in unlocked state
readRMI(ts->client, (SynaF34QueryBase+ 2), &uData[0], 1);
//Device is unlocked
if (uData[0] & 0x02) {
TOUCH_INFO_MSG("Device unlocked. Lock it first...\n");
// Different bootloader version has different block count for the lockdown data
// Need to check the bootloader version from the image file being reflashed
switch (SynafirmwareImgVersion) {
case 2:
lockBlockCount = 3;
break;
case 3:
case 4:
lockBlockCount = 4;
break;
case 5:
lockBlockCount = 5;
break;
default:
lockBlockCount = 0;
break;
}
// Write the lockdown info block by block
// This reference code of lockdown process does not check for bootloader version
// currently programmed on the ASIC against the bootloader version of the image to
// be reflashed. Such case should not happen in practice. Reflashing cross different
// bootloader versions is not supported.
for (uBlockNum = 0; uBlockNum < lockBlockCount; ++uBlockNum) {
uData[0] = uBlockNum & 0xff;
uData[1] = (uBlockNum & 0xff00) >> 8;
/* Write Block Number */
readRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);
/* Write Data Block */
writeRMI(ts->client, SynaF34Reflash_BlockData,
puFirmwareData, SynaFirmwareBlockSize);
/* Move to next data block */
puFirmwareData += SynaFirmwareBlockSize;
/* Issue Write Lockdown Block command */
uData[0] = 4;
writeRMI(ts->client, SynaF34_FlashControl, &uData[0], 1);
/* Wait ATTN until device is done writing the block and is ready for the next. */
SynaWaitATTN(ts);
}
TOUCH_INFO_MSG("Device locking done.\n");
// Enable reflash again to finish the lockdown process.
// Since this lockdown process is part of the reflash process, we are enabling
// reflash instead, rather than resetting the device to finish the unlock procedure.
SynaEnableFlashing(ts);
} else {
TOUCH_INFO_MSG("Device already locked.\n");
}
}
/* ConfigBlockReflash reflashes the config block only
*/
void ConfigBlockReflash(struct synaptics_ts_data *ts)
{
unsigned char uData[2];
TOUCH_INFO_MSG("%s", __FUNCTION__);
SynaInitialize(ts);
SynaReadConfigInfo(ts);
SynaReadFirmwareInfo(ts);
SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
SynaEnableFlashing(ts);
// Check if device is in unlocked state
readRMI(ts->client, (SynaF34QueryBase + 2), &uData[0], 1);
//Device is unlocked
if (uData[0] & 0x02) {
SynaFinalizeReflash(ts);
return;
// Do not reflash config block if not locked.
}
eraseConfigBlock(ts);
//SynaconfigImgData = (unsigned char *)ConfigBlockData;
SynaProgramConfiguration(ts);
SynaFinalizeReflash(ts);
}
/* CompleteReflash reflashes the entire user image, including the configuration block and firmware
*/
void CompleteReflash(struct synaptics_ts_data *ts)
{
TOUCH_INFO_MSG("%s", __FUNCTION__);
SynaInitialize(ts);
SynaReadConfigInfo(ts);
SynaReadFirmwareInfo(ts);
SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
SynaEnableFlashing(ts);
SynaProgramFirmware(ts);
SynaProgramConfiguration(ts);
SynaFinalizeReflash(ts);
}
void CompleteReflash_Lockdown(struct synaptics_ts_data *ts)
{
TOUCH_INFO_MSG("%s", __FUNCTION__);
SynaInitialize(ts);
SynaReadConfigInfo(ts);
SynaReadFirmwareInfo(ts);
SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
SynaEnableFlashing(ts);
SynaBootloaderLock(ts);
SynaProgramFirmware(ts);
SynaProgramConfiguration(ts);
SynaFinalizeReflash(ts);
}

View file

@ -0,0 +1,403 @@
/* include/linux/lge_touch_core.h
*
* Copyright (C) 2011 LGE.
*
* Author: yehan.ahn@lge.com, hyesung.shin@lge.com
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef LGE_TOUCH_CORE_H
#define LGE_TOUCH_CORE_H
//#define LGE_TOUCH_TIME_DEBUG
#define MAX_FINGER 10
#define MAX_BUTTON 4
struct touch_device_caps {
u8 button_support;
u16 y_button_boundary;
u32 button_margin;
u8 number_of_button;
u32 button_name[MAX_BUTTON];
u8 is_width_supported;
u8 is_pressure_supported;
u8 is_id_supported;
u32 max_width;
u32 max_pressure;
u32 max_id;
u32 x_max;
u32 y_max;
u32 lcd_x;
u32 lcd_y;
};
struct touch_operation_role {
u8 operation_mode; /* interrupt = 1 , polling = 0; */
u8 key_type; /* none = 0, hard_touch_key = 1, virtual_key = 2 */
u8 report_mode;
u8 delta_pos_threshold;
u8 orientation; /* 0' = 0, 90' = 1, 180' = 2, 270' = 3 */
u32 report_period; /* ns */
u32 booting_delay; /* ms */
u32 reset_delay; /* ms */
u8 suspend_pwr;
u8 resume_pwr;
int jitter_filter_enable; /* enable = 1, disable = 0 */
int jitter_curr_ratio;
int accuracy_filter_enable; /* enable = 1, disable = 0 */
unsigned long irqflags;
#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
int show_touches;
int pointer_location;
#endif
};
struct touch_power_module {
u8 use_regulator;
char vdd[30];
int vdd_voltage;
char vio[30];
int vio_voltage;
int (*power)(int on);
};
struct touch_platform_data {
u32 int_pin;
u32 reset_pin;
char maker[30];
struct touch_device_caps *caps;
struct touch_operation_role *role;
struct touch_power_module *pwr;
};
struct t_data {
u16 id;
u16 x_position;
u16 y_position;
u16 width_major;
u16 width_minor;
u16 width_orientation;
u16 pressure;
};
struct b_data {
u16 key_code;
u16 state;
};
struct touch_data {
u8 total_num;
u8 prev_total_num;
u8 state;
struct t_data curr_data[MAX_FINGER];
struct t_data prev_data[MAX_FINGER];
struct b_data curr_button;
struct b_data prev_button;
};
struct touch_fw_info {
u8 fw_rev;
u8 fw_image_rev;
u8 manufacturer_id;
u8 product_id[11];
u8 fw_image_product_id[11];
#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
u8 fw_version[5];
u8 fw_image_version[5];
bool fw_force_rework;
#endif
unsigned char *fw_start;
unsigned long fw_size;
};
struct fw_upgrade_info {
char fw_path[256];
u8 fw_force_upgrade;
volatile u8 is_downloading;
};
struct rect {
u16 left;
u16 right;
u16 top;
u16 bottom;
};
struct section_info
{
struct rect panel;
struct rect button[MAX_BUTTON];
struct rect button_cancel[MAX_BUTTON];
u16 b_inner_width;
u16 b_width;
u16 b_margin;
u16 b_height;
u16 b_num;
u16 b_name[MAX_BUTTON];
};
struct ghost_finger_ctrl {
volatile u8 stage;
int count;
int min_count;
int max_count;
int ghost_check_count;
};
struct jitter_history_data {
u16 x;
u16 y;
u16 pressure;
int delta_x;
int delta_y;
};
struct jitter_filter_info {
int id_mask;
int adjust_margin;
struct jitter_history_data his_data[10];
};
struct accuracy_history_data {
u16 x;
u16 y;
u16 pressure;
int count;
int mod_x;
int mod_y;
int axis_x;
int axis_y;
int prev_total_num;
};
struct accuracy_filter_info {
int ignore_pressure_gap;
int touch_max_count;
int delta_max;
int max_pressure;
int direction_count;
int time_to_max_pressure;
u16 finish_filter;
struct accuracy_history_data his_data;
};
struct lge_touch_data {
void* h_touch;
atomic_t next_work;
atomic_t device_init;
u8 work_sync_err_cnt;
u8 ic_init_err_cnt;
volatile int curr_pwr_state;
struct i2c_client *client;
struct input_dev *input_dev;
struct hrtimer timer;
struct work_struct work;
struct delayed_work work_init;
struct delayed_work work_touch_lock;
struct work_struct work_fw_upgrade;
struct early_suspend early_suspend;
struct touch_platform_data *pdata;
struct touch_data ts_data;
struct touch_fw_info fw_info;
struct fw_upgrade_info fw_upgrade;
struct section_info st_info;
struct kobject lge_touch_kobj;
struct ghost_finger_ctrl gf_ctrl;
struct jitter_filter_info jitter_filter;
struct accuracy_filter_info accuracy_filter;
};
struct touch_device_driver {
int (*probe) (struct i2c_client *client);
void (*remove) (struct i2c_client *client);
int (*init) (struct i2c_client *client, struct touch_fw_info* info);
int (*data) (struct i2c_client *client, struct t_data* data,
struct b_data* button, u8* total_num);
int (*power) (struct i2c_client *client, int power_ctrl);
int (*ic_ctrl) (struct i2c_client *client, u8 code, u16 value);
int (*fw_upgrade) (struct i2c_client *client, const char* fw_path);
int (*fw_upgrade_check) (struct lge_touch_data *ts);
};
enum {
POLLING_MODE = 0,
INTERRUPT_MODE,
HYBRIDE_MODE
};
enum {
POWER_OFF = 0,
POWER_ON,
POWER_SLEEP,
POWER_WAKE
};
enum {
KEY_NONE = 0,
TOUCH_HARD_KEY,
TOUCH_SOFT_KEY,
VIRTUAL_KEY,
};
enum {
CONTINUOUS_REPORT_MODE = 0,
REDUCED_REPORT_MODE,
};
enum {
RESET_NONE = 0,
SOFT_RESET,
PIN_RESET,
VDD_RESET,
};
enum {
DOWNLOAD_COMPLETE = 0,
UNDER_DOWNLOADING,
};
enum {
OP_NULL = 0,
OP_RELEASE,
OP_SINGLE,
OP_MULTI,
OP_LOCK,
};
enum {
KEY_NULL=0,
KEY_PANEL,
KEY_BOUNDARY
};
enum {
DO_NOT_ANYTHING = 0,
ABS_PRESS,
ABS_RELEASE,
BUTTON_PRESS,
BUTTON_RELEASE,
BUTTON_CANCEL,
TOUCH_BUTTON_LOCK,
TOUCH_ABS_LOCK
};
enum {
BUTTON_RELEASED = 0,
BUTTON_PRESSED = 1,
BUTTON_CANCLED = 0xff,
};
enum {
KEYGUARD_RESERVED,
KEYGUARD_ENABLE,
};
enum {
GHOST_STAGE_CLEAR = 0,
GHOST_STAGE_1 = 1,
GHOST_STAGE_2 = 2,
GHOST_STAGE_3 = 4,
};
enum {
BASELINE_OPEN = 0,
BASELINE_FIX,
BASELINE_REBASE,
};
enum {
IC_CTRL_CODE_NONE = 0,
IC_CTRL_BASELINE,
IC_CTRL_READ,
IC_CTRL_WRITE,
IC_CTRL_RESET_CMD,
};
enum {
DEBUG_NONE = 0,
DEBUG_BASE_INFO = (1U << 0), // 1
DEBUG_TRACE = (1U << 1), // 2
DEBUG_GET_DATA = (1U << 2), // 4
DEBUG_ABS = (1U << 3), // 8
DEBUG_BUTTON = (1U << 4), // 16
DEBUG_FW_UPGRADE = (1U << 5), // 32
DEBUG_GHOST = (1U << 6), // 64
DEBUG_IRQ_HANDLE = (1U << 7), // 128
DEBUG_POWER = (1U << 8), // 256
DEBUG_JITTER = (1U << 9), // 512
DEBUG_ACCURACY = (1U << 10), // 1024
};
#ifdef LGE_TOUCH_TIME_DEBUG
enum {
TIME_ISR_START = 0,
TIME_INT_INTERVAL,
TIME_THREAD_ISR_START,
TIME_WORKQUEUE_START,
TIME_WORKQUEUE_END,
TIME_FW_UPGRADE_START,
TIME_FW_UPGRADE_END,
TIME_PROFILE_MAX,
};
enum {
DEBUG_TIME_PROFILE_NONE = 0,
DEBUG_TIME_INT_INTERVAL = (1U << 0), // 1
DEBUG_TIME_INT_IRQ_DELAY = (1U << 1), // 2
DEBUG_TIME_INT_THREAD_IRQ_DELAY = (1U << 2), // 4
DEBUG_TIME_DATA_HANDLE = (1U << 3), // 8
DEBUG_TIME_FW_UPGRADE = (1U << 4), // 16
DEBUG_TIME_PROFILE_ALL = (1U << 5), // 32
};
#endif
#define LGE_TOUCH_NAME "lge_touch"
/* Debug Mask setting */
#define TOUCH_DEBUG_PRINT (1)
#define TOUCH_ERROR_PRINT (1)
#define TOUCH_INFO_PRINT (1)
#if defined(TOUCH_INFO_PRINT)
#define TOUCH_INFO_MSG(fmt, args...) printk(KERN_INFO "[Touch] " fmt, ##args)
#else
#define TOUCH_INFO_MSG(fmt, args...)
#endif
#if defined(TOUCH_ERROR_PRINT)
#define TOUCH_ERR_MSG(fmt, args...) printk(KERN_ERR "[Touch E] [%s %d] " fmt, \
__FUNCTION__, __LINE__, ##args)
#else
#define TOUCH_ERR_MSG(fmt, args...)
#endif
#if defined(TOUCH_DEBUG_PRINT)
#define TOUCH_DEBUG_MSG(fmt, args...) printk(KERN_INFO "[Touch D] [%s %d] " fmt, \
__FUNCTION__, __LINE__, ##args);
#else
#define TOUCH_DEBUG_MSG(fmt, args...)
#endif
int touch_driver_register(struct touch_device_driver* driver);
void touch_driver_unregister(void);
void set_touch_handle(struct i2c_client *client, void* h_touch);
void* get_touch_handle(struct i2c_client *client);
int touch_i2c_read(struct i2c_client *client, u8 reg, int len, u8 *buf);
int touch_i2c_write(struct i2c_client *client, u8 reg, int len, u8 *buf);
int touch_i2c_write_byte(struct i2c_client *client, u8 reg, u8 data);
extern u32 touch_debug_mask;
extern u32 touch_time_debug_mask;
#endif

View file

@ -0,0 +1,92 @@
/* include/linux/lge_touch_core.h
*
* Copyright (C) 2011 LGE.
*
* Writer: yehan.ahn@lge.com, hyesung.shin@lge.com
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef LGE_TOUCH_SYNAPTICS_H
#define LGE_TOUCH_SYNAPTICS_H
#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
//do nothing
#else
#define ARRAYED_TOUCH_FW_BIN
#endif
#define NUM_OF_EACH_FINGER_DATA_REG 5
#define MAX_NUM_OF_FINGERS 10
#define DESCRIPTION_TABLE_START 0xe9
struct ts_function_descriptor {
u8 query_base;
u8 command_base;
u8 control_base;
u8 data_base;
u8 int_source_count;
u8 id;
};
struct finger_data {
u8 finger_status_reg[3];
u8 finger_reg[MAX_NUM_OF_FINGERS][NUM_OF_EACH_FINGER_DATA_REG];
};
struct button_data {
u16 key_code;
};
struct cur_touch_data {
u8 device_status_reg; /* DEVICE_STATUS_REG */
u8 interrupt_status_reg;
u8 button_data_reg;
struct finger_data finger;
struct button_data button;
};
struct interrupt_bit_mask {
u8 flash;
u8 status;
u8 abs;
u8 button;
};
struct synaptics_ts_data {
u8 is_probed;
struct regulator *regulator_vdd;
struct regulator *regulator_vio;
struct i2c_client *client;
struct touch_platform_data *pdata;
struct ts_function_descriptor common_dsc;
struct ts_function_descriptor finger_dsc;
struct ts_function_descriptor button_dsc;
struct ts_function_descriptor flash_dsc;
struct cur_touch_data ts_data;
struct touch_fw_info *fw_info;
struct interrupt_bit_mask interrupt_mask;
#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
struct ts_function_descriptor analog_dsc;
#endif
#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
u8 ic_panel_type;
#endif
};
#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
enum {IC7020_GFF, IC7020_G2, IC3203_G2, IC7020_GFF_H_PTN, IC7020_G2_H_PTN};
#endif
/* extern function */
extern int FirmwareUpgrade(struct synaptics_ts_data *ts, const char* fw_path);
#endif