msg2638.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Driver for MStar msg2638 touchscreens
  4. *
  5. * Copyright (c) 2021 Vincent Knecht <vincent.knecht@mailoo.org>
  6. *
  7. * Checksum and IRQ handler based on mstar_drv_common.c and
  8. * mstar_drv_mutual_fw_control.c
  9. * Copyright (c) 2006-2012 MStar Semiconductor, Inc.
  10. *
  11. * Driver structure based on zinitix.c by Michael Srba <Michael.Srba@seznam.cz>
  12. */
  13. #include <linux/delay.h>
  14. #include <linux/gpio/consumer.h>
  15. #include <linux/i2c.h>
  16. #include <linux/input.h>
  17. #include <linux/input/mt.h>
  18. #include <linux/input/touchscreen.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/kernel.h>
  21. #include <linux/mod_devicetable.h>
  22. #include <linux/module.h>
  23. #include <linux/property.h>
  24. #include <linux/regulator/consumer.h>
  25. #include <linux/slab.h>
  26. #define MODE_DATA_RAW 0x5A
  27. #define MSG2138_MAX_FINGERS 2
  28. #define MSG2638_MAX_FINGERS 5
  29. #define MAX_BUTTONS 4
  30. #define CHIP_ON_DELAY_MS 15
  31. #define FIRMWARE_ON_DELAY_MS 50
  32. #define RESET_DELAY_MIN_US 10000
  33. #define RESET_DELAY_MAX_US 11000
  34. struct msg_chip_data {
  35. irq_handler_t irq_handler;
  36. unsigned int max_fingers;
  37. };
  38. struct msg2138_packet {
  39. u8 xy_hi; /* higher bits of x and y coordinates */
  40. u8 x_low;
  41. u8 y_low;
  42. };
  43. struct msg2138_touch_event {
  44. u8 magic;
  45. struct msg2138_packet pkt[MSG2138_MAX_FINGERS];
  46. u8 checksum;
  47. };
  48. struct msg2638_packet {
  49. u8 xy_hi; /* higher bits of x and y coordinates */
  50. u8 x_low;
  51. u8 y_low;
  52. u8 pressure;
  53. };
  54. struct msg2638_touch_event {
  55. u8 mode;
  56. struct msg2638_packet pkt[MSG2638_MAX_FINGERS];
  57. u8 proximity;
  58. u8 checksum;
  59. };
  60. struct msg2638_ts_data {
  61. struct i2c_client *client;
  62. struct input_dev *input_dev;
  63. struct touchscreen_properties prop;
  64. struct regulator_bulk_data supplies[2];
  65. struct gpio_desc *reset_gpiod;
  66. int max_fingers;
  67. u32 keycodes[MAX_BUTTONS];
  68. int num_keycodes;
  69. };
  70. static u8 msg2638_checksum(u8 *data, u32 length)
  71. {
  72. s32 sum = 0;
  73. u32 i;
  74. for (i = 0; i < length; i++)
  75. sum += data[i];
  76. return (u8)((-sum) & 0xFF);
  77. }
  78. static void msg2138_report_keys(struct msg2638_ts_data *msg2638, u8 keys)
  79. {
  80. int i;
  81. /* keys can be 0x00 or 0xff when all keys have been released */
  82. if (keys == 0xff)
  83. keys = 0;
  84. for (i = 0; i < msg2638->num_keycodes; ++i)
  85. input_report_key(msg2638->input_dev, msg2638->keycodes[i],
  86. keys & BIT(i));
  87. }
  88. static irqreturn_t msg2138_ts_irq_handler(int irq, void *msg2638_handler)
  89. {
  90. struct msg2638_ts_data *msg2638 = msg2638_handler;
  91. struct i2c_client *client = msg2638->client;
  92. struct input_dev *input = msg2638->input_dev;
  93. struct msg2138_touch_event touch_event;
  94. u32 len = sizeof(touch_event);
  95. struct i2c_msg msg[] = {
  96. {
  97. .addr = client->addr,
  98. .flags = I2C_M_RD,
  99. .len = sizeof(touch_event),
  100. .buf = (u8 *)&touch_event,
  101. },
  102. };
  103. struct msg2138_packet *p0, *p1;
  104. u16 x, y, delta_x, delta_y;
  105. int ret;
  106. ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
  107. if (ret != ARRAY_SIZE(msg)) {
  108. dev_err(&client->dev,
  109. "Failed I2C transfer in irq handler: %d\n",
  110. ret < 0 ? ret : -EIO);
  111. goto out;
  112. }
  113. if (msg2638_checksum((u8 *)&touch_event, len - 1) !=
  114. touch_event.checksum) {
  115. dev_err(&client->dev, "Failed checksum!\n");
  116. goto out;
  117. }
  118. p0 = &touch_event.pkt[0];
  119. p1 = &touch_event.pkt[1];
  120. /* Ignore non-pressed finger data, but check for key code */
  121. if (p0->xy_hi == 0xFF && p0->x_low == 0xFF && p0->y_low == 0xFF) {
  122. if (p1->xy_hi == 0xFF && p1->y_low == 0xFF)
  123. msg2138_report_keys(msg2638, p1->x_low);
  124. goto report;
  125. }
  126. x = ((p0->xy_hi & 0xF0) << 4) | p0->x_low;
  127. y = ((p0->xy_hi & 0x0F) << 8) | p0->y_low;
  128. input_mt_slot(input, 0);
  129. input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
  130. touchscreen_report_pos(input, &msg2638->prop, x, y, true);
  131. /* Ignore non-pressed finger data */
  132. if (p1->xy_hi == 0xFF && p1->x_low == 0xFF && p1->y_low == 0xFF)
  133. goto report;
  134. /* Second finger is reported as a delta position */
  135. delta_x = ((p1->xy_hi & 0xF0) << 4) | p1->x_low;
  136. delta_y = ((p1->xy_hi & 0x0F) << 8) | p1->y_low;
  137. /* Ignore second finger if both deltas equal 0 */
  138. if (delta_x == 0 && delta_y == 0)
  139. goto report;
  140. x += delta_x;
  141. y += delta_y;
  142. input_mt_slot(input, 1);
  143. input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
  144. touchscreen_report_pos(input, &msg2638->prop, x, y, true);
  145. report:
  146. input_mt_sync_frame(msg2638->input_dev);
  147. input_sync(msg2638->input_dev);
  148. out:
  149. return IRQ_HANDLED;
  150. }
  151. static irqreturn_t msg2638_ts_irq_handler(int irq, void *msg2638_handler)
  152. {
  153. struct msg2638_ts_data *msg2638 = msg2638_handler;
  154. struct i2c_client *client = msg2638->client;
  155. struct input_dev *input = msg2638->input_dev;
  156. struct msg2638_touch_event touch_event;
  157. u32 len = sizeof(touch_event);
  158. struct i2c_msg msg[] = {
  159. {
  160. .addr = client->addr,
  161. .flags = I2C_M_RD,
  162. .len = sizeof(touch_event),
  163. .buf = (u8 *)&touch_event,
  164. },
  165. };
  166. struct msg2638_packet *p;
  167. u16 x, y;
  168. int ret;
  169. int i;
  170. ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
  171. if (ret != ARRAY_SIZE(msg)) {
  172. dev_err(&client->dev,
  173. "Failed I2C transfer in irq handler: %d\n",
  174. ret < 0 ? ret : -EIO);
  175. goto out;
  176. }
  177. if (touch_event.mode != MODE_DATA_RAW)
  178. goto out;
  179. if (msg2638_checksum((u8 *)&touch_event, len - 1) !=
  180. touch_event.checksum) {
  181. dev_err(&client->dev, "Failed checksum!\n");
  182. goto out;
  183. }
  184. for (i = 0; i < msg2638->max_fingers; i++) {
  185. p = &touch_event.pkt[i];
  186. /* Ignore non-pressed finger data */
  187. if (p->xy_hi == 0xFF && p->x_low == 0xFF && p->y_low == 0xFF)
  188. continue;
  189. x = (((p->xy_hi & 0xF0) << 4) | p->x_low);
  190. y = (((p->xy_hi & 0x0F) << 8) | p->y_low);
  191. input_mt_slot(input, i);
  192. input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
  193. touchscreen_report_pos(input, &msg2638->prop, x, y, true);
  194. }
  195. input_mt_sync_frame(msg2638->input_dev);
  196. input_sync(msg2638->input_dev);
  197. out:
  198. return IRQ_HANDLED;
  199. }
  200. static void msg2638_reset(struct msg2638_ts_data *msg2638)
  201. {
  202. gpiod_set_value_cansleep(msg2638->reset_gpiod, 1);
  203. usleep_range(RESET_DELAY_MIN_US, RESET_DELAY_MAX_US);
  204. gpiod_set_value_cansleep(msg2638->reset_gpiod, 0);
  205. msleep(FIRMWARE_ON_DELAY_MS);
  206. }
  207. static int msg2638_start(struct msg2638_ts_data *msg2638)
  208. {
  209. int error;
  210. error = regulator_bulk_enable(ARRAY_SIZE(msg2638->supplies),
  211. msg2638->supplies);
  212. if (error) {
  213. dev_err(&msg2638->client->dev,
  214. "Failed to enable regulators: %d\n", error);
  215. return error;
  216. }
  217. msleep(CHIP_ON_DELAY_MS);
  218. msg2638_reset(msg2638);
  219. enable_irq(msg2638->client->irq);
  220. return 0;
  221. }
  222. static int msg2638_stop(struct msg2638_ts_data *msg2638)
  223. {
  224. int error;
  225. disable_irq(msg2638->client->irq);
  226. error = regulator_bulk_disable(ARRAY_SIZE(msg2638->supplies),
  227. msg2638->supplies);
  228. if (error) {
  229. dev_err(&msg2638->client->dev,
  230. "Failed to disable regulators: %d\n", error);
  231. return error;
  232. }
  233. return 0;
  234. }
  235. static int msg2638_input_open(struct input_dev *dev)
  236. {
  237. struct msg2638_ts_data *msg2638 = input_get_drvdata(dev);
  238. return msg2638_start(msg2638);
  239. }
  240. static void msg2638_input_close(struct input_dev *dev)
  241. {
  242. struct msg2638_ts_data *msg2638 = input_get_drvdata(dev);
  243. msg2638_stop(msg2638);
  244. }
  245. static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638)
  246. {
  247. struct device *dev = &msg2638->client->dev;
  248. struct input_dev *input_dev;
  249. int error;
  250. int i;
  251. input_dev = devm_input_allocate_device(dev);
  252. if (!input_dev) {
  253. dev_err(dev, "Failed to allocate input device.\n");
  254. return -ENOMEM;
  255. }
  256. input_set_drvdata(input_dev, msg2638);
  257. msg2638->input_dev = input_dev;
  258. input_dev->name = "MStar TouchScreen";
  259. input_dev->phys = "input/ts";
  260. input_dev->id.bustype = BUS_I2C;
  261. input_dev->open = msg2638_input_open;
  262. input_dev->close = msg2638_input_close;
  263. if (msg2638->num_keycodes) {
  264. input_dev->keycode = msg2638->keycodes;
  265. input_dev->keycodemax = msg2638->num_keycodes;
  266. input_dev->keycodesize = sizeof(msg2638->keycodes[0]);
  267. for (i = 0; i < msg2638->num_keycodes; i++)
  268. input_set_capability(input_dev,
  269. EV_KEY, msg2638->keycodes[i]);
  270. }
  271. input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
  272. input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
  273. touchscreen_parse_properties(input_dev, true, &msg2638->prop);
  274. if (!msg2638->prop.max_x || !msg2638->prop.max_y) {
  275. dev_err(dev, "touchscreen-size-x and/or touchscreen-size-y not set in properties\n");
  276. return -EINVAL;
  277. }
  278. error = input_mt_init_slots(input_dev, msg2638->max_fingers,
  279. INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
  280. if (error) {
  281. dev_err(dev, "Failed to initialize MT slots: %d\n", error);
  282. return error;
  283. }
  284. error = input_register_device(input_dev);
  285. if (error) {
  286. dev_err(dev, "Failed to register input device: %d\n", error);
  287. return error;
  288. }
  289. return 0;
  290. }
  291. static int msg2638_ts_probe(struct i2c_client *client)
  292. {
  293. const struct msg_chip_data *chip_data;
  294. struct device *dev = &client->dev;
  295. struct msg2638_ts_data *msg2638;
  296. int error;
  297. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  298. dev_err(dev, "Failed to assert adapter's support for plain I2C.\n");
  299. return -ENXIO;
  300. }
  301. msg2638 = devm_kzalloc(dev, sizeof(*msg2638), GFP_KERNEL);
  302. if (!msg2638)
  303. return -ENOMEM;
  304. msg2638->client = client;
  305. i2c_set_clientdata(client, msg2638);
  306. chip_data = device_get_match_data(&client->dev);
  307. if (!chip_data || !chip_data->max_fingers) {
  308. dev_err(dev, "Invalid or missing chip data\n");
  309. return -EINVAL;
  310. }
  311. msg2638->max_fingers = chip_data->max_fingers;
  312. msg2638->supplies[0].supply = "vdd";
  313. msg2638->supplies[1].supply = "vddio";
  314. error = devm_regulator_bulk_get(dev, ARRAY_SIZE(msg2638->supplies),
  315. msg2638->supplies);
  316. if (error) {
  317. dev_err(dev, "Failed to get regulators: %d\n", error);
  318. return error;
  319. }
  320. msg2638->reset_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
  321. if (IS_ERR(msg2638->reset_gpiod)) {
  322. error = PTR_ERR(msg2638->reset_gpiod);
  323. dev_err(dev, "Failed to request reset GPIO: %d\n", error);
  324. return error;
  325. }
  326. msg2638->num_keycodes = device_property_count_u32(dev,
  327. "linux,keycodes");
  328. if (msg2638->num_keycodes == -EINVAL) {
  329. msg2638->num_keycodes = 0;
  330. } else if (msg2638->num_keycodes < 0) {
  331. dev_err(dev, "Unable to parse linux,keycodes property: %d\n",
  332. msg2638->num_keycodes);
  333. return msg2638->num_keycodes;
  334. } else if (msg2638->num_keycodes > ARRAY_SIZE(msg2638->keycodes)) {
  335. dev_warn(dev, "Found %d linux,keycodes but max is %zd, ignoring the rest\n",
  336. msg2638->num_keycodes, ARRAY_SIZE(msg2638->keycodes));
  337. msg2638->num_keycodes = ARRAY_SIZE(msg2638->keycodes);
  338. }
  339. if (msg2638->num_keycodes > 0) {
  340. error = device_property_read_u32_array(dev, "linux,keycodes",
  341. msg2638->keycodes,
  342. msg2638->num_keycodes);
  343. if (error) {
  344. dev_err(dev, "Unable to read linux,keycodes values: %d\n",
  345. error);
  346. return error;
  347. }
  348. }
  349. error = devm_request_threaded_irq(dev, client->irq,
  350. NULL, chip_data->irq_handler,
  351. IRQF_ONESHOT | IRQF_NO_AUTOEN,
  352. client->name, msg2638);
  353. if (error) {
  354. dev_err(dev, "Failed to request IRQ: %d\n", error);
  355. return error;
  356. }
  357. error = msg2638_init_input_dev(msg2638);
  358. if (error) {
  359. dev_err(dev, "Failed to initialize input device: %d\n", error);
  360. return error;
  361. }
  362. return 0;
  363. }
  364. static int msg2638_suspend(struct device *dev)
  365. {
  366. struct i2c_client *client = to_i2c_client(dev);
  367. struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client);
  368. mutex_lock(&msg2638->input_dev->mutex);
  369. if (input_device_enabled(msg2638->input_dev))
  370. msg2638_stop(msg2638);
  371. mutex_unlock(&msg2638->input_dev->mutex);
  372. return 0;
  373. }
  374. static int msg2638_resume(struct device *dev)
  375. {
  376. struct i2c_client *client = to_i2c_client(dev);
  377. struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client);
  378. int ret = 0;
  379. mutex_lock(&msg2638->input_dev->mutex);
  380. if (input_device_enabled(msg2638->input_dev))
  381. ret = msg2638_start(msg2638);
  382. mutex_unlock(&msg2638->input_dev->mutex);
  383. return ret;
  384. }
  385. static DEFINE_SIMPLE_DEV_PM_OPS(msg2638_pm_ops, msg2638_suspend, msg2638_resume);
  386. static const struct msg_chip_data msg2138_data = {
  387. .irq_handler = msg2138_ts_irq_handler,
  388. .max_fingers = MSG2138_MAX_FINGERS,
  389. };
  390. static const struct msg_chip_data msg2638_data = {
  391. .irq_handler = msg2638_ts_irq_handler,
  392. .max_fingers = MSG2638_MAX_FINGERS,
  393. };
  394. static const struct of_device_id msg2638_of_match[] = {
  395. { .compatible = "mstar,msg2138", .data = &msg2138_data },
  396. { .compatible = "mstar,msg2638", .data = &msg2638_data },
  397. { }
  398. };
  399. MODULE_DEVICE_TABLE(of, msg2638_of_match);
  400. static struct i2c_driver msg2638_ts_driver = {
  401. .probe = msg2638_ts_probe,
  402. .driver = {
  403. .name = "MStar-TS",
  404. .pm = pm_sleep_ptr(&msg2638_pm_ops),
  405. .of_match_table = msg2638_of_match,
  406. },
  407. };
  408. module_i2c_driver(msg2638_ts_driver);
  409. MODULE_AUTHOR("Vincent Knecht <vincent.knecht@mailoo.org>");
  410. MODULE_DESCRIPTION("MStar MSG2638 touchscreen driver");
  411. MODULE_LICENSE("GPL v2");