SHARE
TWEET

Untitled

a guest Jul 18th, 2016 23 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top