|
@@ -0,0 +1,288 @@
|
|
|
+diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
|
|
|
+index 2dd6066..c2aaa20 100644
|
|
|
+--- a/drivers/input/touchscreen/edt-ft5x06.c
|
|
|
++++ b/drivers/input/touchscreen/edt-ft5x06.c
|
|
|
+@@ -53,6 +53,7 @@
|
|
|
+ #define M09_REGISTER_OFFSET 0x93
|
|
|
+ #define M09_REGISTER_NUM_X 0x94
|
|
|
+ #define M09_REGISTER_NUM_Y 0x95
|
|
|
++#define M09_REGISTER_REPORT_RATE 0x88
|
|
|
+
|
|
|
+ #define M12_REGISTER_THRESHOLD 0x80
|
|
|
+ #define M12_REGISTER_GAIN 0x92
|
|
|
+@@ -61,6 +62,13 @@
|
|
|
+ #define M12_REGISTER_NUM_Y 0x95
|
|
|
+ #define M12_REGISTER_REPORT_RATE 0x88
|
|
|
+
|
|
|
++#define MG1_REGISTER_THRESHOLD 0x80
|
|
|
++#define MG1_REGISTER_GAIN 0x92
|
|
|
++#define MG1_REGISTER_OFFSET 0x93
|
|
|
++#define MG1_REGISTER_NUM_X 0x94
|
|
|
++#define MG1_REGISTER_NUM_Y 0x95
|
|
|
++#define MG1_REGISTER_REPORT_RATE 0x88
|
|
|
++
|
|
|
+ #define NO_REGISTER 0xff
|
|
|
+
|
|
|
+ #define WORK_REGISTER_OPMODE 0x3c
|
|
|
+@@ -81,6 +89,7 @@ enum edt_ver {
|
|
|
+ M06,
|
|
|
+ M09,
|
|
|
+ M12,
|
|
|
++ MG1,
|
|
|
+ };
|
|
|
+
|
|
|
+ struct edt_reg_addr {
|
|
|
+@@ -184,7 +193,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
|
|
+ struct edt_ft5x06_ts_data *tsdata = dev_id;
|
|
|
+ struct device *dev = &tsdata->client->dev;
|
|
|
+ u8 cmd;
|
|
|
+- u8 rdbuf[29];
|
|
|
++ u8 rdbuf[30];
|
|
|
+ int i, type, x, y, id;
|
|
|
+ int offset, tplen, datalen;
|
|
|
+ int error;
|
|
|
+@@ -205,6 +214,13 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
|
|
+ datalen = 29;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case MG1:
|
|
|
++ cmd = 0x02;
|
|
|
++ offset = 1;
|
|
|
++ tplen = 6;
|
|
|
++ datalen = 29;
|
|
|
++ break;
|
|
|
++
|
|
|
+ default:
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+@@ -291,17 +307,17 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
|
|
|
+ case M06:
|
|
|
+ wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
|
|
|
+ wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
|
|
|
+- wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
|
|
|
+ wrbuf[2] = value;
|
|
|
+ wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
|
|
|
+ return edt_ft5x06_ts_readwrite(tsdata->client, 4, wrbuf, 0, NULL);
|
|
|
+
|
|
|
+ case M12:
|
|
|
+ case M09:
|
|
|
++ case MG1:
|
|
|
+ wrbuf[0] = addr;
|
|
|
+ wrbuf[1] = value;
|
|
|
+
|
|
|
+- return edt_ft5x06_ts_readwrite(tsdata->client, 3,
|
|
|
++ return edt_ft5x06_ts_readwrite(tsdata->client, 2,
|
|
|
+ wrbuf, 0, NULL);
|
|
|
+
|
|
|
+ default:
|
|
|
+@@ -337,6 +353,7 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
|
|
|
+
|
|
|
+ case M12:
|
|
|
+ case M09:
|
|
|
++ case MG1:
|
|
|
+ wrbuf[0] = addr;
|
|
|
+ error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
|
|
|
+ wrbuf, 1, rdbuf);
|
|
|
+@@ -359,10 +376,11 @@ struct edt_ft5x06_attribute {
|
|
|
+ u8 addr_m06;
|
|
|
+ u8 addr_m09;
|
|
|
+ u8 addr_m12;
|
|
|
++ u8 addr_mg1;
|
|
|
+ };
|
|
|
+
|
|
|
+-#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, _addr_m12, \
|
|
|
+- _limit_low, _limit_high) \
|
|
|
++#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, _addr_m12, \
|
|
|
++ _addr_mg1, _limit_low, _limit_high) \
|
|
|
+ struct edt_ft5x06_attribute edt_ft5x06_attr_##_field = { \
|
|
|
+ .dattr = __ATTR(_field, _mode, \
|
|
|
+ edt_ft5x06_setting_show, \
|
|
|
+@@ -371,6 +389,7 @@ struct edt_ft5x06_attribute {
|
|
|
+ .addr_m06 = _addr_m06, \
|
|
|
+ .addr_m09 = _addr_m09, \
|
|
|
+ .addr_m12 = _addr_m12, \
|
|
|
++ .addr_mg1 = _addr_mg1, \
|
|
|
+ .limit_low = _limit_low, \
|
|
|
+ .limit_high = _limit_high, \
|
|
|
+ }
|
|
|
+@@ -405,6 +424,10 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
|
|
|
+ addr = attr->addr_m12;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case MG1:
|
|
|
++ addr = attr->addr_mg1;
|
|
|
++ break;
|
|
|
++
|
|
|
+ case M09:
|
|
|
+ addr = attr->addr_m09;
|
|
|
+ break;
|
|
|
+@@ -478,6 +501,10 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
|
|
|
+ addr = attr->addr_m12;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case MG1:
|
|
|
++ addr = attr->addr_mg1;
|
|
|
++ break;
|
|
|
++
|
|
|
+ case M09:
|
|
|
+ addr = attr->addr_m09;
|
|
|
+ break;
|
|
|
+@@ -504,13 +531,13 @@ out:
|
|
|
+ }
|
|
|
+
|
|
|
+ static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
|
|
|
+- M09_REGISTER_GAIN, M12_REGISTER_GAIN, 0, 31);
|
|
|
++ M09_REGISTER_GAIN, M12_REGISTER_GAIN, MG1_REGISTER_GAIN, 0, 31);
|
|
|
+ static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
|
|
|
+- M09_REGISTER_OFFSET, M12_REGISTER_OFFSET, 0, 31);
|
|
|
++ M09_REGISTER_OFFSET, M12_REGISTER_OFFSET, MG1_REGISTER_OFFSET, 0, 31);
|
|
|
+ static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
|
|
|
+- M09_REGISTER_THRESHOLD, M12_REGISTER_THRESHOLD, 1, 255);
|
|
|
++ M09_REGISTER_THRESHOLD, M12_REGISTER_THRESHOLD, MG1_REGISTER_THRESHOLD, 1, 255);
|
|
|
+ static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
|
|
|
+- NO_REGISTER, M12_REGISTER_REPORT_RATE, 3, 14);
|
|
|
++ M09_REGISTER_REPORT_RATE, M12_REGISTER_REPORT_RATE, MG1_REGISTER_REPORT_RATE, 3, 14);
|
|
|
+
|
|
|
+ static struct attribute *edt_ft5x06_attrs[] = {
|
|
|
+ &edt_ft5x06_attr_gain.dattr.attr,
|
|
|
+@@ -530,7 +557,7 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
|
|
|
+ struct i2c_client *client = tsdata->client;
|
|
|
+ int retries = EDT_SWITCH_MODE_RETRIES;
|
|
|
+ int ret;
|
|
|
+- int error;
|
|
|
++ int error = 0;
|
|
|
+
|
|
|
+ disable_irq(client->irq);
|
|
|
+
|
|
|
+@@ -545,7 +572,7 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
|
|
|
+ }
|
|
|
+
|
|
|
+ /* mode register is 0x3c when in the work mode */
|
|
|
+- if ((tsdata->version == M09) || (tsdata->version == M12))
|
|
|
++ if ((tsdata->version == M09) || (tsdata->version == M12) || (tsdata->version == MG1))
|
|
|
+ goto m09_out;
|
|
|
+
|
|
|
+ error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03);
|
|
|
+@@ -570,7 +597,8 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
|
|
|
+ error = -EIO;
|
|
|
+ goto err_out;
|
|
|
+ }
|
|
|
+-
|
|
|
++
|
|
|
++ printk(KERN_INFO "EDT-TC: %s: set to factory mode\n", __func__);
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ err_out:
|
|
|
+@@ -582,7 +610,7 @@ err_out:
|
|
|
+ return error;
|
|
|
+
|
|
|
+ m09_out:
|
|
|
+- dev_err(&client->dev, "No factory mode support for M09 and M12\n");
|
|
|
++ dev_err(&client->dev, "No factory mode support for M09, M12 and MG1\n");
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ }
|
|
|
+@@ -891,7 +919,8 @@ edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
|
|
|
+ tsdata->debug_dir, tsdata, &debugfs_raw_data_fops);
|
|
|
+
|
|
|
+ if (reg_addr->reg_report_rate != NO_REGISTER)
|
|
|
+- debugfs_create_u32("report_rate", S_IRUSR, tsdata->debug_dir, &tsdata->report_rate);
|
|
|
++ debugfs_create_u32("report_rate", S_IRUSR, tsdata->debug_dir,
|
|
|
++ &tsdata->report_rate);
|
|
|
+
|
|
|
+ debugfs_create_u32("invert_x", S_IRUSR | S_IWUSR,
|
|
|
+ tsdata->debug_dir, &tsdata->invert_x);
|
|
|
+@@ -986,14 +1015,17 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
|
|
|
+ error = edt_ft5x06_ts_readwrite(client, 1, "\xbb",
|
|
|
+ EDT_NAME_LEN - 1,
|
|
|
+ rdbuf);
|
|
|
++
|
|
|
++ printk(KERN_INFO "EDT-TC: %s: err %d rdbuf %s\n", __func__,
|
|
|
++ error, rdbuf);
|
|
|
++
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+
|
|
|
+- printk(KERN_INFO "EDT-TC:: %s ::-----%s----\n", __func__, rdbuf);
|
|
|
+ /* if we find something consistent, stay with that assumption
|
|
|
+ * at least M09 won't send 3 bytes here
|
|
|
+ */
|
|
|
+- if ((strnicmp(rdbuf + 1, "EP0", 3) == 0) && (strnicmp(rdbuf + 6, "M12", 3) != 0)) {
|
|
|
++ if ((strncasecmp(rdbuf + 1, "EP0", 3) == 0) && (strncasecmp(rdbuf + 6, "M12", 3) != 0)) {
|
|
|
+ tsdata->version = M06;
|
|
|
+
|
|
|
+ /* remove last '$' end marker */
|
|
|
+@@ -1007,7 +1039,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
|
|
|
+ *p++ = '\0';
|
|
|
+ strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
|
|
|
+ strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
|
|
|
+- } else if (!(strnicmp(rdbuf + 6, "M12", 3))) {
|
|
|
++ } else if (!(strncasecmp(rdbuf + 6, "M12", 3))) {
|
|
|
+ tsdata->version = M12;
|
|
|
+
|
|
|
+ error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
|
|
|
+@@ -1024,6 +1056,21 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
|
|
|
+
|
|
|
+ snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M12",
|
|
|
+ rdbuf[0] >> 4, rdbuf[0] & 0x0F);
|
|
|
++ }else if (!(strncasecmp(rdbuf + 6, "MG1", 3))) {
|
|
|
++ tsdata->version = MG1;
|
|
|
++ error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
|
|
|
++ 2, rdbuf);
|
|
|
++ if (error)
|
|
|
++ return error;
|
|
|
++
|
|
|
++ strlcpy(fw_version, rdbuf, 2);
|
|
|
++ error = edt_ft5x06_ts_readwrite(client, 1, "\xA8",
|
|
|
++ 1, rdbuf);
|
|
|
++ if (error)
|
|
|
++ return error;
|
|
|
++
|
|
|
++ snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0MG1",
|
|
|
++ rdbuf[0] >> 4, rdbuf[0] & 0x0F);
|
|
|
+ } else {
|
|
|
+ tsdata->version = M09;
|
|
|
+
|
|
|
+@@ -1069,6 +1116,12 @@ static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
|
|
|
+ EDT_GET_PROP(offset_M12, reg_addr->reg_offset);
|
|
|
+ break;
|
|
|
+
|
|
|
++ case MG1:
|
|
|
++ EDT_GET_PROP(threshold_MG1, reg_addr->reg_threshold);
|
|
|
++ EDT_GET_PROP(gain_MG1, reg_addr->reg_gain);
|
|
|
++ EDT_GET_PROP(offset_MG1, reg_addr->reg_offset);
|
|
|
++ break;
|
|
|
++
|
|
|
+ case M09:
|
|
|
+ EDT_GET_PROP(threshold_M09, reg_addr->reg_threshold);
|
|
|
+ EDT_GET_PROP(gain_M09, reg_addr->reg_gain);
|
|
|
+@@ -1114,6 +1167,10 @@ edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
|
|
|
+ reg_addr->reg_report_rate);
|
|
|
+ tsdata->num_x = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_x);
|
|
|
+ tsdata->num_y = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_y);
|
|
|
++
|
|
|
++ printk(KERN_INFO "EDT-TC:: %s ::VERS %d NUMX %d NUMY %d\n", __func__,
|
|
|
++ tsdata->version, tsdata->num_x, tsdata->num_y);
|
|
|
++
|
|
|
+
|
|
|
+ if(tsdata->max_x == 0)
|
|
|
+ tsdata->max_x = tsdata->num_x * 64;
|
|
|
+@@ -1146,8 +1203,18 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
|
|
|
+ reg_addr->reg_num_y = M12_REGISTER_NUM_Y;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case MG1:
|
|
|
++ reg_addr->reg_threshold = MG1_REGISTER_THRESHOLD;
|
|
|
++ reg_addr->reg_report_rate = MG1_REGISTER_REPORT_RATE;
|
|
|
++ reg_addr->reg_gain = MG1_REGISTER_GAIN;
|
|
|
++ reg_addr->reg_offset = MG1_REGISTER_OFFSET;
|
|
|
++ reg_addr->reg_num_x = MG1_REGISTER_NUM_X;
|
|
|
++ reg_addr->reg_num_y = MG1_REGISTER_NUM_Y;
|
|
|
++ break;
|
|
|
++
|
|
|
+ case M09:
|
|
|
+ reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
|
|
|
++ reg_addr->reg_report_rate = M09_REGISTER_REPORT_RATE;
|
|
|
+ reg_addr->reg_gain = M09_REGISTER_GAIN;
|
|
|
+ reg_addr->reg_offset = M09_REGISTER_OFFSET;
|
|
|
+ reg_addr->reg_num_x = M09_REGISTER_NUM_X;
|