cyttsp5.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Parade TrueTouch(TM) Standard Product V5 Module.
  4. *
  5. * Copyright (C) 2015 Parade Technologies
  6. * Copyright (C) 2012-2015 Cypress Semiconductor
  7. * Copyright (C) 2018 Bootlin
  8. *
  9. * Authors: Mylène Josserand <mylene.josserand@bootlin.com>
  10. * Alistair Francis <alistair@alistair23.me>
  11. */
  12. #include <linux/crc-itu-t.h>
  13. #include <linux/delay.h>
  14. #include <linux/device.h>
  15. #include <linux/gpio/consumer.h>
  16. #include <linux/input/mt.h>
  17. #include <linux/input/touchscreen.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/i2c.h>
  20. #include <linux/mod_devicetable.h>
  21. #include <linux/module.h>
  22. #include <linux/regmap.h>
  23. #include <linux/unaligned.h>
  24. #define CYTTSP5_NAME "cyttsp5"
  25. #define CY_I2C_DATA_SIZE (2 * 256)
  26. #define HID_VERSION 0x0100
  27. #define CY_MAX_INPUT 512
  28. #define CYTTSP5_PREALLOCATED_CMD_BUFFER 32
  29. #define CY_BITS_PER_BTN 1
  30. #define CY_NUM_BTN_EVENT_ID GENMASK(CY_BITS_PER_BTN - 1, 0)
  31. #define MAX_AREA 255
  32. #define HID_OUTPUT_BL_SOP 0x1
  33. #define HID_OUTPUT_BL_EOP 0x17
  34. #define HID_OUTPUT_BL_LAUNCH_APP 0x3B
  35. #define HID_OUTPUT_BL_LAUNCH_APP_SIZE 11
  36. #define HID_OUTPUT_GET_SYSINFO 0x2
  37. #define HID_OUTPUT_GET_SYSINFO_SIZE 5
  38. #define HID_OUTPUT_MAX_CMD_SIZE 12
  39. #define HID_DESC_REG 0x1
  40. #define HID_INPUT_REG 0x3
  41. #define HID_OUTPUT_REG 0x4
  42. #define HID_COMMAND_REG 0x5
  43. #define REPORT_ID_TOUCH 0x1
  44. #define REPORT_ID_BTN 0x3
  45. #define REPORT_SIZE_5 5
  46. #define REPORT_SIZE_8 8
  47. #define REPORT_SIZE_16 16
  48. /* Touch reports offsets */
  49. /* Header offsets */
  50. #define TOUCH_REPORT_DESC_HDR_CONTACTCOUNT 16
  51. /* Record offsets */
  52. #define TOUCH_REPORT_DESC_CONTACTID 8
  53. #define TOUCH_REPORT_DESC_X 16
  54. #define TOUCH_REPORT_DESC_Y 32
  55. #define TOUCH_REPORT_DESC_P 48
  56. #define TOUCH_REPORT_DESC_MAJ 56
  57. #define TOUCH_REPORT_DESC_MIN 64
  58. /* HID */
  59. #define HID_TOUCH_REPORT_ID 0x1
  60. #define HID_BTN_REPORT_ID 0x3
  61. #define HID_APP_RESPONSE_REPORT_ID 0x1F
  62. #define HID_APP_OUTPUT_REPORT_ID 0x2F
  63. #define HID_BL_RESPONSE_REPORT_ID 0x30
  64. #define HID_BL_OUTPUT_REPORT_ID 0x40
  65. #define HID_RESPONSE_REPORT_ID 0xF0
  66. #define HID_OUTPUT_RESPONSE_REPORT_OFFSET 2
  67. #define HID_OUTPUT_RESPONSE_CMD_OFFSET 4
  68. #define HID_OUTPUT_RESPONSE_CMD_MASK GENMASK(6, 0)
  69. #define HID_SYSINFO_SENSING_OFFSET 33
  70. #define HID_SYSINFO_BTN_OFFSET 48
  71. #define HID_SYSINFO_BTN_MASK GENMASK(7, 0)
  72. #define HID_SYSINFO_MAX_BTN 8
  73. #define HID_CMD_SET_POWER 0x8
  74. #define HID_POWER_ON 0x0
  75. #define HID_POWER_SLEEP 0x1
  76. #define CY_HID_OUTPUT_TIMEOUT_MS 200
  77. #define CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS 3000
  78. #define CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS 4000
  79. #define CY_HID_SET_POWER_TIMEOUT 500
  80. /* maximum number of concurrent tracks */
  81. #define TOUCH_REPORT_SIZE 10
  82. #define TOUCH_INPUT_HEADER_SIZE 7
  83. #define BTN_REPORT_SIZE 9
  84. #define BTN_INPUT_HEADER_SIZE 5
  85. #define MAX_CY_TCH_T_IDS 32
  86. /* All usage pages for Touch Report */
  87. #define TOUCH_REPORT_USAGE_PG_X 0x00010030
  88. #define TOUCH_REPORT_USAGE_PG_Y 0x00010031
  89. #define TOUCH_REPORT_USAGE_PG_P 0x000D0030
  90. #define TOUCH_REPORT_USAGE_PG_CONTACTID 0x000D0051
  91. #define TOUCH_REPORT_USAGE_PG_CONTACTCOUNT 0x000D0054
  92. #define TOUCH_REPORT_USAGE_PG_MAJ 0xFF010062
  93. #define TOUCH_REPORT_USAGE_PG_MIN 0xFF010063
  94. #define TOUCH_COL_USAGE_PG 0x000D0022
  95. #define SET_CMD_LOW(byte, bits) \
  96. ((byte) = (((byte) & 0xF0) | ((bits) & 0x0F)))
  97. #define SET_CMD_HIGH(byte, bits)\
  98. ((byte) = (((byte) & 0x0F) | ((bits) & 0xF0)))
  99. #define SET_CMD_OPCODE(byte, opcode) SET_CMD_LOW(byte, opcode)
  100. #define SET_CMD_REPORT_TYPE(byte, type) SET_CMD_HIGH(byte, ((type) << 4))
  101. #define SET_CMD_REPORT_ID(byte, id) SET_CMD_LOW(byte, id)
  102. /* System Information interface definitions */
  103. struct cyttsp5_sensing_conf_data_dev {
  104. u8 electrodes_x;
  105. u8 electrodes_y;
  106. __le16 len_x;
  107. __le16 len_y;
  108. __le16 res_x;
  109. __le16 res_y;
  110. __le16 max_z;
  111. u8 origin_x;
  112. u8 origin_y;
  113. u8 panel_id;
  114. u8 btn;
  115. u8 scan_mode;
  116. u8 max_num_of_tch_per_refresh_cycle;
  117. } __packed;
  118. struct cyttsp5_sensing_conf_data {
  119. u16 res_x;
  120. u16 res_y;
  121. u16 max_z;
  122. u16 len_x;
  123. u16 len_y;
  124. u8 origin_x;
  125. u8 origin_y;
  126. u8 max_tch;
  127. };
  128. enum cyttsp5_tch_abs { /* for ordering within the extracted touch data array */
  129. CY_TCH_X, /* X */
  130. CY_TCH_Y, /* Y */
  131. CY_TCH_P, /* P (Z) */
  132. CY_TCH_T, /* TOUCH ID */
  133. CY_TCH_MAJ, /* TOUCH_MAJOR */
  134. CY_TCH_MIN, /* TOUCH_MINOR */
  135. CY_TCH_NUM_ABS
  136. };
  137. struct cyttsp5_tch_abs_params {
  138. size_t ofs; /* abs byte offset */
  139. size_t size; /* size in bits */
  140. size_t min; /* min value */
  141. size_t max; /* max value */
  142. size_t bofs; /* bit offset */
  143. };
  144. struct cyttsp5_touch {
  145. int abs[CY_TCH_NUM_ABS];
  146. };
  147. struct cyttsp5_sysinfo {
  148. struct cyttsp5_sensing_conf_data sensing_conf_data;
  149. int num_btns;
  150. struct cyttsp5_tch_abs_params tch_hdr;
  151. struct cyttsp5_tch_abs_params tch_abs[CY_TCH_NUM_ABS];
  152. u32 key_code[HID_SYSINFO_MAX_BTN];
  153. };
  154. struct cyttsp5_hid_desc {
  155. __le16 hid_desc_len;
  156. u8 packet_id;
  157. u8 reserved_byte;
  158. __le16 bcd_version;
  159. __le16 report_desc_len;
  160. __le16 report_desc_register;
  161. __le16 input_register;
  162. __le16 max_input_len;
  163. __le16 output_register;
  164. __le16 max_output_len;
  165. __le16 command_register;
  166. __le16 data_register;
  167. __le16 vendor_id;
  168. __le16 product_id;
  169. __le16 version_id;
  170. u8 reserved[4];
  171. } __packed;
  172. struct cyttsp5 {
  173. struct device *dev;
  174. struct completion cmd_done;
  175. struct cyttsp5_sysinfo sysinfo;
  176. struct cyttsp5_hid_desc hid_desc;
  177. u8 cmd_buf[CYTTSP5_PREALLOCATED_CMD_BUFFER];
  178. u8 input_buf[CY_MAX_INPUT];
  179. u8 response_buf[CY_MAX_INPUT];
  180. struct gpio_desc *reset_gpio;
  181. struct input_dev *input;
  182. char phys[NAME_MAX];
  183. int num_prv_rec;
  184. struct regmap *regmap;
  185. struct touchscreen_properties prop;
  186. struct regulator_bulk_data supplies[2];
  187. };
  188. /*
  189. * For what is understood in the datasheet, the register does not
  190. * matter. For consistency, use the Input Register address
  191. * but it does mean anything to the device. The important data
  192. * to send is the I2C address
  193. */
  194. static int cyttsp5_read(struct cyttsp5 *ts, u8 *buf, u32 max)
  195. {
  196. int error;
  197. u32 size;
  198. u8 temp[2];
  199. /* Read the frame to retrieve the size */
  200. error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, temp, sizeof(temp));
  201. if (error)
  202. return error;
  203. size = get_unaligned_le16(temp);
  204. if (!size || size == 2)
  205. return 0;
  206. if (size > max)
  207. return -EINVAL;
  208. /* Get the real value */
  209. return regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, size);
  210. }
  211. static int cyttsp5_write(struct cyttsp5 *ts, unsigned int reg, u8 *data,
  212. size_t size)
  213. {
  214. u8 cmd[HID_OUTPUT_MAX_CMD_SIZE];
  215. if (size + 1 > HID_OUTPUT_MAX_CMD_SIZE)
  216. return -E2BIG;
  217. /* High bytes of register address needed as first byte of cmd */
  218. cmd[0] = (reg >> 8) & 0xFF;
  219. /* Copy the rest of the data */
  220. if (data)
  221. memcpy(&cmd[1], data, size);
  222. /*
  223. * The hardware wants to receive a frame with the address register
  224. * contained in the first two bytes. As the regmap_write function
  225. * add the register adresse in the frame, we use the low byte as
  226. * first frame byte for the address register and the first
  227. * data byte is the high register + left of the cmd to send
  228. */
  229. return regmap_bulk_write(ts->regmap, reg & 0xFF, cmd, size + 1);
  230. }
  231. static void cyttsp5_get_touch_axis(int *axis, int size, int max, u8 *xy_data,
  232. int bofs)
  233. {
  234. int nbyte;
  235. for (nbyte = 0, *axis = 0; nbyte < size; nbyte++)
  236. *axis += ((xy_data[nbyte] >> bofs) << (nbyte * 8));
  237. *axis &= max - 1;
  238. }
  239. static void cyttsp5_get_touch_record(struct cyttsp5 *ts,
  240. struct cyttsp5_touch *touch, u8 *xy_data)
  241. {
  242. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  243. enum cyttsp5_tch_abs abs;
  244. for (abs = CY_TCH_X; abs < CY_TCH_NUM_ABS; abs++)
  245. cyttsp5_get_touch_axis(&touch->abs[abs],
  246. si->tch_abs[abs].size,
  247. si->tch_abs[abs].max,
  248. xy_data + si->tch_abs[abs].ofs,
  249. si->tch_abs[abs].bofs);
  250. }
  251. static void cyttsp5_get_mt_touches(struct cyttsp5 *ts,
  252. struct cyttsp5_touch *tch, int num_cur_tch)
  253. {
  254. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  255. int i, t = 0, offset = 0;
  256. DECLARE_BITMAP(ids, MAX_CY_TCH_T_IDS);
  257. u8 *tch_addr;
  258. int tmp;
  259. bitmap_zero(ids, MAX_CY_TCH_T_IDS);
  260. memset(tch->abs, 0, sizeof(tch->abs));
  261. switch (ts->input_buf[2]) {
  262. case HID_TOUCH_REPORT_ID:
  263. offset = TOUCH_INPUT_HEADER_SIZE;
  264. break;
  265. case HID_BTN_REPORT_ID:
  266. offset = BTN_INPUT_HEADER_SIZE;
  267. break;
  268. }
  269. for (i = 0; i < num_cur_tch; i++) {
  270. tch_addr = ts->input_buf + offset + (i * TOUCH_REPORT_SIZE);
  271. cyttsp5_get_touch_record(ts, tch, tch_addr);
  272. /* Convert MAJOR/MINOR from mm to resolution */
  273. tmp = tch->abs[CY_TCH_MAJ] * 100 * si->sensing_conf_data.res_x;
  274. tch->abs[CY_TCH_MAJ] = tmp / si->sensing_conf_data.len_x;
  275. tmp = tch->abs[CY_TCH_MIN] * 100 * si->sensing_conf_data.res_x;
  276. tch->abs[CY_TCH_MIN] = tmp / si->sensing_conf_data.len_x;
  277. t = tch->abs[CY_TCH_T];
  278. input_mt_slot(ts->input, t);
  279. input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
  280. __set_bit(t, ids);
  281. /* position and pressure fields */
  282. touchscreen_report_pos(ts->input, &ts->prop,
  283. tch->abs[CY_TCH_X], tch->abs[CY_TCH_Y],
  284. true);
  285. input_report_abs(ts->input, ABS_MT_PRESSURE,
  286. tch->abs[CY_TCH_P]);
  287. /* Get the extended touch fields */
  288. input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
  289. tch->abs[CY_TCH_MAJ]);
  290. input_report_abs(ts->input, ABS_MT_TOUCH_MINOR,
  291. tch->abs[CY_TCH_MIN]);
  292. }
  293. ts->num_prv_rec = num_cur_tch;
  294. }
  295. static int cyttsp5_mt_attention(struct device *dev)
  296. {
  297. struct cyttsp5 *ts = dev_get_drvdata(dev);
  298. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  299. int max_tch = si->sensing_conf_data.max_tch;
  300. struct cyttsp5_touch tch;
  301. int num_cur_tch;
  302. cyttsp5_get_touch_axis(&num_cur_tch, si->tch_hdr.size,
  303. si->tch_hdr.max,
  304. ts->input_buf + 3 + si->tch_hdr.ofs,
  305. si->tch_hdr.bofs);
  306. if (num_cur_tch > max_tch) {
  307. dev_err(dev, "Num touch err detected (n=%d)\n", num_cur_tch);
  308. num_cur_tch = max_tch;
  309. }
  310. if (num_cur_tch == 0 && ts->num_prv_rec == 0)
  311. return 0;
  312. /* extract xy_data for all currently reported touches */
  313. if (num_cur_tch)
  314. cyttsp5_get_mt_touches(ts, &tch, num_cur_tch);
  315. input_mt_sync_frame(ts->input);
  316. input_sync(ts->input);
  317. return 0;
  318. }
  319. static int cyttsp5_setup_input_device(struct device *dev)
  320. {
  321. struct cyttsp5 *ts = dev_get_drvdata(dev);
  322. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  323. int max_x, max_y, max_p;
  324. int max_x_tmp, max_y_tmp;
  325. int error;
  326. max_x_tmp = si->sensing_conf_data.res_x;
  327. max_y_tmp = si->sensing_conf_data.res_y;
  328. max_x = max_x_tmp - 1;
  329. max_y = max_y_tmp - 1;
  330. max_p = si->sensing_conf_data.max_z;
  331. input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
  332. input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
  333. input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, max_p, 0, 0);
  334. input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
  335. input_set_abs_params(ts->input, ABS_MT_TOUCH_MINOR, 0, MAX_AREA, 0, 0);
  336. error = input_mt_init_slots(ts->input, si->tch_abs[CY_TCH_T].max,
  337. INPUT_MT_DROP_UNUSED | INPUT_MT_DIRECT);
  338. if (error)
  339. return error;
  340. error = input_register_device(ts->input);
  341. if (error) {
  342. dev_err(dev, "failed to register input device: %d\n", error);
  343. return error;
  344. }
  345. return error;
  346. }
  347. static int cyttsp5_parse_dt_key_code(struct device *dev)
  348. {
  349. struct cyttsp5 *ts = dev_get_drvdata(dev);
  350. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  351. if (!si->num_btns)
  352. return 0;
  353. /* Initialize the button to RESERVED */
  354. memset32(si->key_code, KEY_RESERVED, si->num_btns);
  355. return device_property_read_u32_array(dev, "linux,keycodes",
  356. si->key_code, si->num_btns);
  357. }
  358. static int cyttsp5_btn_attention(struct device *dev)
  359. {
  360. struct cyttsp5 *ts = dev_get_drvdata(dev);
  361. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  362. int cur_btn, offset = 0;
  363. int cur_btn_state;
  364. switch (ts->input_buf[2]) {
  365. case HID_TOUCH_REPORT_ID:
  366. offset = TOUCH_INPUT_HEADER_SIZE;
  367. break;
  368. case HID_BTN_REPORT_ID:
  369. offset = BTN_INPUT_HEADER_SIZE;
  370. break;
  371. }
  372. if (ts->input_buf[2] != HID_BTN_REPORT_ID)
  373. return 0;
  374. /* extract button press/release touch information */
  375. for (cur_btn = 0; cur_btn < si->num_btns; cur_btn++) {
  376. /* Get current button state */
  377. cur_btn_state = (ts->input_buf[offset] >> (cur_btn * CY_BITS_PER_BTN))
  378. & CY_NUM_BTN_EVENT_ID;
  379. input_report_key(ts->input, si->key_code[cur_btn],
  380. cur_btn_state);
  381. input_sync(ts->input);
  382. }
  383. return 0;
  384. }
  385. static int cyttsp5_validate_cmd_response(struct cyttsp5 *ts, u8 code)
  386. {
  387. u16 size, crc;
  388. u8 status, report_id;
  389. int command_code;
  390. size = get_unaligned_le16(&ts->response_buf[0]);
  391. if (!size)
  392. return 0;
  393. report_id = ts->response_buf[HID_OUTPUT_RESPONSE_REPORT_OFFSET];
  394. switch (report_id) {
  395. case HID_BL_RESPONSE_REPORT_ID:
  396. if (ts->response_buf[4] != HID_OUTPUT_BL_SOP) {
  397. dev_err(ts->dev, "HID output response, wrong SOP\n");
  398. return -EPROTO;
  399. }
  400. if (ts->response_buf[size - 1] != HID_OUTPUT_BL_EOP) {
  401. dev_err(ts->dev, "HID output response, wrong EOP\n");
  402. return -EPROTO;
  403. }
  404. crc = crc_itu_t(0xFFFF, &ts->response_buf[4], size - 7);
  405. if (get_unaligned_le16(&ts->response_buf[size - 3]) != crc) {
  406. dev_err(ts->dev,
  407. "HID output response, wrong CRC 0x%X\n",
  408. crc);
  409. return -EPROTO;
  410. }
  411. status = ts->response_buf[5];
  412. if (status) {
  413. dev_err(ts->dev, "HID output response, ERROR:%d\n",
  414. status);
  415. return -EPROTO;
  416. }
  417. break;
  418. case HID_APP_RESPONSE_REPORT_ID:
  419. command_code = ts->response_buf[HID_OUTPUT_RESPONSE_CMD_OFFSET]
  420. & HID_OUTPUT_RESPONSE_CMD_MASK;
  421. if (command_code != code) {
  422. dev_err(ts->dev,
  423. "HID output response, wrong command_code:%X\n",
  424. command_code);
  425. return -EPROTO;
  426. }
  427. break;
  428. }
  429. return 0;
  430. }
  431. static void cyttsp5_si_get_btn_data(struct cyttsp5 *ts)
  432. {
  433. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  434. unsigned int btns = ts->response_buf[HID_SYSINFO_BTN_OFFSET] &
  435. HID_SYSINFO_BTN_MASK;
  436. si->num_btns = hweight8(btns);
  437. }
  438. static int cyttsp5_get_sysinfo_regs(struct cyttsp5 *ts)
  439. {
  440. struct cyttsp5_sensing_conf_data *scd = &ts->sysinfo.sensing_conf_data;
  441. struct cyttsp5_sensing_conf_data_dev *scd_dev =
  442. (struct cyttsp5_sensing_conf_data_dev *)
  443. &ts->response_buf[HID_SYSINFO_SENSING_OFFSET];
  444. cyttsp5_si_get_btn_data(ts);
  445. scd->max_tch = scd_dev->max_num_of_tch_per_refresh_cycle;
  446. scd->res_x = get_unaligned_le16(&scd_dev->res_x);
  447. scd->res_y = get_unaligned_le16(&scd_dev->res_y);
  448. scd->max_z = get_unaligned_le16(&scd_dev->max_z);
  449. scd->len_x = get_unaligned_le16(&scd_dev->len_x);
  450. scd->len_y = get_unaligned_le16(&scd_dev->len_y);
  451. return 0;
  452. }
  453. static int cyttsp5_hid_output_get_sysinfo(struct cyttsp5 *ts)
  454. {
  455. int rc;
  456. u8 cmd[HID_OUTPUT_GET_SYSINFO_SIZE];
  457. /* HI bytes of Output register address */
  458. put_unaligned_le16(HID_OUTPUT_GET_SYSINFO_SIZE, cmd);
  459. cmd[2] = HID_APP_OUTPUT_REPORT_ID;
  460. cmd[3] = 0x0; /* Reserved */
  461. cmd[4] = HID_OUTPUT_GET_SYSINFO;
  462. rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd,
  463. HID_OUTPUT_GET_SYSINFO_SIZE);
  464. if (rc) {
  465. dev_err(ts->dev, "Failed to write command %d", rc);
  466. return rc;
  467. }
  468. rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
  469. msecs_to_jiffies(CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS));
  470. if (rc <= 0) {
  471. dev_err(ts->dev, "HID output cmd execution timed out\n");
  472. rc = -ETIMEDOUT;
  473. return rc;
  474. }
  475. rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_GET_SYSINFO);
  476. if (rc) {
  477. dev_err(ts->dev, "Validation of the response failed\n");
  478. return rc;
  479. }
  480. return cyttsp5_get_sysinfo_regs(ts);
  481. }
  482. static int cyttsp5_power_control(struct cyttsp5 *ts, bool on)
  483. {
  484. u8 state = on ? HID_POWER_ON : HID_POWER_SLEEP;
  485. u8 cmd[2] = { 0 };
  486. int rc;
  487. SET_CMD_REPORT_TYPE(cmd[0], 0);
  488. SET_CMD_REPORT_ID(cmd[0], state);
  489. SET_CMD_OPCODE(cmd[1], HID_CMD_SET_POWER);
  490. rc = cyttsp5_write(ts, HID_COMMAND_REG, cmd, sizeof(cmd));
  491. if (rc) {
  492. dev_err(ts->dev, "Failed to write power command %d", rc);
  493. return rc;
  494. }
  495. rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
  496. msecs_to_jiffies(CY_HID_SET_POWER_TIMEOUT));
  497. if (rc <= 0) {
  498. dev_err(ts->dev, "HID power cmd execution timed out\n");
  499. return -ETIMEDOUT;
  500. }
  501. if (ts->response_buf[2] != HID_RESPONSE_REPORT_ID ||
  502. (ts->response_buf[3] & 0x03) != state ||
  503. (ts->response_buf[4] & 0x0f) != HID_CMD_SET_POWER) {
  504. dev_err(ts->dev, "Validation of the %s response failed\n",
  505. on ? "wakeup" : "sleep");
  506. return -EINVAL;
  507. }
  508. return 0;
  509. }
  510. static int cyttsp5_hid_output_bl_launch_app(struct cyttsp5 *ts)
  511. {
  512. int rc;
  513. u8 cmd[HID_OUTPUT_BL_LAUNCH_APP_SIZE];
  514. u16 crc;
  515. put_unaligned_le16(HID_OUTPUT_BL_LAUNCH_APP_SIZE, cmd);
  516. cmd[2] = HID_BL_OUTPUT_REPORT_ID;
  517. cmd[3] = 0x0; /* Reserved */
  518. cmd[4] = HID_OUTPUT_BL_SOP;
  519. cmd[5] = HID_OUTPUT_BL_LAUNCH_APP;
  520. put_unaligned_le16(0x00, &cmd[6]);
  521. crc = crc_itu_t(0xFFFF, &cmd[4], 4);
  522. put_unaligned_le16(crc, &cmd[8]);
  523. cmd[10] = HID_OUTPUT_BL_EOP;
  524. rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd,
  525. HID_OUTPUT_BL_LAUNCH_APP_SIZE);
  526. if (rc) {
  527. dev_err(ts->dev, "Failed to write command %d", rc);
  528. return rc;
  529. }
  530. rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
  531. msecs_to_jiffies(CY_HID_OUTPUT_TIMEOUT_MS));
  532. if (rc <= 0) {
  533. dev_err(ts->dev, "HID output cmd execution timed out\n");
  534. rc = -ETIMEDOUT;
  535. return rc;
  536. }
  537. rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_BL_LAUNCH_APP);
  538. if (rc) {
  539. dev_err(ts->dev, "Validation of the response failed\n");
  540. return rc;
  541. }
  542. return 0;
  543. }
  544. static int cyttsp5_get_hid_descriptor(struct cyttsp5 *ts,
  545. struct cyttsp5_hid_desc *desc)
  546. {
  547. struct device *dev = ts->dev;
  548. int rc;
  549. rc = cyttsp5_write(ts, HID_DESC_REG, NULL, 0);
  550. if (rc) {
  551. dev_err(dev, "Failed to get HID descriptor, rc=%d\n", rc);
  552. return rc;
  553. }
  554. rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
  555. msecs_to_jiffies(CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS));
  556. if (rc <= 0) {
  557. dev_err(ts->dev, "HID get descriptor timed out\n");
  558. rc = -ETIMEDOUT;
  559. return rc;
  560. }
  561. memcpy(desc, ts->response_buf, sizeof(*desc));
  562. /* Check HID descriptor length and version */
  563. if (le16_to_cpu(desc->hid_desc_len) != sizeof(*desc) ||
  564. le16_to_cpu(desc->bcd_version) != HID_VERSION) {
  565. dev_err(dev, "Unsupported HID version\n");
  566. return -ENODEV;
  567. }
  568. return 0;
  569. }
  570. static int fill_tch_abs(struct cyttsp5_tch_abs_params *tch_abs, int report_size,
  571. int offset)
  572. {
  573. tch_abs->ofs = offset / 8;
  574. tch_abs->size = report_size / 8;
  575. if (report_size % 8)
  576. tch_abs->size += 1;
  577. tch_abs->min = 0;
  578. tch_abs->max = 1 << report_size;
  579. tch_abs->bofs = offset - (tch_abs->ofs << 3);
  580. return 0;
  581. }
  582. static irqreturn_t cyttsp5_handle_irq(int irq, void *handle)
  583. {
  584. struct cyttsp5 *ts = handle;
  585. int report_id;
  586. int size;
  587. int error;
  588. error = cyttsp5_read(ts, ts->input_buf, CY_MAX_INPUT);
  589. if (error)
  590. return IRQ_HANDLED;
  591. size = get_unaligned_le16(&ts->input_buf[0]);
  592. if (size == 0) {
  593. /* reset */
  594. report_id = 0;
  595. size = 2;
  596. } else {
  597. report_id = ts->input_buf[2];
  598. }
  599. switch (report_id) {
  600. case HID_TOUCH_REPORT_ID:
  601. cyttsp5_mt_attention(ts->dev);
  602. break;
  603. case HID_BTN_REPORT_ID:
  604. cyttsp5_btn_attention(ts->dev);
  605. break;
  606. case HID_RESPONSE_REPORT_ID:
  607. memcpy(ts->response_buf, ts->input_buf, size);
  608. complete(&ts->cmd_done);
  609. break;
  610. default:
  611. /* It is not an input but a command response */
  612. memcpy(ts->response_buf, ts->input_buf, size);
  613. complete(&ts->cmd_done);
  614. }
  615. return IRQ_HANDLED;
  616. }
  617. static int cyttsp5_deassert_int(struct cyttsp5 *ts)
  618. {
  619. u16 size;
  620. u8 buf[2];
  621. int error;
  622. error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, sizeof(buf));
  623. if (error < 0)
  624. return error;
  625. size = get_unaligned_le16(&buf[0]);
  626. if (size == 2 || size == 0)
  627. return 0;
  628. return -EINVAL;
  629. }
  630. static int cyttsp5_fill_all_touch(struct cyttsp5 *ts)
  631. {
  632. struct cyttsp5_sysinfo *si = &ts->sysinfo;
  633. fill_tch_abs(&si->tch_abs[CY_TCH_X], REPORT_SIZE_16,
  634. TOUCH_REPORT_DESC_X);
  635. fill_tch_abs(&si->tch_abs[CY_TCH_Y], REPORT_SIZE_16,
  636. TOUCH_REPORT_DESC_Y);
  637. fill_tch_abs(&si->tch_abs[CY_TCH_P], REPORT_SIZE_8,
  638. TOUCH_REPORT_DESC_P);
  639. fill_tch_abs(&si->tch_abs[CY_TCH_T], REPORT_SIZE_5,
  640. TOUCH_REPORT_DESC_CONTACTID);
  641. fill_tch_abs(&si->tch_hdr, REPORT_SIZE_5,
  642. TOUCH_REPORT_DESC_HDR_CONTACTCOUNT);
  643. fill_tch_abs(&si->tch_abs[CY_TCH_MAJ], REPORT_SIZE_8,
  644. TOUCH_REPORT_DESC_MAJ);
  645. fill_tch_abs(&si->tch_abs[CY_TCH_MIN], REPORT_SIZE_8,
  646. TOUCH_REPORT_DESC_MIN);
  647. return 0;
  648. }
  649. static int cyttsp5_startup(struct cyttsp5 *ts)
  650. {
  651. int error;
  652. error = cyttsp5_deassert_int(ts);
  653. if (error) {
  654. dev_err(ts->dev, "Error on deassert int r=%d\n", error);
  655. return -ENODEV;
  656. }
  657. /*
  658. * Launch the application as the device starts in bootloader mode
  659. * because of a power-on-reset
  660. */
  661. error = cyttsp5_hid_output_bl_launch_app(ts);
  662. if (error < 0) {
  663. dev_err(ts->dev, "Error on launch app r=%d\n", error);
  664. return error;
  665. }
  666. error = cyttsp5_get_hid_descriptor(ts, &ts->hid_desc);
  667. if (error < 0) {
  668. dev_err(ts->dev, "Error on getting HID descriptor r=%d\n", error);
  669. return error;
  670. }
  671. error = cyttsp5_fill_all_touch(ts);
  672. if (error < 0) {
  673. dev_err(ts->dev, "Error on report descriptor r=%d\n", error);
  674. return error;
  675. }
  676. error = cyttsp5_hid_output_get_sysinfo(ts);
  677. if (error) {
  678. dev_err(ts->dev, "Error on getting sysinfo r=%d\n", error);
  679. return error;
  680. }
  681. return error;
  682. }
  683. static void cyttsp5_cleanup(void *data)
  684. {
  685. struct cyttsp5 *ts = data;
  686. regulator_bulk_disable(ARRAY_SIZE(ts->supplies), ts->supplies);
  687. }
  688. static int cyttsp5_probe(struct device *dev, struct regmap *regmap, int irq,
  689. const char *name)
  690. {
  691. struct cyttsp5 *ts;
  692. struct cyttsp5_sysinfo *si;
  693. int error, i;
  694. ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
  695. if (!ts)
  696. return -ENOMEM;
  697. /* Initialize device info */
  698. ts->regmap = regmap;
  699. ts->dev = dev;
  700. si = &ts->sysinfo;
  701. dev_set_drvdata(dev, ts);
  702. init_completion(&ts->cmd_done);
  703. /* Power up the device */
  704. ts->supplies[0].supply = "vdd";
  705. ts->supplies[1].supply = "vddio";
  706. error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->supplies),
  707. ts->supplies);
  708. if (error) {
  709. dev_err(ts->dev, "Failed to get regulators, error %d\n", error);
  710. return error;
  711. }
  712. error = devm_add_action_or_reset(dev, cyttsp5_cleanup, ts);
  713. if (error)
  714. return error;
  715. error = regulator_bulk_enable(ARRAY_SIZE(ts->supplies), ts->supplies);
  716. if (error) {
  717. dev_err(ts->dev, "Failed to enable regulators, error %d\n", error);
  718. return error;
  719. }
  720. ts->input = devm_input_allocate_device(dev);
  721. if (!ts->input) {
  722. dev_err(dev, "Error, failed to allocate input device\n");
  723. return -ENODEV;
  724. }
  725. ts->input->name = "cyttsp5";
  726. scnprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
  727. ts->input->phys = ts->phys;
  728. input_set_drvdata(ts->input, ts);
  729. /* Assert gpio to be in a reset state */
  730. ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
  731. if (IS_ERR(ts->reset_gpio)) {
  732. error = PTR_ERR(ts->reset_gpio);
  733. dev_err(dev, "Failed to request reset gpio, error %d\n", error);
  734. return error;
  735. }
  736. fsleep(10); /* Ensure long-enough reset pulse (minimum 10us). */
  737. gpiod_set_value_cansleep(ts->reset_gpio, 0);
  738. /* Need a delay to have device up */
  739. msleep(20);
  740. error = devm_request_threaded_irq(dev, irq, NULL, cyttsp5_handle_irq,
  741. IRQF_ONESHOT, name, ts);
  742. if (error) {
  743. dev_err(dev, "unable to request IRQ\n");
  744. return error;
  745. }
  746. error = cyttsp5_startup(ts);
  747. if (error) {
  748. dev_err(ts->dev, "Fail initial startup r=%d\n", error);
  749. return error;
  750. }
  751. error = cyttsp5_parse_dt_key_code(dev);
  752. if (error < 0) {
  753. dev_err(ts->dev, "Error while parsing dts %d\n", error);
  754. return error;
  755. }
  756. touchscreen_parse_properties(ts->input, true, &ts->prop);
  757. __set_bit(EV_KEY, ts->input->evbit);
  758. for (i = 0; i < si->num_btns; i++)
  759. __set_bit(si->key_code[i], ts->input->keybit);
  760. return cyttsp5_setup_input_device(dev);
  761. }
  762. static int cyttsp5_i2c_probe(struct i2c_client *client)
  763. {
  764. struct regmap *regmap;
  765. static const struct regmap_config config = {
  766. .reg_bits = 8,
  767. .val_bits = 8,
  768. };
  769. regmap = devm_regmap_init_i2c(client, &config);
  770. if (IS_ERR(regmap)) {
  771. dev_err(&client->dev, "regmap allocation failed: %pe\n",
  772. regmap);
  773. return PTR_ERR(regmap);
  774. }
  775. return cyttsp5_probe(&client->dev, regmap, client->irq, client->name);
  776. }
  777. static const struct of_device_id cyttsp5_of_match[] = {
  778. { .compatible = "cypress,tt21000", },
  779. { }
  780. };
  781. MODULE_DEVICE_TABLE(of, cyttsp5_of_match);
  782. static const struct i2c_device_id cyttsp5_i2c_id[] = {
  783. { CYTTSP5_NAME },
  784. { }
  785. };
  786. MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id);
  787. static int __maybe_unused cyttsp5_suspend(struct device *dev)
  788. {
  789. struct cyttsp5 *ts = dev_get_drvdata(dev);
  790. if (!device_may_wakeup(dev))
  791. cyttsp5_power_control(ts, false);
  792. return 0;
  793. }
  794. static int __maybe_unused cyttsp5_resume(struct device *dev)
  795. {
  796. struct cyttsp5 *ts = dev_get_drvdata(dev);
  797. if (!device_may_wakeup(dev))
  798. cyttsp5_power_control(ts, true);
  799. return 0;
  800. }
  801. static SIMPLE_DEV_PM_OPS(cyttsp5_pm, cyttsp5_suspend, cyttsp5_resume);
  802. static struct i2c_driver cyttsp5_i2c_driver = {
  803. .driver = {
  804. .name = CYTTSP5_NAME,
  805. .of_match_table = cyttsp5_of_match,
  806. .pm = &cyttsp5_pm,
  807. },
  808. .probe = cyttsp5_i2c_probe,
  809. .id_table = cyttsp5_i2c_id,
  810. };
  811. module_i2c_driver(cyttsp5_i2c_driver);
  812. MODULE_LICENSE("GPL");
  813. MODULE_DESCRIPTION("Touchscreen driver for Cypress TrueTouch Gen 5 Product");
  814. MODULE_AUTHOR("Mylène Josserand <mylene.josserand@bootlin.com>");