Guest User

Untitled

a guest
Jul 18th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.87 KB | None | 0 0
  1. From 1ac1694be1a98d899247ff1597866a06422dce27 Mon Sep 17 00:00:00 2001
  2. From: Robert Woerle <robert@linuxdevelopment.de>
  3. Date: Thu, 30 Jun 2016 14:01:59 +0200
  4. Subject: backport edt touch
  5.  
  6. Signed-off-by: Robert Woerle <robert@linuxdevelopment.de>
  7. ---
  8. drivers/input/touchscreen/edt-ft5x06.c | 761 +++++++++++++++++++++++++--------
  9. 1 file changed, 571 insertions(+), 190 deletions(-)
  10.  
  11. diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
  12. index 83fa1b1..f0c036c 100644
  13. --- a/drivers/input/touchscreen/edt-ft5x06.c
  14. +++ b/drivers/input/touchscreen/edt-ft5x06.c
  15. @@ -1,5 +1,7 @@
  16. /*
  17. * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de>
  18. + * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support)
  19. + * Lothar Waßmann <LW@KARO-electronics.de> (DT support)
  20. *
  21. * This software is licensed under the terms of the GNU General Public
  22. * License version 2, as published by the Free Software Foundation, and
  23. @@ -33,10 +35,12 @@
  24. #include <linux/debugfs.h>
  25. #include <linux/slab.h>
  26. #include <linux/gpio.h>
  27. +#include <linux/of_gpio.h>
  28. +#include <linux/of_device.h>
  29. #include <linux/input/mt.h>
  30. #include <linux/input/edt-ft5x06.h>
  31.  
  32. -#define MAX_SUPPORT_POINTS 5
  33. +#define DRIVER_VERSION "v1.0.1"
  34.  
  35. #define WORK_REGISTER_THRESHOLD 0x00
  36. #define WORK_REGISTER_REPORT_RATE 0x08
  37. @@ -45,6 +49,14 @@
  38. #define WORK_REGISTER_NUM_X 0x33
  39. #define WORK_REGISTER_NUM_Y 0x34
  40.  
  41. +#define M09_REGISTER_THRESHOLD 0x80
  42. +#define M09_REGISTER_GAIN 0x92
  43. +#define M09_REGISTER_OFFSET 0x93
  44. +#define M09_REGISTER_NUM_X 0x94
  45. +#define M09_REGISTER_NUM_Y 0x95
  46. +
  47. +#define NO_REGISTER 0xff
  48. +
  49. #define WORK_REGISTER_OPMODE 0x3c
  50. #define FACTORY_REGISTER_OPMODE 0x01
  51.  
  52. @@ -59,12 +71,34 @@
  53. #define EDT_RAW_DATA_RETRIES 100
  54. #define EDT_RAW_DATA_DELAY 1 /* msec */
  55.  
  56. +enum edt_ver {
  57. + M06,
  58. + M09,
  59. +};
  60. +
  61. +struct edt_reg_addr {
  62. + int reg_threshold;
  63. + int reg_report_rate;
  64. + int reg_gain;
  65. + int reg_offset;
  66. + int reg_num_x;
  67. + int reg_num_y;
  68. +};
  69. +
  70. struct edt_ft5x06_ts_data {
  71. struct i2c_client *client;
  72. struct input_dev *input;
  73. u16 num_x;
  74. u16 num_y;
  75.  
  76. +/* struct gpio_desc *reset_pin;
  77. + struct gpio_desc *wake_pin;
  78. + struct gpio_desc *irq_pin;
  79. +*/
  80. + int reset_pin;
  81. + int wake_pin;
  82. + int irq_pin;
  83. +
  84. #if defined(CONFIG_DEBUG_FS)
  85. struct dentry *debug_dir;
  86. u8 *raw_buffer;
  87. @@ -77,8 +111,25 @@ struct edt_ft5x06_ts_data {
  88. int gain;
  89. int offset;
  90. int report_rate;
  91. + int max_support_points;
  92. +
  93. + unsigned char rdbuf[20][61];
  94. +
  95. + int queue_size;
  96. + int queue_ptn;
  97. + int invalidate_queue;
  98. + struct timer_list queue_up_timer;
  99. + bool events_valid;
  100. + int filter_cnt;
  101.  
  102. char name[EDT_NAME_LEN];
  103. +
  104. + struct edt_reg_addr reg_addr;
  105. + enum edt_ver version;
  106. +};
  107. +
  108. +struct edt_i2c_chip_data {
  109. + int max_support_points;
  110. };
  111.  
  112. static int edt_ft5x06_ts_readwrite(struct i2c_client *client,
  113. @@ -132,37 +183,26 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
  114. return true;
  115. }
  116.  
  117. -static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
  118. +static void edt_ft5x06_report_event( void *dev_id)
  119. {
  120. struct edt_ft5x06_ts_data *tsdata = dev_id;
  121. - struct device *dev = &tsdata->client->dev;
  122. - u8 cmd = 0xf9;
  123. - u8 rdbuf[26];
  124. - int i, type, x, y, id;
  125. - int error;
  126. -
  127. - memset(rdbuf, 0, sizeof(rdbuf));
  128. -
  129. - error = edt_ft5x06_ts_readwrite(tsdata->client,
  130. - sizeof(cmd), &cmd,
  131. - sizeof(rdbuf), rdbuf);
  132. - if (error) {
  133. - dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
  134. - error);
  135. + int i, type, x, y, id, tplen, offset;
  136. +
  137. + switch (tsdata->version){
  138. + case M06:
  139. + offset = 5;
  140. + tplen = 4;
  141. + break;
  142. + case M09:
  143. + offset = 3;
  144. + tplen = 6;
  145. + break;
  146. + default:
  147. goto out;
  148. }
  149.  
  150. - if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || rdbuf[2] != 26) {
  151. - dev_err_ratelimited(dev, "Unexpected header: %02x%02x%02x!\n",
  152. - rdbuf[0], rdbuf[1], rdbuf[2]);
  153. - goto out;
  154. - }
  155. -
  156. - if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, 26))
  157. - goto out;
  158. -
  159. - for (i = 0; i < MAX_SUPPORT_POINTS; i++) {
  160. - u8 *buf = &rdbuf[i * 4 + 5];
  161. + for (i = 0; i < tsdata->max_support_points; i++) {
  162. + u8 *buf = &tsdata->rdbuf[tsdata->queue_ptn][i * tplen + offset];
  163. bool down;
  164.  
  165. type = buf[0] >> 6;
  166. @@ -170,10 +210,14 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
  167. if (type == TOUCH_EVENT_RESERVED)
  168. continue;
  169.  
  170. + /* M06 sometimes sends bogus coordinates in TOUCH_DOWN */
  171. + if (tsdata->version == M06 && type == TOUCH_EVENT_DOWN)
  172. + continue;
  173. +
  174. x = ((buf[0] << 8) | buf[1]) & 0x0fff;
  175. y = ((buf[2] << 8) | buf[3]) & 0x0fff;
  176. id = (buf[2] >> 4) & 0x0f;
  177. - down = (type != TOUCH_EVENT_UP);
  178. + down = type != TOUCH_EVENT_UP;
  179.  
  180. input_mt_slot(tsdata->input, id);
  181. input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, down);
  182. @@ -189,20 +233,122 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
  183. input_sync(tsdata->input);
  184.  
  185. out:
  186. + return;
  187. +}
  188. +
  189. +static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
  190. +{
  191. + struct edt_ft5x06_ts_data *tsdata = dev_id;
  192. + struct device *dev = &tsdata->client->dev;
  193. + u8 cmd;
  194. + int offset, tplen, datalen;
  195. + int error;
  196. +
  197. + switch (tsdata->version) {
  198. + case M06:
  199. + cmd = 0xf9; /* tell the controller to send touch data */
  200. + offset = 5; /* where the actual touch data starts */
  201. + tplen = 4; /* data comes in so called frames */
  202. +
  203. + /* how many bytes to listen for */
  204. + datalen = tplen * tsdata->max_support_points + offset + 1;
  205. + break;
  206. +
  207. + case M09:
  208. + cmd = 0x0;
  209. + offset = 3;
  210. + tplen = 6;
  211. + datalen = tplen * tsdata->max_support_points + 1 - cmd;
  212. + break;
  213. +
  214. + default:
  215. + goto out;
  216. + }
  217. +
  218. + memset(tsdata->rdbuf[tsdata->queue_ptn], 0, sizeof(tsdata->rdbuf[tsdata->queue_ptn]));
  219. +
  220. + error = edt_ft5x06_ts_readwrite(tsdata->client,
  221. + sizeof(cmd), &cmd,
  222. + datalen, tsdata->rdbuf[tsdata->queue_ptn]);
  223. + if (error) {
  224. + dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
  225. + error);
  226. + goto out;
  227. + }
  228. +
  229. + /* M09 does not send header or CRC */
  230. + if (tsdata->version == M06) {
  231. + if (tsdata->rdbuf[tsdata->queue_ptn][0] != 0xaa
  232. + || tsdata->rdbuf[tsdata->queue_ptn][1] != 0xaa
  233. + || tsdata->rdbuf[tsdata->queue_ptn][2] != datalen) {
  234. + dev_err_ratelimited(dev,
  235. + "Unexpected header: %02x%02x%02x!\n",
  236. + tsdata->rdbuf[tsdata->queue_ptn][0],
  237. + tsdata->rdbuf[tsdata->queue_ptn][1],
  238. + tsdata->rdbuf[tsdata->queue_ptn][2]);
  239. + goto out;
  240. + }
  241. +
  242. + if (!edt_ft5x06_ts_check_crc(tsdata, tsdata->rdbuf[tsdata->queue_ptn], datalen))
  243. + goto out;
  244. + }
  245. +
  246. + if (!tsdata->events_valid)
  247. + tsdata->queue_ptn++;
  248. + else
  249. + edt_ft5x06_report_event(dev_id);
  250. +
  251. + if (tsdata->queue_ptn >= tsdata->queue_size) {
  252. + for (tsdata->queue_ptn = 0; tsdata->queue_ptn < tsdata->queue_size; tsdata->queue_ptn++) {
  253. + mod_timer(&tsdata->queue_up_timer, jiffies + msecs_to_jiffies(tsdata->invalidate_queue));
  254. + edt_ft5x06_report_event(dev_id);
  255. + }
  256. + tsdata->events_valid = 1;
  257. + tsdata->queue_ptn = 0;
  258. + }
  259. + mod_timer(&tsdata->queue_up_timer, jiffies + msecs_to_jiffies(tsdata->invalidate_queue));
  260. +
  261. +out:
  262. return IRQ_HANDLED;
  263. }
  264.  
  265. +static void edt_ft5x06_queue_up_timer(unsigned long data)
  266. +{
  267. + struct edt_ft5x06_ts_data *tsdata = (void *)data;
  268. +
  269. + /* count up if filter timeout came but had no valid amount */
  270. + if (!tsdata->events_valid)
  271. + tsdata->filter_cnt++;
  272. +
  273. + tsdata->events_valid = 0;
  274. + tsdata->queue_ptn = 0;
  275. + /* clear queue again */
  276. + memset(tsdata->rdbuf, 0, sizeof(tsdata->rdbuf));
  277. +}
  278. +
  279. static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
  280. u8 addr, u8 value)
  281. {
  282. u8 wrbuf[4];
  283.  
  284. - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
  285. - wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  286. - wrbuf[2] = value;
  287. - wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
  288. -
  289. - return edt_ft5x06_ts_readwrite(tsdata->client, 4, wrbuf, 0, NULL);
  290. + switch (tsdata->version) {
  291. + case M06:
  292. + wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
  293. + wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  294. + wrbuf[2] = value;
  295. + wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
  296. + return edt_ft5x06_ts_readwrite(tsdata->client, 4,
  297. + wrbuf, 0, NULL);
  298. + case M09:
  299. + wrbuf[0] = addr;
  300. + wrbuf[1] = value;
  301. +
  302. + return edt_ft5x06_ts_readwrite(tsdata->client, 2,
  303. + wrbuf, 0, NULL);
  304. +
  305. + default:
  306. + return -EINVAL;
  307. + }
  308. }
  309.  
  310. static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
  311. @@ -211,19 +357,36 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
  312. u8 wrbuf[2], rdbuf[2];
  313. int error;
  314.  
  315. - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
  316. - wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  317. - wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
  318. + switch (tsdata->version) {
  319. + case M06:
  320. + wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
  321. + wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
  322. + wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
  323.  
  324. - error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2, rdbuf);
  325. - if (error)
  326. - return error;
  327. + error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2,
  328. + rdbuf);
  329. + if (error)
  330. + return error;
  331.  
  332. - if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
  333. - dev_err(&tsdata->client->dev,
  334. - "crc error: 0x%02x expected, got 0x%02x\n",
  335. - wrbuf[0] ^ wrbuf[1] ^ rdbuf[0], rdbuf[1]);
  336. - return -EIO;
  337. + if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
  338. + dev_err(&tsdata->client->dev,
  339. + "crc error: 0x%02x expected, got 0x%02x\n",
  340. + wrbuf[0] ^ wrbuf[1] ^ rdbuf[0],
  341. + rdbuf[1]);
  342. + return -EIO;
  343. + }
  344. + break;
  345. +
  346. + case M09:
  347. + wrbuf[0] = addr;
  348. + error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
  349. + wrbuf, 1, rdbuf);
  350. + if (error)
  351. + return error;
  352. + break;
  353. +
  354. + default:
  355. + return -EINVAL;
  356. }
  357.  
  358. return rdbuf[0];
  359. @@ -234,19 +397,21 @@ struct edt_ft5x06_attribute {
  360. size_t field_offset;
  361. u8 limit_low;
  362. u8 limit_high;
  363. - u8 addr;
  364. + u8 addr_m06;
  365. + u8 addr_m09;
  366. };
  367.  
  368. -#define EDT_ATTR(_field, _mode, _addr, _limit_low, _limit_high) \
  369. +#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, \
  370. + _limit_low, _limit_high) \
  371. struct edt_ft5x06_attribute edt_ft5x06_attr_##_field = { \
  372. .dattr = __ATTR(_field, _mode, \
  373. edt_ft5x06_setting_show, \
  374. edt_ft5x06_setting_store), \
  375. - .field_offset = \
  376. - offsetof(struct edt_ft5x06_ts_data, _field), \
  377. + .field_offset = offsetof(struct edt_ft5x06_ts_data, _field), \
  378. + .addr_m06 = _addr_m06, \
  379. + .addr_m09 = _addr_m09, \
  380. .limit_low = _limit_low, \
  381. .limit_high = _limit_high, \
  382. - .addr = _addr, \
  383. }
  384.  
  385. static ssize_t edt_ft5x06_setting_show(struct device *dev,
  386. @@ -257,10 +422,11 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
  387. struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
  388. struct edt_ft5x06_attribute *attr =
  389. container_of(dattr, struct edt_ft5x06_attribute, dattr);
  390. - u8 *field = (u8 *)((char *)tsdata + attr->field_offset);
  391. + u8 *field = (u8 *)tsdata + attr->field_offset;
  392. int val;
  393. size_t count = 0;
  394. int error = 0;
  395. + u8 addr;
  396.  
  397. mutex_lock(&tsdata->mutex);
  398.  
  399. @@ -269,15 +435,33 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
  400. goto out;
  401. }
  402.  
  403. - val = edt_ft5x06_register_read(tsdata, attr->addr);
  404. - if (val < 0) {
  405. - error = val;
  406. - dev_err(&tsdata->client->dev,
  407. - "Failed to fetch attribute %s, error %d\n",
  408. - dattr->attr.name, error);
  409. + switch (tsdata->version) {
  410. + case M06:
  411. + addr = attr->addr_m06;
  412. + break;
  413. +
  414. + case M09:
  415. + addr = attr->addr_m09;
  416. + break;
  417. +
  418. + default:
  419. + error = -ENODEV;
  420. goto out;
  421. }
  422.  
  423. + if (addr != NO_REGISTER) {
  424. + val = edt_ft5x06_register_read(tsdata, addr);
  425. + if (val < 0) {
  426. + error = val;
  427. + dev_err(&tsdata->client->dev,
  428. + "Failed to fetch attribute %s, error %d\n",
  429. + dattr->attr.name, error);
  430. + goto out;
  431. + }
  432. + } else {
  433. + val = *field;
  434. + }
  435. +
  436. if (val != *field) {
  437. dev_warn(&tsdata->client->dev,
  438. "%s: read (%d) and stored value (%d) differ\n",
  439. @@ -299,9 +483,10 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
  440. struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
  441. struct edt_ft5x06_attribute *attr =
  442. container_of(dattr, struct edt_ft5x06_attribute, dattr);
  443. - u8 *field = (u8 *)((char *)tsdata + attr->field_offset);
  444. + u8 *field = (u8 *)tsdata + attr->field_offset;
  445. unsigned int val;
  446. int error;
  447. + u8 addr;
  448.  
  449. mutex_lock(&tsdata->mutex);
  450.  
  451. @@ -319,14 +504,29 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
  452. goto out;
  453. }
  454.  
  455. - error = edt_ft5x06_register_write(tsdata, attr->addr, val);
  456. - if (error) {
  457. - dev_err(&tsdata->client->dev,
  458. - "Failed to update attribute %s, error: %d\n",
  459. - dattr->attr.name, error);
  460. + switch (tsdata->version) {
  461. + case M06:
  462. + addr = attr->addr_m06;
  463. + break;
  464. +
  465. + case M09:
  466. + addr = attr->addr_m09;
  467. + break;
  468. +
  469. + default:
  470. + error = -ENODEV;
  471. goto out;
  472. }
  473.  
  474. + if (addr != NO_REGISTER) {
  475. + error = edt_ft5x06_register_write(tsdata, addr, val);
  476. + if (error) {
  477. + dev_err(&tsdata->client->dev,
  478. + "Failed to update attribute %s, error: %d\n",
  479. + dattr->attr.name, error);
  480. + goto out;
  481. + }
  482. + }
  483. *field = val;
  484.  
  485. out:
  486. @@ -334,18 +534,29 @@ out:
  487. return error ?: count;
  488. }
  489.  
  490. -static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN, 0, 31);
  491. -static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET, 0, 31);
  492. -static EDT_ATTR(threshold, S_IWUSR | S_IRUGO,
  493. - WORK_REGISTER_THRESHOLD, 20, 80);
  494. -static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO,
  495. - WORK_REGISTER_REPORT_RATE, 3, 14);
  496. +static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
  497. + M09_REGISTER_GAIN, 0, 31);
  498. +static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
  499. + M09_REGISTER_OFFSET, 0, 31);
  500. +static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
  501. + M09_REGISTER_THRESHOLD, 20, 80);
  502. +static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
  503. + NO_REGISTER, 3, 14);
  504. +static EDT_ATTR(queue_size, S_IWUSR | S_IRUGO,
  505. + NO_REGISTER, NO_REGISTER, 0, 20);
  506. +static EDT_ATTR(invalidate_queue, S_IWUSR | S_IRUGO,
  507. + NO_REGISTER, NO_REGISTER, 28, 100);
  508. +static EDT_ATTR(filter_cnt, S_IWUSR | S_IRUGO,
  509. + NO_REGISTER, NO_REGISTER, 0, 255);
  510.  
  511. static struct attribute *edt_ft5x06_attrs[] = {
  512. &edt_ft5x06_attr_gain.dattr.attr,
  513. &edt_ft5x06_attr_offset.dattr.attr,
  514. &edt_ft5x06_attr_threshold.dattr.attr,
  515. &edt_ft5x06_attr_report_rate.dattr.attr,
  516. + &edt_ft5x06_attr_queue_size.dattr.attr,
  517. + &edt_ft5x06_attr_invalidate_queue.dattr.attr,
  518. + &edt_ft5x06_attr_filter_cnt.dattr.attr,
  519. NULL
  520. };
  521.  
  522. @@ -374,6 +585,9 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
  523. }
  524.  
  525. /* mode register is 0x3c when in the work mode */
  526. + if (tsdata->version == M09)
  527. + goto m09_out;
  528. +
  529. error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03);
  530. if (error) {
  531. dev_err(&client->dev,
  532. @@ -406,12 +620,18 @@ err_out:
  533. enable_irq(client->irq);
  534.  
  535. return error;
  536. +
  537. +m09_out:
  538. + dev_err(&client->dev, "No factory mode support for M09\n");
  539. + return -EINVAL;
  540. +
  541. }
  542.  
  543. static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
  544. {
  545. struct i2c_client *client = tsdata->client;
  546. int retries = EDT_SWITCH_MODE_RETRIES;
  547. + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  548. int ret;
  549. int error;
  550.  
  551. @@ -444,13 +664,14 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
  552. tsdata->raw_buffer = NULL;
  553.  
  554. /* restore parameters */
  555. - edt_ft5x06_register_write(tsdata, WORK_REGISTER_THRESHOLD,
  556. + edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
  557. tsdata->threshold);
  558. - edt_ft5x06_register_write(tsdata, WORK_REGISTER_GAIN,
  559. + edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
  560. tsdata->gain);
  561. - edt_ft5x06_register_write(tsdata, WORK_REGISTER_OFFSET,
  562. + edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
  563. tsdata->offset);
  564. - edt_ft5x06_register_write(tsdata, WORK_REGISTER_REPORT_RATE,
  565. + if (reg_addr->reg_report_rate)
  566. + edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
  567. tsdata->report_rate);
  568.  
  569. enable_irq(client->irq);
  570. @@ -479,7 +700,7 @@ static int edt_ft5x06_debugfs_mode_set(void *data, u64 mode)
  571.  
  572. if (mode != tsdata->factory_mode) {
  573. retval = mode ? edt_ft5x06_factory_mode(tsdata) :
  574. - edt_ft5x06_work_mode(tsdata);
  575. + edt_ft5x06_work_mode(tsdata);
  576. }
  577.  
  578. mutex_unlock(&tsdata->mutex);
  579. @@ -568,7 +789,6 @@ out:
  580. return error ?: read;
  581. };
  582.  
  583. -
  584. static const struct file_operations debugfs_raw_data_fops = {
  585. .open = simple_open,
  586. .read = edt_ft5x06_debugfs_raw_data_read,
  587. @@ -594,8 +814,7 @@ edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
  588. static void
  589. edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
  590. {
  591. - if (tsdata->debug_dir)
  592. - debugfs_remove_recursive(tsdata->debug_dir);
  593. + debugfs_remove_recursive(tsdata->debug_dir);
  594. kfree(tsdata->raw_buffer);
  595. }
  596.  
  597. @@ -614,131 +833,261 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
  598.  
  599. #endif /* CONFIG_DEBUGFS */
  600.  
  601. -
  602. -
  603. -static int edt_ft5x06_ts_reset(struct i2c_client *client,
  604. - int reset_pin)
  605. -{
  606. - int error;
  607. -
  608. - if (gpio_is_valid(reset_pin)) {
  609. - /* this pulls reset down, enabling the low active reset */
  610. - error = gpio_request_one(reset_pin, GPIOF_OUT_INIT_LOW,
  611. - "edt-ft5x06 reset");
  612. - if (error) {
  613. - dev_err(&client->dev,
  614. - "Failed to request GPIO %d as reset pin, error %d\n",
  615. - reset_pin, error);
  616. - return error;
  617. - }
  618. -
  619. - mdelay(50);
  620. - gpio_set_value(reset_pin, 1);
  621. - mdelay(100);
  622. - }
  623. -
  624. - return 0;
  625. -}
  626. -
  627. static int edt_ft5x06_ts_identify(struct i2c_client *client,
  628. - char *model_name,
  629. - char *fw_version)
  630. + struct edt_ft5x06_ts_data *tsdata,
  631. + char *fw_version)
  632. {
  633. u8 rdbuf[EDT_NAME_LEN];
  634. char *p;
  635. int error;
  636. + char *model_name = tsdata->name;
  637.  
  638. + /* see what we find if we assume it is a M06 *
  639. + * if we get less than EDT_NAME_LEN, we don't want
  640. + * to have garbage in there
  641. + */
  642. + memset(rdbuf, 0, sizeof(rdbuf));
  643. error = edt_ft5x06_ts_readwrite(client, 1, "\xbb",
  644. EDT_NAME_LEN - 1, rdbuf);
  645. if (error)
  646. return error;
  647.  
  648. - /* remove last '$' end marker */
  649. - rdbuf[EDT_NAME_LEN - 1] = '\0';
  650. - if (rdbuf[EDT_NAME_LEN - 2] == '$')
  651. - rdbuf[EDT_NAME_LEN - 2] = '\0';
  652. + /* if we find something consistent, stay with that assumption
  653. + * at least M09 won't send 3 bytes here
  654. + */
  655. + if (!(strncasecmp(rdbuf + 1, "EP0", 3))) {
  656. + tsdata->version = M06;
  657. +
  658. + /* remove last '$' end marker */
  659. + rdbuf[EDT_NAME_LEN - 1] = '\0';
  660. + if (rdbuf[EDT_NAME_LEN - 2] == '$')
  661. + rdbuf[EDT_NAME_LEN - 2] = '\0';
  662. +
  663. + /* look for Model/Version separator */
  664. + p = strchr(rdbuf, '*');
  665. + if (p)
  666. + *p++ = '\0';
  667. + strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
  668. + strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
  669. + } else {
  670. + /* since there are only two versions around (M06, M09) */
  671. + tsdata->version = M09;
  672. +
  673. + error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
  674. + 2, rdbuf);
  675. + if (error)
  676. + return error;
  677. +
  678. + strlcpy(fw_version, rdbuf, 2);
  679.  
  680. - /* look for Model/Version separator */
  681. - p = strchr(rdbuf, '*');
  682. - if (p)
  683. - *p++ = '\0';
  684. + error = edt_ft5x06_ts_readwrite(client, 1, "\xA8",
  685. + 1, rdbuf);
  686. + if (error)
  687. + return error;
  688.  
  689. - strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
  690. - strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
  691. + snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09",
  692. + rdbuf[0] >> 4, rdbuf[0] & 0x0F);
  693. + }
  694.  
  695. return 0;
  696. }
  697.  
  698. #define EDT_ATTR_CHECKSET(name, reg) \
  699. +do { \
  700. if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \
  701. pdata->name <= edt_ft5x06_attr_##name.limit_high) \
  702. - edt_ft5x06_register_write(tsdata, reg, pdata->name)
  703. + edt_ft5x06_register_write(tsdata, reg, pdata->name); \
  704. +} while (0)
  705. +
  706. +#define EDT_GET_PROP(name, reg) { \
  707. + u32 val; \
  708. + if (of_property_read_u32(np, #name, &val) == 0) \
  709. + edt_ft5x06_register_write(tsdata, reg, val); \
  710. +}
  711. +
  712. +static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
  713. + struct edt_ft5x06_ts_data *tsdata)
  714. +{
  715. + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  716. +
  717. + EDT_GET_PROP(threshold, reg_addr->reg_threshold);
  718. + EDT_GET_PROP(gain, reg_addr->reg_gain);
  719. + EDT_GET_PROP(offset, reg_addr->reg_offset);
  720. +}
  721.  
  722. static void
  723. edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata,
  724. const struct edt_ft5x06_platform_data *pdata)
  725. {
  726. + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  727. +
  728. if (!pdata->use_parameters)
  729. return;
  730.  
  731. /* pick up defaults from the platform data */
  732. - EDT_ATTR_CHECKSET(threshold, WORK_REGISTER_THRESHOLD);
  733. - EDT_ATTR_CHECKSET(gain, WORK_REGISTER_GAIN);
  734. - EDT_ATTR_CHECKSET(offset, WORK_REGISTER_OFFSET);
  735. - EDT_ATTR_CHECKSET(report_rate, WORK_REGISTER_REPORT_RATE);
  736. + EDT_ATTR_CHECKSET(threshold, reg_addr->reg_threshold);
  737. + EDT_ATTR_CHECKSET(gain, reg_addr->reg_gain);
  738. + EDT_ATTR_CHECKSET(offset, reg_addr->reg_offset);
  739. + if (reg_addr->reg_report_rate != NO_REGISTER)
  740. + EDT_ATTR_CHECKSET(report_rate, reg_addr->reg_report_rate);
  741. }
  742.  
  743. static void
  744. edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
  745. {
  746. + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  747. +
  748. tsdata->threshold = edt_ft5x06_register_read(tsdata,
  749. - WORK_REGISTER_THRESHOLD);
  750. - tsdata->gain = edt_ft5x06_register_read(tsdata, WORK_REGISTER_GAIN);
  751. - tsdata->offset = edt_ft5x06_register_read(tsdata, WORK_REGISTER_OFFSET);
  752. - tsdata->report_rate = edt_ft5x06_register_read(tsdata,
  753. - WORK_REGISTER_REPORT_RATE);
  754. - tsdata->num_x = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_X);
  755. - tsdata->num_y = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_Y);
  756. + reg_addr->reg_threshold);
  757. + tsdata->gain = edt_ft5x06_register_read(tsdata, reg_addr->reg_gain);
  758. + tsdata->offset = edt_ft5x06_register_read(tsdata, reg_addr->reg_offset);
  759. + if (reg_addr->reg_report_rate != NO_REGISTER)
  760. + tsdata->report_rate = edt_ft5x06_register_read(tsdata,
  761. + reg_addr->reg_report_rate);
  762. + tsdata->num_x = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_x);
  763. + tsdata->num_y = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_y);
  764. +}
  765. +
  766. +static void
  767. +edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
  768. +{
  769. + struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
  770. +
  771. + switch (tsdata->version) {
  772. + case M06:
  773. + reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD;
  774. + reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE;
  775. + reg_addr->reg_gain = WORK_REGISTER_GAIN;
  776. + reg_addr->reg_offset = WORK_REGISTER_OFFSET;
  777. + reg_addr->reg_num_x = WORK_REGISTER_NUM_X;
  778. + reg_addr->reg_num_y = WORK_REGISTER_NUM_Y;
  779. + break;
  780. +
  781. + case M09:
  782. + reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
  783. + reg_addr->reg_gain = M09_REGISTER_GAIN;
  784. + reg_addr->reg_offset = M09_REGISTER_OFFSET;
  785. + reg_addr->reg_num_x = M09_REGISTER_NUM_X;
  786. + reg_addr->reg_num_y = M09_REGISTER_NUM_Y;
  787. + break;
  788. + }
  789. +}
  790. +
  791. +#ifdef CONFIG_OF
  792. +
  793. +static const struct of_device_id edt_ft5x06_of_match[];
  794. +
  795. +static void edt_ft5x06_ts_set_max_support_points(struct device *dev,
  796. + struct edt_ft5x06_ts_data *tsdata)
  797. +{
  798. + struct edt_i2c_chip_data *chip_data;
  799. + const struct of_device_id *match;
  800. +
  801. + match = of_match_device(of_match_ptr(edt_ft5x06_of_match), dev);
  802. +
  803. + if (match) {
  804. + chip_data = (struct edt_i2c_chip_data *)match->data;
  805. + tsdata->max_support_points = chip_data->max_support_points;
  806. + } else {
  807. + tsdata->max_support_points = 5;
  808. + }
  809. +
  810. +}
  811. +#else
  812. +static void edt_ft5x06_ts_set_max_support_points(struct device *dev,
  813. + struct edt_ft5x06_ts_data *tsdata)
  814. +{
  815. }
  816. +#endif
  817.  
  818. static int edt_ft5x06_ts_probe(struct i2c_client *client,
  819. const struct i2c_device_id *id)
  820. {
  821. const struct edt_ft5x06_platform_data *pdata =
  822. - client->dev.platform_data;
  823. + dev_get_platdata(&client->dev);
  824. + struct device *dev = &client->dev;
  825. struct edt_ft5x06_ts_data *tsdata;
  826. struct input_dev *input;
  827. - int error;
  828. + int error, i;
  829. char fw_version[EDT_NAME_LEN];
  830.  
  831. - dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
  832. + dev_info(&client->dev, "%s probing for EDT FT5x06 I2C\n", DRIVER_VERSION);
  833.  
  834. - if (!pdata) {
  835. - dev_err(&client->dev, "no platform data?\n");
  836. - return -EINVAL;
  837. + tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
  838. + if (!tsdata) {
  839. + dev_err(&client->dev, "failed to allocate driver data.\n");
  840. + return -ENOMEM;
  841. }
  842.  
  843. - error = edt_ft5x06_ts_reset(client, pdata->reset_pin);
  844. - if (error)
  845. - return error;
  846. + tsdata->reset_pin = 157;
  847. + tsdata->irq_pin = 140;
  848.  
  849. - if (gpio_is_valid(pdata->irq_pin)) {
  850. - error = gpio_request_one(pdata->irq_pin,
  851. - GPIOF_IN, "edt-ft5x06 irq");
  852. + if (gpio_is_valid(tsdata->reset_pin)) {
  853. + /* this pulls reset down, enabling the low active reset */
  854. + error = gpio_request_one(tsdata->reset_pin, GPIOF_OUT_INIT_LOW,
  855. + "edt-ft5x06 reset");
  856. if (error) {
  857. dev_err(&client->dev,
  858. - "Failed to request GPIO %d, error %d\n",
  859. - pdata->irq_pin, error);
  860. + "Failed to request GPIO %d as reset pin, error %d\n",
  861. + tsdata->reset_pin, error);
  862. return error;
  863. }
  864. +
  865. + mdelay(50);
  866. + gpio_set_value(tsdata->reset_pin, 1);
  867. + mdelay(300);
  868. }
  869.  
  870. - tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
  871. - input = input_allocate_device();
  872. - if (!tsdata || !input) {
  873. - dev_err(&client->dev, "failed to allocate driver data.\n");
  874. - error = -ENOMEM;
  875. - goto err_free_mem;
  876. +
  877. + edt_ft5x06_ts_set_max_support_points(dev, tsdata);
  878. +/*
  879. + gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
  880. + if (IS_ERR(gpio)) {
  881. + error = PTR_ERR(gpio);
  882. + dev_err(&client->dev,
  883. + "Failed to request GPIO reset pin, error %d\n", error);
  884. + return error;
  885. + }
  886. +
  887. + tsdata->reset_pin = gpio;
  888. +
  889. + gpio = devm_gpiod_get_optional(&client->dev, "wake", GPIOD_OUT_LOW);
  890. +
  891. + if (IS_ERR(gpio)) {
  892. + error = PTR_ERR(gpio);
  893. + dev_err(&client->dev,
  894. + "Failed to request GPIO wake pin, error %d\n", error);
  895. + return error;
  896. + }
  897. +
  898. + tsdata->wake_pin = gpio;
  899. +
  900. + gpio = devm_gpiod_get_optional(&client->dev, "irq", GPIOD_IN);
  901. +
  902. + if (IS_ERR(gpio)) {
  903. + error = PTR_ERR(gpio);
  904. + dev_err(&client->dev,
  905. + "Failed to request GPIO irq pin, error %d\n", error);
  906. + return error;
  907. + }
  908. +
  909. + tsdata->irq_pin = gpio;
  910. +
  911. + if (tsdata->wake_pin) {
  912. + usleep_range(5000, 6000);
  913. + gpiod_set_value_cansleep(tsdata->wake_pin, 1);
  914. + }
  915. +
  916. + if (tsdata->reset_pin) {
  917. + usleep_range(5000, 6000);
  918. + gpiod_set_value_cansleep(tsdata->reset_pin, 0);
  919. + msleep(300);
  920. + }
  921. +*/
  922. + input = devm_input_allocate_device(&client->dev);
  923. + if (!input) {
  924. + dev_err(&client->dev, "failed to allocate input device.\n");
  925. + return -ENOMEM;
  926. }
  927.  
  928. mutex_init(&tsdata->mutex);
  929. @@ -746,16 +1095,28 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
  930. tsdata->input = input;
  931. tsdata->factory_mode = false;
  932.  
  933. - error = edt_ft5x06_ts_identify(client, tsdata->name, fw_version);
  934. + error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
  935. if (error) {
  936. dev_err(&client->dev, "touchscreen probe failed\n");
  937. - goto err_free_mem;
  938. + return error;
  939. }
  940.  
  941. - edt_ft5x06_ts_get_defaults(tsdata, pdata);
  942. + /* default queue size to 5 */
  943. + tsdata->queue_size = 5;
  944. +
  945. + /* default queue timeout to 35ms */
  946. + tsdata->invalidate_queue = 35;
  947. +
  948. + edt_ft5x06_ts_set_regs(tsdata);
  949. +
  950. + if (!pdata)
  951. + edt_ft5x06_ts_get_dt_defaults(client->dev.of_node, tsdata);
  952. + else
  953. + edt_ft5x06_ts_get_defaults(tsdata, pdata);
  954. +
  955. edt_ft5x06_ts_get_parameters(tsdata);
  956.  
  957. - dev_dbg(&client->dev,
  958. + dev_info(&client->dev,
  959. "Model \"%s\", Rev. \"%s\", %dx%d sensors\n",
  960. tsdata->name, fw_version, tsdata->num_x, tsdata->num_y);
  961.  
  962. @@ -766,33 +1127,48 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
  963. __set_bit(EV_SYN, input->evbit);
  964. __set_bit(EV_KEY, input->evbit);
  965. __set_bit(EV_ABS, input->evbit);
  966. + __set_bit(INPUT_PROP_DIRECT, input->propbit);
  967. __set_bit(BTN_TOUCH, input->keybit);
  968. input_set_abs_params(input, ABS_X, 0, tsdata->num_x * 64 - 1, 0, 0);
  969. input_set_abs_params(input, ABS_Y, 0, tsdata->num_y * 64 - 1, 0, 0);
  970. - input_set_abs_params(input, ABS_MT_POSITION_X,
  971. - 0, tsdata->num_x * 64 - 1, 0, 0);
  972. input_set_abs_params(input, ABS_MT_POSITION_Y,
  973. 0, tsdata->num_y * 64 - 1, 0, 0);
  974. - error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0);
  975. + input_set_abs_params(input, ABS_MT_POSITION_X,
  976. + 0, tsdata->num_x * 64 - 1, 0, 0);
  977. +
  978. + //if (!pdata)
  979. + // touchscreen_parse_properties(input, true);
  980. +
  981. + error = input_mt_init_slots(input, tsdata->max_support_points, 0);
  982. if (error) {
  983. dev_err(&client->dev, "Unable to init MT slots.\n");
  984. - goto err_free_mem;
  985. + return error;
  986. }
  987.  
  988. input_set_drvdata(input, tsdata);
  989. i2c_set_clientdata(client, tsdata);
  990.  
  991. - error = request_threaded_irq(client->irq, NULL, edt_ft5x06_ts_isr,
  992. - IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  993. - client->name, tsdata);
  994. + for (i = 0; i < tsdata->queue_size; i++)
  995. + memset(tsdata->rdbuf[i], 0, sizeof(tsdata->rdbuf[i]));
  996. +
  997. + setup_timer(&tsdata->queue_up_timer, edt_ft5x06_queue_up_timer,
  998. + (unsigned long)tsdata);
  999. +
  1000. + tsdata->events_valid = 0;
  1001. + tsdata->queue_ptn = 0;
  1002. +
  1003. + error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
  1004. + edt_ft5x06_ts_isr,
  1005. + IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  1006. + client->name, tsdata);
  1007. if (error) {
  1008. dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
  1009. - goto err_free_mem;
  1010. + return error;
  1011. }
  1012.  
  1013. error = sysfs_create_group(&client->dev.kobj, &edt_ft5x06_attr_group);
  1014. if (error)
  1015. - goto err_free_irq;
  1016. + return error;
  1017.  
  1018. error = input_register_device(input);
  1019. if (error)
  1020. @@ -801,50 +1177,31 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
  1021. edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
  1022. device_init_wakeup(&client->dev, 1);
  1023.  
  1024. - dev_dbg(&client->dev,
  1025. - "EDT FT5x06 initialized: IRQ pin %d, Reset pin %d.\n",
  1026. - pdata->irq_pin, pdata->reset_pin);
  1027. + dev_info(&client->dev,
  1028. + "EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
  1029. + client->irq,
  1030. + tsdata->wake_pin,
  1031. + tsdata->reset_pin);
  1032.  
  1033. return 0;
  1034.  
  1035. err_remove_attrs:
  1036. sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
  1037. -err_free_irq:
  1038. - free_irq(client->irq, tsdata);
  1039. -err_free_mem:
  1040. - input_free_device(input);
  1041. - kfree(tsdata);
  1042. -
  1043. - if (gpio_is_valid(pdata->irq_pin))
  1044. - gpio_free(pdata->irq_pin);
  1045. -
  1046. return error;
  1047. }
  1048.  
  1049. static int edt_ft5x06_ts_remove(struct i2c_client *client)
  1050. {
  1051. - const struct edt_ft5x06_platform_data *pdata =
  1052. - dev_get_platdata(&client->dev);
  1053. struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
  1054.  
  1055. edt_ft5x06_ts_teardown_debugfs(tsdata);
  1056. + del_timer_sync(&tsdata->queue_up_timer);
  1057. sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
  1058.  
  1059. - free_irq(client->irq, tsdata);
  1060. - input_unregister_device(tsdata->input);
  1061. -
  1062. - if (gpio_is_valid(pdata->irq_pin))
  1063. - gpio_free(pdata->irq_pin);
  1064. - if (gpio_is_valid(pdata->reset_pin))
  1065. - gpio_free(pdata->reset_pin);
  1066. -
  1067. - kfree(tsdata);
  1068. -
  1069. return 0;
  1070. }
  1071.  
  1072. -#ifdef CONFIG_PM_SLEEP
  1073. -static int edt_ft5x06_ts_suspend(struct device *dev)
  1074. +static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
  1075. {
  1076. struct i2c_client *client = to_i2c_client(dev);
  1077.  
  1078. @@ -854,7 +1211,7 @@ static int edt_ft5x06_ts_suspend(struct device *dev)
  1079. return 0;
  1080. }
  1081.  
  1082. -static int edt_ft5x06_ts_resume(struct device *dev)
  1083. +static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
  1084. {
  1085. struct i2c_client *client = to_i2c_client(dev);
  1086.  
  1087. @@ -863,21 +1220,41 @@ static int edt_ft5x06_ts_resume(struct device *dev)
  1088.  
  1089. return 0;
  1090. }
  1091. -#endif
  1092.  
  1093. static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
  1094. edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
  1095.  
  1096. static const struct i2c_device_id edt_ft5x06_ts_id[] = {
  1097. - { "edt-ft5x06", 0 },
  1098. - { }
  1099. + { "edt-ft5x06", 0, },
  1100. + { /* sentinel */ }
  1101. };
  1102. MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
  1103.  
  1104. +#ifdef CONFIG_OF
  1105. +
  1106. +static const struct edt_i2c_chip_data edt_ft5x06_data = {
  1107. + .max_support_points = 5,
  1108. +};
  1109. +
  1110. +static const struct edt_i2c_chip_data edt_ft5506_data = {
  1111. + .max_support_points = 10,
  1112. +};
  1113. +
  1114. +static const struct of_device_id edt_ft5x06_of_match[] = {
  1115. + { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data},
  1116. + { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data},
  1117. + { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data},
  1118. + { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data},
  1119. + { /* sentinel */ }
  1120. +};
  1121. +MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
  1122. +#endif
  1123. +
  1124. static struct i2c_driver edt_ft5x06_ts_driver = {
  1125. .driver = {
  1126. .owner = THIS_MODULE,
  1127. .name = "edt_ft5x06",
  1128. + .of_match_table = of_match_ptr(edt_ft5x06_of_match),
  1129. .pm = &edt_ft5x06_ts_pm_ops,
  1130. },
  1131. .id_table = edt_ft5x06_ts_id,
  1132. @@ -887,6 +1264,10 @@ static struct i2c_driver edt_ft5x06_ts_driver = {
  1133.  
  1134. module_i2c_driver(edt_ft5x06_ts_driver);
  1135.  
  1136. +MODULE_ALIAS("i2c:edt-ft5206");
  1137. +MODULE_ALIAS("i2c:edt-ft5306");
  1138. +MODULE_ALIAS("i2c:edt-ft5406");
  1139. +MODULE_ALIAS("i2c:edt-ft5506");
  1140. MODULE_AUTHOR("Simon Budig <simon.budig@kernelconcepts.de>");
  1141. MODULE_DESCRIPTION("EDT FT5x06 I2C Touchscreen Driver");
  1142. MODULE_LICENSE("GPL");
  1143. --
  1144. cgit v0.11.0
Add Comment
Please, Sign In to add comment