resistive-adc-touch.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * ADC generic resistive touchscreen (GRTS)
  4. * This is a generic input driver that connects to an ADC
  5. * given the channels in device tree, and reports events to the input
  6. * subsystem.
  7. *
  8. * Copyright (C) 2017,2018 Microchip Technology,
  9. * Author: Eugen Hristev <[email protected]>
  10. *
  11. */
  12. #include <linux/input.h>
  13. #include <linux/input/touchscreen.h>
  14. #include <linux/iio/consumer.h>
  15. #include <linux/iio/iio.h>
  16. #include <linux/mod_devicetable.h>
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/property.h>
  20. #define DRIVER_NAME "resistive-adc-touch"
  21. #define GRTS_DEFAULT_PRESSURE_MIN 50000
  22. #define GRTS_DEFAULT_PRESSURE_MAX 65535
  23. #define GRTS_MAX_POS_MASK GENMASK(11, 0)
  24. #define GRTS_MAX_CHANNELS 4
  25. enum grts_ch_type {
  26. GRTS_CH_X,
  27. GRTS_CH_Y,
  28. GRTS_CH_PRESSURE,
  29. GRTS_CH_Z1,
  30. GRTS_CH_Z2,
  31. GRTS_CH_MAX = GRTS_CH_Z2 + 1
  32. };
  33. /**
  34. * struct grts_state - generic resistive touch screen information struct
  35. * @x_plate_ohms: resistance of the X plate
  36. * @pressure_min: number representing the minimum for the pressure
  37. * @pressure: are we getting pressure info or not
  38. * @iio_chans: list of channels acquired
  39. * @iio_cb: iio_callback buffer for the data
  40. * @input: the input device structure that we register
  41. * @prop: touchscreen properties struct
  42. * @ch_map: map of channels that are defined for the touchscreen
  43. */
  44. struct grts_state {
  45. u32 x_plate_ohms;
  46. u32 pressure_min;
  47. bool pressure;
  48. struct iio_channel *iio_chans;
  49. struct iio_cb_buffer *iio_cb;
  50. struct input_dev *input;
  51. struct touchscreen_properties prop;
  52. u8 ch_map[GRTS_CH_MAX];
  53. };
  54. static int grts_cb(const void *data, void *private)
  55. {
  56. const u16 *touch_info = data;
  57. struct grts_state *st = private;
  58. unsigned int x, y, press = 0;
  59. x = touch_info[st->ch_map[GRTS_CH_X]];
  60. y = touch_info[st->ch_map[GRTS_CH_Y]];
  61. if (st->ch_map[GRTS_CH_PRESSURE] < GRTS_MAX_CHANNELS) {
  62. press = touch_info[st->ch_map[GRTS_CH_PRESSURE]];
  63. } else if (st->ch_map[GRTS_CH_Z1] < GRTS_MAX_CHANNELS) {
  64. unsigned int z1 = touch_info[st->ch_map[GRTS_CH_Z1]];
  65. unsigned int z2 = touch_info[st->ch_map[GRTS_CH_Z2]];
  66. unsigned int Rt;
  67. if (likely(x && z1)) {
  68. Rt = z2;
  69. Rt -= z1;
  70. Rt *= st->x_plate_ohms;
  71. Rt = DIV_ROUND_CLOSEST(Rt, 16);
  72. Rt *= x;
  73. Rt /= z1;
  74. Rt = DIV_ROUND_CLOSEST(Rt, 256);
  75. /*
  76. * On increased pressure the resistance (Rt) is
  77. * decreasing so, convert values to make it looks as
  78. * real pressure.
  79. */
  80. if (Rt < GRTS_DEFAULT_PRESSURE_MAX)
  81. press = GRTS_DEFAULT_PRESSURE_MAX - Rt;
  82. }
  83. }
  84. if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
  85. /* report end of touch */
  86. input_report_key(st->input, BTN_TOUCH, 0);
  87. input_sync(st->input);
  88. return 0;
  89. }
  90. /* report proper touch to subsystem*/
  91. touchscreen_report_pos(st->input, &st->prop, x, y, false);
  92. if (st->pressure)
  93. input_report_abs(st->input, ABS_PRESSURE, press);
  94. input_report_key(st->input, BTN_TOUCH, 1);
  95. input_sync(st->input);
  96. return 0;
  97. }
  98. static int grts_open(struct input_dev *dev)
  99. {
  100. int error;
  101. struct grts_state *st = input_get_drvdata(dev);
  102. error = iio_channel_start_all_cb(st->iio_cb);
  103. if (error) {
  104. dev_err(dev->dev.parent, "failed to start callback buffer.\n");
  105. return error;
  106. }
  107. return 0;
  108. }
  109. static void grts_close(struct input_dev *dev)
  110. {
  111. struct grts_state *st = input_get_drvdata(dev);
  112. iio_channel_stop_all_cb(st->iio_cb);
  113. }
  114. static void grts_disable(void *data)
  115. {
  116. iio_channel_release_all_cb(data);
  117. }
  118. static int grts_map_channel(struct grts_state *st, struct device *dev,
  119. enum grts_ch_type type, const char *name,
  120. bool optional)
  121. {
  122. int idx;
  123. idx = device_property_match_string(dev, "io-channel-names", name);
  124. if (idx < 0) {
  125. if (!optional)
  126. return idx;
  127. idx = GRTS_MAX_CHANNELS;
  128. } else if (idx >= GRTS_MAX_CHANNELS) {
  129. return -EOVERFLOW;
  130. }
  131. st->ch_map[type] = idx;
  132. return 0;
  133. }
  134. static int grts_get_properties(struct grts_state *st, struct device *dev)
  135. {
  136. int error;
  137. error = grts_map_channel(st, dev, GRTS_CH_X, "x", false);
  138. if (error)
  139. return error;
  140. error = grts_map_channel(st, dev, GRTS_CH_Y, "y", false);
  141. if (error)
  142. return error;
  143. /* pressure is optional */
  144. error = grts_map_channel(st, dev, GRTS_CH_PRESSURE, "pressure", true);
  145. if (error)
  146. return error;
  147. if (st->ch_map[GRTS_CH_PRESSURE] < GRTS_MAX_CHANNELS) {
  148. st->pressure = true;
  149. return 0;
  150. }
  151. /* if no pressure is defined, try optional z1 + z2 */
  152. error = grts_map_channel(st, dev, GRTS_CH_Z1, "z1", true);
  153. if (error)
  154. return error;
  155. if (st->ch_map[GRTS_CH_Z1] >= GRTS_MAX_CHANNELS)
  156. return 0;
  157. /* if z1 is provided z2 is not optional */
  158. error = grts_map_channel(st, dev, GRTS_CH_Z2, "z2", true);
  159. if (error)
  160. return error;
  161. error = device_property_read_u32(dev,
  162. "touchscreen-x-plate-ohms",
  163. &st->x_plate_ohms);
  164. if (error) {
  165. dev_err(dev, "can't get touchscreen-x-plate-ohms property\n");
  166. return error;
  167. }
  168. st->pressure = true;
  169. return 0;
  170. }
  171. static int grts_probe(struct platform_device *pdev)
  172. {
  173. struct grts_state *st;
  174. struct input_dev *input;
  175. struct device *dev = &pdev->dev;
  176. int error;
  177. st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL);
  178. if (!st)
  179. return -ENOMEM;
  180. /* get the channels from IIO device */
  181. st->iio_chans = devm_iio_channel_get_all(dev);
  182. if (IS_ERR(st->iio_chans)) {
  183. error = PTR_ERR(st->iio_chans);
  184. if (error != -EPROBE_DEFER)
  185. dev_err(dev, "can't get iio channels.\n");
  186. return error;
  187. }
  188. if (!device_property_present(dev, "io-channel-names"))
  189. return -ENODEV;
  190. error = grts_get_properties(st, dev);
  191. if (error) {
  192. dev_err(dev, "Failed to parse properties\n");
  193. return error;
  194. }
  195. if (st->pressure) {
  196. error = device_property_read_u32(dev,
  197. "touchscreen-min-pressure",
  198. &st->pressure_min);
  199. if (error) {
  200. dev_dbg(dev, "can't get touchscreen-min-pressure property.\n");
  201. st->pressure_min = GRTS_DEFAULT_PRESSURE_MIN;
  202. }
  203. }
  204. input = devm_input_allocate_device(dev);
  205. if (!input) {
  206. dev_err(dev, "failed to allocate input device.\n");
  207. return -ENOMEM;
  208. }
  209. input->name = DRIVER_NAME;
  210. input->id.bustype = BUS_HOST;
  211. input->open = grts_open;
  212. input->close = grts_close;
  213. input_set_abs_params(input, ABS_X, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
  214. input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
  215. if (st->pressure)
  216. input_set_abs_params(input, ABS_PRESSURE, st->pressure_min,
  217. GRTS_DEFAULT_PRESSURE_MAX, 0, 0);
  218. input_set_capability(input, EV_KEY, BTN_TOUCH);
  219. /* parse optional device tree properties */
  220. touchscreen_parse_properties(input, false, &st->prop);
  221. st->input = input;
  222. input_set_drvdata(input, st);
  223. error = input_register_device(input);
  224. if (error) {
  225. dev_err(dev, "failed to register input device.");
  226. return error;
  227. }
  228. st->iio_cb = iio_channel_get_all_cb(dev, grts_cb, st);
  229. if (IS_ERR(st->iio_cb)) {
  230. dev_err(dev, "failed to allocate callback buffer.\n");
  231. return PTR_ERR(st->iio_cb);
  232. }
  233. error = devm_add_action_or_reset(dev, grts_disable, st->iio_cb);
  234. if (error) {
  235. dev_err(dev, "failed to add disable action.\n");
  236. return error;
  237. }
  238. return 0;
  239. }
  240. static const struct of_device_id grts_of_match[] = {
  241. {
  242. .compatible = "resistive-adc-touch",
  243. }, {
  244. /* sentinel */
  245. },
  246. };
  247. MODULE_DEVICE_TABLE(of, grts_of_match);
  248. static struct platform_driver grts_driver = {
  249. .probe = grts_probe,
  250. .driver = {
  251. .name = DRIVER_NAME,
  252. .of_match_table = grts_of_match,
  253. },
  254. };
  255. module_platform_driver(grts_driver);
  256. MODULE_AUTHOR("Eugen Hristev <[email protected]>");
  257. MODULE_DESCRIPTION("Generic ADC Resistive Touch Driver");
  258. MODULE_LICENSE("GPL v2");