cy8ctma140.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Driver for Cypress CY8CTMA140 (TMA140) touchscreen
  4. * (C) 2020 Linus Walleij <[email protected]>
  5. * (C) 2007 Cypress
  6. * (C) 2007 Google, Inc.
  7. *
  8. * Inspired by the tma140_skomer.c driver in the Samsung GT-S7710 code
  9. * drop. The GT-S7710 is codenamed "Skomer", the code also indicates
  10. * that the same touchscreen was used in a product called "Lucas".
  11. *
  12. * The code drop for GT-S7710 also contains a firmware downloader and
  13. * 15 (!) versions of the firmware drop from Cypress. But here we assume
  14. * the firmware got downloaded to the touchscreen flash successfully and
  15. * just use it to read the fingers. The shipped vendor driver does the
  16. * same.
  17. */
  18. #include <asm/unaligned.h>
  19. #include <linux/module.h>
  20. #include <linux/kernel.h>
  21. #include <linux/input.h>
  22. #include <linux/input/touchscreen.h>
  23. #include <linux/input/mt.h>
  24. #include <linux/slab.h>
  25. #include <linux/interrupt.h>
  26. #include <linux/io.h>
  27. #include <linux/i2c.h>
  28. #include <linux/regulator/consumer.h>
  29. #include <linux/delay.h>
  30. #define CY8CTMA140_NAME "cy8ctma140"
  31. #define CY8CTMA140_MAX_FINGERS 4
  32. #define CY8CTMA140_GET_FINGERS 0x00
  33. #define CY8CTMA140_GET_FW_INFO 0x19
  34. /* This message also fits some bytes for touchkeys, if used */
  35. #define CY8CTMA140_PACKET_SIZE 31
  36. #define CY8CTMA140_INVALID_BUFFER_BIT 5
  37. struct cy8ctma140 {
  38. struct input_dev *input;
  39. struct touchscreen_properties props;
  40. struct device *dev;
  41. struct i2c_client *client;
  42. struct regulator_bulk_data regulators[2];
  43. u8 prev_fingers;
  44. u8 prev_f1id;
  45. u8 prev_f2id;
  46. };
  47. static void cy8ctma140_report(struct cy8ctma140 *ts, u8 *data, int n_fingers)
  48. {
  49. static const u8 contact_offsets[] = { 0x03, 0x09, 0x10, 0x16 };
  50. u8 *buf;
  51. u16 x, y;
  52. u8 w;
  53. u8 id;
  54. int slot;
  55. int i;
  56. for (i = 0; i < n_fingers; i++) {
  57. buf = &data[contact_offsets[i]];
  58. /*
  59. * Odd contacts have contact ID in the lower nibble of
  60. * the preceding byte, whereas even contacts have it in
  61. * the upper nibble of the following byte.
  62. */
  63. id = i % 2 ? buf[-1] & 0x0f : buf[5] >> 4;
  64. slot = input_mt_get_slot_by_key(ts->input, id);
  65. if (slot < 0)
  66. continue;
  67. x = get_unaligned_be16(buf);
  68. y = get_unaligned_be16(buf + 2);
  69. w = buf[4];
  70. dev_dbg(ts->dev, "finger %d: ID %02x (%d, %d) w: %d\n",
  71. slot, id, x, y, w);
  72. input_mt_slot(ts->input, slot);
  73. input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
  74. touchscreen_report_pos(ts->input, &ts->props, x, y, true);
  75. input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, w);
  76. }
  77. input_mt_sync_frame(ts->input);
  78. input_sync(ts->input);
  79. }
  80. static irqreturn_t cy8ctma140_irq_thread(int irq, void *d)
  81. {
  82. struct cy8ctma140 *ts = d;
  83. u8 cmdbuf[] = { CY8CTMA140_GET_FINGERS };
  84. u8 buf[CY8CTMA140_PACKET_SIZE];
  85. struct i2c_msg msg[] = {
  86. {
  87. .addr = ts->client->addr,
  88. .flags = 0,
  89. .len = sizeof(cmdbuf),
  90. .buf = cmdbuf,
  91. }, {
  92. .addr = ts->client->addr,
  93. .flags = I2C_M_RD,
  94. .len = sizeof(buf),
  95. .buf = buf,
  96. },
  97. };
  98. u8 n_fingers;
  99. int ret;
  100. ret = i2c_transfer(ts->client->adapter, msg, ARRAY_SIZE(msg));
  101. if (ret != ARRAY_SIZE(msg)) {
  102. if (ret < 0)
  103. dev_err(ts->dev, "error reading message: %d\n", ret);
  104. else
  105. dev_err(ts->dev, "wrong number of messages\n");
  106. goto out;
  107. }
  108. if (buf[1] & BIT(CY8CTMA140_INVALID_BUFFER_BIT)) {
  109. dev_dbg(ts->dev, "invalid event\n");
  110. goto out;
  111. }
  112. n_fingers = buf[2] & 0x0f;
  113. if (n_fingers > CY8CTMA140_MAX_FINGERS) {
  114. dev_err(ts->dev, "unexpected number of fingers: %d\n",
  115. n_fingers);
  116. goto out;
  117. }
  118. cy8ctma140_report(ts, buf, n_fingers);
  119. out:
  120. return IRQ_HANDLED;
  121. }
  122. static int cy8ctma140_init(struct cy8ctma140 *ts)
  123. {
  124. u8 addr[1];
  125. u8 buf[5];
  126. int ret;
  127. addr[0] = CY8CTMA140_GET_FW_INFO;
  128. ret = i2c_master_send(ts->client, addr, 1);
  129. if (ret < 0) {
  130. dev_err(ts->dev, "error sending FW info message\n");
  131. return ret;
  132. }
  133. ret = i2c_master_recv(ts->client, buf, 5);
  134. if (ret < 0) {
  135. dev_err(ts->dev, "error receiving FW info message\n");
  136. return ret;
  137. }
  138. if (ret != 5) {
  139. dev_err(ts->dev, "got only %d bytes\n", ret);
  140. return -EIO;
  141. }
  142. dev_dbg(ts->dev, "vendor %c%c, HW ID %.2d, FW ver %.4d\n",
  143. buf[0], buf[1], buf[3], buf[4]);
  144. return 0;
  145. }
  146. static int cy8ctma140_power_up(struct cy8ctma140 *ts)
  147. {
  148. int error;
  149. error = regulator_bulk_enable(ARRAY_SIZE(ts->regulators),
  150. ts->regulators);
  151. if (error) {
  152. dev_err(ts->dev, "failed to enable regulators\n");
  153. return error;
  154. }
  155. msleep(250);
  156. return 0;
  157. }
  158. static void cy8ctma140_power_down(struct cy8ctma140 *ts)
  159. {
  160. regulator_bulk_disable(ARRAY_SIZE(ts->regulators),
  161. ts->regulators);
  162. }
  163. /* Called from the registered devm action */
  164. static void cy8ctma140_power_off_action(void *d)
  165. {
  166. struct cy8ctma140 *ts = d;
  167. cy8ctma140_power_down(ts);
  168. }
  169. static int cy8ctma140_probe(struct i2c_client *client,
  170. const struct i2c_device_id *id)
  171. {
  172. struct cy8ctma140 *ts;
  173. struct input_dev *input;
  174. struct device *dev = &client->dev;
  175. int error;
  176. ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
  177. if (!ts)
  178. return -ENOMEM;
  179. input = devm_input_allocate_device(dev);
  180. if (!input)
  181. return -ENOMEM;
  182. ts->dev = dev;
  183. ts->client = client;
  184. ts->input = input;
  185. input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
  186. input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
  187. /* One byte for width 0..255 so this is the limit */
  188. input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
  189. /*
  190. * This sets up event max/min capabilities and fuzz.
  191. * Some DT properties are compulsory so we do not need
  192. * to provide defaults for X/Y max or pressure max.
  193. *
  194. * We just initialize a very simple MT touchscreen here,
  195. * some devices use the capability of this touchscreen to
  196. * provide touchkeys, and in that case this needs to be
  197. * extended to handle touchkey input.
  198. *
  199. * The firmware takes care of finger tracking and dropping
  200. * invalid ranges.
  201. */
  202. touchscreen_parse_properties(input, true, &ts->props);
  203. input_abs_set_fuzz(input, ABS_MT_POSITION_X, 0);
  204. input_abs_set_fuzz(input, ABS_MT_POSITION_Y, 0);
  205. error = input_mt_init_slots(input, CY8CTMA140_MAX_FINGERS,
  206. INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
  207. if (error)
  208. return error;
  209. input->name = CY8CTMA140_NAME;
  210. input->id.bustype = BUS_I2C;
  211. input_set_drvdata(input, ts);
  212. /*
  213. * VCPIN is the analog voltage supply
  214. * VDD is the digital voltage supply
  215. * since the voltage range of VDD overlaps that of VCPIN,
  216. * many designs to just supply both with a single voltage
  217. * source of ~3.3 V.
  218. */
  219. ts->regulators[0].supply = "vcpin";
  220. ts->regulators[1].supply = "vdd";
  221. error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->regulators),
  222. ts->regulators);
  223. if (error) {
  224. if (error != -EPROBE_DEFER)
  225. dev_err(dev, "Failed to get regulators %d\n",
  226. error);
  227. return error;
  228. }
  229. error = cy8ctma140_power_up(ts);
  230. if (error)
  231. return error;
  232. error = devm_add_action_or_reset(dev, cy8ctma140_power_off_action, ts);
  233. if (error) {
  234. dev_err(dev, "failed to install power off handler\n");
  235. return error;
  236. }
  237. error = devm_request_threaded_irq(dev, client->irq,
  238. NULL, cy8ctma140_irq_thread,
  239. IRQF_ONESHOT, CY8CTMA140_NAME, ts);
  240. if (error) {
  241. dev_err(dev, "irq %d busy? error %d\n", client->irq, error);
  242. return error;
  243. }
  244. error = cy8ctma140_init(ts);
  245. if (error)
  246. return error;
  247. error = input_register_device(input);
  248. if (error)
  249. return error;
  250. i2c_set_clientdata(client, ts);
  251. return 0;
  252. }
  253. static int __maybe_unused cy8ctma140_suspend(struct device *dev)
  254. {
  255. struct i2c_client *client = to_i2c_client(dev);
  256. struct cy8ctma140 *ts = i2c_get_clientdata(client);
  257. if (!device_may_wakeup(&client->dev))
  258. cy8ctma140_power_down(ts);
  259. return 0;
  260. }
  261. static int __maybe_unused cy8ctma140_resume(struct device *dev)
  262. {
  263. struct i2c_client *client = to_i2c_client(dev);
  264. struct cy8ctma140 *ts = i2c_get_clientdata(client);
  265. int error;
  266. if (!device_may_wakeup(&client->dev)) {
  267. error = cy8ctma140_power_up(ts);
  268. if (error)
  269. return error;
  270. }
  271. return 0;
  272. }
  273. static SIMPLE_DEV_PM_OPS(cy8ctma140_pm, cy8ctma140_suspend, cy8ctma140_resume);
  274. static const struct i2c_device_id cy8ctma140_idtable[] = {
  275. { CY8CTMA140_NAME, 0 },
  276. { /* sentinel */ }
  277. };
  278. MODULE_DEVICE_TABLE(i2c, cy8ctma140_idtable);
  279. static const struct of_device_id cy8ctma140_of_match[] = {
  280. { .compatible = "cypress,cy8ctma140", },
  281. { /* sentinel */ }
  282. };
  283. MODULE_DEVICE_TABLE(of, cy8ctma140_of_match);
  284. static struct i2c_driver cy8ctma140_driver = {
  285. .driver = {
  286. .name = CY8CTMA140_NAME,
  287. .pm = &cy8ctma140_pm,
  288. .of_match_table = cy8ctma140_of_match,
  289. },
  290. .id_table = cy8ctma140_idtable,
  291. .probe = cy8ctma140_probe,
  292. };
  293. module_i2c_driver(cy8ctma140_driver);
  294. MODULE_AUTHOR("Linus Walleij <[email protected]>");
  295. MODULE_DESCRIPTION("CY8CTMA140 TouchScreen Driver");
  296. MODULE_LICENSE("GPL v2");