Merge "input: touchscreen: fix compilation errors for Goodix driver"
This commit is contained in:
commit
970b543f51
5 changed files with 339 additions and 326 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -301,11 +300,11 @@ static s32 fill_update_info(char __user *user_buf,
|
||||||
* Function:
|
* Function:
|
||||||
* Goodix tool write function.
|
* Goodix tool write function.
|
||||||
* Input:
|
* Input:
|
||||||
* standard proc write function param.
|
* standard proc write function param.
|
||||||
* 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(>_client->dev, "wr:0x%02x, flag:0x%02x, flag addr:0x%02x%02x,
|
dev_dbg(>_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(>_client->dev,
|
||||||
cmd_head.flag_relation);
|
"flag val:0x%02x, flag rel:0x%02x,\n", cmd_head.flag_val,
|
||||||
dev_dbg(>_client->dev, "circle:%d, times:%d, retry:%d, delay:%d,
|
cmd_head.flag_relation);
|
||||||
data len:%d, addr len:%d, addr:0x%02x%02x, write len: %d",
|
dev_dbg(>_client->dev, "circle:%u, times:%u, retry:%u, delay:%u\n",
|
||||||
(s32)cmd_head.circle, (s32)cmd_head.times, (s32)cmd_head.retry,
|
(s32) cmd_head.circle, (s32) cmd_head.times,
|
||||||
(s32)cmd_head.delay, (s32)cmd_head.data_len,
|
(s32) cmd_head.retry, (s32)cmd_head.delay);
|
||||||
(s32)cmd_head.addr_len, cmd_head.addr[0], cmd_head.addr[1],
|
dev_dbg(>_client->dev,
|
||||||
(s32)count);
|
"data len:%u, addr len:%u, addr:0x%02x%02x, write len: %u\n",
|
||||||
|
(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(>_client->dev, "data len %d > data buff %d, rejected\n",
|
dev_err(>_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(>_client->dev,
|
dev_err(>_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(>_client->dev, "data len %d > data buff %d, rejected\n",
|
dev_err(>_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;
|
||||||
|
@ -470,11 +471,11 @@ exit:
|
||||||
* Function:
|
* Function:
|
||||||
* Goodix tool read function.
|
* Goodix tool read function.
|
||||||
* Input:
|
* Input:
|
||||||
* standard proc read function param.
|
* standard proc read function param.
|
||||||
* 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;
|
||||||
|
|
|
@ -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,24 +267,25 @@ 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->fixed_cfg) {
|
if (ts->pdata->driver_send_cfg) {
|
||||||
dev_dbg(&ts->client->dev,
|
if (ts->fixed_cfg) {
|
||||||
"Ic fixed config, no config sent!");
|
dev_dbg(&ts->client->dev,
|
||||||
ret = 2;
|
"Ic fixed config, no config sent!");
|
||||||
} else {
|
ret = 2;
|
||||||
for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
|
} else {
|
||||||
ret = gtp_i2c_write(ts->client,
|
for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
|
||||||
ts->config_data,
|
ret = gtp_i2c_write(ts->client,
|
||||||
GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH);
|
ts->config_data,
|
||||||
if (ret > 0)
|
GTP_CONFIG_MAX_LENGTH +
|
||||||
break;
|
GTP_ADDR_LENGTH);
|
||||||
|
if (ret > 0)
|
||||||
|
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,55 +409,59 @@ 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) {
|
||||||
if (doze_buf[2] == 0xAA) {
|
if (doze_buf[2] == 0xAA) {
|
||||||
dev_dbg(&ts->client->dev,
|
dev_dbg(&ts->client->dev,
|
||||||
"Slide(0xAA) To Light up the screen!");
|
"Slide(0xAA) To Light up the screen!");
|
||||||
doze_status = DOZE_WAKEUP;
|
doze_status = DOZE_WAKEUP;
|
||||||
input_report_key(
|
input_report_key(
|
||||||
ts->input_dev, KEY_POWER, 1);
|
ts->input_dev, KEY_POWER, 1);
|
||||||
input_sync(ts->input_dev);
|
input_sync(ts->input_dev);
|
||||||
input_report_key(
|
input_report_key(
|
||||||
ts->input_dev, KEY_POWER, 0);
|
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;
|
||||||
gtp_i2c_write(ts->client, doze_buf, 3);
|
gtp_i2c_write(ts->client, doze_buf, 3);
|
||||||
} else if (doze_buf[2] == 0xBB) {
|
} else if (doze_buf[2] == 0xBB) {
|
||||||
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,
|
||||||
input_sync(ts->input_dev);
|
KEY_POWER, 1);
|
||||||
input_report_key(ts->input_dev, KEY_POWER, 0);
|
input_sync(ts->input_dev);
|
||||||
input_sync(ts->input_dev);
|
input_report_key(ts->input_dev,
|
||||||
/* clear 0x814B*/
|
KEY_POWER, 0);
|
||||||
doze_buf[2] = 0x00;
|
input_sync(ts->input_dev);
|
||||||
gtp_i2c_write(ts->client, doze_buf, 3);
|
/* clear 0x814B*/
|
||||||
} else if (0xC0 == (doze_buf[2] & 0xC0)) {
|
doze_buf[2] = 0x00;
|
||||||
dev_dbg(&ts->client->dev,
|
gtp_i2c_write(ts->client, doze_buf, 3);
|
||||||
"double click to light up the screen!");
|
} else if (0xC0 == (doze_buf[2] & 0xC0)) {
|
||||||
doze_status = DOZE_WAKEUP;
|
dev_dbg(&ts->client->dev,
|
||||||
input_report_key(ts->input_dev, KEY_POWER, 1);
|
"double click to light up the screen!");
|
||||||
input_sync(ts->input_dev);
|
doze_status = DOZE_WAKEUP;
|
||||||
input_report_key(ts->input_dev, KEY_POWER, 0);
|
input_report_key(ts->input_dev,
|
||||||
input_sync(ts->input_dev);
|
KEY_POWER, 1);
|
||||||
/* clear 0x814B */
|
input_sync(ts->input_dev);
|
||||||
doze_buf[2] = 0x00;
|
input_report_key(ts->input_dev,
|
||||||
gtp_i2c_write(ts->client, doze_buf, 3);
|
KEY_POWER, 0);
|
||||||
} else {
|
input_sync(ts->input_dev);
|
||||||
gtp_enter_doze(ts);
|
/* clear 0x814B */
|
||||||
|
doze_buf[2] = 0x00;
|
||||||
|
gtp_i2c_write(ts->client, doze_buf, 3);
|
||||||
|
} else {
|
||||||
|
gtp_enter_doze(ts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (ts->use_irq)
|
||||||
if (ts->use_irq)
|
gtp_irq_enable(ts);
|
||||||
gtp_irq_enable(ts);
|
|
||||||
|
|
||||||
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,15 +502,16 @@ 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);
|
||||||
input_mt_slot(ts->input_dev, 5);
|
input_mt_slot(ts->input_dev, 5);
|
||||||
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,45 +519,45 @@ 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,
|
||||||
"Pen touch DOWN(Slot)!");
|
"Pen touch DOWN(Slot)!");
|
||||||
input_x = coor_data[pos + 1]
|
input_x = coor_data[pos + 1]
|
||||||
| (coor_data[pos + 2] << 8);
|
| (coor_data[pos + 2] << 8);
|
||||||
input_y = coor_data[pos + 3]
|
input_y = coor_data[pos + 3]
|
||||||
| (coor_data[pos + 4] << 8);
|
| (coor_data[pos + 4] << 8);
|
||||||
input_w = coor_data[pos + 5]
|
input_w = coor_data[pos + 5]
|
||||||
| (coor_data[pos + 6] << 8);
|
| (coor_data[pos + 6] << 8);
|
||||||
|
|
||||||
input_report_key(ts->input_dev,
|
input_report_key(ts->input_dev,
|
||||||
BTN_TOOL_PEN, 1);
|
BTN_TOOL_PEN, 1);
|
||||||
input_mt_slot(ts->input_dev, 5);
|
input_mt_slot(ts->input_dev, 5);
|
||||||
input_report_abs(ts->input_dev,
|
input_report_abs(ts->input_dev,
|
||||||
ABS_MT_TRACKING_ID, 5);
|
ABS_MT_TRACKING_ID, 5);
|
||||||
input_report_abs(ts->input_dev,
|
input_report_abs(ts->input_dev,
|
||||||
ABS_MT_POSITION_X, input_x);
|
ABS_MT_POSITION_X, input_x);
|
||||||
input_report_abs(ts->input_dev,
|
input_report_abs(ts->input_dev,
|
||||||
ABS_MT_POSITION_Y, input_y);
|
ABS_MT_POSITION_Y, input_y);
|
||||||
input_report_abs(ts->input_dev,
|
input_report_abs(ts->input_dev,
|
||||||
ABS_MT_TOUCH_MAJOR, input_w);
|
ABS_MT_TOUCH_MAJOR, input_w);
|
||||||
dev_dbg(&ts->client->dev,
|
dev_dbg(&ts->client->dev,
|
||||||
"Pen/Stylus: (%d, %d)[%d]",
|
"Pen/Stylus: (%d, %d)[%d]",
|
||||||
input_x, input_y, input_w);
|
input_x, input_y, input_w);
|
||||||
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,33 +798,34 @@ 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
|
|
||||||
if (chip_gt9xxs == 1) {
|
|
||||||
gtp_reset_guitar(ts, 10);
|
|
||||||
} else {
|
} else {
|
||||||
ret = gpio_direction_output(ts->pdata->irq_gpio, 1);
|
if (chip_gt9xxs == 1) {
|
||||||
usleep(5000);
|
gtp_reset_guitar(ts, 10);
|
||||||
|
} else {
|
||||||
|
ret = gpio_direction_output(
|
||||||
|
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);
|
||||||
#if GTP_ESD_PROTECT
|
#if GTP_ESD_PROTECT
|
||||||
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,123 +849,126 @@ 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;
|
||||||
|
|
||||||
for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
|
if (ts->pdata->driver_send_cfg) {
|
||||||
dev_dbg(&client->dev, "Config Groups(%d) Lengths: %d",
|
for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
|
||||||
i, ts->pdata->config_data_len[i]);
|
dev_dbg(&client->dev, "Config Groups(%d) Lengths: %zu",
|
||||||
|
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);
|
||||||
if (ret == SUCCESS) {
|
if (ret == SUCCESS) {
|
||||||
if (opr_buf[0] != 0xBE) {
|
if (opr_buf[0] != 0xBE) {
|
||||||
ts->fw_error = 1;
|
ts->fw_error = 1;
|
||||||
|
dev_err(&client->dev,
|
||||||
|
"Firmware error, no config sent!");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < GOODIX_MAX_CFG_GROUP; i++) {
|
||||||
|
if (ts->pdata->config_data_len[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == GOODIX_MAX_CFG_GROUP) {
|
||||||
|
sensor_id = 0;
|
||||||
|
} else {
|
||||||
|
ret = gtp_i2c_read_dbl_check(ts->client,
|
||||||
|
GTP_REG_SENSOR_ID, &sensor_id, 1);
|
||||||
|
if (ret == SUCCESS) {
|
||||||
|
if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
|
||||||
|
dev_err(&client->dev,
|
||||||
|
"Invalid sensor_id(0x%02X), No Config Sent!",
|
||||||
|
sensor_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dev_err(&client->dev,
|
||||||
|
"Failed to get sensor_id, No config sent!");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&client->dev, "Sensor ID selected: %d", sensor_id);
|
||||||
|
|
||||||
|
if (ts->pdata->config_data_len[sensor_id] <
|
||||||
|
GTP_CONFIG_MIN_LENGTH ||
|
||||||
|
!ts->pdata->config_data[sensor_id]) {
|
||||||
dev_err(&client->dev,
|
dev_err(&client->dev,
|
||||||
"Firmware error, no config sent!");
|
"Sensor_ID(%d) matches with NULL or invalid config group!\n",
|
||||||
|
sensor_id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < GOODIX_MAX_CFG_GROUP; i++) {
|
ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA,
|
||||||
if (ts->pdata->config_data_len[i])
|
&opr_buf[0], 1);
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == GOODIX_MAX_CFG_GROUP) {
|
|
||||||
sensor_id = 0;
|
|
||||||
} else {
|
|
||||||
ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID,
|
|
||||||
&sensor_id, 1);
|
|
||||||
if (ret == SUCCESS) {
|
if (ret == SUCCESS) {
|
||||||
if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
|
if (opr_buf[0] < 90) {
|
||||||
dev_err(&client->dev,
|
/* backup group config version */
|
||||||
"Invalid sensor_id(0x%02X), No Config Sent!",
|
grp_cfg_version =
|
||||||
sensor_id);
|
ts->pdata->
|
||||||
return -EINVAL;
|
config_data[sensor_id][GTP_ADDR_LENGTH];
|
||||||
|
ts->pdata->
|
||||||
|
config_data[sensor_id][GTP_ADDR_LENGTH]
|
||||||
|
= 0x00;
|
||||||
|
ts->fixed_cfg = 0;
|
||||||
|
} else {
|
||||||
|
/* treated as fixed config, not send config */
|
||||||
|
dev_warn(&client->dev,
|
||||||
|
"Ic fixed config with config version(%d, 0x%02X)",
|
||||||
|
opr_buf[0], opr_buf[0]);
|
||||||
|
ts->fixed_cfg = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dev_err(&client->dev,
|
dev_err(&client->dev,
|
||||||
"Failed to get sensor_id, No config sent!");
|
"Failed to get ic config version!No config sent!");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(&client->dev, "Sensor ID selected: %d", sensor_id);
|
config_data = ts->pdata->config_data[sensor_id];
|
||||||
|
ts->config_data = ts->pdata->config_data[sensor_id];
|
||||||
if (ts->pdata->config_data_len[sensor_id] < GTP_CONFIG_MIN_LENGTH ||
|
ts->gtp_cfg_len = ts->pdata->config_data_len[sensor_id];
|
||||||
!ts->pdata->config_data[sensor_id]) {
|
|
||||||
dev_err(&client->dev,
|
|
||||||
"Sensor_ID(%d) matches with NULL or invalid config group!\n",
|
|
||||||
sensor_id);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA,
|
|
||||||
&opr_buf[0], 1);
|
|
||||||
if (ret == SUCCESS) {
|
|
||||||
if (opr_buf[0] < 90) {
|
|
||||||
/* backup group config version */
|
|
||||||
grp_cfg_version =
|
|
||||||
ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH];
|
|
||||||
ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH] =
|
|
||||||
0x00;
|
|
||||||
ts->fixed_cfg = 0;
|
|
||||||
} else {
|
|
||||||
/* treated as fixed config, not send config */
|
|
||||||
dev_warn(&client->dev,
|
|
||||||
"Ic fixed config with config version(%d, 0x%02X)",
|
|
||||||
opr_buf[0], opr_buf[0]);
|
|
||||||
ts->fixed_cfg = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dev_err(&client->dev,
|
|
||||||
"Failed to get ic config version!No config sent!");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_data = ts->pdata->config_data[sensor_id];
|
|
||||||
ts->config_data = ts->pdata->config_data[sensor_id];
|
|
||||||
ts->gtp_cfg_len = ts->pdata->config_data_len[sensor_id];
|
|
||||||
|
|
||||||
#if GTP_CUSTOM_CFG
|
#if GTP_CUSTOM_CFG
|
||||||
config_data[RESOLUTION_LOC] =
|
config_data[RESOLUTION_LOC] =
|
||||||
(unsigned char)(GTP_MAX_WIDTH && 0xFF);
|
(unsigned char)(GTP_MAX_WIDTH && 0xFF);
|
||||||
config_data[RESOLUTION_LOC + 1] =
|
config_data[RESOLUTION_LOC + 1] =
|
||||||
(unsigned char)(GTP_MAX_WIDTH >> 8);
|
(unsigned char)(GTP_MAX_WIDTH >> 8);
|
||||||
config_data[RESOLUTION_LOC + 2] =
|
config_data[RESOLUTION_LOC + 2] =
|
||||||
(unsigned char)(GTP_MAX_HEIGHT && 0xFF);
|
(unsigned char)(GTP_MAX_HEIGHT && 0xFF);
|
||||||
config_data[RESOLUTION_LOC + 3] =
|
config_data[RESOLUTION_LOC + 3] =
|
||||||
(unsigned char)(GTP_MAX_HEIGHT >> 8);
|
(unsigned char)(GTP_MAX_HEIGHT >> 8);
|
||||||
|
|
||||||
if (GTP_INT_TRIGGER == 0)
|
if (GTP_INT_TRIGGER == 0)
|
||||||
config_data[TRIGGER_LOC] &= 0xfe;
|
config_data[TRIGGER_LOC] &= 0xfe;
|
||||||
else if (GTP_INT_TRIGGER == 1)
|
else if (GTP_INT_TRIGGER == 1)
|
||||||
config_data[TRIGGER_LOC] |= 0x01;
|
config_data[TRIGGER_LOC] |= 0x01;
|
||||||
#endif /* !GTP_CUSTOM_CFG */
|
#endif /* !GTP_CUSTOM_CFG */
|
||||||
|
|
||||||
check_sum = 0;
|
check_sum = 0;
|
||||||
for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
|
for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
|
||||||
check_sum += config_data[i];
|
check_sum += config_data[i];
|
||||||
|
|
||||||
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);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&client->dev,
|
dev_err(&client->dev,
|
||||||
"Read Config Failed, Using DEFAULT Resolution & INT Trigger!\n");
|
"Read Config Failed, Using DEFAULT Resolution & INT Trigger!\n");
|
||||||
ts->abs_x_max = GTP_MAX_WIDTH;
|
ts->abs_x_max = GTP_MAX_WIDTH;
|
||||||
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);
|
||||||
|
|
||||||
for (index = 0; index < ts->pdata->num_button; index++) {
|
if (ts->pdata->have_touch_key) {
|
||||||
input_set_capability(ts->input_dev,
|
for (index = 0; index < ts->pdata->num_button; index++) {
|
||||||
|
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)
|
||||||
|
input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
|
||||||
|
|
||||||
#if GTP_SLIDE_WAKEUP
|
if (ts->pdata->with_pen) { /* pen support */
|
||||||
input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
|
__set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
|
||||||
#endif
|
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
|
||||||
|
__set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
|
||||||
|
}
|
||||||
|
|
||||||
#if GTP_WITH_PEN
|
if (ts->pdata->change_x2y)
|
||||||
/* pen support */
|
swap(ts->abs_x_max, ts->abs_y_max);
|
||||||
__set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
|
|
||||||
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
|
|
||||||
__set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GTP_CHANGE_X2Y
|
|
||||||
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,23 +2236,21 @@ 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);
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -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,\
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue