Commit 7ccc4359be6d2c42e064ca03ea997e13aa8d7cce

Authored by Lothar Waßmann
Committed by Sekhar Nori
1 parent 61801fcf75

Input: edt-ft5x06 - add support for M09 firmware version

[ Upstream commit fd335ab04b3f1b3309dfbfea71a1a79a7bacc4ad ]

There is a new firmware version for the EDT-FT5x06 chip.
Add support for detecting the firmware version and handle the
differences appropriately.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>

Showing 1 changed file with 276 additions and 82 deletions Side-by-side Diff

drivers/input/touchscreen/edt-ft5x06.c
1 1 /*
2 2 * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de>
  3 + * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support)
3 4 * Lothar Waßmann <LW@KARO-electronics.de> (DT support)
4 5 *
5 6 * This software is licensed under the terms of the GNU General Public
... ... @@ -47,6 +48,14 @@
47 48 #define WORK_REGISTER_NUM_X 0x33
48 49 #define WORK_REGISTER_NUM_Y 0x34
49 50  
  51 +#define M09_REGISTER_THRESHOLD 0x80
  52 +#define M09_REGISTER_GAIN 0x92
  53 +#define M09_REGISTER_OFFSET 0x93
  54 +#define M09_REGISTER_NUM_X 0x94
  55 +#define M09_REGISTER_NUM_Y 0x95
  56 +
  57 +#define NO_REGISTER 0xff
  58 +
50 59 #define WORK_REGISTER_OPMODE 0x3c
51 60 #define FACTORY_REGISTER_OPMODE 0x01
52 61  
... ... @@ -61,6 +70,20 @@
61 70 #define EDT_RAW_DATA_RETRIES 100
62 71 #define EDT_RAW_DATA_DELAY 1 /* msec */
63 72  
  73 +enum edt_ver {
  74 + M06,
  75 + M09,
  76 +};
  77 +
  78 +struct edt_reg_addr {
  79 + int reg_threshold;
  80 + int reg_report_rate;
  81 + int reg_gain;
  82 + int reg_offset;
  83 + int reg_num_x;
  84 + int reg_num_y;
  85 +};
  86 +
64 87 struct edt_ft5x06_ts_data {
65 88 struct i2c_client *client;
66 89 struct input_dev *input;
... ... @@ -85,6 +108,9 @@
85 108 int report_rate;
86 109  
87 110 char name[EDT_NAME_LEN];
  111 +
  112 + struct edt_reg_addr reg_addr;
  113 + enum edt_ver version;
88 114 };
89 115  
90 116 static int edt_ft5x06_ts_readwrite(struct i2c_client *client,
91 117  
92 118  
93 119  
94 120  
95 121  
96 122  
... ... @@ -142,33 +168,58 @@
142 168 {
143 169 struct edt_ft5x06_ts_data *tsdata = dev_id;
144 170 struct device *dev = &tsdata->client->dev;
145   - u8 cmd = 0xf9;
146   - u8 rdbuf[26];
  171 + u8 cmd;
  172 + u8 rdbuf[29];
147 173 int i, type, x, y, id;
  174 + int offset, tplen, datalen;
148 175 int error;
149 176  
  177 + switch (tsdata->version) {
  178 + case M06:
  179 + cmd = 0xf9; /* tell the controller to send touch data */
  180 + offset = 5; /* where the actual touch data starts */
  181 + tplen = 4; /* data comes in so called frames */
  182 + datalen = 26; /* how much bytes to listen for */
  183 + break;
  184 +
  185 + case M09:
  186 + cmd = 0x02;
  187 + offset = 1;
  188 + tplen = 6;
  189 + datalen = 29;
  190 + break;
  191 +
  192 + default:
  193 + goto out;
  194 + }
  195 +
150 196 memset(rdbuf, 0, sizeof(rdbuf));
151 197  
152 198 error = edt_ft5x06_ts_readwrite(tsdata->client,
153 199 sizeof(cmd), &cmd,
154   - sizeof(rdbuf), rdbuf);
  200 + datalen, rdbuf);
155 201 if (error) {
156 202 dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
157 203 error);
158 204 goto out;
159 205 }
160 206  
161   - if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || rdbuf[2] != 26) {
162   - dev_err_ratelimited(dev, "Unexpected header: %02x%02x%02x!\n",
163   - rdbuf[0], rdbuf[1], rdbuf[2]);
164   - goto out;
  207 + /* M09 does not send header or CRC */
  208 + if (tsdata->version == M06) {
  209 + if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
  210 + rdbuf[2] != datalen) {
  211 + dev_err_ratelimited(dev,
  212 + "Unexpected header: %02x%02x%02x!\n",
  213 + rdbuf[0], rdbuf[1], rdbuf[2]);
  214 + goto out;
  215 + }
  216 +
  217 + if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen))
  218 + goto out;
165 219 }
166 220  
167   - if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, 26))
168   - goto out;
169   -
170 221 for (i = 0; i < MAX_SUPPORT_POINTS; i++) {
171   - u8 *buf = &rdbuf[i * 4 + 5];
  222 + u8 *buf = &rdbuf[i * tplen + offset];
172 223 bool down;
173 224  
174 225 type = buf[0] >> 6;
... ... @@ -176,8 +227,8 @@
176 227 if (type == TOUCH_EVENT_RESERVED)
177 228 continue;
178 229  
179   - /* ignore TOUCH_DOWN events, might have bogus coordinates */
180   - if (type == TOUCH_EVENT_DOWN)
  230 + /* M06 sometimes sends bogus coordinates in TOUCH_DOWN */
  231 + if (tsdata->version == M06 && type == TOUCH_EVENT_DOWN)
181 232 continue;
182 233  
183 234 x = ((buf[0] << 8) | buf[1]) & 0x0fff;
184 235  
... ... @@ -207,12 +258,25 @@
207 258 {
208 259 u8 wrbuf[4];
209 260  
210   - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
211   - wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
212   - wrbuf[2] = value;
213   - wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
  261 + switch (tsdata->version) {
  262 + case M06:
  263 + wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
  264 + wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  265 + wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  266 + wrbuf[2] = value;
  267 + wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
  268 + return edt_ft5x06_ts_readwrite(tsdata->client, 4,
  269 + wrbuf, 0, NULL);
  270 + case M09:
  271 + wrbuf[0] = addr;
  272 + wrbuf[1] = value;
214 273  
215   - return edt_ft5x06_ts_readwrite(tsdata->client, 4, wrbuf, 0, NULL);
  274 + return edt_ft5x06_ts_readwrite(tsdata->client, 3,
  275 + wrbuf, 0, NULL);
  276 +
  277 + default:
  278 + return -EINVAL;
  279 + }
216 280 }
217 281  
218 282 static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
219 283  
220 284  
... ... @@ -221,19 +285,35 @@
221 285 u8 wrbuf[2], rdbuf[2];
222 286 int error;
223 287  
224   - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
225   - wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
226   - wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
  288 + switch (tsdata->version) {
  289 + case M06:
  290 + wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
  291 + wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  292 + wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
227 293  
228   - error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2, rdbuf);
229   - if (error)
  294 + error = edt_ft5x06_ts_readwrite(tsdata->client,
  295 + 2, wrbuf, 2, rdbuf);
230 296 return error;
231 297  
232   - if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
233   - dev_err(&tsdata->client->dev,
234   - "crc error: 0x%02x expected, got 0x%02x\n",
235   - wrbuf[0] ^ wrbuf[1] ^ rdbuf[0], rdbuf[1]);
236   - return -EIO;
  298 + if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
  299 + dev_err(&tsdata->client->dev,
  300 + "crc error: 0x%02x expected, got 0x%02x\n",
  301 + wrbuf[0] ^ wrbuf[1] ^ rdbuf[0],
  302 + rdbuf[1]);
  303 + return -EIO;
  304 + }
  305 + break;
  306 +
  307 + case M09:
  308 + wrbuf[0] = addr;
  309 + error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
  310 + wrbuf, 1, rdbuf);
  311 + if (error)
  312 + return error;
  313 + break;
  314 +
  315 + default:
  316 + return -EINVAL;
237 317 }
238 318  
239 319 return rdbuf[0];
240 320  
241 321  
242 322  
... ... @@ -244,19 +324,21 @@
244 324 size_t field_offset;
245 325 u8 limit_low;
246 326 u8 limit_high;
247   - u8 addr;
  327 + u8 addr_m06;
  328 + u8 addr_m09;
248 329 };
249 330  
250   -#define EDT_ATTR(_field, _mode, _addr, _limit_low, _limit_high) \
  331 +#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, \
  332 + _limit_low, _limit_high) \
251 333 struct edt_ft5x06_attribute edt_ft5x06_attr_##_field = { \
252 334 .dattr = __ATTR(_field, _mode, \
253 335 edt_ft5x06_setting_show, \
254 336 edt_ft5x06_setting_store), \
255   - .field_offset = \
256   - offsetof(struct edt_ft5x06_ts_data, _field), \
  337 + .field_offset = offsetof(struct edt_ft5x06_ts_data, _field), \
  338 + .addr_m06 = _addr_m06, \
  339 + .addr_m09 = _addr_m09, \
257 340 .limit_low = _limit_low, \
258 341 .limit_high = _limit_high, \
259   - .addr = _addr, \
260 342 }
261 343  
262 344 static ssize_t edt_ft5x06_setting_show(struct device *dev,
... ... @@ -271,6 +353,7 @@
271 353 int val;
272 354 size_t count = 0;
273 355 int error = 0;
  356 + u8 addr;
274 357  
275 358 mutex_lock(&tsdata->mutex);
276 359  
277 360  
... ... @@ -279,15 +362,33 @@
279 362 goto out;
280 363 }
281 364  
282   - val = edt_ft5x06_register_read(tsdata, attr->addr);
283   - if (val < 0) {
284   - error = val;
285   - dev_err(&tsdata->client->dev,
286   - "Failed to fetch attribute %s, error %d\n",
287   - dattr->attr.name, error);
  365 + switch (tsdata->version) {
  366 + case M06:
  367 + addr = attr->addr_m06;
  368 + break;
  369 +
  370 + case M09:
  371 + addr = attr->addr_m09;
  372 + break;
  373 +
  374 + default:
  375 + error = -ENODEV;
288 376 goto out;
289 377 }
290 378  
  379 + if (addr != NO_REGISTER) {
  380 + val = edt_ft5x06_register_read(tsdata, addr);
  381 + if (val < 0) {
  382 + error = val;
  383 + dev_err(&tsdata->client->dev,
  384 + "Failed to fetch attribute %s, error %d\n",
  385 + dattr->attr.name, error);
  386 + goto out;
  387 + }
  388 + } else {
  389 + val = *field;
  390 + }
  391 +
291 392 if (val != *field) {
292 393 dev_warn(&tsdata->client->dev,
293 394 "%s: read (%d) and stored value (%d) differ\n",
... ... @@ -312,6 +413,7 @@
312 413 u8 *field = (u8 *)tsdata + attr->field_offset;
313 414 unsigned int val;
314 415 int error;
  416 + u8 addr;
315 417  
316 418 mutex_lock(&tsdata->mutex);
317 419  
318 420  
... ... @@ -329,14 +431,29 @@
329 431 goto out;
330 432 }
331 433  
332   - error = edt_ft5x06_register_write(tsdata, attr->addr, val);
333   - if (error) {
334   - dev_err(&tsdata->client->dev,
335   - "Failed to update attribute %s, error: %d\n",
336   - dattr->attr.name, error);
  434 + switch (tsdata->version) {
  435 + case M06:
  436 + addr = attr->addr_m06;
  437 + break;
  438 +
  439 + case M09:
  440 + addr = attr->addr_m09;
  441 + break;
  442 +
  443 + default:
  444 + error = -ENODEV;
337 445 goto out;
338 446 }
339 447  
  448 + if (addr != NO_REGISTER) {
  449 + error = edt_ft5x06_register_write(tsdata, addr, val);
  450 + if (error) {
  451 + dev_err(&tsdata->client->dev,
  452 + "Failed to update attribute %s, error: %d\n",
  453 + dattr->attr.name, error);
  454 + goto out;
  455 + }
  456 + }
340 457 *field = val;
341 458  
342 459 out:
... ... @@ -344,12 +461,14 @@
344 461 return error ?: count;
345 462 }
346 463  
347   -static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN, 0, 31);
348   -static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET, 0, 31);
349   -static EDT_ATTR(threshold, S_IWUSR | S_IRUGO,
350   - WORK_REGISTER_THRESHOLD, 20, 80);
351   -static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO,
352   - WORK_REGISTER_REPORT_RATE, 3, 14);
  464 +static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
  465 + M09_REGISTER_GAIN, 0, 31);
  466 +static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
  467 + M09_REGISTER_OFFSET, 0, 31);
  468 +static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
  469 + M09_REGISTER_THRESHOLD, 20, 80);
  470 +static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
  471 + NO_REGISTER, 3, 14);
353 472  
354 473 static struct attribute *edt_ft5x06_attrs[] = {
355 474 &edt_ft5x06_attr_gain.dattr.attr,
... ... @@ -384,6 +503,9 @@
384 503 }
385 504  
386 505 /* mode register is 0x3c when in the work mode */
  506 + if (tsdata->version == M09)
  507 + goto m09_out;
  508 +
