Merge "input: touchscreen: fix compilation errors for Goodix driver"

This commit is contained in:
Linux Build Service Account 2016-10-27 15:48:48 -07:00 committed by Gerrit - the friendly Code Review server
commit 970b543f51
5 changed files with 339 additions and 326 deletions

View file

@ -57,6 +57,12 @@ Optional properties:
- goodix,cfg-data5 : Touch screen controller config data group 5. Ask vendor - goodix,cfg-data5 : Touch screen controller config data group 5. Ask vendor
to provide that. to provide that.
- goodix,fw-name : Touch screen controller firmware file name. - goodix,fw-name : Touch screen controller firmware file name.
- goodix,slide-wakeup : To specify slide-wakeup property is enabled or not.
- goodix,dbl-clk-wakeup : To specify dbl-clk-wakeup property is enabled or not.
- goodix,change-x2y : To specify change-x2y property is enabled or not.
- goodix,driver-send-cfg : To specify driver-send-cfg property is enabled or not.
- goodix,have-touch-key : To specify have-touch-key property is enabled or not.
- goodix,with-pen : To specify with-pen property is enabled or not.
Example: Example:
i2c@f9927000 { i2c@f9927000 {
goodix@5d { goodix@5d {
@ -92,5 +98,7 @@ i2c@f9927000 {
FF FF FF FF FF FF FF 22 22 22 FF FF FF FF FF FF FF 22 22 22
22 22 22 FF 07 01]; 22 22 22 FF 07 01];
goodix,fw_name = "gtp_fw.bin"; goodix,fw_name = "gtp_fw.bin";
goodix,have-touch-key;
goodix,driver-send-cfg;
}; };
}; };

View file

