mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
mako: touch driver merge
- lge touch common driver - synaptics touch driver integration with lge common driver Change-Id: I72e53f8d16610155ab1a31a366e33910a41643be
This commit is contained in:
parent
911aed249d
commit
000adcf065
11 changed files with 11392 additions and 141 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
2934
drivers/input/touchscreen/SynaImage.h
Normal file
2934
drivers/input/touchscreen/SynaImage.h
Normal file
File diff suppressed because it is too large
Load diff
2934
drivers/input/touchscreen/SynaImage_Jp.h
Normal file
2934
drivers/input/touchscreen/SynaImage_Jp.h
Normal file
File diff suppressed because it is too large
Load diff
3057
drivers/input/touchscreen/lge_touch_core.c
Normal file
3057
drivers/input/touchscreen/lge_touch_core.c
Normal file
File diff suppressed because it is too large
Load diff
1134
drivers/input/touchscreen/touch_synaptics.c
Normal file
1134
drivers/input/touchscreen/touch_synaptics.c
Normal file
File diff suppressed because it is too large
Load diff
811
drivers/input/touchscreen/touch_synaptics_ds4_fw_upgrade.c
Normal file
811
drivers/input/touchscreen/touch_synaptics_ds4_fw_upgrade.c
Normal 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);
|
||||
}
|
||||
|
||||
|
403
include/linux/input/lge_touch_core.h
Normal file
403
include/linux/input/lge_touch_core.h
Normal 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
|
92
include/linux/input/touch_synaptics.h
Normal file
92
include/linux/input/touch_synaptics.h
Normal 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
|
Loading…
Reference in a new issue