387 509 error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03);
388 510 if (error) {
389 511 dev_err(&client->dev,
390 512  
... ... @@ -416,12 +538,18 @@
416 538 enable_irq(client->irq);
417 539  
418 540 return error;
  541 +
  542 +m09_out:
  543 + dev_err(&client->dev, "No factory mode support for M09\n");
  544 + return -EINVAL;
  545 +
419 546 }
420 547  
421 548 static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
422 549 {
423 550 struct i2c_client *client = tsdata->client;
424 551 int retries = EDT_SWITCH_MODE_RETRIES;
  552 + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
425 553 int ret;
426 554 int error;
427 555  
428 556  
429 557  
430 558  
... ... @@ -454,13 +582,14 @@
454 582 tsdata->raw_buffer = NULL;
455 583  
456 584 /* restore parameters */
457   - edt_ft5x06_register_write(tsdata, WORK_REGISTER_THRESHOLD,
  585 + edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
458 586 tsdata->threshold);
459   - edt_ft5x06_register_write(tsdata, WORK_REGISTER_GAIN,
  587 + edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
460 588 tsdata->gain);
461   - edt_ft5x06_register_write(tsdata, WORK_REGISTER_OFFSET,
  589 + edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
462 590 tsdata->offset);
463   - edt_ft5x06_register_write(tsdata, WORK_REGISTER_REPORT_RATE,
  591 + if (reg_addr->reg_report_rate)
  592 + edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
464 593 tsdata->report_rate);
465 594  
466 595 enable_irq(client->irq);
467 596  
468 597  
469 598  
470 599  
471 600  
472 601  
... ... @@ -663,31 +792,61 @@
663 792 }
664 793  
665 794 static int edt_ft5x06_ts_identify(struct i2c_client *client,
666   - char *model_name,
667   - char *fw_version)
  795 + struct edt_ft5x06_ts_data *tsdata,
  796 + char *fw_version)
668 797 {
669 798 u8 rdbuf[EDT_NAME_LEN];
670 799 char *p;
671 800 int error;
  801 + char *model_name = tsdata->name;
672 802  
  803 + /* see what we find if we assume it is a M06 *
  804 + * if we get less than EDT_NAME_LEN, we don't want
  805 + * to have garbage in there
  806 + */
  807 + memset(rdbuf, 0, sizeof(rdbuf));
673 808 error = edt_ft5x06_ts_readwrite(client, 1, "\xbb",
674 809 EDT_NAME_LEN - 1, rdbuf);
675 810 if (error)
676 811 return error;
677 812  
678   - /* remove last '$' end marker */
679   - rdbuf[EDT_NAME_LEN - 1] = '\0';
680   - if (rdbuf[EDT_NAME_LEN - 2] == '$')
681   - rdbuf[EDT_NAME_LEN - 2] = '\0';
  813 + /* if we find something consistent, stay with that assumption
  814 + * at least M09 won't send 3 bytes here
  815 + */
  816 + if (!(strnicmp(rdbuf + 1, "EP0", 3))) {
  817 + tsdata->version = M06;
682 818  
683   - /* look for Model/Version separator */
684   - p = strchr(rdbuf, '*');
685   - if (p)
686   - *p++ = '\0';
  819 + /* remove last '$' end marker */
  820 + rdbuf[EDT_NAME_LEN - 1] = '\0';
  821 + if (rdbuf[EDT_NAME_LEN - 2] == '$')
  822 + rdbuf[EDT_NAME_LEN - 2] = '\0';
687 823  
688   - strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
689   - strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
  824 + /* look for Model/Version separator */
  825 + p = strchr(rdbuf, '*');
  826 + if (p)
  827 + *p++ = '\0';
  828 + strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
  829 + strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
  830 + } else {
  831 + /* since there are only two versions around (M06, M09) */
  832 + tsdata->version = M09;
690 833  
  834 + error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
  835 + 2, rdbuf);
  836 + if (error)
  837 + return error;
  838 +
  839 + strlcpy(fw_version, rdbuf, 2);
  840 +
  841 + error = edt_ft5x06_ts_readwrite(client, 1, "\xA8",
  842 + 1, rdbuf);
  843 + if (error)
  844 + return error;
  845 +
  846 + snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09",
  847 + rdbuf[0] >> 4, rdbuf[0] & 0x0F);
  848 + }
  849 +
691 850 return 0;
692 851 }
693 852  
694 853  
695 854  
696 855  
697 856  
698 857  
... ... @@ -705,38 +864,71 @@
705 864 static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
706 865 struct edt_ft5x06_ts_data *tsdata)
707 866 {
708   - EDT_GET_PROP(threshold, WORK_REGISTER_THRESHOLD);
709   - EDT_GET_PROP(gain, WORK_REGISTER_GAIN);
710   - EDT_GET_PROP(offset, WORK_REGISTER_OFFSET);
  867 + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  868 +
  869 + EDT_GET_PROP(threshold, reg_addr->reg_threshold);
  870 + EDT_GET_PROP(gain, reg_addr->reg_gain);
  871 + EDT_GET_PROP(offset, reg_addr->reg_offset);
711 872 }
712 873  
713 874 static void
714 875 edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata,
715 876 const struct edt_ft5x06_platform_data *pdata)
716 877 {
  878 + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  879 +
717 880 if (!pdata->use_parameters)
718 881 return;
719 882  
720 883 /* pick up defaults from the platform data */
721   - EDT_ATTR_CHECKSET(threshold, WORK_REGISTER_THRESHOLD);
722   - EDT_ATTR_CHECKSET(gain, WORK_REGISTER_GAIN);
723   - EDT_ATTR_CHECKSET(offset, WORK_REGISTER_OFFSET);
724   - EDT_ATTR_CHECKSET(report_rate, WORK_REGISTER_REPORT_RATE);
  884 + EDT_ATTR_CHECKSET(threshold, reg_addr->reg_threshold);
  885 + EDT_ATTR_CHECKSET(gain, reg_addr->reg_gain);
  886 + EDT_ATTR_CHECKSET(offset, reg_addr->reg_offset);
  887 + if (reg_addr->reg_report_rate != NO_REGISTER)
  888 + EDT_ATTR_CHECKSET(report_rate, reg_addr->reg_report_rate);
725 889 }
726 890  
727 891 static void
728 892 edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
729 893 {
  894 + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  895 +
730 896 tsdata->threshold = edt_ft5x06_register_read(tsdata,
731   - WORK_REGISTER_THRESHOLD);
732   - tsdata->gain = edt_ft5x06_register_read(tsdata, WORK_REGISTER_GAIN);
733   - tsdata->offset = edt_ft5x06_register_read(tsdata, WORK_REGISTER_OFFSET);
734   - tsdata->report_rate = edt_ft5x06_register_read(tsdata,
735   - WORK_REGISTER_REPORT_RATE);
736   - tsdata->num_x = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_X);
737   - tsdata->num_y = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_Y);
  897 + reg_addr->reg_threshold);
  898 + tsdata->gain = edt_ft5x06_register_read(tsdata, reg_addr->reg_gain);
  899 + tsdata->offset = edt_ft5x06_register_read(tsdata, reg_addr->reg_offset);
  900 + if (reg_addr->reg_report_rate != NO_REGISTER)
  901 + tsdata->report_rate = edt_ft5x06_register_read(tsdata,
  902 + reg_addr->reg_report_rate);
  903 + tsdata->num_x = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_x);
  904 + tsdata->num_y = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_y);
738 905 }
739 906  
  907 +static void
  908 +edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
  909 +{
  910 + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  911 +
  912 + switch (tsdata->version) {
  913 + case M06:
  914 + reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD;
  915 + reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE;
  916 + reg_addr->reg_gain = WORK_REGISTER_GAIN;
  917 + reg_addr->reg_offset = WORK_REGISTER_OFFSET;
  918 + reg_addr->reg_num_x = WORK_REGISTER_NUM_X;
  919 + reg_addr->reg_num_y = WORK_REGISTER_NUM_Y;
  920 + break;
  921 +
  922 + case M09:
  923 + reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
  924 + reg_addr->reg_gain = M09_REGISTER_GAIN;
  925 + reg_addr->reg_offset = M09_REGISTER_OFFSET;
  926 + reg_addr->reg_num_x = M09_REGISTER_NUM_X;
  927 + reg_addr->reg_num_y = M09_REGISTER_NUM_Y;
  928 + break;
  929 + }
  930 +}
  931 +
740 932 #ifdef CONFIG_OF
741 933 static int edt_ft5x06_i2c_ts_probe_dt(struct device *dev,
742 934 struct edt_ft5x06_ts_data *tsdata)
743 935  
... ... @@ -818,11 +1010,13 @@
818 1010 tsdata->input = input;
819 1011 tsdata->factory_mode = false;
820 1012  
821   - error = edt_ft5x06_ts_identify(client, tsdata->name, fw_version);
  1013 + error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
822 1014 if (error) {
823 1015 dev_err(&client->dev, "touchscreen probe failed\n");
824 1016 return error;
825 1017 }
  1018 +
  1019 + edt_ft5x06_ts_set_regs(tsdata);
826 1020  
827 1021 if (!pdata)
828 1022 edt_ft5x06_ts_get_dt_defaults(client->dev.of_node, tsdata);