@ -236,14 +236,13 @@ static u8 relation(u8 src, u8 dst, u8 rlt)
return ret; return ret;
} }
/******************************************************* /*
* Function: * Function:
* Comfirm function. * Comfirm function.
* Input: * Input:
* None. * None.
* Output: * Output:
* Return write length. * Return write length.
*******************************************************
*/ */
static u8 comfirm(void) static u8 comfirm(void)
{ {
@ -305,7 +304,7 @@ static s32 fill_update_info(char __user *user_buf,
* Output: * Output:
* Return write length. * Return write length.
*/ */
static s32 goodix_tool_write(struct file *filp, const char __user *userbuf, static ssize_t goodix_tool_write(struct file *filp, const char __user *userbuf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
s32 ret = 0; s32 ret = 0;
@ -318,20 +317,22 @@ static s32 goodix_tool_write(struct file *filp, const char __user *userbuf,
goto exit; goto exit;
} }
dev_dbg(&gt_client->dev, "wr:0x%02x, flag:0x%02x, flag addr:0x%02x%02x, dev_dbg(&gt_client->dev,
flag val:0x%02x, flag rel:0x%02x,", cmd_headd.wr, "wr: 0x%02x, flag:0x%02x, flag addr:0x%02x%02x\n", cmd_head.wr,
cmd_head.flag, cmd_head.flag_addr[0], cmd_head.flag, cmd_head.flag_addr[0], cmd_head.flag_addr[1]);
cmd_head.flag_addr[1], cmd_head.flag_val, dev_dbg(&gt_client->dev,
"flag val:0x%02x, flag rel:0x%02x,\n", cmd_head.flag_val,
cmd_head.flag_relation); cmd_head.flag_relation);
dev_dbg(&gt_client->dev, "circle:%d, times:%d, retry:%d, delay:%d, dev_dbg(&gt_client->dev, "circle:%u, times:%u, retry:%u, delay:%u\n",
data len:%d, addr len:%d, addr:0x%02x%02x, write len: %d", (s32) cmd_head.circle, (s32) cmd_head.times,
(s32)cmd_head.circle, (s32)cmd_head.times, (s32)cmd_head.retry, (s32) cmd_head.retry, (s32)cmd_head.delay);
(s32)cmd_head.delay, (s32)cmd_head.data_len, dev_dbg(&gt_client->dev,
(s32)cmd_head.addr_len, cmd_head.addr[0], cmd_head.addr[1], "data len:%u, addr len:%u, addr:0x%02x%02x, write len: %u\n",
(s32)count); (s32)cmd_head.data_len, (s32)cmd_head.addr_len,
cmd_head.addr[0], cmd_head.addr[1], (s32)count);
if (cmd_head.data_len > (data_length - GTP_ADDR_LENGTH)) { if (cmd_head.data_len > (data_length - GTP_ADDR_LENGTH)) {
dev_err(&gt_client->dev, "data len %d > data buff %d, rejected\n", dev_err(&gt_client->dev, "data len %u > data buff %d, rejected\n",
cmd_head.data_len, (data_length - GTP_ADDR_LENGTH)); cmd_head.data_len, (data_length - GTP_ADDR_LENGTH));
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
@ -383,7 +384,7 @@ static s32 goodix_tool_write(struct file *filp, const char __user *userbuf,
if (cmd_head.data_len > sizeof(ic_type)) { if (cmd_head.data_len > sizeof(ic_type)) {
dev_err(&gt_client->dev, dev_err(&gt_client->dev,
"data len %d > data buff %d, rejected\n", "data len %u > data buff %zu, rejected\n",
cmd_head.data_len, sizeof(ic_type)); cmd_head.data_len, sizeof(ic_type));
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
@ -445,7 +446,7 @@ static s32 goodix_tool_write(struct file *filp, const char __user *userbuf,
show_len = 0; show_len = 0;
total_len = 0; total_len = 0;
if (cmd_head.data_len + 1 > data_length) { if (cmd_head.data_len + 1 > data_length) {
dev_err(&gt_client->dev, "data len %d > data buff %d, rejected\n", dev_err(&gt_client->dev, "data len %u > data buff %d, rejected\n",
cmd_head.data_len + 1, data_length); cmd_head.data_len + 1, data_length);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
@ -474,7 +475,7 @@ exit:
* Output: * Output:
* Return read length. * Return read length.
*/ */
static s32 goodix_tool_read(struct file *file, char __user *user_buf, static ssize_t goodix_tool_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
u16 data_len = 0; u16 data_len = 0;

View file

@ -48,6 +48,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/interrupt.h>
#define GOODIX_DEV_NAME "Goodix-CTP" #define GOODIX_DEV_NAME "Goodix-CTP"
#define CFG_MAX_TOUCH_POINTS 5 #define CFG_MAX_TOUCH_POINTS 5
@ -65,6 +66,8 @@
#define RESET_DELAY_T3_US 200 /* T3: > 100us */ #define RESET_DELAY_T3_US 200 /* T3: > 100us */
#define RESET_DELAY_T4 20 /* T4: > 5ms */ #define RESET_DELAY_T4 20 /* T4: > 5ms */
#define SLEEP_DELAY_US 5000
#define WAKE_UP_DELAY_US 5000
#define PHY_BUF_SIZE 32 #define PHY_BUF_SIZE 32
#define PROP_NAME_SIZE 24 #define PROP_NAME_SIZE 24
@ -72,11 +75,6 @@
#define GTP_MAX_TOUCH 5 #define GTP_MAX_TOUCH 5
#define GTP_ESD_CHECK_CIRCLE_MS 2000 #define GTP_ESD_CHECK_CIRCLE_MS 2000
#if GTP_HAVE_TOUCH_KEY
static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK};
#endif
static void gtp_int_sync(struct goodix_ts_data *ts, int ms); static void gtp_int_sync(struct goodix_ts_data *ts, int ms);
static int gtp_i2c_test(struct i2c_client *client); static int gtp_i2c_test(struct i2c_client *client);
static int goodix_power_off(struct goodix_ts_data *ts); static int goodix_power_off(struct goodix_ts_data *ts);
@ -99,15 +97,14 @@ static void gtp_esd_check_func(struct work_struct *work);
static int gtp_init_ext_watchdog(struct i2c_client *client); static int gtp_init_ext_watchdog(struct i2c_client *client);
#endif #endif
#if GTP_SLIDE_WAKEUP enum doze {
enum doze_status {
DOZE_DISABLED = 0, DOZE_DISABLED = 0,
DOZE_ENABLED = 1, DOZE_ENABLED = 1,
DOZE_WAKEUP = 2, DOZE_WAKEUP = 2,
}; };
static enum doze_status = DOZE_DISABLED; static enum doze doze_status = DOZE_DISABLED;
static s8 gtp_enter_doze(struct goodix_ts_data *ts); static s8 gtp_enter_doze(struct goodix_ts_data *ts);
#endif
bool init_done; bool init_done;
static u8 chip_gt9xxs; /* true if ic is gt9xxs, like gt915s */ static u8 chip_gt9xxs; /* true if ic is gt9xxs, like gt915s */
u8 grp_cfg_version; u8 grp_cfg_version;
@ -157,11 +154,11 @@ int gtp_i2c_read(struct i2c_client *client, u8 *buf, int len)
dev_err(&client->dev, "I2C retry: %d\n", retries + 1); dev_err(&client->dev, "I2C retry: %d\n", retries + 1);
} }
if (retries == GTP_I2C_RETRY_5) { if (retries == GTP_I2C_RETRY_5) {
#if GTP_SLIDE_WAKEUP if (ts->pdata->slide_wakeup)
/* reset chip would quit doze mode */ /* reset chip would quit doze mode */
if (doze_status == DOZE_ENABLED) if (doze_status == DOZE_ENABLED)
return ret; return ret;
#endif
if (init_done) if (init_done)
gtp_reset_guitar(ts, 10); gtp_reset_guitar(ts, 10);
else else
@ -203,10 +200,10 @@ int gtp_i2c_write(struct i2c_client *client, u8 *buf, int len)
dev_err(&client->dev, "I2C retry: %d\n", retries + 1); dev_err(&client->dev, "I2C retry: %d\n", retries + 1);
} }
if (retries == GTP_I2C_RETRY_5) { if (retries == GTP_I2C_RETRY_5) {
#if GTP_SLIDE_WAKEUP if (ts->pdata->slide_wakeup)
if (doze_status == DOZE_ENABLED) if (doze_status == DOZE_ENABLED)
return ret; return ret;
#endif
if (init_done) if (init_done)
gtp_reset_guitar(ts, 10); gtp_reset_guitar(ts, 10);
else else
@ -270,10 +267,10 @@ Output:
*********************************************************/ *********************************************************/
int gtp_send_cfg(struct goodix_ts_data *ts) int gtp_send_cfg(struct goodix_ts_data *ts)
{ {
int ret; int ret = 0;
#if GTP_DRIVER_SEND_CFG int retry;
int retry = 0;
if (ts->pdata->driver_send_cfg) {
if (ts->fixed_cfg) { if (ts->fixed_cfg) {
dev_dbg(&ts->client->dev, dev_dbg(&ts->client->dev,
"Ic fixed config, no config sent!"); "Ic fixed config, no config sent!");
@ -282,12 +279,13 @@ int gtp_send_cfg(struct goodix_ts_data *ts)
for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) { for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
ret = gtp_i2c_write(ts->client, ret = gtp_i2c_write(ts->client,
ts->config_data, ts->config_data,
GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); GTP_CONFIG_MAX_LENGTH +
GTP_ADDR_LENGTH);
if (ret > 0) if (ret > 0)
break; break;
} }
} }
#endif }
return ret; return ret;
} }
@ -347,9 +345,8 @@ Output:
static void gtp_touch_down(struct goodix_ts_data *ts, int id, int x, int y, static void gtp_touch_down(struct goodix_ts_data *ts, int id, int x, int y,
int w) int w)
{ {
#if GTP_CHANGE_X2Y if (ts->pdata->change_x2y)
swap(x, y); swap(x, y);
#endif
input_mt_slot(ts->input_dev, id); input_mt_slot(ts->input_dev, id);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
@ -394,9 +391,7 @@ static void goodix_ts_work_func(struct work_struct *work)
u8 finger = 0; u8 finger = 0;
static u16 pre_touch; static u16 pre_touch;
static u8 pre_key; static u8 pre_key;
#if GTP_WITH_PEN
static u8 pre_pen; static u8 pre_pen;
#endif
u8 key_value = 0; u8 key_value = 0;
u8 *coor_data = NULL; u8 *coor_data = NULL;
s32 input_x = 0; s32 input_x = 0;
@ -406,10 +401,7 @@ static void goodix_ts_work_func(struct work_struct *work)
s32 i = 0; s32 i = 0;
int ret = -1; int ret = -1;
struct goodix_ts_data *ts = NULL; struct goodix_ts_data *ts = NULL;
#if GTP_SLIDE_WAKEUP
u8 doze_buf[3] = {0x81, 0x4B}; u8 doze_buf[3] = {0x81, 0x4B};
#endif
ts = container_of(work, struct goodix_ts_data, work); ts = container_of(work, struct goodix_ts_data, work);
#ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
@ -417,7 +409,7 @@ static void goodix_ts_work_func(struct work_struct *work)
return; return;
#endif #endif
#if GTP_SLIDE_WAKEUP if (ts->pdata->slide_wakeup) {
if (doze_status == DOZE_ENABLED) { if (doze_status == DOZE_ENABLED) {
ret = gtp_i2c_read(ts->client, doze_buf, 3); ret = gtp_i2c_read(ts->client, doze_buf, 3);
if (ret > 0) { if (ret > 0) {
@ -438,9 +430,11 @@ static void goodix_ts_work_func(struct work_struct *work)
dev_dbg(&ts->client->dev, dev_dbg(&ts->client->dev,
"Slide(0xBB) To Light up the screen!"); "Slide(0xBB) To Light up the screen!");
doze_status = DOZE_WAKEUP; doze_status = DOZE_WAKEUP;
input_report_key(ts->input_dev, KEY_POWER, 1); input_report_key(ts->input_dev,
KEY_POWER, 1);
input_sync(ts->input_dev); input_sync(ts->input_dev);
input_report_key(ts->input_dev, KEY_POWER, 0); input_report_key(ts->input_dev,
KEY_POWER, 0);
input_sync(ts->input_dev); input_sync(ts->input_dev);
/* clear 0x814B*/ /* clear 0x814B*/
doze_buf[2] = 0x00; doze_buf[2] = 0x00;
@ -449,9 +443,11 @@ static void goodix_ts_work_func(struct work_struct *work)
dev_dbg(&ts->client->dev, dev_dbg(&ts->client->dev,
"double click to light up the screen!"); "double click to light up the screen!");
doze_status = DOZE_WAKEUP; doze_status = DOZE_WAKEUP;
input_report_key(ts->input_dev, KEY_POWER, 1); input_report_key(ts->input_dev,
KEY_POWER, 1);
input_sync(ts->input_dev); input_sync(ts->input_dev);
input_report_key(ts->input_dev, KEY_POWER, 0); input_report_key(ts->input_dev,
KEY_POWER, 0);
input_sync(ts->input_dev); input_sync(ts->input_dev);
/* clear 0x814B */ /* clear 0x814B */
doze_buf[2] = 0x00; doze_buf[2] = 0x00;
@ -465,7 +461,7 @@ static void goodix_ts_work_func(struct work_struct *work)
return; return;
} }
#endif }
ret = gtp_i2c_read(ts->client, point_data, 12); ret = gtp_i2c_read(ts->client, point_data, 12);
if (ret < 0) { if (ret < 0) {
@ -506,7 +502,7 @@ static void goodix_ts_work_func(struct work_struct *work)
pre_key = key_value; pre_key = key_value;
#if GTP_WITH_PEN if (ts->pdata->with_pen) {
if (pre_pen && (touch_num == 0)) { if (pre_pen && (touch_num == 0)) {
dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!"); dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!");
input_report_key(ts->input_dev, BTN_TOOL_PEN, 0); input_report_key(ts->input_dev, BTN_TOOL_PEN, 0);
@ -514,7 +510,8 @@ static void goodix_ts_work_func(struct work_struct *work)
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
pre_pen = 0; pre_pen = 0;
} }
#endif }
if (pre_touch || touch_num) { if (pre_touch || touch_num) {
s32 pos = 0; s32 pos = 0;
u16 touch_index = 0; u16 touch_index = 0;
@ -522,7 +519,7 @@ static void goodix_ts_work_func(struct work_struct *work)
coor_data = &point_data[3]; coor_data = &point_data[3];
if (touch_num) { if (touch_num) {
id = coor_data[pos] & 0x0F; id = coor_data[pos] & 0x0F;
#if GTP_WITH_PEN if (ts->pdata->with_pen) {
id = coor_data[pos]; id = coor_data[pos];
if (id == 128) { if (id == 128) {
dev_dbg(&ts->client->dev, dev_dbg(&ts->client->dev,
@ -551,16 +548,16 @@ static void goodix_ts_work_func(struct work_struct *work)
pre_pen = 1; pre_pen = 1;
pre_touch = 0; pre_touch = 0;
} }
#endif }
touch_index |= (0x01<<id); touch_index |= (0x01<<id);
} }
for (i = 0; i < GTP_MAX_TOUCH; i++) { for (i = 0; i < GTP_MAX_TOUCH; i++) {
#if GTP_WITH_PEN if (ts->pdata->with_pen)
if (pre_pen == 1) if (pre_pen == 1)
break; break;
#endif
if (touch_index & (0x01<<i)) { if (touch_index & (0x01<<i)) {
input_x = coor_data[pos + 1] | input_x = coor_data[pos + 1] |
coor_data[pos + 2] << 8; coor_data[pos + 2] << 8;
@ -651,7 +648,7 @@ void gtp_reset_guitar(struct goodix_ts_data *ts, int ms)
else else
gpio_direction_output(ts->pdata->irq_gpio, 0); gpio_direction_output(ts->pdata->irq_gpio, 0);
usleep(RESET_DELAY_T3_US); usleep_range(RESET_DELAY_T3_US, RESET_DELAY_T3_US + 1);
gpio_direction_output(ts->pdata->reset_gpio, 1); gpio_direction_output(ts->pdata->reset_gpio, 1);
msleep(RESET_DELAY_T4); msleep(RESET_DELAY_T4);
@ -665,7 +662,6 @@ void gtp_reset_guitar(struct goodix_ts_data *ts, int ms)
} }
#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB) #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB)
#if GTP_SLIDE_WAKEUP
/******************************************************* /*******************************************************
Function: Function:
Enter doze mode for sliding wakeup. Enter doze mode for sliding wakeup.
@ -682,9 +678,9 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts)
(u8)(GTP_REG_SLEEP >> 8), (u8)(GTP_REG_SLEEP >> 8),
(u8)GTP_REG_SLEEP, 8}; (u8)GTP_REG_SLEEP, 8};
#if GTP_DBL_CLK_WAKEUP if (ts->pdata->dbl_clk_wakeup)
i2c_control_buf[2] = 0x09; i2c_control_buf[2] = 0x09;
#endif
gtp_irq_disable(ts); gtp_irq_disable(ts);
while (retry++ < GTP_I2C_RETRY_3) { while (retry++ < GTP_I2C_RETRY_3) {
@ -713,7 +709,6 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts)
gtp_irq_enable(ts); gtp_irq_enable(ts);
return ret; return ret;
} }
#else
/** /**
* gtp_enter_sleep - Enter sleep mode * gtp_enter_sleep - Enter sleep mode
* @ts: driver private data * @ts: driver private data
@ -746,7 +741,7 @@ static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
} }
return 0; return 0;
} }
usleep(5000); usleep_range(SLEEP_DELAY_US, SLEEP_DELAY_US + 1);
while (retry++ < GTP_I2C_RETRY_5) { while (retry++ < GTP_I2C_RETRY_5) {
ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); ret = gtp_i2c_write(ts->client, i2c_control_buf, 3);
if (ret == 1) { if (ret == 1) {
@ -758,7 +753,6 @@ static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
dev_err(&ts->client->dev, "GTP send sleep cmd failed.\n"); dev_err(&ts->client->dev, "GTP send sleep cmd failed.\n");
return ret; return ret;
} }
#endif /* !GTP_SLIDE_WAKEUP */
/******************************************************* /*******************************************************
Function: Function:
@ -804,25 +798,26 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts)
"Wakeup sleep send config success."); "Wakeup sleep send config success.");
} else { } else {
err_retry: err_retry:
#if GTP_SLIDE_WAKEUP if (ts->pdata->slide_wakeup) { /* wakeup not by slide */
/* wakeup not by slide */
if (doze_status != DOZE_WAKEUP) if (doze_status != DOZE_WAKEUP)
gtp_reset_guitar(ts, 10); gtp_reset_guitar(ts, 10);
else else
/* wakeup by slide */ /* wakeup by slide */
doze_status = DOZE_DISABLED; doze_status = DOZE_DISABLED;
#else } else {
if (chip_gt9xxs == 1) { if (chip_gt9xxs == 1) {
gtp_reset_guitar(ts, 10); gtp_reset_guitar(ts, 10);
} else { } else {
ret = gpio_direction_output(ts->pdata->irq_gpio, 1); ret = gpio_direction_output(
usleep(5000); ts->pdata->irq_gpio, 1);
usleep_range(WAKE_UP_DELAY_US,
WAKE_UP_DELAY_US + 1);
}
} }
#endif
ret = gtp_i2c_test(ts->client); ret = gtp_i2c_test(ts->client);
if (ret == 2) { if (ret == 2) {
dev_dbg(&ts->client->dev, "GTP wakeup sleep."); dev_dbg(&ts->client->dev, "GTP wakeup sleep.");
#if (!GTP_SLIDE_WAKEUP) if (!ts->pdata->slide_wakeup) {
if (chip_gt9xxs == 0) { if (chip_gt9xxs == 0) {
gtp_int_sync(ts, 25); gtp_int_sync(ts, 25);
msleep(20); msleep(20);
@ -830,7 +825,7 @@ err_retry:
gtp_init_ext_watchdog(ts->client); gtp_init_ext_watchdog(ts->client);
#endif #endif
} }
#endif }
return ret; return ret;
} }
gtp_reset_guitar(ts, 20); gtp_reset_guitar(ts, 20);
@ -854,17 +849,16 @@ Output:
static int gtp_init_panel(struct goodix_ts_data *ts) static int gtp_init_panel(struct goodix_ts_data *ts)
{ {
struct i2c_client *client = ts->client; struct i2c_client *client = ts->client;
unsigned char *config_data; unsigned char *config_data = NULL;
int ret = -EIO; int ret = -EIO;
#if GTP_DRIVER_SEND_CFG
int i; int i;
u8 check_sum = 0; u8 check_sum = 0;
u8 opr_buf[16]; u8 opr_buf[16];
u8 sensor_id = 0; u8 sensor_id = 0;
if (ts->pdata->driver_send_cfg) {
for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++) for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
dev_dbg(&client->dev, "Config Groups(%d) Lengths: %d", dev_dbg(&client->dev, "Config Groups(%d) Lengths: %zu",
i, ts->pdata->config_data_len[i]); i, ts->pdata->config_data_len[i]);
ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1); ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);
@ -881,11 +875,12 @@ static int gtp_init_panel(struct goodix_ts_data *ts)
if (ts->pdata->config_data_len[i]) if (ts->pdata->config_data_len[i])
break; break;
} }
if (i == GOODIX_MAX_CFG_GROUP) { if (i == GOODIX_MAX_CFG_GROUP) {
sensor_id = 0; sensor_id = 0;
} else { } else {
ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, ret = gtp_i2c_read_dbl_check(ts->client,
&sensor_id, 1); GTP_REG_SENSOR_ID, &sensor_id, 1);
if (ret == SUCCESS) { if (ret == SUCCESS) {
if (sensor_id >= GOODIX_MAX_CFG_GROUP) { if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
dev_err(&client->dev, dev_err(&client->dev,
@ -900,9 +895,10 @@ static int gtp_init_panel(struct goodix_ts_data *ts)
} }
} }
dev_dbg(&client->dev, "Sensor ID selected: %d", sensor_id); dev_info(&client->dev, "Sensor ID selected: %d", sensor_id);
if (ts->pdata->config_data_len[sensor_id] < GTP_CONFIG_MIN_LENGTH || if (ts->pdata->config_data_len[sensor_id] <
GTP_CONFIG_MIN_LENGTH ||
!ts->pdata->config_data[sensor_id]) { !ts->pdata->config_data[sensor_id]) {
dev_err(&client->dev, dev_err(&client->dev,
"Sensor_ID(%d) matches with NULL or invalid config group!\n", "Sensor_ID(%d) matches with NULL or invalid config group!\n",
@ -916,9 +912,11 @@ static int gtp_init_panel(struct goodix_ts_data *ts)
if (opr_buf[0] < 90) { if (opr_buf[0] < 90) {
/* backup group config version */ /* backup group config version */
grp_cfg_version = grp_cfg_version =
ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH]; ts->pdata->
ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH] = config_data[sensor_id][GTP_ADDR_LENGTH];
0x00; ts->pdata->
config_data[sensor_id][GTP_ADDR_LENGTH]
= 0x00;
ts->fixed_cfg = 0; ts->fixed_cfg = 0;
} else { } else {
/* treated as fixed config, not send config */ /* treated as fixed config, not send config */
@ -959,7 +957,7 @@ static int gtp_init_panel(struct goodix_ts_data *ts)
config_data[ts->gtp_cfg_len] = (~check_sum) + 1; config_data[ts->gtp_cfg_len] = (~check_sum) + 1;
#else /* DRIVER NOT SEND CONFIG */ } else { /* DRIVER NOT SEND CONFIG */
ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH;
ret = gtp_i2c_read(ts->client, config_data, ret = gtp_i2c_read(ts->client, config_data,
ts->gtp_cfg_len + GTP_ADDR_LENGTH); ts->gtp_cfg_len + GTP_ADDR_LENGTH);
@ -970,7 +968,7 @@ static int gtp_init_panel(struct goodix_ts_data *ts)
ts->abs_y_max = GTP_MAX_HEIGHT; ts->abs_y_max = GTP_MAX_HEIGHT;
ts->int_trigger_type = GTP_INT_TRIGGER; ts->int_trigger_type = GTP_INT_TRIGGER;
} }
#endif /* !DRIVER NOT SEND CONFIG */ } /* !DRIVER NOT SEND CONFIG */
if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) { if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) {
ts->abs_x_max = (config_data[RESOLUTION_LOC + 1] << 8) ts->abs_x_max = (config_data[RESOLUTION_LOC + 1] << 8)
@ -1177,7 +1175,8 @@ static int gtp_request_irq(struct goodix_ts_data *ts)
int ret; int ret;
const u8 irq_table[] = GTP_IRQ_TAB; const u8 irq_table[] = GTP_IRQ_TAB;
GTP_DEBUG("INT trigger type:%x, irq=%d", ts->int_trigger_type, dev_dbg(&ts->client->dev, "INT trigger type:%x, irq=%d",
ts->int_trigger_type,
ts->client->irq); ts->client->irq);
ret = request_threaded_irq(ts->client->irq, NULL, ret = request_threaded_irq(ts->client->irq, NULL,
@ -1206,9 +1205,7 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts)
{ {
int ret; int ret;
char phys[PHY_BUF_SIZE]; char phys[PHY_BUF_SIZE];
#if GTP_HAVE_TOUCH_KEY
int index = 0; int index = 0;
#endif
ts->input_dev = input_allocate_device(); ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) { if (ts->input_dev == NULL) {
@ -1224,26 +1221,24 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts)
/* in case of "out of memory" */ /* in case of "out of memory" */
input_mt_init_slots(ts->input_dev, 10, 0); input_mt_init_slots(ts->input_dev, 10, 0);
if (ts->pdata->have_touch_key) {
for (index = 0; index < ts->pdata->num_button; index++) { for (index = 0; index < ts->pdata->num_button; index++) {
input_set_capability(ts->input_dev, input_set_capability(ts->input_dev,
EV_KEY, ts->pdata->button_map[index]); EV_KEY, ts->pdata->button_map[index]);
} }
}
if (ts->pdata->slide_wakeup)
#if GTP_SLIDE_WAKEUP
input_set_capability(ts->input_dev, EV_KEY, KEY_POWER); input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
#endif
#if GTP_WITH_PEN if (ts->pdata->with_pen) { /* pen support */
/* pen support */
__set_bit(BTN_TOOL_PEN, ts->input_dev->keybit); __set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
__set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit); __set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
#endif }
#if GTP_CHANGE_X2Y if (ts->pdata->change_x2y)
swap(ts->abs_x_max, ts->abs_y_max); swap(ts->abs_x_max, ts->abs_y_max);
#endif
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
0, ts->abs_x_max, 0, 0); 0, ts->abs_x_max, 0, 0);
@ -1283,7 +1278,7 @@ exit_free_inputdev:
static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA) static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
{ {
return (regulator_count_voltages(reg) > 0) ? return (regulator_count_voltages(reg) > 0) ?
regulator_set_optimum_mode(reg, load_uA) : 0; regulator_set_load(reg, load_uA) : 0;
} }
/** /**
@ -1828,7 +1823,7 @@ static int goodix_parse_dt(struct device *dev,
u32 temp_val, num_buttons; u32 temp_val, num_buttons;
u32 button_map[MAX_BUTTONS]; u32 button_map[MAX_BUTTONS];
char prop_name[PROP_NAME_SIZE]; char prop_name[PROP_NAME_SIZE];
int i, read_cfg_num; int i, read_cfg_num, temp;
rc = goodix_ts_get_dt_coords(dev, "goodix,panel-coords", pdata); rc = goodix_ts_get_dt_coords(dev, "goodix,panel-coords", pdata);
if (rc && (rc != -EINVAL)) if (rc && (rc != -EINVAL))
@ -1846,6 +1841,25 @@ static int goodix_parse_dt(struct device *dev,
pdata->enable_power_off = of_property_read_bool(np, pdata->enable_power_off = of_property_read_bool(np,
"goodix,enable-power-off"); "goodix,enable-power-off");
pdata->have_touch_key = of_property_read_bool(np,
"goodix,have-touch-key");
pdata->driver_send_cfg = of_property_read_bool(np,
"goodix,driver-send-cfg");
pdata->change_x2y = of_property_read_bool(np,
"goodix,change-x2y");
pdata->with_pen = of_property_read_bool(np,
"goodix,with-pen");
pdata->slide_wakeup = of_property_read_bool(np,
"goodix,slide-wakeup");
pdata->dbl_clk_wakeup = of_property_read_bool(np,
"goodix,dbl_clk_wakeup");
/* reset, irq gpio info */ /* reset, irq gpio info */
pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios",
0, &pdata->reset_gpio_flags); 0, &pdata->reset_gpio_flags);
@ -1891,14 +1905,15 @@ static int goodix_parse_dt(struct device *dev,
read_cfg_num = 0; read_cfg_num = 0;
for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++) { for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++) {
temp = 0;
snprintf(prop_name, sizeof(prop_name), "goodix,cfg-data%d", i); snprintf(prop_name, sizeof(prop_name), "goodix,cfg-data%d", i);
prop = of_find_property(np, prop_name, prop = of_find_property(np, prop_name, &temp);
&pdata->config_data_len[i]);
if (!prop || !prop->value) { if (!prop || !prop->value) {
pdata->config_data_len[i] = 0; pdata->config_data_len[i] = 0;
pdata->config_data[i] = NULL; pdata->config_data[i] = NULL;
continue; continue;
} }
pdata->config_data_len[i] = temp;
pdata->config_data[i] = devm_kzalloc(dev, pdata->config_data[i] = devm_kzalloc(dev,
GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH, GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH,
GFP_KERNEL); GFP_KERNEL);
@ -2101,8 +2116,6 @@ exit_free_irq:
#endif #endif
if (ts->use_irq) if (ts->use_irq)
free_irq(client->irq, ts); free_irq(client->irq, ts);
else
hrtimer_cancel(&ts->timer);
cancel_work_sync(&ts->work); cancel_work_sync(&ts->work);
flush_workqueue(ts->goodix_wq); flush_workqueue(ts->goodix_wq);
destroy_workqueue(ts->goodix_wq); destroy_workqueue(ts->goodix_wq);
@ -2166,8 +2179,6 @@ static int goodix_ts_remove(struct i2c_client *client)
if (ts) { if (ts) {
if (ts->use_irq) if (ts->use_irq)
free_irq(client->irq, ts); free_irq(client->irq, ts);
else
hrtimer_cancel(&ts->timer);
cancel_work_sync(&ts->work); cancel_work_sync(&ts->work);
flush_workqueue(ts->goodix_wq); flush_workqueue(ts->goodix_wq);
@ -2225,13 +2236,11 @@ static int goodix_ts_suspend(struct device *dev)
gtp_esd_switch(ts->client, SWITCH_OFF); gtp_esd_switch(ts->client, SWITCH_OFF);
#endif #endif
#if GTP_SLIDE_WAKEUP if (ts->pdata->slide_wakeup) {
ret = gtp_enter_doze(ts); ret = gtp_enter_doze(ts);
#else } else {
if (ts->use_irq) if (ts->use_irq)
gtp_irq_disable(ts); gtp_irq_disable(ts);
else
hrtimer_cancel(&ts->timer);
for (i = 0; i < GTP_MAX_TOUCH; i++) for (i = 0; i < GTP_MAX_TOUCH; i++)
gtp_touch_up(ts, i); gtp_touch_up(ts, i);
@ -2239,9 +2248,9 @@ static int goodix_ts_suspend(struct device *dev)
input_sync(ts->input_dev); input_sync(ts->input_dev);
ret = gtp_enter_sleep(ts); ret = gtp_enter_sleep(ts);
#endif
if (ret < 0) if (ret < 0)
dev_err(&ts->client->dev, "GTP early suspend failed\n"); dev_err(&ts->client->dev, "GTP early suspend failed.\n");
}
/* to avoid waking up while not sleeping, /* to avoid waking up while not sleeping,
* delay 48 + 10ms to ensure reliability * delay 48 + 10ms to ensure reliability
*/ */
@ -2273,18 +2282,14 @@ static int goodix_ts_resume(struct device *dev)
mutex_lock(&ts->lock); mutex_lock(&ts->lock);
ret = gtp_wakeup_sleep(ts); ret = gtp_wakeup_sleep(ts);
#if GTP_SLIDE_WAKEUP if (ts->pdata->slide_wakeup)
doze_status = DOZE_DISABLED; doze_status = DOZE_DISABLED;
#endif
if (ret <= 0) if (ret <= 0)
dev_err(&ts->client->dev, "GTP resume failed\n"); dev_err(&ts->client->dev, "GTP resume failed\n");
if (ts->use_irq) if (ts->use_irq)
gtp_irq_enable(ts); gtp_irq_enable(ts);
else
hrtimer_start(&ts->timer,
ktime_set(1, 0), HRTIMER_MODE_REL);
#if GTP_ESD_PROTECT #if GTP_ESD_PROTECT
gtp_esd_switch(ts->client, SWITCH_ON); gtp_esd_switch(ts->client, SWITCH_ON);

View file

@ -60,6 +60,12 @@ struct goodix_ts_platform_data {
u8 *config_data[GOODIX_MAX_CFG_GROUP]; u8 *config_data[GOODIX_MAX_CFG_GROUP];
u32 button_map[MAX_BUTTONS]; u32 button_map[MAX_BUTTONS];
u8 num_button; u8 num_button;
bool have_touch_key;
bool driver_send_cfg;
bool change_x2y;
bool with_pen;
bool slide_wakeup;
bool dbl_clk_wakeup;
}; };
struct goodix_ts_data { struct goodix_ts_data {
spinlock_t irq_lock; spinlock_t irq_lock;
@ -69,6 +75,7 @@ struct goodix_ts_data {
struct hrtimer timer; struct hrtimer timer;
struct workqueue_struct *goodix_wq; struct workqueue_struct *goodix_wq;
struct work_struct work; struct work_struct work;
char fw_name[GTP_FW_NAME_MAXSIZE];
struct delayed_work goodix_update_work; struct delayed_work goodix_update_work;
s32 irq_is_disabled; s32 irq_is_disabled;
s32 use_irq; s32 use_irq;
@ -107,17 +114,7 @@ extern u16 total_len;
/***************************PART1:ON/OFF define*******************************/ /***************************PART1:ON/OFF define*******************************/
#define GTP_CUSTOM_CFG 0 #define GTP_CUSTOM_CFG 0
#define GTP_CHANGE_X2Y 0
#define GTP_DRIVER_SEND_CFG 1
#define GTP_HAVE_TOUCH_KEY 1
#define GTP_ESD_PROTECT 0 #define GTP_ESD_PROTECT 0
#define GTP_WITH_PEN 0
/* This cannot work when enable-power-off is on */
#define GTP_SLIDE_WAKEUP 0
/* double-click wakeup, function together with GTP_SLIDE_WAKEUP */
#define GTP_DBL_CLK_WAKEUP 0
#define GTP_IRQ_TAB {\ #define GTP_IRQ_TAB {\
IRQ_TYPE_EDGE_RISING,\ IRQ_TYPE_EDGE_RISING,\

View file

@ -67,6 +67,8 @@
#define FAIL 0 #define FAIL 0
#define SUCCESS 1 #define SUCCESS 1
#define RESET_DELAY_US 20000
struct st_fw_head { struct st_fw_head {
u8 hw_info[4]; /* hardware info */ u8 hw_info[4]; /* hardware info */
u8 pid[8]; /* product id */ u8 pid[8]; /* product id */
@ -390,7 +392,7 @@ s32 gup_enter_update_mode(struct i2c_client *client)
/* step1:RST output low last at least 2ms */ /* step1:RST output low last at least 2ms */
gpio_direction_output(ts->pdata->reset_gpio, 0); gpio_direction_output(ts->pdata->reset_gpio, 0);
usleep(20000); usleep_range(RESET_DELAY_US, RESET_DELAY_US + 1);
/* step2:select I2C slave addr,INT:0--0xBA;1--0x28. */ /* step2:select I2C slave addr,INT:0--0xBA;1--0x28. */
gpio_direction_output(ts->pdata->irq_gpio, gpio_direction_output(ts->pdata->irq_gpio,
@ -565,8 +567,8 @@ static s8 gup_update_config(struct i2c_client *client,
!memcmp(&pid[GTP_ADDR_LENGTH], "960", 3)) { !memcmp(&pid[GTP_ADDR_LENGTH], "960", 3)) {
chip_cfg_len = 228; chip_cfg_len = 228;
} }
pr_debug("config file ASCII len:%d", cfg->size); pr_debug("config file ASCII len: %zu", cfg->size);
pr_debug("need config binary len:%d", chip_cfg_len); pr_debug("need config binary len: %u", chip_cfg_len);
if ((cfg->size + 5) < chip_cfg_len * 5) { if ((cfg->size + 5) < chip_cfg_len * 5) {
pr_err("Config length error"); pr_err("Config length error");
return -EINVAL; return -EINVAL;
@ -643,7 +645,7 @@ static s32 gup_get_firmware_file(struct i2c_client *client,
return -EEXIST; return -EEXIST;
} }
dev_dbg(&client->dev, "Config File: %s size=%d", path, fw->size); dev_dbg(&client->dev, "Config File: %s size: %zu", path, fw->size);
msg->fw_data = msg->fw_data =
devm_kzalloc(&client->dev, fw->size, GFP_KERNEL); devm_kzalloc(&client->dev, fw->size, GFP_KERNEL);
if (!msg->fw_data) { if (!msg->fw_data) {