diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-08-18 12:03:54 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-08-18 12:03:54 -0700 |
commit | a18fa34ff288a8df05224c95c9bd7679cf740a43 (patch) | |
tree | 910fc1f455264f8877af2f9bfc883819979bc49f /drivers/input | |
parent | 86f3aea3e0ef79b4d4500b4276bc316ceb454e36 (diff) | |
parent | fe7a0cf51a101ebb5639ba4190dcc49d1502bf11 (diff) |
Merge "input: msg21xx_ts: Mstar touch driver optimization"
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/msg21xx_ts.c | 1455 |
1 files changed, 761 insertions, 694 deletions
diff --git a/drivers/input/touchscreen/msg21xx_ts.c b/drivers/input/touchscreen/msg21xx_ts.c index 8f2c4da578fc..fe8c6e1647f8 100644 --- a/drivers/input/touchscreen/msg21xx_ts.c +++ b/drivers/input/touchscreen/msg21xx_ts.c @@ -30,10 +30,8 @@ #include <linux/init.h> #include <linux/mutex.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/firmware.h> -#include <linux/string.h> -#include <linux/kthread.h> +#include <linux/debugfs.h> #include <linux/regulator/consumer.h> #if defined(CONFIG_FB) @@ -67,6 +65,13 @@ #define MSTAR_CHIPTOP_REGISTER_BANK 0x1E #define MSTAR_CHIPTOP_REGISTER_ICTYPE 0xCC #define MSTAR_INIT_SW_ID 0x7FF +#define MSTAR_DEBUG_DIR_NAME "ts_debug" + +#define MSG_FW_FILE_MAJOR_VERSION(x) \ + (((x)->data[0x7f4f] << 8) + ((x)->data[0x7f4e])) + +#define MSG_FW_FILE_MINOR_VERSION(x) \ + (((x)->data[0x7f51] << 8) + ((x)->data[0x7f50])) /* * Note. @@ -89,7 +94,6 @@ static unsigned char MSG_FIRMWARE[1][33*1024] = { { #endif #define CONFIG_TP_HAVE_KEY - #define PINCTRL_STATE_ACTIVE "pmx_ts_active" #define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" #define PINCTRL_STATE_RELEASE "pmx_ts_release" @@ -97,30 +101,16 @@ static unsigned char MSG_FIRMWARE[1][33*1024] = { { #define SLAVE_I2C_ID_DBBUS (0xC4>>1) #define DEMO_MODE_PACKET_LENGTH (8) -#define MAX_TOUCH_NUM (2) #define TP_PRINT -#ifdef TP_PRINT -static int tp_print_proc_read(void); -static void tp_print_create_entry(void); -#endif static char *fw_version; /* customer firmware version */ static unsigned short fw_version_major; static unsigned short fw_version_minor; static unsigned char temp[94][1024]; static unsigned int crc32_table[256]; -static int FwDataCnt; -static unsigned char bFwUpdating; -static struct class *firmware_class; -static struct device *firmware_cmd_dev; -static struct i2c_client *i2c_client; - -static u32 button_map[MAX_BUTTONS]; -static u32 num_buttons; - -static unsigned short update_bin_major, update_bin_minor; +static unsigned short fw_file_major, fw_file_minor; static unsigned short main_sw_id = MSTAR_INIT_SW_ID; static unsigned short info_sw_id = MSTAR_INIT_SW_ID; static unsigned int bin_conf_crc32; @@ -128,15 +118,12 @@ static unsigned int bin_conf_crc32; struct msg21xx_ts_platform_data { const char *name; char fw_name[MSTAR_FW_NAME_MAX_LEN]; - char *fw_version; - unsigned short fw_version_major; - unsigned short fw_version_minor; - u32 irqflags; + u8 fw_version_major; + u8 fw_version_minor; u32 irq_gpio; u32 irq_gpio_flags; u32 reset_gpio; u32 reset_gpio_flags; - u32 family_id; u32 x_max; u32 y_max; u32 x_min; @@ -153,26 +140,33 @@ struct msg21xx_ts_platform_data { int (*power_on)(bool); int (*power_init)(bool); int (*power_on)(bool); + u8 ic_type; + u32 button_map[MAX_BUTTONS]; + u32 num_buttons; + u32 hard_reset_delay_ms; + u32 post_hard_reset_delay_ms; + bool updating_fw; +}; + +/* Touch Data Type Definition */ +struct touchPoint_t { + unsigned short x; + unsigned short y; }; -static struct msg21xx_ts_platform_data *pdata; +struct touchInfo_t { + struct touchPoint_t *point; + unsigned char count; + unsigned char keycode; +}; struct msg21xx_ts_data { struct i2c_client *client; struct input_dev *input_dev; - const struct msg21xx_ts_platform_data *pdata; + struct msg21xx_ts_platform_data *pdata; struct regulator *vdd; struct regulator *vcc_i2c; - bool loading_fw; - u8 family_id; - struct dentry *dir; - u16 addr; bool suspended; - char *ts_info; - u8 *tch_data; - u32 tch_data_len; - u8 fw_ver[3]; - u8 fw_vendor_id; #if defined(CONFIG_FB) struct notifier_block fb_notif; #endif @@ -181,10 +175,9 @@ struct msg21xx_ts_data { struct pinctrl_state *pinctrl_state_suspend; struct pinctrl_state *pinctrl_state_release; struct mutex ts_mutex; + struct touchInfo_t info; }; -static struct msg21xx_ts_data *ts_data; - #if defined(CONFIG_FB) static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); @@ -195,23 +188,15 @@ static unsigned char bEnableTpProximity; static unsigned char bFaceClosingTp; #endif -static struct mutex msg21xx_mutex; -static struct input_dev *input_dev; - - -/* Data Type Definition */ +#ifdef TP_PRINT +static int tp_print_proc_read(struct msg21xx_ts_data *ts_data); +static void tp_print_create_entry(struct msg21xx_ts_data *ts_data); +#endif -struct touchPoint_t { - unsigned short x; - unsigned short y; -}; - -struct touchInfo_t { - struct touchPoint_t point[MAX_TOUCH_NUM]; - unsigned char count; - unsigned char keycode; -}; +static void _ReadBinConfig(struct msg21xx_ts_data *ts_data); +static unsigned int _CalMainCRC32(struct msg21xx_ts_data *ts_data); +static struct mutex msg21xx_mutex; enum EMEM_TYPE_t { EMEM_ALL = 0, @@ -259,26 +244,25 @@ static void _CRC_initTable(void) } } -static void reset_hw(void) +static void msg21xx_reset_hw(struct msg21xx_ts_platform_data *pdata) { - DBG("reset_hw()\n"); - gpio_direction_output(pdata->reset_gpio, 1); gpio_set_value_cansleep(pdata->reset_gpio, 0); - msleep(100); /* Note that the RST must be in LOW 10ms at least */ + /* Note that the RST must be in LOW 10ms at least */ + usleep(pdata->hard_reset_delay_ms * 1000); gpio_set_value_cansleep(pdata->reset_gpio, 1); /* Enable the interrupt service thread/routine for INT after 50ms */ - msleep(100); + usleep(pdata->post_hard_reset_delay_ms * 1000); } -static int read_i2c_seq(unsigned char addr, unsigned char *buf, - unsigned short size) +static int read_i2c_seq(struct msg21xx_ts_data *ts_data, unsigned char addr, + unsigned char *buf, unsigned short size) { int rc = 0; struct i2c_msg msgs[] = { { .addr = addr, - .flags = I2C_M_RD, /* read flag*/ + .flags = I2C_M_RD, /* read flag */ .len = size, .buf = buf, }, @@ -287,25 +271,27 @@ static int read_i2c_seq(unsigned char addr, unsigned char *buf, /* If everything went ok (i.e. 1 msg transmitted), return #bytes * transmitted, else error code. */ - if (i2c_client != NULL) { - rc = i2c_transfer(i2c_client->adapter, msgs, 1); + if (ts_data->client != NULL) { + rc = i2c_transfer(ts_data->client->adapter, msgs, 1); if (rc < 0) - DBG("read_i2c_seq() error %d\n", rc); + dev_err(&ts_data->client->dev, + "%s error %d\n", __func__, rc); } else { - DBG("i2c_client is NULL\n"); + dev_err(&ts_data->client->dev, "ts_data->client is NULL\n"); } return rc; } -static int write_i2c_seq(unsigned char addr, unsigned char *buf, - unsigned short size) +static int write_i2c_seq(struct msg21xx_ts_data *ts_data, unsigned char addr, + unsigned char *buf, unsigned short size) { int rc = 0; struct i2c_msg msgs[] = { { .addr = addr, - /* if read flag is undefined, + /* + * if read flag is undefined, * then it means write flag. */ .flags = 0, @@ -314,48 +300,55 @@ static int write_i2c_seq(unsigned char addr, unsigned char *buf, }, }; - /* If everything went ok (i.e. 1 msg transmitted), return #bytes + /* + * If everything went ok (i.e. 1 msg transmitted), return #bytes * transmitted, else error code. */ - if (i2c_client != NULL) { - rc = i2c_transfer(i2c_client->adapter, msgs, 1); + if (ts_data->client != NULL) { + rc = i2c_transfer(ts_data->client->adapter, msgs, 1); if (rc < 0) - DBG("write_i2c_seq() error %d\n", rc); + dev_err(&ts_data->client->dev, + "%s error %d\n", __func__, rc); } else { - DBG("i2c_client is NULL\n"); + dev_err(&ts_data->client->dev, "ts_data->client is NULL\n"); } return rc; } -static unsigned short read_reg(unsigned char bank, unsigned char addr) +static unsigned short read_reg(struct msg21xx_ts_data *ts_data, + unsigned char bank, unsigned char addr) { unsigned char tx_data[3] = {0x10, bank, addr}; unsigned char rx_data[2] = {0}; - write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 3); - read_i2c_seq(SLAVE_I2C_ID_DBBUS, &rx_data[0], 2); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, tx_data, sizeof(tx_data)); + read_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, rx_data, sizeof(rx_data)); return rx_data[1] << 8 | rx_data[0]; } -static void write_reg(unsigned char bank, unsigned char addr, +static void write_reg(struct msg21xx_ts_data *ts_data, unsigned char bank, + unsigned char addr, unsigned short data) { unsigned char tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8}; write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 5); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, tx_data, sizeof(tx_data)); } -static void write_reg_8bit(unsigned char bank, unsigned char addr, +static void write_reg_8bit(struct msg21xx_ts_data *ts_data, unsigned char bank, + unsigned char addr, unsigned char data) { unsigned char tx_data[4] = {0x10, bank, addr, data}; write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 4); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, tx_data, sizeof(tx_data)); } -static void dbbusDWIICEnterSerialDebugMode(void) +static void dbbusDWIICEnterSerialDebugMode(struct msg21xx_ts_data *ts_data) { unsigned char data[5]; @@ -366,120 +359,109 @@ static void dbbusDWIICEnterSerialDebugMode(void) data[3] = 0x44; data[4] = 0x42; - write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 5); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data)); } -static void dbbusDWIICStopMCU(void) +static void dbbusDWIICStopMCU(struct msg21xx_ts_data *ts_data) { unsigned char data[1]; /* Stop the MCU */ data[0] = 0x37; - write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data)); } -static void dbbusDWIICIICUseBus(void) +static void dbbusDWIICIICUseBus(struct msg21xx_ts_data *ts_data) { unsigned char data[1]; /* IIC Use Bus */ data[0] = 0x35; - write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data)); } -static void dbbusDWIICIICReshape(void) +static void dbbusDWIICIICReshape(struct msg21xx_ts_data *ts_data) { unsigned char data[1]; /* IIC Re-shape */ data[0] = 0x71; - write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1); + write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data)); } -static unsigned char get_ic_type(void) +static unsigned char msg21xx_get_ic_type(struct msg21xx_ts_data *ts_data) { unsigned char ic_type = 0; unsigned char bank; unsigned char addr; - reset_hw(); - dbbusDWIICEnterSerialDebugMode(); - dbbusDWIICStopMCU(); - dbbusDWIICIICUseBus(); - dbbusDWIICIICReshape(); + msg21xx_reset_hw(ts_data->pdata); + dbbusDWIICEnterSerialDebugMode(ts_data); + dbbusDWIICStopMCU(ts_data); + dbbusDWIICIICUseBus(ts_data); + dbbusDWIICIICReshape(ts_data); msleep(300); /* stop mcu */ - write_reg_8bit(0x0F, 0xE6, 0x01); + write_reg_8bit(ts_data, 0x0F, 0xE6, 0x01); /* disable watch dog */ - write_reg(0x3C, 0x60, 0xAA55); + write_reg(ts_data, 0x3C, 0x60, 0xAA55); /* get ic type */ bank = MSTAR_CHIPTOP_REGISTER_BANK; addr = MSTAR_CHIPTOP_REGISTER_ICTYPE; - ic_type = (0xff)&(read_reg(bank, addr)); + ic_type = (0xff)&(read_reg(ts_data, bank, addr)); - if (ic_type != 1 /* msg2133 */ - && ic_type != 2 /* msg21xxA */ - && ic_type != 3) /* msg26xxM */ { + if (ic_type != ts_data->pdata->ic_type) ic_type = 0; - } - reset_hw(); + msg21xx_reset_hw(ts_data->pdata); return ic_type; } -static int msg21xx_read_firmware_id(void) +static int msg21xx_read_firmware_id(struct msg21xx_ts_data *ts_data) { - unsigned char dbbus_tx_data[3] = {0}; - unsigned char dbbus_rx_data[4] = {0}; - int ret = 0; + unsigned char command[3] = { 0x53, 0x00, 0x2A}; + unsigned char response[4] = { 0 }; - dbbus_tx_data[0] = 0x53; - dbbus_tx_data[1] = 0x00; - dbbus_tx_data[2] = 0x2A; mutex_lock(&msg21xx_mutex); - write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3); - read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4); + write_i2c_seq(ts_data, ts_data->client->addr, command, sizeof(command)); + read_i2c_seq(ts_data, ts_data->client->addr, response, + sizeof(response)); mutex_unlock(&msg21xx_mutex); - pdata->fw_version_major = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0]; - pdata->fw_version_minor = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2]; - - dev_dbg(&i2c_client->dev, "major num = %d, minor num = %d\n", - pdata->fw_version_major, pdata->fw_version_minor); - - if (pdata->fw_version == NULL) - pdata->fw_version = kzalloc(sizeof(char), GFP_KERNEL); + ts_data->pdata->fw_version_major = (response[1]<<8) + response[0]; + ts_data->pdata->fw_version_minor = (response[3]<<8) + response[2]; - snprintf(pdata->fw_version, sizeof(char) * 7, "%03d%03d", - pdata->fw_version_major, - pdata->fw_version_minor); + dev_info(&ts_data->client->dev, "major num = %d, minor num = %d\n", + ts_data->pdata->fw_version_major, + ts_data->pdata->fw_version_minor); - return ret; + return 0; } -static int firmware_erase_c33(enum EMEM_TYPE_t emem_type) +static int firmware_erase_c33(struct msg21xx_ts_data *ts_data, + enum EMEM_TYPE_t emem_type) { /* stop mcu */ - write_reg(0x0F, 0xE6, 0x0001); + write_reg(ts_data, 0x0F, 0xE6, 0x0001); /* disable watch dog */ - write_reg_8bit(0x3C, 0x60, 0x55); - write_reg_8bit(0x3C, 0x61, 0xAA); + write_reg_8bit(ts_data, 0x3C, 0x60, 0x55); + write_reg_8bit(ts_data, 0x3C, 0x61, 0xAA); /* set PROGRAM password */ - write_reg_8bit(0x16, 0x1A, 0xBA); - write_reg_8bit(0x16, 0x1B, 0xAB); + write_reg_8bit(ts_data, 0x16, 0x1A, 0xBA); + write_reg_8bit(ts_data, 0x16, 0x1B, 0xAB); - write_reg_8bit(0x16, 0x18, 0x80); + write_reg_8bit(ts_data, 0x16, 0x18, 0x80); if (emem_type == EMEM_ALL) - write_reg_8bit(0x16, 0x08, 0x10); + write_reg_8bit(ts_data, 0x16, 0x08, 0x10); - write_reg_8bit(0x16, 0x18, 0x40); + write_reg_8bit(ts_data, 0x16, 0x18, 0x40); msleep(20); /* clear pce */ @@ -487,7 +469,7 @@ static int firmware_erase_c33(enum EMEM_TYPE_t emem_type) /* erase trigger */ if (emem_type == EMEM_MAIN) - write_reg_8bit(0x16, 0x0E, 0x04); /* erase main */ + write_reg_8bit(ts_data, 0x16, 0x0E, 0x04); /* erase main */ else write_reg_8bit(0x16, 0x0E, 0x08); /* erase all block */ @@ -513,7 +495,9 @@ static int check_fw_update(void) } } return ret; + write_reg_8bit(ts_data, 0x16, 0x0E, 0x08); /* erase all block */ + return 0; } static ssize_t firmware_update_c33(struct device *dev, @@ -526,71 +510,85 @@ static ssize_t firmware_update_c33(struct device *dev, unsigned int crc_info, crc_info_tp; unsigned short reg_data = 0; int update_pass = 1; + bool fw_upgrade = false; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); crc_main = 0xffffffff; crc_info = 0xffffffff; - reset_hw(); + msg21xx_reset_hw(ts_data->pdata); - if (!check_fw_update() && !isForce) { - DBG("****no need to update\n"); - reset_hw(); - FwDataCnt = 0; + msg21xx_read_firmware_id(ts_data); + _ReadBinConfig(ts_data); + if ((main_sw_id == info_sw_id) && + (_CalMainCRC32(ts_data) == bin_conf_crc32) && + (fw_file_major == ts_data->pdata->fw_version_major) && + (fw_file_minor > ts_data->pdata->fw_version_minor)) { + fw_upgrade = true; + } + + if (!fw_upgrade && !isForce) { + dev_dbg(dev, "no need to update\n"); + msg21xx_reset_hw(ts_data->pdata); return size; } - reset_hw(); + msg21xx_reset_hw(ts_data->pdata); msleep(300); - dbbusDWIICEnterSerialDebugMode(); - dbbusDWIICStopMCU(); - dbbusDWIICIICUseBus(); - dbbusDWIICIICReshape(); + dbbusDWIICEnterSerialDebugMode(ts_data); + dbbusDWIICStopMCU(ts_data); + dbbusDWIICIICUseBus(ts_data); + dbbusDWIICIICReshape(ts_data); msleep(300); /* erase main */ - firmware_erase_c33(EMEM_MAIN); + firmware_erase_c33(ts_data, EMEM_MAIN); msleep(1000); - reset_hw(); - dbbusDWIICEnterSerialDebugMode(); - dbbusDWIICStopMCU(); - dbbusDWIICIICUseBus(); - dbbusDWIICIICReshape(); + msg21xx_reset_hw(ts_data->pdata); + dbbusDWIICEnterSerialDebugMode(ts_data); + dbbusDWIICStopMCU(ts_data); + dbbusDWIICIICUseBus(ts_data); + dbbusDWIICIICReshape(ts_data); msleep(300); - + /* + * Program + */ /* polling 0x3CE4 is 0x1C70 */ if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) { do { - reg_data = read_reg(0x3C, 0xE4); + reg_data = read_reg(ts_data, 0x3C, 0xE4); } while (reg_data != 0x1C70); } switch (emem_type) { case EMEM_ALL: - write_reg(0x3C, 0xE4, 0xE38F); /* for all-blocks */ + write_reg(ts_data, 0x3C, 0xE4, 0xE38F); /* for all-blocks */ break; case EMEM_MAIN: - write_reg(0x3C, 0xE4, 0x7731); /* for main block */ + write_reg(ts_data, 0x3C, 0xE4, 0x7731); /* for main block */ break; case EMEM_INFO: - write_reg(0x3C, 0xE4, 0x7731); /* for info block */ + write_reg(ts_data, 0x3C, 0xE4, 0x7731); /* for info block */ - write_reg_8bit(0x0F, 0xE6, 0x01); + write_reg_8bit(ts_data, 0x0F, 0xE6, 0x01); - write_reg_8bit(0x3C, 0xE4, 0xC5); - write_reg_8bit(0x3C, 0xE5, 0x78); + write_reg_8bit(ts_data, 0x3C, 0xE4, 0xC5); + write_reg_8bit(ts_data, 0x3C, 0xE5, 0x78); - write_reg_8bit(MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x9F); - write_reg_8bit(MSTAR_CHIPTOP_REGISTER_BANK, 0x05, 0x82); + write_reg_8bit(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, + 0x04, 0x9F); + write_reg_8bit(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, + 0x05, 0x82); - write_reg_8bit(0x0F, 0xE6, 0x00); + write_reg_8bit(ts_data, 0x0F, 0xE6, 0x00); msleep(100); break; } /* polling 0x3CE4 is 0x2F43 */ do { - reg_data = read_reg(0x3C, 0xE4); + reg_data = read_reg(ts_data, 0x3C, 0xE4); } while (reg_data != 0x2F43); /* calculate CRC 32 */ @@ -612,28 +610,28 @@ static ssize_t firmware_update_c33(struct device *dev, } for (j = 0; j < 8; j++) - write_i2c_seq(ts_data->client->addr, + write_i2c_seq(ts_data, ts_data->client->addr, &fw_bin_data[i][j * 128], 128); msleep(100); /* polling 0x3CE4 is 0xD0BC */ do { - reg_data = read_reg(0x3C, 0xE4); + reg_data = read_reg(ts_data, 0x3C, 0xE4); } while (reg_data != 0xD0BC); - write_reg(0x3C, 0xE4, 0x2F43); + write_reg(ts_data, 0x3C, 0xE4, 0x2F43); } if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) { /* write file done and check crc */ - write_reg(0x3C, 0xE4, 0x1380); + write_reg(ts_data, 0x3C, 0xE4, 0x1380); } msleep(20); if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) { /* polling 0x3CE4 is 0x9432 */ do { - reg_data = read_reg(0x3C, 0xE4); + reg_data = read_reg(ts_data, 0x3C, 0xE4); } while (reg_data != 0x9432); } @@ -642,12 +640,14 @@ static ssize_t firmware_update_c33(struct device *dev, if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) { /* CRC Main from TP */ - crc_main_tp = read_reg(0x3C, 0x80); - crc_main_tp = (crc_main_tp << 16) | read_reg(0x3C, 0x82); + crc_main_tp = read_reg(ts_data, 0x3C, 0x80); + crc_main_tp = (crc_main_tp << 16) | + read_reg(ts_data, 0x3C, 0x82); /* CRC Info from TP */ - crc_info_tp = read_reg(0x3C, 0xA0); - crc_info_tp = (crc_info_tp << 16) | read_reg(0x3C, 0xA2); + crc_info_tp = read_reg(ts_data, 0x3C, 0xA0); + crc_info_tp = (crc_info_tp << 16) | + read_reg(ts_data, 0x3C, 0xA2); } update_pass = 1; @@ -657,94 +657,93 @@ static ssize_t firmware_update_c33(struct device *dev, } if (!update_pass) { - DBG("update_C33 failed\n"); - reset_hw(); - FwDataCnt = 0; + dev_err(dev, "update_C33 failed\n"); + msg21xx_reset_hw(ts_data->pdata); return 0; } - DBG("update_C33 OK\n"); - reset_hw(); - FwDataCnt = 0; + dev_dbg(dev, "update_C33 OK\n"); + msg21xx_reset_hw(ts_data->pdata); return size; } -static unsigned int _CalMainCRC32(void) +static unsigned int _CalMainCRC32(struct msg21xx_ts_data *ts_data) { unsigned int ret = 0; unsigned short reg_data = 0; - reset_hw(); + msg21xx_reset_hw(ts_data->pdata); - dbbusDWIICEnterSerialDebugMode(); - dbbusDWIICStopMCU(); - dbbusDWIICIICUseBus(); - dbbusDWIICIICReshape(); + dbbusDWIICEnterSerialDebugMode(ts_data); + dbbusDWIICStopMCU(ts_data); + dbbusDWIICIICUseBus(ts_data); + dbbusDWIICIICReshape(ts_data); msleep(100); /* Stop MCU */ - write_reg(0x0F, 0xE6, 0x0001); + write_reg(ts_data, 0x0F, 0xE6, 0x0001); /* Stop Watchdog */ - write_reg_8bit(0x3C, 0x60, 0x55); - write_reg_8bit(0x3C, 0x61, 0xAA); + write_reg_8bit(ts_data, 0x3C, 0x60, 0x55); + write_reg_8bit(ts_data, 0x3C, 0x61, 0xAA); /* cmd */ - write_reg(0x3C, 0xE4, 0xDF4C); - write_reg(0x1E, 0x04, 0x7d60); + write_reg(ts_data, 0x3C, 0xE4, 0xDF4C); + write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x7d60); /* TP SW reset */ - write_reg(0x1E, 0x04, 0x829F); + write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x829F); /* MCU run */ - write_reg(0x0F, 0xE6, 0x0000); + write_reg(ts_data, 0x0F, 0xE6, 0x0000); /* polling 0x3CE4 */ do { - reg_data = read_reg(0x3C, 0xE4); + reg_data = read_reg(ts_data, 0x3C, 0xE4); } while (reg_data != 0x9432); /* Cal CRC Main from TP */ - ret = read_reg(0x3C, 0x80); - ret = (ret << 16) | read_reg(0x3C, 0x82); + ret = read_reg(ts_data, 0x3C, 0x80); + ret = (ret << 16) | read_reg(ts_data, 0x3C, 0x82); - DBG("[21xxA]:Current main crc32=0x%x\n", ret); + dev_dbg(&ts_data->client->dev, + "[21xxA]:Current main crc32=0x%x\n", ret); return ret; } -static void _ReadBinConfig(void) +static void _ReadBinConfig(struct msg21xx_ts_data *ts_data) { unsigned char dbbus_tx_data[5] = {0}; unsigned char dbbus_rx_data[4] = {0}; unsigned short reg_data = 0; - reset_hw(); + msg21xx_reset_hw(ts_data->pdata); - dbbusDWIICEnterSerialDebugMode(); - dbbusDWIICStopMCU(); - dbbusDWIICIICUseBus(); - dbbusDWIICIICReshape(); + dbbusDWIICEnterSerialDebugMode(ts_data); + dbbusDWIICStopMCU(ts_data); + dbbusDWIICIICUseBus(ts_data); + dbbusDWIICIICReshape(ts_data); msleep(100); /* Stop MCU */ - write_reg(0x0F, 0xE6, 0x0001); + write_reg(ts_data, 0x0F, 0xE6, 0x0001); /* Stop Watchdog */ - write_reg_8bit(0x3C, 0x60, 0x55); - write_reg_8bit(0x3C, 0x61, 0xAA); + write_reg_8bit(ts_data, 0x3C, 0x60, 0x55); + write_reg_8bit(ts_data, 0x3C, 0x61, 0xAA); /* cmd */ - write_reg(0x3C, 0xE4, 0xA4AB); - write_reg(MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x7d60); + write_reg(ts_data, 0x3C, 0xE4, 0xA4AB); + write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x7d60); + /* TP SW reset */ - write_reg(0x1E, 0x04, 0x829F); - /* TP SW reset*/ + write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x829F); /* MCU run */ - write_reg(0x0F, 0xE6, 0x0000); + write_reg(ts_data, 0x0F, 0xE6, 0x0000); /* polling 0x3CE4 */ do { - reg_data = read_reg(0x3C, 0xE4); + reg_data = read_reg(ts_data, 0x3C, 0xE4); } while (reg_data != 0x5B58); dbbus_tx_data[0] = 0x72; @@ -752,8 +751,8 @@ static void _ReadBinConfig(void) dbbus_tx_data[2] = 0x55; dbbus_tx_data[3] = 0x00; dbbus_tx_data[4] = 0x04; - write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5); - read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4); + write_i2c_seq(ts_data, ts_data->client->addr, &dbbus_tx_data[0], 5); + read_i2c_seq(ts_data, ts_data->client->addr, &dbbus_rx_data[0], 4); if ((dbbus_rx_data[0] >= 0x30 && dbbus_rx_data[0] <= 0x39) && (dbbus_rx_data[1] >= 0x30 && dbbus_rx_data[1] <= 0x39) && (dbbus_rx_data[2] >= 0x31 && dbbus_rx_data[2] <= 0x39)) { @@ -767,20 +766,20 @@ static void _ReadBinConfig(void) dbbus_tx_data[2] = 0xFC; dbbus_tx_data[3] = 0x00; dbbus_tx_data[4] = 0x04; - write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5); - read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4); - bin_conf_crc32 = dbbus_rx_data[0]; - bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[1]; - bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[2]; - bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[3]; + write_i2c_seq(ts_data, ts_data->client->addr, &dbbus_tx_data[0], 5); + read_i2c_seq(ts_data, ts_data->client->addr, &dbbus_rx_data[0], 4); + bin_conf_crc32 = (dbbus_rx_data[0] << 24) | + (dbbus_rx_data[1] << 16) | + (dbbus_rx_data[2] << 8) | + (dbbus_rx_data[3]); dbbus_tx_data[0] = 0x72; dbbus_tx_data[1] = 0x83; dbbus_tx_data[2] = 0x00; dbbus_tx_data[3] = 0x00; dbbus_tx_data[4] = 0x04; - write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5); - read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4); + write_i2c_seq(ts_data, ts_data->client->addr, &dbbus_tx_data[0], 5); + read_i2c_seq(ts_data, ts_data->client->addr, &dbbus_rx_data[0], 4); if ((dbbus_rx_data[0] >= 0x30 && dbbus_rx_data[0] <= 0x39) && (dbbus_rx_data[1] >= 0x30 && dbbus_rx_data[1] <= 0x39) && (dbbus_rx_data[2] >= 0x31 && dbbus_rx_data[2] <= 0x39)) { @@ -789,18 +788,18 @@ static void _ReadBinConfig(void) (dbbus_rx_data[2] - 0x30); } - DBG("[21xxA]:main_sw_id = %d, info_sw_id = %d, bin_conf_crc32=0x%x\n", - main_sw_id, info_sw_id, bin_conf_crc32); + dev_dbg(&ts_data->client->dev, + "[21xxA]:main_sw_id = %d, info_sw_id = %d, bin_conf_crc32 = 0x%x\n", + main_sw_id, info_sw_id, bin_conf_crc32); } static ssize_t firmware_update_show(struct device *dev, struct device_attribute *attr, char *buf) { - DBG("*** firmware_update_show() pdata->fw_version = %s ***\n", - pdata->fw_version); + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); - return snprintf(buf, sizeof(char) - 1, "%s\n", pdata->fw_version); + return snprintf(buf, 3, "%d\n", ts_data->pdata->updating_fw); } static ssize_t firmware_update_store(struct device *dev, @@ -808,14 +807,15 @@ static ssize_t firmware_update_store(struct device *dev, const char *buf, size_t size) { - bFwUpdating = 1; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); + + ts_data->pdata->updating_fw = true; disable_irq(ts_data->client->irq); - DBG("*** update fw size = %d ***\n", FwDataCnt); size = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN, false); enable_irq(ts_data->client->irq); - bFwUpdating = 0; + ts_data->pdata->updating_fw = false; return size; } @@ -830,27 +830,24 @@ static int prepare_fw_data(struct device *dev) int i; int ret; const struct firmware *fw = NULL; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); - ret = request_firmware(&fw, pdata->fw_name, dev); + ret = request_firmware(&fw, ts_data->pdata->fw_name, dev); if (ret < 0) { dev_err(dev, "Request firmware failed - %s (%d)\n", - pdata->fw_name, ret); + ts_data->pdata->fw_name, ret); return ret; } - DBG("*** prepare_fw_data() ret = %d, size = %d***\n", ret, fw->size); count = fw->size / 1024; - for (i = 0; i < count; i++) { - memcpy(fw_bin_data[FwDataCnt], fw->data + (i * 1024), 1024); - FwDataCnt++; - } - update_bin_major = (fw->data[0x7f4f] << 8) + fw->data[0x7f4e]; - update_bin_minor = (fw->data[0x7f51] << 8) + fw->data[0x7f50]; - DBG("*** prepare_fw_data bin major = %d ***\n", update_bin_major); - DBG("*** prepare_fw_data bin minor = %d ***\n", update_bin_minor); + for (i = 0; i < count; i++) + memcpy(fw_bin_data[i], fw->data + (i * 1024), 1024); - DBG("***FwDataCnt = %d ***\n", FwDataCnt); + fw_file_major = MSG_FW_FILE_MAJOR_VERSION(fw); + fw_file_minor = MSG_FW_FILE_MINOR_VERSION(fw); + dev_dbg(dev, "New firmware: %d.%d", + fw_file_major, fw_file_minor); return fw->size; } @@ -861,22 +858,22 @@ static ssize_t firmware_update_smart_store(struct device *dev, size_t size) { int ret; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); ret = prepare_fw_data(dev); if (ret < 0) { dev_err(dev, "Request firmware failed -(%d)\n", ret); return ret; } - bFwUpdating = 1; + ts_data->pdata->updating_fw = true; disable_irq(ts_data->client->irq); - DBG("*** update fw size = %d ***\n", FwDataCnt); ret = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN, false); if (ret == 0) - DBG("*** firmware_update_c33 ret = %d ***\n", ret); + dev_err(dev, "firmware_update_c33 ret = %d\n", ret); enable_irq(ts_data->client->irq); - bFwUpdating = 0; + ts_data->pdata->updating_fw = false; return ret; } @@ -887,22 +884,22 @@ static ssize_t firmware_force_update_smart_store(struct device *dev, size_t size) { int ret; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); ret = prepare_fw_data(dev); if (ret < 0) { dev_err(dev, "Request firmware failed -(%d)\n", ret); return ret; } - bFwUpdating = 1; + ts_data->pdata->updating_fw = true; disable_irq(ts_data->client->irq); - DBG("*** update fw size = %d ***\n", FwDataCnt); ret = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN, true); if (ret == 0) - DBG("*** firmware_update_c33 et = %d ***\n", ret); + dev_err(dev, "firmware_update_c33 et = %d\n", ret); enable_irq(ts_data->client->irq); - bFwUpdating = 0; + ts_data->pdata->updating_fw = false; return ret; } @@ -919,44 +916,40 @@ static ssize_t firmware_version_show(struct device *dev, struct device_attribute *attr, char *buf) { - msg21xx_read_firmware_id(); - return snprintf(buf, 8, "%s\n", pdata->fw_version); -} - -static ssize_t firmware_version_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t size) -{ - msg21xx_read_firmware_id(); - DBG("*** firmware_version_store() pdata->fw_version = %s ***\n", - pdata->fw_version); + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); - return size; + msg21xx_read_firmware_id(ts_data); + return snprintf(buf, sizeof(char) * 8, "%03d%03d\n", + ts_data->pdata->fw_version_major, + ts_data->pdata->fw_version_minor); } -static DEVICE_ATTR(version, (S_IRUGO | S_IWUSR), +static DEVICE_ATTR(version, S_IRUGO, firmware_version_show, - firmware_version_store); + NULL); static ssize_t msg21xx_fw_name_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, MSTAR_FW_NAME_MAX_LEN - 1, "%s\n", pdata->fw_name); + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); + + return snprintf(buf, MSTAR_FW_NAME_MAX_LEN - 1, + "%s\n", ts_data->pdata->fw_name); } static ssize_t msg21xx_fw_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); if (size > MSTAR_FW_NAME_MAX_LEN - 1) return -EINVAL; - strlcpy(pdata->fw_name, buf, size); - if (pdata->fw_name[size - 1] == '\n') - pdata->fw_name[size - 1] = 0; + strlcpy(ts_data->pdata->fw_name, buf, size); + if (ts_data->pdata->fw_name[size - 1] == '\n') + ts_data->pdata->fw_name[size - 1] = 0; return size; } @@ -964,15 +957,6 @@ static ssize_t msg21xx_fw_name_store(struct device *dev, static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR), msg21xx_fw_name_show, msg21xx_fw_name_store); -static ssize_t firmware_data_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - DBG("*** firmware_data_show() FwDataCnt = %d ***\n", FwDataCnt); - - return FwDataCnt; -} - static ssize_t firmware_data_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -981,31 +965,26 @@ static ssize_t firmware_data_store(struct device *dev, int count = size / 1024; int i; - for (i = 0; i < count; i++) { - memcpy(fw_bin_data[FwDataCnt], buf + (i * 1024), 1024); - - FwDataCnt++; - } - - DBG("***FwDataCnt = %d ***\n", FwDataCnt); + for (i = 0; i < count; i++) + memcpy(fw_bin_data[i], buf + (i * 1024), 1024); if (buf != NULL) - DBG("*** buf[0] = %c ***\n", buf[0]); + dev_dbg(dev, "buf[0] = %c\n", buf[0]); return size; } -static DEVICE_ATTR(data, (S_IRUGO | S_IWUSR), - firmware_data_show, firmware_data_store); +static DEVICE_ATTR(data, S_IWUSR, NULL, firmware_data_store); -#ifdef TP_PRINT static ssize_t tp_print_show(struct device *dev, struct device_attribute *attr, char *buf) { - tp_print_proc_read(); + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); - return snprintf(buf, sizeof(char) - 1, "%d\n", ts_data->suspended); + tp_print_proc_read(ts_data); + + return snprintf(buf, 3, "%d\n", ts_data->suspended); } static ssize_t tp_print_store(struct device *dev, @@ -1013,21 +992,17 @@ static ssize_t tp_print_store(struct device *dev, const char *buf, size_t size) { - DBG("*** tp_print_store() ***\n"); - return size; } static DEVICE_ATTR(tpp, (S_IRUGO | S_IWUSR), tp_print_show, tp_print_store); -#endif #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR static void _msg_enable_proximity(void) { unsigned char tx_data[4] = {0}; - DBG("_msg_enable_proximity!"); tx_data[0] = 0x52; tx_data[1] = 0x00; tx_data[2] = 0x47; @@ -1043,7 +1018,6 @@ static void _msg_disable_proximity(void) { unsigned char tx_data[4] = {0}; - DBG("_msg_disable_proximity!"); tx_data[0] = 0x52; tx_data[1] = 0x00; tx_data[2] = 0x47; @@ -1070,15 +1044,15 @@ static int tsps_msg21xx_data(void) } #endif -static int msg21xx_pinctrl_init(void) +static int msg21xx_pinctrl_init(struct msg21xx_ts_data *ts_data) { int retval; /* Get pinctrl if target uses pinctrl */ - ts_data->ts_pinctrl = devm_pinctrl_get(&(i2c_client->dev)); + ts_data->ts_pinctrl = devm_pinctrl_get(&(ts_data->client->dev)); if (IS_ERR_OR_NULL(ts_data->ts_pinctrl)) { retval = PTR_ERR(ts_data->ts_pinctrl); - dev_dbg(&i2c_client->dev, + dev_dbg(&ts_data->client->dev, "Target does not use pinctrl %d\n", retval); goto err_pinctrl_get; } @@ -1087,7 +1061,7 @@ static int msg21xx_pinctrl_init(void) ts_data->ts_pinctrl, PINCTRL_STATE_ACTIVE); if (IS_ERR_OR_NULL(ts_data->pinctrl_state_active)) { retval = PTR_ERR(ts_data->pinctrl_state_active); - dev_dbg(&i2c_client->dev, + dev_dbg(&ts_data->client->dev, "Can't lookup %s pinstate %d\n", PINCTRL_STATE_ACTIVE, retval); goto err_pinctrl_lookup; @@ -1097,7 +1071,7 @@ static int msg21xx_pinctrl_init(void) ts_data->ts_pinctrl, PINCTRL_STATE_SUSPEND); if (IS_ERR_OR_NULL(ts_data->pinctrl_state_suspend)) { retval = PTR_ERR(ts_data->pinctrl_state_suspend); - dev_dbg(&i2c_client->dev, + dev_dbg(&ts_data->client->dev, "Can't lookup %s pinstate %d\n", PINCTRL_STATE_SUSPEND, retval); goto err_pinctrl_lookup; @@ -1107,7 +1081,7 @@ static int msg21xx_pinctrl_init(void) ts_data->ts_pinctrl, PINCTRL_STATE_RELEASE); if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) { retval = PTR_ERR(ts_data->pinctrl_state_release); - dev_dbg(&i2c_client->dev, + dev_dbg(&ts_data->client->dev, "Can't lookup %s pinstate %d\n", PINCTRL_STATE_RELEASE, retval); } @@ -1131,7 +1105,7 @@ static unsigned char calculate_checksum(unsigned char *msg, int length) return (unsigned char)((-checksum) & 0xFF); } -static int parse_info(struct touchInfo_t *info) +static int parse_info(struct msg21xx_ts_data *ts_data) { unsigned char data[DEMO_MODE_PACKET_LENGTH] = {0}; unsigned char checksum = 0; @@ -1140,33 +1114,36 @@ static int parse_info(struct touchInfo_t *info) unsigned int delta_x = 0, delta_y = 0; mutex_lock(&msg21xx_mutex); - read_i2c_seq(ts_data->client->addr, &data[0], DEMO_MODE_PACKET_LENGTH); + read_i2c_seq(ts_data, ts_data->client->addr, &data[0], + DEMO_MODE_PACKET_LENGTH); mutex_unlock(&msg21xx_mutex); checksum = calculate_checksum(&data[0], (DEMO_MODE_PACKET_LENGTH-1)); - DBG("check sum: [%x] == [%x]?\n", + dev_dbg(&ts_data->client->dev, "check sum: [%x] == [%x]?\n", data[DEMO_MODE_PACKET_LENGTH-1], checksum); if (data[DEMO_MODE_PACKET_LENGTH-1] != checksum) { - DBG("WRONG CHECKSUM\n"); + dev_err(&ts_data->client->dev, "WRONG CHECKSUM\n"); return -EINVAL; } if (data[0] != 0x52) { - DBG("WRONG HEADER\n"); + dev_err(&ts_data->client->dev, "WRONG HEADER\n"); return -EINVAL; } - info->keycode = 0xFF; + ts_data->info.keycode = 0xFF; if ((data[1] == 0xFF) && (data[2] == 0xFF) && (data[3] == 0xFF) && (data[4] == 0xFF) && (data[6] == 0xFF)) { if ((data[5] == 0xFF) || (data[5] == 0)) { - info->keycode = 0xFF; + ts_data->info.keycode = 0xFF; } else if ((data[5] == 1) || (data[5] == 2) || (data[5] == 4) || (data[5] == 8)) { - info->keycode = data[5] >> 1; + ts_data->info.keycode = data[5] >> 1; - DBG("info->keycode index %d\n", info->keycode); + dev_dbg(&ts_data->client->dev, + "ts_data->info.keycode index %d\n", + ts_data->info.keycode); } #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR else if (bEnableTpProximity && ((data[5] == 0x80) || @@ -1180,7 +1157,7 @@ static int parse_info(struct touchInfo_t *info) } #endif else { - DBG("WRONG KEY\n"); + dev_err(&ts_data->client->dev, "WRONG KEY\n"); return -EINVAL; } } else { @@ -1190,9 +1167,11 @@ static int parse_info(struct touchInfo_t *info) delta_y = (((data[4] & 0x0F) << 8) | data[6]); if ((delta_x == 0) && (delta_y == 0)) { - info->point[0].x = x * pdata->x_max / TPD_WIDTH; - info->point[0].y = y * pdata->y_max / TPD_HEIGHT; - info->count = 1; + ts_data->info.point[0].x = + x * ts_data->pdata->x_max / TPD_WIDTH; + ts_data->info.point[0].y = + y * ts_data->pdata->y_max / TPD_HEIGHT; + ts_data->info.count = 1; } else { if (delta_x > 2048) delta_x -= 4096; @@ -1204,31 +1183,34 @@ static int parse_info(struct touchInfo_t *info) (signed short)delta_x); y2 = (unsigned int)((signed short)y + (signed short)delta_y); - info->point[0].x = x * pdata->x_max / TPD_WIDTH; - info->point[0].y = y * pdata->y_max / TPD_HEIGHT; - info->point[1].x = x2 * pdata->x_max / TPD_WIDTH; - info->point[1].y = y2 * pdata->y_max / TPD_HEIGHT; - info->count = 2; + ts_data->info.point[0].x = + x * ts_data->pdata->x_max / TPD_WIDTH; + ts_data->info.point[0].y = + y * ts_data->pdata->y_max / TPD_HEIGHT; + ts_data->info.point[1].x = + x2 * ts_data->pdata->x_max / TPD_WIDTH; + ts_data->info.point[1].y = + y2 * ts_data->pdata->y_max / TPD_HEIGHT; + ts_data->info.count = ts_data->pdata->num_max_touches; } } return 0; } -static void touch_driver_touch_released(void) +static void touch_driver_touch_released(struct msg21xx_ts_data *ts_data) { int i; - DBG("point touch released\n"); - - for (i = 0; i < MAX_TOUCH_NUM; i++) { - input_mt_slot(input_dev, i); - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); + for (i = 0; i < ts_data->pdata->num_max_touches; i++) { + input_mt_slot(ts_data->input_dev, i); + input_mt_report_slot_state(ts_data->input_dev, + MT_TOOL_FINGER, 0); } - input_report_key(input_dev, BTN_TOUCH, 0); - input_report_key(input_dev, BTN_TOOL_FINGER, 0); - input_sync(input_dev); + input_report_key(ts_data->input_dev, BTN_TOUCH, 0); + input_report_key(ts_data->input_dev, BTN_TOOL_FINGER, 0); + input_sync(ts_data->input_dev); } /* read data through I2C then report data to input @@ -1236,62 +1218,62 @@ static void touch_driver_touch_released(void) */ static irqreturn_t msg21xx_ts_interrupt(int irq, void *dev_id) { - struct touchInfo_t info; int i = 0; static int last_keycode = 0xFF; static int last_count; - - DBG("touch_driver_do_work()\n"); - - memset(&info, 0x0, sizeof(info)); - if (parse_info(&info) == 0) { - #ifdef CONFIG_TP_HAVE_KEY - if (info.keycode != 0xFF) { /* key touch pressed */ - if (info.keycode < num_buttons) { - if (info.keycode != last_keycode) { - DBG("key touch pressed"); - - input_report_key(input_dev, + struct msg21xx_ts_data *ts_data = dev_id; + + ts_data->info.count = 0; + if (parse_info(ts_data) == 0) { + if (ts_data->info.keycode != 0xFF) { /* key touch pressed */ + if (ts_data->info.keycode < + ts_data->pdata->num_buttons) { + if (ts_data->info.keycode != last_keycode) { + dev_dbg(&ts_data->client->dev, + "key touch pressed"); + + input_report_key(ts_data->input_dev, BTN_TOUCH, 1); - input_report_key(input_dev, - button_map[info.keycode], 1); + input_report_key(ts_data->input_dev, + ts_data->pdata->button_map[ + ts_data->info.keycode], 1); - last_keycode = info.keycode; + last_keycode = ts_data->info.keycode; } else { /* pass duplicate key-pressing */ - DBG("REPEATED KEY\n"); + dev_dbg(&ts_data->client->dev, + "REPEATED KEY\n"); } } else { - DBG("WRONG KEY\n"); + dev_dbg(&ts_data->client->dev, "WRONG KEY\n"); } } else { /* key touch released */ if (last_keycode != 0xFF) { - DBG("key touch released"); + dev_dbg(&ts_data->client->dev, "key touch released"); - input_report_key(input_dev, + input_report_key(ts_data->input_dev, BTN_TOUCH, 0); - input_report_key(input_dev, - button_map[last_keycode], - 0); + input_report_key(ts_data->input_dev, + ts_data->pdata->button_map[last_keycode], + 0); last_keycode = 0xFF; } } - #endif /* CONFIG_TP_HAVE_KEY */ - if (info.count > 0) { /* point touch pressed */ - for (i = 0; i < info.count; i++) { - input_mt_slot(input_dev, i); - input_mt_report_slot_state(input_dev, + if (ts_data->info.count > 0) { /* point touch pressed */ + for (i = 0; i < ts_data->info.count; i++) { + input_mt_slot(ts_data->input_dev, i); + input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, 1); - input_report_abs(input_dev, + input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR, 1); - input_report_abs(input_dev, + input_report_abs(ts_data->input_dev, ABS_MT_POSITION_X, - info.point[i].x); - input_report_abs(input_dev, + ts_data->info.point[i].x); + input_report_abs(ts_data->input_dev, ABS_MT_POSITION_Y, - info.point[i].y); + ts_data->info.point[i].y); } } @@ -1299,60 +1281,87 @@ static irqreturn_t msg21xx_ts_interrupt(int irq, void *dev_id) for (i = info.count; i < MAX_TOUCH_NUM; i++) { input_mt_slot(input_dev, i); input_mt_report_slot_state(input_dev, + } + + if (last_count > ts_data->info.count) { + for (i = ts_data->info.count; + i < ts_data->pdata->num_max_touches; + i++) { + input_mt_slot(ts_data->input_dev, i); + input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, 0); } } - last_count = info.count; + last_count = ts_data->info.count; - input_report_key(input_dev, BTN_TOUCH, info.count > 0); - input_report_key(input_dev, BTN_TOOL_FINGER, info.count > 0); + input_report_key(ts_data->input_dev, BTN_TOUCH, + ts_data->info.count > 0); + input_report_key(ts_data->input_dev, BTN_TOOL_FINGER, + ts_data->info.count > 0); - input_sync(input_dev); + input_sync(ts_data->input_dev); } return IRQ_HANDLED; } - -static int msg21xx_ts_power_init(void) +static int msg21xx_ts_power_init(struct msg21xx_ts_data *ts_data, bool init) { int rc; - ts_data->vdd = regulator_get(&i2c_client->dev, "vdd"); - if (IS_ERR(ts_data->vdd)) { - rc = PTR_ERR(ts_data->vdd); - dev_err(&i2c_client->dev, - "Regulator get failed vdd rc=%d\n", rc); - return rc; - } + if (init) { + ts_data->vdd = regulator_get(&ts_data->client->dev, + "vdd"); + if (IS_ERR(ts_data->vdd)) { + rc = PTR_ERR(ts_data->vdd); + dev_err(&ts_data->client->dev, + "Regulator get failed vdd rc=%d\n", rc); + return rc; + } - if (regulator_count_voltages(ts_data->vdd) > 0) { - rc = regulator_set_voltage(ts_data->vdd, MSTAR_VTG_MIN_UV, - MSTAR_VTG_MAX_UV); - if (rc) { - dev_err(&i2c_client->dev, - "Regulator set_vtg failed vdd rc=%d\n", rc); - goto reg_vdd_put; + if (regulator_count_voltages(ts_data->vdd) > 0) { + rc = regulator_set_voltage(ts_data->vdd, + MSTAR_VTG_MIN_UV, + MSTAR_VTG_MAX_UV); + if (rc) { + dev_err(&ts_data->client->dev, + "Regulator set_vtg failed vdd rc=%d\n", + rc); + goto reg_vdd_put; + } } - } - ts_data->vcc_i2c = regulator_get(&i2c_client->dev, "vcc_i2c"); - if (IS_ERR(ts_data->vcc_i2c)) { - rc = PTR_ERR(ts_data->vcc_i2c); - dev_err(&i2c_client->dev, - "Regulator get failed vcc_i2c rc=%d\n", rc); - goto reg_vdd_set_vtg; - } + ts_data->vcc_i2c = regulator_get(&ts_data->client->dev, + "vcc_i2c"); + if (IS_ERR(ts_data->vcc_i2c)) { + rc = PTR_ERR(ts_data->vcc_i2c); + dev_err(&ts_data->client->dev, + "Regulator get failed vcc_i2c rc=%d\n", rc); + goto reg_vdd_set_vtg; + } - if (regulator_count_voltages(ts_data->vcc_i2c) > 0) { - rc = regulator_set_voltage(ts_data->vcc_i2c, - MSTAR_I2C_VTG_MIN_UV, - MSTAR_I2C_VTG_MAX_UV); - if (rc) { - dev_err(&i2c_client->dev, - "Regulator set_vtg failed vcc_i2c rc=%d\n", rc); - goto reg_vcc_i2c_put; + if (regulator_count_voltages(ts_data->vcc_i2c) > 0) { + rc = regulator_set_voltage(ts_data->vcc_i2c, + MSTAR_I2C_VTG_MIN_UV, + MSTAR_I2C_VTG_MAX_UV); + if (rc) { + dev_err(&ts_data->client->dev, + "Regulator set_vtg failed vcc_i2c rc=%d\n", rc); + goto reg_vcc_i2c_put; + } } + } else { + if (regulator_count_voltages(ts_data->vdd) > 0) + regulator_set_voltage(ts_data->vdd, 0, + MSTAR_VTG_MAX_UV); + + regulator_put(ts_data->vdd); + + if (regulator_count_voltages(ts_data->vcc_i2c) > 0) + regulator_set_voltage(ts_data->vcc_i2c, 0, + MSTAR_I2C_VTG_MAX_UV); + + regulator_put(ts_data->vcc_i2c); } return 0; @@ -1367,59 +1376,42 @@ reg_vdd_put: return rc; } - -static int msg21xx_ts_power_deinit(void) -{ - if (regulator_count_voltages(ts_data->vdd) > 0) - regulator_set_voltage(ts_data->vdd, 0, MSTAR_VTG_MAX_UV); - - regulator_put(ts_data->vdd); - - if (regulator_count_voltages(ts_data->vcc_i2c) > 0) - regulator_set_voltage(ts_data->vcc_i2c, 0, - MSTAR_I2C_VTG_MAX_UV); - - regulator_put(ts_data->vcc_i2c); - return 0; -} - -static int msg21xx_ts_power_on(void) +static int msg21xx_ts_power_on(struct msg21xx_ts_data *ts_data, bool on) { int rc; + if (!on) + goto power_off; + rc = regulator_enable(ts_data->vdd); if (rc) { - dev_err(&i2c_client->dev, + dev_err(&ts_data->client->dev, "Regulator vdd enable failed rc=%d\n", rc); return rc; } rc = regulator_enable(ts_data->vcc_i2c); if (rc) { - dev_err(&i2c_client->dev, + dev_err(&ts_data->client->dev, "Regulator vcc_i2c enable failed rc=%d\n", rc); regulator_disable(ts_data->vdd); } return rc; -} - -static int msg21xx_ts_power_off(void) -{ - int rc; DBG("*** %s ***\n", __func__); rc = regulator_disable(vdd); +power_off: rc = regulator_disable(ts_data->vdd); if (rc) { - dev_err(&i2c_client->dev, + dev_err(&ts_data->client->dev, "Regulator vdd disable failed rc=%d\n", rc); return rc; } rc = regulator_disable(ts_data->vcc_i2c); if (rc) { - dev_err(&i2c_client->dev, + dev_err(&ts_data->client->dev, "Regulator vcc_i2c disable failed rc=%d\n", rc); rc = regulator_enable(ts_data->vdd); } @@ -1427,57 +1419,42 @@ static int msg21xx_ts_power_off(void) return rc; } -static int msg21xx_ts_gpio_configure(bool on) +static int msg21xx_ts_gpio_configure(struct msg21xx_ts_data *ts_data, bool on) { int ret = 0; - if (on) { - if (gpio_is_valid(pdata->irq_gpio)) { - ret = gpio_request(pdata->irq_gpio, "msg21xx_irq_gpio"); - if (ret) { - dev_err(&i2c_client->dev, - "Failed to request GPIO[%d], %d\n", - pdata->irq_gpio, ret); - goto err_irq_gpio_req; - } - ret = gpio_direction_input(pdata->irq_gpio); - if (ret) { - dev_err(&i2c_client->dev, - "Failed to set direction for gpio[%d], %d\n", - pdata->irq_gpio, ret); - goto err_irq_gpio_dir; - } - gpio_set_value_cansleep(pdata->irq_gpio, 1); - } else { - dev_err(&i2c_client->dev, "irq gpio not provided\n"); + if (!on) + goto pwr_deinit; + + if (gpio_is_valid(ts_data->pdata->irq_gpio)) { + ret = gpio_request(ts_data->pdata->irq_gpio, + "msg21xx_irq_gpio"); + if (ret) { + dev_err(&ts_data->client->dev, + "Failed to request GPIO[%d], %d\n", + ts_data->pdata->irq_gpio, ret); goto err_irq_gpio_req; } + ret = gpio_direction_input(ts_data->pdata->irq_gpio); + if (ret) { + dev_err(&ts_data->client->dev, + "Failed to set direction for gpio[%d], %d\n", + ts_data->pdata->irq_gpio, ret); + goto err_irq_gpio_dir; + } + gpio_set_value_cansleep(ts_data->pdata->irq_gpio, 1); + } else { + dev_err(&ts_data->client->dev, "irq gpio not provided\n"); + goto err_irq_gpio_req; + } - if (gpio_is_valid(pdata->reset_gpio)) { - ret = gpio_request(pdata->reset_gpio, - "msg21xx_reset_gpio"); - if (ret) { - dev_err(&i2c_client->dev, - "Failed to request GPIO[%d], %d\n", - pdata->reset_gpio, ret); - goto err_reset_gpio_req; - } - - /* power on TP */ - ret = gpio_direction_output(pdata->reset_gpio, 1); - if (ret) { - dev_err(&i2c_client->dev, - "Failed to set direction for GPIO[%d], %d\n", - pdata->reset_gpio, ret); - goto err_reset_gpio_dir; - } - msleep(100); - gpio_set_value_cansleep(pdata->reset_gpio, 0); - msleep(20); - gpio_set_value_cansleep(pdata->reset_gpio, 1); - msleep(200); - } else { - dev_err(&i2c_client->dev, "reset gpio not provided\n"); + if (gpio_is_valid(ts_data->pdata->reset_gpio)) { + ret = gpio_request(ts_data->pdata->reset_gpio, + "msg21xx_reset_gpio"); + if (ret) { + dev_err(&ts_data->client->dev, + "Failed to request GPIO[%d], %d\n", + ts_data->pdata->reset_gpio, ret); goto err_reset_gpio_req; } @@ -1495,55 +1472,93 @@ static int msg21xx_ts_gpio_configure(bool on) } } return 0; + /* power on TP */ + ret = gpio_direction_output( + ts_data->pdata->reset_gpio, 1); + if (ret) { + dev_err(&ts_data->client->dev, + "Failed to set direction for GPIO[%d], %d\n", + ts_data->pdata->reset_gpio, ret); + goto err_reset_gpio_dir; + } + msleep(100); + gpio_set_value_cansleep(ts_data->pdata->reset_gpio, 0); + msleep(20); + gpio_set_value_cansleep(ts_data->pdata->reset_gpio, 1); + msleep(200); + } else { + dev_err(&ts_data->client->dev, "reset gpio not provided\n"); + goto err_reset_gpio_req; + } + + return 0; + err_reset_gpio_dir: - if (gpio_is_valid(pdata->reset_gpio)) - gpio_free(pdata->irq_gpio); + if (gpio_is_valid(ts_data->pdata->reset_gpio)) + gpio_free(ts_data->pdata->irq_gpio); err_reset_gpio_req: err_irq_gpio_dir: - if (gpio_is_valid(pdata->irq_gpio)) - gpio_free(pdata->irq_gpio); + if (gpio_is_valid(ts_data->pdata->irq_gpio)) + gpio_free(ts_data->pdata->irq_gpio); err_irq_gpio_req: return ret; + +pwr_deinit: + if (gpio_is_valid(ts_data->pdata->irq_gpio)) + gpio_free(ts_data->pdata->irq_gpio); + if (gpio_is_valid(ts_data->pdata->reset_gpio)) { + gpio_set_value_cansleep(ts_data->pdata->reset_gpio, 0); + ret = gpio_direction_input(ts_data->pdata->reset_gpio); + if (ret) + dev_err(&ts_data->client->dev, + "Unable to set direction for gpio [%d]\n", + ts_data->pdata->reset_gpio); + gpio_free(ts_data->pdata->reset_gpio); + } + return 0; } #ifdef CONFIG_PM static int msg21xx_ts_resume(struct device *dev) { int retval; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); - mutex_lock(&ts_data->ts_mutex); - if (ts_data->suspended) { - if (ts_data->ts_pinctrl) { - retval = pinctrl_select_state(ts_data->ts_pinctrl, - ts_data->pinctrl_state_active); - if (retval < 0) { - dev_err(dev, "Cannot get active pinctrl state\n"); - mutex_unlock(&ts_data->ts_mutex); - return retval; - } - } + if (!ts_data->suspended) { + dev_info(dev, "msg21xx_ts already in resume\n"); + return 0; + } - retval = msg21xx_ts_gpio_configure(true); - if (retval) { - dev_err(dev, "Failed to put gpios in active state %d", - retval); - mutex_unlock(&ts_data->ts_mutex); - return retval; - } + mutex_lock(&ts_data->ts_mutex); - enable_irq(ts_data->client->irq); + retval = msg21xx_ts_power_on(ts_data, true); + if (retval) { + dev_err(dev, "msg21xx_ts power on failed"); + mutex_unlock(&ts_data->ts_mutex); + return retval; + } - retval = msg21xx_ts_power_on(); - if (retval) { - dev_err(dev, "msg21xx_ts power on failed"); + if (ts_data->ts_pinctrl) { + retval = pinctrl_select_state(ts_data->ts_pinctrl, + ts_data->pinctrl_state_active); + if (retval < 0) { + dev_err(dev, "Cannot get active pinctrl state\n"); mutex_unlock(&ts_data->ts_mutex); return retval; } + } - ts_data->suspended = 0; - } else { - dev_info(dev, "msg21xx_ts already in resume\n"); + retval = msg21xx_ts_gpio_configure(ts_data, true); + if (retval) { + dev_err(dev, "Failed to put gpios in active state %d", + retval); + mutex_unlock(&ts_data->ts_mutex); + return retval; } + + enable_irq(ts_data->client->irq); + ts_data->suspended = false; + mutex_unlock(&ts_data->ts_mutex); return 0; @@ -1552,56 +1567,61 @@ static int msg21xx_ts_resume(struct device *dev) static int msg21xx_ts_suspend(struct device *dev) { int retval; + struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev); - if (bFwUpdating) { - DBG("suspend bFwUpdating=%d\n", bFwUpdating); + if (ts_data->pdata->updating_fw) { + dev_info(dev, "Firmware loading in progress\n"); + return 0; + } + + if (ts_data->suspended) { + dev_info(dev, "msg21xx_ts already in suspend\n"); return 0; } #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR if (bEnableTpProximity) { - DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity); + dev_dbg(dev, "suspend bEnableTpProximity=%d\n", + bEnableTpProximity); return 0; } #endif mutex_lock(&ts_data->ts_mutex); - if (ts_data->suspended == 0) { - disable_irq(ts_data->client->irq); - - touch_driver_touch_released(); - retval = msg21xx_ts_power_off(); - if (retval) { - dev_err(dev, "msg21xx_ts power off failed"); - mutex_unlock(&ts_data->ts_mutex); - return retval; - } + disable_irq(ts_data->client->irq); - if (ts_data->ts_pinctrl) { - retval = pinctrl_select_state(ts_data->ts_pinctrl, - ts_data->pinctrl_state_suspend); - if (retval < 0) { - dev_err(&i2c_client->dev, "Cannot get idle pinctrl state\n"); - mutex_unlock(&ts_data->ts_mutex); - return retval; - } - } + touch_driver_touch_released(ts_data); - retval = msg21xx_ts_gpio_configure(false); - if (retval) { - dev_err(dev, "Failed to put gpios in idle state %d", - retval); + if (ts_data->ts_pinctrl) { + retval = pinctrl_select_state(ts_data->ts_pinctrl, + ts_data->pinctrl_state_suspend); + if (retval < 0) { + dev_err(dev, "Cannot get idle pinctrl state %d\n", + retval); mutex_unlock(&ts_data->ts_mutex); return retval; } + } - ts_data->suspended = 1; - } else { - dev_err(dev, "msg21xx_ts already in suspend\n"); + retval = msg21xx_ts_gpio_configure(ts_data, false); + if (retval) { + dev_err(dev, "Failed to put gpios in idle state %d", + retval); + mutex_unlock(&ts_data->ts_mutex); + return retval; + } + + retval = msg21xx_ts_power_on(ts_data, false); + if (retval) { + dev_err(dev, "msg21xx_ts power off failed"); + mutex_unlock(&ts_data->ts_mutex); + return retval; } - mutex_unlock(&ts_data->ts_mutex); + ts_data->suspended = true; + + mutex_unlock(&ts_data->ts_mutex); return 0; } @@ -1616,19 +1636,52 @@ static int msg21xx_ts_suspend(struct device *dev) } #endif +static int msg21xx_debug_suspend_set(void *_data, u64 val) +{ + struct msg21xx_ts_data *data = _data; + + mutex_lock(&data->input_dev->mutex); + + if (val) + msg21xx_ts_suspend(&data->client->dev); + else + msg21xx_ts_resume(&data->client->dev); + + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +static int msg21xx_debug_suspend_get(void *_data, u64 *val) +{ + struct msg21xx_ts_data *data = _data; + + mutex_lock(&data->input_dev->mutex); + *val = data->suspended; + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, msg21xx_debug_suspend_get, + msg21xx_debug_suspend_set, "%lld\n"); + + #if defined(CONFIG_FB) static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { struct fb_event *evdata = data; int *blank; + struct msg21xx_ts_data *ts_data = + container_of(self, struct msg21xx_ts_data, fb_notif); if (evdata && evdata->data && event == FB_EVENT_BLANK) { blank = evdata->data; if (*blank == FB_BLANK_UNBLANK) - msg21xx_ts_resume(&i2c_client->dev); + msg21xx_ts_resume(&ts_data->client->dev); else if (*blank == FB_BLANK_POWERDOWN) - msg21xx_ts_suspend(&i2c_client->dev); + msg21xx_ts_suspend(&ts_data->client->dev); } return 0; @@ -1695,6 +1748,20 @@ static int msg21xx_parse_dt(struct device *dev, if (rc) return rc; + rc = of_property_read_u32(np, "mstar,hard-reset-delay-ms", + &temp_val); + if (!rc) + pdata->hard_reset_delay_ms = temp_val; + else + return rc; + + rc = of_property_read_u32(np, "mstar,post-hard-reset-delay-ms", + &temp_val); + if (!rc) + pdata->post_hard_reset_delay_ms = temp_val; + else + return rc; + /* reset, irq gpio info */ pdata->reset_gpio = of_get_named_gpio_flags(np, "mstar,reset-gpio", 0, &pdata->reset_gpio_flags); @@ -1706,16 +1773,27 @@ static int msg21xx_parse_dt(struct device *dev, if (pdata->irq_gpio < 0) return pdata->irq_gpio; + rc = of_property_read_u32(np, "mstar,ic-type", &temp_val); + if (rc && (rc != -EINVAL)) + return rc; + + pdata->ic_type = temp_val; + + rc = of_property_read_u32(np, "mstar,num-max-touches", &temp_val); + if (!rc) + pdata->num_max_touches = temp_val; + else + return rc; prop = of_find_property(np, "mstar,button-map", NULL); if (prop) { - num_buttons = prop->length / sizeof(temp_val); - if (num_buttons > MAX_BUTTONS) + pdata->num_buttons = prop->length / sizeof(temp_val); + if (pdata->num_buttons > MAX_BUTTONS) return -EINVAL; rc = of_property_read_u32_array(np, - "mstar,button-map", button_map, - num_buttons); + "mstar,button-map", pdata->button_map, + pdata->num_buttons); if (rc) { dev_err(dev, "Unable to read key codes\n"); return rc; @@ -1729,12 +1807,11 @@ static int msg21xx_parse_dt(struct device *dev, static int msg21xx_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int ret = 0; - - if (input_dev != NULL) { - DBG("input device has found\n"); - return -EINVAL; - } + int ret = 0, i; + struct dentry *temp, *dir; + struct input_dev *input_dev; + struct msg21xx_ts_data *ts_data; + struct msg21xx_ts_platform_data *pdata; if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, @@ -1750,43 +1827,80 @@ static int msg21xx_ts_probe(struct i2c_client *client, } else pdata = client->dev.platform_data; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "I2C not supported\n"); + return -ENODEV; + } + ts_data = devm_kzalloc(&client->dev, sizeof(struct msg21xx_ts_data), GFP_KERNEL); if (!ts_data) return -ENOMEM; - DBG("*** %s ***\n", __func__); + ts_data->client = client; + ts_data->info.point = devm_kzalloc(&client->dev, + sizeof(struct touchPoint_t) * pdata->num_max_touches, + GFP_KERNEL); + if (!ts_data->info.point) { + dev_err(&client->dev, "Not enough memory\n"); + return -ENOMEM; + } - i2c_client = client; + /* allocate an input device */ + input_dev = input_allocate_device(); + if (!input_dev) { + ret = -ENOMEM; + dev_err(&client->dev, "input device allocation failed\n"); + goto err_input_allocate_dev; + } - ret = msg21xx_ts_power_init(); - if (ret) + input_dev->name = client->name; + input_dev->phys = "I2C"; + input_dev->dev.parent = &client->dev; + input_dev->id.bustype = BUS_I2C; + + ts_data->input_dev = input_dev; + ts_data->client = client; + ts_data->pdata = pdata; + + input_set_drvdata(input_dev, ts_data); + i2c_set_clientdata(client, ts_data); + + ret = msg21xx_ts_power_init(ts_data, true); + if (ret) { dev_err(&client->dev, "Mstar power init failed\n"); + return ret; + } - ret = msg21xx_ts_power_on(); + ret = msg21xx_ts_power_on(ts_data, true); if (ret) { dev_err(&client->dev, "Mstar power on failed\n"); goto exit_deinit_power; } - ret = msg21xx_pinctrl_init(); + ret = msg21xx_pinctrl_init(ts_data); if (!ret && ts_data->ts_pinctrl) { + /* + * Pinctrl handle is optional. If pinctrl handle is found + * let pins to be configured in active state. If not + * found continue further without error. + */ ret = pinctrl_select_state(ts_data->ts_pinctrl, ts_data->pinctrl_state_active); if (ret < 0) - goto exit_pinctrl_select; - } else { - goto exit_pinctrl_init; + dev_err(&client->dev, + "Failed to select %s pinatate %d\n", + PINCTRL_STATE_ACTIVE, ret); } - ret = msg21xx_ts_gpio_configure(true); + ret = msg21xx_ts_gpio_configure(ts_data, true); if (ret) { dev_err(&client->dev, "Failed to configure gpio %d\n", ret); goto exit_gpio_config; } - if (get_ic_type() == 0) { - pr_err("the currnet ic is not Mstar\n"); + if (msg21xx_get_ic_type(ts_data) == 0) { + dev_err(&client->dev, "The current IC is not Mstar\n"); ret = -1; goto err_wrong_ic_type; } @@ -1794,19 +1908,6 @@ static int msg21xx_ts_probe(struct i2c_client *client, mutex_init(&msg21xx_mutex); mutex_init(&ts_data->ts_mutex); - /* allocate an input device */ - input_dev = input_allocate_device(); - if (!input_dev) { - ret = -ENOMEM; - pr_err("*** input device allocation failed ***\n"); - goto err_input_allocate_dev; - } - - input_dev->name = client->name; - input_dev->phys = "I2C"; - input_dev->dev.parent = &client->dev; - input_dev->id.bustype = BUS_I2C; - /* set the supported event type for input device */ set_bit(EV_ABS, input_dev->evbit); set_bit(EV_SYN, input_dev->evbit); @@ -1815,9 +1916,8 @@ static int msg21xx_ts_probe(struct i2c_client *client, set_bit(BTN_TOOL_FINGER, input_dev->keybit); set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - ts_data->input_dev = input_dev; - ts_data->client = client; - ts_data->pdata = pdata; + for (i = 0; i < pdata->num_buttons; i++) + input_set_capability(input_dev, EV_KEY, pdata->button_map[i]); input_set_drvdata(input_dev, ts_data); i2c_set_clientdata(client, ts_data); @@ -1833,64 +1933,82 @@ static int msg21xx_ts_probe(struct i2c_client *client, input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 2, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 2, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); - ret = input_mt_init_slots(input_dev, MAX_TOUCH_NUM, 0); + ret = input_mt_init_slots(input_dev, pdata->num_max_touches, 0); if (ret) { - pr_err("Error %d initialising slots\n", ret); + dev_err(&client->dev, + "Error %d initialising slots\n", ret); goto err_free_mem; } /* register the input device to input sub-system */ ret = input_register_device(input_dev); if (ret < 0) { - pr_err("*** Unable to register ms-touchscreen input device ***\n"); + dev_err(&client->dev, + "Unable to register ms-touchscreen input device\n"); goto err_input_reg_dev; } - /* set sysfs for firmware */ - firmware_class = class_create(THIS_MODULE, "ms-touchscreen-msg21xx"); - if (IS_ERR(firmware_class)) - pr_err("Failed to create class(firmware)!\n"); - - firmware_cmd_dev = device_create(firmware_class, NULL, 0, - NULL, "device"); - if (IS_ERR(firmware_cmd_dev)) - pr_err("Failed to create device(firmware_cmd_dev)!\n"); - /* version */ - if (device_create_file(firmware_cmd_dev, &dev_attr_version) < 0) - pr_err("Failed to create device file(%s)!\n", - dev_attr_version.attr.name); + if (device_create_file(&client->dev, &dev_attr_version) < 0) { + dev_err(&client->dev, + "Failed to create device file(%s)!\n", + dev_attr_version.attr.name); + goto err_create_fw_ver_file; + } /* update */ - if (device_create_file(firmware_cmd_dev, &dev_attr_update) < 0) - pr_err("Failed to create device file(%s)!\n", - dev_attr_update.attr.name); + if (device_create_file(&client->dev, &dev_attr_update) < 0) { + dev_err(&client->dev, + "Failed to create device file(%s)!\n", + dev_attr_update.attr.name); + goto err_create_fw_update_file; + } /* data */ - if (device_create_file(firmware_cmd_dev, &dev_attr_data) < 0) - pr_err("Failed to create device file(%s)!\n", - dev_attr_data.attr.name); - /* fw name*/ - if (device_create_file(firmware_cmd_dev, &dev_attr_fw_name) < 0) - pr_err("Failed to create device file(%s)!\n", - dev_attr_fw_name.attr.name); - /* smart fw update*/ - if (device_create_file(firmware_cmd_dev, &dev_attr_update_fw) < 0) - pr_err("Failed to create device file(%s)!\n", - dev_attr_update_fw.attr.name); - /* smart fw force update*/ - if (device_create_file(firmware_cmd_dev, &dev_attr_force_update_fw) < 0) - pr_err("Failed to create device file(%s)!\n", - dev_attr_force_update_fw.attr.name); + if (device_create_file(&client->dev, &dev_attr_data) < 0) { + dev_err(&client->dev, + "Failed to create device file(%s)!\n", + dev_attr_data.attr.name); + goto err_create_fw_data_file; + } + /* fw name */ + if (device_create_file(&client->dev, &dev_attr_fw_name) < 0) { + dev_err(&client->dev, + "Failed to create device file(%s)!\n", + dev_attr_fw_name.attr.name); + goto err_create_fw_name_file; + } + /* smart fw update */ + if (device_create_file(&client->dev, &dev_attr_update_fw) < 0) { + dev_err(&client->dev, + "Failed to create device file(%s)!\n", + dev_attr_update_fw.attr.name); + goto err_create_update_fw_file; + } + /* smart fw force update */ + if (device_create_file(&client->dev, + &dev_attr_force_update_fw) < 0) { + dev_err(&client->dev, + "Failed to create device file(%s)!\n", + dev_attr_force_update_fw.attr.name); + goto err_create_force_update_fw_file; + } + dir = debugfs_create_dir(MSTAR_DEBUG_DIR_NAME, NULL); + temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, dir, + ts_data, &debug_suspend_fops); + if (temp == NULL || IS_ERR(temp)) { + dev_err(&client->dev, + "debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp)); + goto free_debug_dir; + } #ifdef TP_PRINT - tp_print_create_entry(); + tp_print_create_entry(ts_data); #endif - dev_set_drvdata(firmware_cmd_dev, NULL); - ret = request_threaded_irq(client->irq, NULL, msg21xx_ts_interrupt, pdata->irq_gpio_flags | IRQF_ONESHOT, @@ -1898,7 +2016,7 @@ static int msg21xx_ts_probe(struct i2c_client *client, if (ret) goto err_req_irq; - disable_irq(ts_data->client->irq); + disable_irq(client->irq); #if defined(CONFIG_FB) ts_data->fb_notif.notifier_call = fb_notifier_callback; @@ -1910,91 +2028,38 @@ static int msg21xx_ts_probe(struct i2c_client *client, &tsps_msg21xx_data); #endif -#ifdef FIRMWARE_AUTOUPDATE - get_customer_firmware_version(); - _ReadBinConfig(); - - if (main_sw_id == info_sw_id) { - if (_CalMainCRC32() == bin_conf_crc32) { - if ((main_sw_id >= SWID_START) && - (main_sw_id < SWID_NULL)) { - update_bin_major = (MSG_FIRMWARE - [main_sw_id - SWID_START][0x7f4f] << 8) - + MSG_FIRMWARE[main_sw_id - SWID_START][0x7f4e]; - update_bin_minor = (MSG_FIRMWARE - [main_sw_id - SWID_START][0x7f51] << 8) - + MSG_FIRMWARE[main_sw_id - SWID_START][0x7f50]; - - /* check upgrading */ - if ((update_bin_major == fw_version_major) && - (update_bin_minor > fw_version_minor)) { - update_flag = 1; - } - } - } else { - if ((info_sw_id >= SWID_START) && - (info_sw_id < SWID_NULL)) { - update_bin_major = (MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f4f] << 8) - + MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f4e]; - update_bin_minor = (MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f51] << 8) - + MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f50]; - update_flag = 1; - } - } - } else { - if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL)) { - update_bin_major = (MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f4f] << 8) - + MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f4e]; - update_bin_minor = (MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f51] << 8) - + MSG_FIRMWARE - [info_sw_id - SWID_START][0x7f50]; - update_flag = 1; - } - } - - if (update_flag == 1) { - DBG("MSG21XX_fw_auto_update begin....\n"); - /* transfer data */ - for (i = 0; i < 33; i++) { - firmware_data_store(NULL, NULL, - &(MSG_FIRMWARE[info_sw_id - SWID_START][i * 1024]), - 1024); - } - - kthread_run(fwAutoUpdate, 0, "MSG21XX_fw_auto_update"); - DBG("*** mstar touch screen registered ***\n"); - return 0; - } - - reset_hw(); -#endif - - DBG("*** mstar touch screen registered ***\n"); - enable_irq(ts_data->client->irq); + dev_dbg(&client->dev, "mstar touch screen registered\n"); + enable_irq(client->irq); return 0; err_req_irq: - free_irq(ts_data->client->irq, ts_data); + free_irq(client->irq, ts_data); + device_remove_file(&client->dev, &dev_attr_data); +free_debug_dir: + debugfs_remove_recursive(dir); +err_create_fw_data_file: + device_remove_file(&client->dev, &dev_attr_update); +err_create_fw_update_file: + device_remove_file(&client->dev, &dev_attr_version); +err_create_fw_name_file: + device_remove_file(&client->dev, &dev_attr_fw_name); +err_create_update_fw_file: + device_remove_file(&client->dev, &dev_attr_update_fw); +err_create_force_update_fw_file: + device_remove_file(&client->dev, &dev_attr_force_update_fw); +err_create_fw_ver_file: + input_unregister_device(input_dev); err_input_reg_dev: + input_free_device(input_dev); + input_dev = NULL; err_input_allocate_dev: mutex_destroy(&msg21xx_mutex); mutex_destroy(&ts_data->ts_mutex); - input_unregister_device(input_dev); - input_free_device(input_dev); - input_dev = NULL; err_wrong_ic_type: - msg21xx_ts_gpio_configure(false); + msg21xx_ts_gpio_configure(ts_data, false); exit_gpio_config: -exit_pinctrl_select: if (ts_data->ts_pinctrl) { if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) { devm_pinctrl_put(ts_data->ts_pinctrl); @@ -2003,13 +2068,13 @@ exit_pinctrl_select: ret = pinctrl_select_state(ts_data->ts_pinctrl, ts_data->pinctrl_state_release); if (ret < 0) - pr_err("Cannot get release pinctrl state\n"); + dev_err(&ts_data->client->dev, + "Cannot get release pinctrl state\n"); } } -exit_pinctrl_init: - msg21xx_ts_power_off(); + msg21xx_ts_power_on(ts_data, false); exit_deinit_power: - msg21xx_ts_power_deinit(); + msg21xx_ts_power_init(ts_data, false); err_free_mem: input_free_device(input_dev); @@ -2022,12 +2087,11 @@ err_free_mem: static int touch_driver_remove(struct i2c_client *client) { int retval = 0; - - DBG("touch_driver_remove()\n"); + struct msg21xx_ts_data *ts_data = i2c_get_clientdata(client); free_irq(ts_data->client->irq, ts_data); - gpio_free(pdata->irq_gpio); - gpio_free(pdata->reset_gpio); + gpio_free(ts_data->pdata->irq_gpio); + gpio_free(ts_data->pdata->reset_gpio); if (ts_data->ts_pinctrl) { if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) { @@ -2037,11 +2101,12 @@ static int touch_driver_remove(struct i2c_client *client) retval = pinctrl_select_state(ts_data->ts_pinctrl, ts_data->pinctrl_state_release); if (retval < 0) - pr_err("Cannot get release pinctrl state\n"); + dev_err(&ts_data->client->dev, + "Cannot get release pinctrl state\n"); } } - input_unregister_device(input_dev); + input_unregister_device(ts_data->input_dev); mutex_destroy(&msg21xx_mutex); mutex_destroy(&ts_data->ts_mutex); @@ -2082,7 +2147,7 @@ module_i2c_driver(touch_device_driver); static unsigned short InfoAddr = 0x0F, PoolAddr = 0x10, TransLen = 256; static unsigned char row, units, cnt; -static int tp_print_proc_read(void) +static int tp_print_proc_read(struct msg21xx_ts_data *ts_data) { unsigned short i, j; unsigned short left, offset = 0; @@ -2106,9 +2171,9 @@ static int tp_print_proc_read(void) & 0xFF; dbbus_tx_data[2] = (PoolAddr + offset) & 0xFF; mutex_lock(&msg21xx_mutex); - write_i2c_seq(ts_data->client->addr, + write_i2c_seq(ts_data, ts_data->client->addr, &dbbus_tx_data[0], 3); - read_i2c_seq(ts_data->client->addr, + read_i2c_seq(ts_data, ts_data->client->addr, &buf[offset], left > TransLen ? TransLen : left); mutex_unlock(&msg21xx_mutex); @@ -2151,7 +2216,7 @@ static int tp_print_proc_read(void) return 0; } -static void tp_print_create_entry(void) +static void tp_print_create_entry(struct msg21xx_ts_data *ts_data) { unsigned char dbbus_tx_data[3] = {0}; unsigned char dbbus_rx_data[8] = {0}; @@ -2160,8 +2225,8 @@ static void tp_print_create_entry(void) dbbus_tx_data[1] = 0x00; dbbus_tx_data[2] = 0x58; mutex_lock(&msg21xx_mutex); - write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3); - read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4); + write_i2c_seq(ts_data, ts_data->client->addr, &dbbus_tx_data[0], 3); + read_i2c_seq(ts_data, ts_data->client->addr, &dbbus_rx_data[0], 4); mutex_unlock(&msg21xx_mutex); InfoAddr = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0]; PoolAddr = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2]; @@ -2172,8 +2237,10 @@ static void tp_print_create_entry(void) dbbus_tx_data[1] = (InfoAddr >> 8) & 0xFF; dbbus_tx_data[2] = InfoAddr & 0xFF; mutex_lock(&msg21xx_mutex); - write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3); - read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 8); + write_i2c_seq(ts_data, ts_data->client->addr, + &dbbus_tx_data[0], 3); + read_i2c_seq(ts_data, ts_data->client->addr, + &dbbus_rx_data[0], 8); mutex_unlock(&msg21xx_mutex); units = dbbus_rx_data[0]; @@ -2181,10 +2248,10 @@ static void tp_print_create_entry(void) cnt = dbbus_rx_data[2]; TransLen = (dbbus_rx_data[7]<<8) + dbbus_rx_data[6]; - if (device_create_file(firmware_cmd_dev, &dev_attr_tpp) < 0) { - pr_err("Failed to create device file(%s)!\n", + if (device_create_file(&ts_data->client->dev, + &dev_attr_tpp) < 0) + dev_err(&ts_data->client->dev, "Failed to create device file(%s)!\n", dev_attr_tpp.attr.name); - } } } #endif |