sentelic.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*-
  3. * Finger Sensing Pad PS/2 mouse driver.
  4. *
  5. * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
  6. * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
  7. */
  8. #include <linux/module.h>
  9. #include <linux/input.h>
  10. #include <linux/input/mt.h>
  11. #include <linux/ctype.h>
  12. #include <linux/libps2.h>
  13. #include <linux/serio.h>
  14. #include <linux/jiffies.h>
  15. #include <linux/slab.h>
  16. #include "psmouse.h"
  17. #include "sentelic.h"
  18. /*
  19. * Timeout for FSP PS/2 command only (in milliseconds).
  20. */
  21. #define FSP_CMD_TIMEOUT 200
  22. #define FSP_CMD_TIMEOUT2 30
  23. #define GET_ABS_X(packet) ((packet[1] << 2) | ((packet[3] >> 2) & 0x03))
  24. #define GET_ABS_Y(packet) ((packet[2] << 2) | (packet[3] & 0x03))
  25. /** Driver version. */
  26. static const char fsp_drv_ver[] = "1.1.0-K";
  27. /*
  28. * Make sure that the value being sent to FSP will not conflict with
  29. * possible sample rate values.
  30. */
  31. static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
  32. {
  33. switch (reg_val) {
  34. case 10: case 20: case 40: case 60: case 80: case 100: case 200:
  35. /*
  36. * The requested value being sent to FSP matched to possible
  37. * sample rates, swap the given value such that the hardware
  38. * wouldn't get confused.
  39. */
  40. return (reg_val >> 4) | (reg_val << 4);
  41. default:
  42. return reg_val; /* swap isn't necessary */
  43. }
  44. }
  45. /*
  46. * Make sure that the value being sent to FSP will not conflict with certain
  47. * commands.
  48. */
  49. static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
  50. {
  51. switch (reg_val) {
  52. case 0xe9: case 0xee: case 0xf2: case 0xff:
  53. /*
  54. * The requested value being sent to FSP matched to certain
  55. * commands, inverse the given value such that the hardware
  56. * wouldn't get confused.
  57. */
  58. return ~reg_val;
  59. default:
  60. return reg_val; /* inversion isn't necessary */
  61. }
  62. }
  63. static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
  64. {
  65. struct ps2dev *ps2dev = &psmouse->ps2dev;
  66. unsigned char param[3];
  67. unsigned char addr;
  68. int rc = -1;
  69. /*
  70. * We need to shut off the device and switch it into command
  71. * mode so we don't confuse our protocol handler. We don't need
  72. * to do that for writes because sysfs set helper does this for
  73. * us.
  74. */
  75. psmouse_deactivate(psmouse);
  76. ps2_begin_command(ps2dev);
  77. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  78. goto out;
  79. /* should return 0xfe(request for resending) */
  80. ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
  81. /* should return 0xfc(failed) */
  82. ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
  83. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  84. goto out;
  85. if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
  86. ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
  87. } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
  88. /* swapping is required */
  89. ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
  90. /* expect 0xfe */
  91. } else {
  92. /* swapping isn't necessary */
  93. ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
  94. /* expect 0xfe */
  95. }
  96. /* should return 0xfc(failed) */
  97. ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
  98. if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
  99. goto out;
  100. *reg_val = param[2];
  101. rc = 0;
  102. out:
  103. ps2_end_command(ps2dev);
  104. psmouse_activate(psmouse);
  105. psmouse_dbg(psmouse,
  106. "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
  107. reg_addr, *reg_val, rc);
  108. return rc;
  109. }
  110. static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
  111. {
  112. struct ps2dev *ps2dev = &psmouse->ps2dev;
  113. unsigned char v;
  114. int rc = -1;
  115. ps2_begin_command(ps2dev);
  116. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  117. goto out;
  118. if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
  119. /* inversion is required */
  120. ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
  121. } else {
  122. if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
  123. /* swapping is required */
  124. ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
  125. } else {
  126. /* swapping isn't necessary */
  127. ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
  128. }
  129. }
  130. /* write the register address in correct order */
  131. ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
  132. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  133. goto out;
  134. if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
  135. /* inversion is required */
  136. ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
  137. } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
  138. /* swapping is required */
  139. ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
  140. } else {
  141. /* swapping isn't necessary */
  142. ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
  143. }
  144. /* write the register value in correct order */
  145. ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
  146. rc = 0;
  147. out:
  148. ps2_end_command(ps2dev);
  149. psmouse_dbg(psmouse,
  150. "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
  151. reg_addr, reg_val, rc);
  152. return rc;
  153. }
  154. /* Enable register clock gating for writing certain registers */
  155. static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
  156. {
  157. int v, nv;
  158. if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
  159. return -1;
  160. if (enable)
  161. nv = v | FSP_BIT_EN_REG_CLK;
  162. else
  163. nv = v & ~FSP_BIT_EN_REG_CLK;
  164. /* only write if necessary */
  165. if (nv != v)
  166. if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
  167. return -1;
  168. return 0;
  169. }
  170. static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
  171. {
  172. struct ps2dev *ps2dev = &psmouse->ps2dev;
  173. unsigned char param[3];
  174. int rc = -1;
  175. psmouse_deactivate(psmouse);
  176. ps2_begin_command(ps2dev);
  177. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  178. goto out;
  179. ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
  180. ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
  181. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  182. goto out;
  183. ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
  184. ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
  185. /* get the returned result */
  186. if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
  187. goto out;
  188. *reg_val = param[2];
  189. rc = 0;
  190. out:
  191. ps2_end_command(ps2dev);
  192. psmouse_activate(psmouse);
  193. psmouse_dbg(psmouse,
  194. "READ PAGE REG: 0x%02x (rc = %d)\n",
  195. *reg_val, rc);
  196. return rc;
  197. }
  198. static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
  199. {
  200. struct ps2dev *ps2dev = &psmouse->ps2dev;
  201. unsigned char v;
  202. int rc = -1;
  203. ps2_begin_command(ps2dev);
  204. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  205. goto out;
  206. ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
  207. ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
  208. if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  209. goto out;
  210. if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
  211. ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
  212. } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
  213. /* swapping is required */
  214. ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
  215. } else {
  216. /* swapping isn't necessary */
  217. ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
  218. }
  219. ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
  220. rc = 0;
  221. out:
  222. ps2_end_command(ps2dev);
  223. psmouse_dbg(psmouse,
  224. "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
  225. reg_val, rc);
  226. return rc;
  227. }
  228. static int fsp_get_version(struct psmouse *psmouse, int *version)
  229. {
  230. if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
  231. return -EIO;
  232. return 0;
  233. }
  234. static int fsp_get_revision(struct psmouse *psmouse, int *rev)
  235. {
  236. if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
  237. return -EIO;
  238. return 0;
  239. }
  240. static int fsp_get_sn(struct psmouse *psmouse, int *sn)
  241. {
  242. int v0, v1, v2;
  243. int rc = -EIO;
  244. /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */
  245. if (fsp_page_reg_write(psmouse, FSP_PAGE_0B))
  246. goto out;
  247. if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0))
  248. goto out;
  249. if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1))
  250. goto out;
  251. if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2))
  252. goto out;
  253. *sn = (v0 << 16) | (v1 << 8) | v2;
  254. rc = 0;
  255. out:
  256. fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT);
  257. return rc;
  258. }
  259. static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
  260. {
  261. static const int buttons[] = {
  262. 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
  263. 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
  264. 0x04, /* Left/Middle/Right & Scroll Up/Down */
  265. 0x02, /* Left/Middle/Right */
  266. };
  267. int val;
  268. if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1)
  269. return -EIO;
  270. *btn = buttons[(val & 0x30) >> 4];
  271. return 0;
  272. }
  273. /* Enable on-pad command tag output */
  274. static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
  275. {
  276. int v, nv;
  277. int res = 0;
  278. if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
  279. psmouse_err(psmouse, "Unable get OPC state.\n");
  280. return -EIO;
  281. }
  282. if (enable)
  283. nv = v | FSP_BIT_EN_OPC_TAG;
  284. else
  285. nv = v & ~FSP_BIT_EN_OPC_TAG;
  286. /* only write if necessary */
  287. if (nv != v) {
  288. fsp_reg_write_enable(psmouse, true);
  289. res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
  290. fsp_reg_write_enable(psmouse, false);
  291. }
  292. if (res != 0) {
  293. psmouse_err(psmouse, "Unable to enable OPC tag.\n");
  294. res = -EIO;
  295. }
  296. return res;
  297. }
  298. static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
  299. {
  300. struct fsp_data *pad = psmouse->private;
  301. int val;
  302. if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
  303. return -EIO;
  304. pad->vscroll = enable;
  305. if (enable)
  306. val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
  307. else
  308. val &= ~FSP_BIT_FIX_VSCR;
  309. if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
  310. return -EIO;
  311. return 0;
  312. }
  313. static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
  314. {
  315. struct fsp_data *pad = psmouse->private;
  316. int val, v2;
  317. if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
  318. return -EIO;
  319. if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
  320. return -EIO;
  321. pad->hscroll = enable;
  322. if (enable) {
  323. val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
  324. v2 |= FSP_BIT_EN_MSID6;
  325. } else {
  326. val &= ~FSP_BIT_FIX_HSCR;
  327. v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
  328. }
  329. if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
  330. return -EIO;
  331. /* reconfigure horizontal scrolling packet output */
  332. if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
  333. return -EIO;
  334. return 0;
  335. }
  336. /*
  337. * Write device specific initial parameters.
  338. *
  339. * ex: 0xab 0xcd - write oxcd into register 0xab
  340. */
  341. static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
  342. const char *buf, size_t count)
  343. {
  344. unsigned int reg, val;
  345. char *rest;
  346. ssize_t retval;
  347. reg = simple_strtoul(buf, &rest, 16);
  348. if (rest == buf || *rest != ' ' || reg > 0xff)
  349. return -EINVAL;
  350. retval = kstrtouint(rest + 1, 16, &val);
  351. if (retval)
  352. return retval;
  353. if (val > 0xff)
  354. return -EINVAL;
  355. if (fsp_reg_write_enable(psmouse, true))
  356. return -EIO;
  357. retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
  358. fsp_reg_write_enable(psmouse, false);
  359. return retval;
  360. }
  361. PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
  362. static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
  363. void *data, char *buf)
  364. {
  365. struct fsp_data *pad = psmouse->private;
  366. return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
  367. }
  368. /*
  369. * Read a register from device.
  370. *
  371. * ex: 0xab -- read content from register 0xab
  372. */
  373. static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
  374. const char *buf, size_t count)
  375. {
  376. struct fsp_data *pad = psmouse->private;
  377. unsigned int reg, val;
  378. int err;
  379. err = kstrtouint(buf, 16, &reg);
  380. if (err)
  381. return err;
  382. if (reg > 0xff)
  383. return -EINVAL;
  384. if (fsp_reg_read(psmouse, reg, &val))
  385. return -EIO;
  386. pad->last_reg = reg;
  387. pad->last_val = val;
  388. return count;
  389. }
  390. PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
  391. fsp_attr_show_getreg, fsp_attr_set_getreg);
  392. static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
  393. void *data, char *buf)
  394. {
  395. int val = 0;
  396. if (fsp_page_reg_read(psmouse, &val))
  397. return -EIO;
  398. return sprintf(buf, "%02x\n", val);
  399. }
  400. static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
  401. const char *buf, size_t count)
  402. {
  403. unsigned int val;
  404. int err;
  405. err = kstrtouint(buf, 16, &val);
  406. if (err)
  407. return err;
  408. if (val > 0xff)
  409. return -EINVAL;
  410. if (fsp_page_reg_write(psmouse, val))
  411. return -EIO;
  412. return count;
  413. }
  414. PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
  415. fsp_attr_show_pagereg, fsp_attr_set_pagereg);
  416. static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
  417. void *data, char *buf)
  418. {
  419. struct fsp_data *pad = psmouse->private;
  420. return sprintf(buf, "%d\n", pad->vscroll);
  421. }
  422. static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
  423. const char *buf, size_t count)
  424. {
  425. unsigned int val;
  426. int err;
  427. err = kstrtouint(buf, 10, &val);
  428. if (err)
  429. return err;
  430. if (val > 1)
  431. return -EINVAL;
  432. fsp_onpad_vscr(psmouse, val);
  433. return count;
  434. }
  435. PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
  436. fsp_attr_show_vscroll, fsp_attr_set_vscroll);
  437. static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
  438. void *data, char *buf)
  439. {
  440. struct fsp_data *pad = psmouse->private;
  441. return sprintf(buf, "%d\n", pad->hscroll);
  442. }
  443. static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
  444. const char *buf, size_t count)
  445. {
  446. unsigned int val;
  447. int err;
  448. err = kstrtouint(buf, 10, &val);
  449. if (err)
  450. return err;
  451. if (val > 1)
  452. return -EINVAL;
  453. fsp_onpad_hscr(psmouse, val);
  454. return count;
  455. }
  456. PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
  457. fsp_attr_show_hscroll, fsp_attr_set_hscroll);
  458. static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
  459. void *data, char *buf)
  460. {
  461. struct fsp_data *pad = psmouse->private;
  462. return sprintf(buf, "%c\n",
  463. pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
  464. }
  465. static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
  466. const char *buf, size_t count)
  467. {
  468. struct fsp_data *pad = psmouse->private;
  469. size_t i;
  470. for (i = 0; i < count; i++) {
  471. switch (buf[i]) {
  472. case 'C':
  473. pad->flags |= FSPDRV_FLAG_EN_OPC;
  474. break;
  475. case 'c':
  476. pad->flags &= ~FSPDRV_FLAG_EN_OPC;
  477. break;
  478. default:
  479. return -EINVAL;
  480. }
  481. }
  482. return count;
  483. }
  484. PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
  485. fsp_attr_show_flags, fsp_attr_set_flags);
  486. static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
  487. void *data, char *buf)
  488. {
  489. return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
  490. }
  491. PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
  492. static struct attribute *fsp_attributes[] = {
  493. &psmouse_attr_setreg.dattr.attr,
  494. &psmouse_attr_getreg.dattr.attr,
  495. &psmouse_attr_page.dattr.attr,
  496. &psmouse_attr_vscroll.dattr.attr,
  497. &psmouse_attr_hscroll.dattr.attr,
  498. &psmouse_attr_flags.dattr.attr,
  499. &psmouse_attr_ver.dattr.attr,
  500. NULL
  501. };
  502. static struct attribute_group fsp_attribute_group = {
  503. .attrs = fsp_attributes,
  504. };
  505. #ifdef FSP_DEBUG
  506. static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
  507. {
  508. static unsigned int ps2_packet_cnt;
  509. static unsigned int ps2_last_second;
  510. unsigned int jiffies_msec;
  511. const char *packet_type = "UNKNOWN";
  512. unsigned short abs_x = 0, abs_y = 0;
  513. /* Interpret & dump the packet data. */
  514. switch (packet[0] >> FSP_PKT_TYPE_SHIFT) {
  515. case FSP_PKT_TYPE_ABS:
  516. packet_type = "Absolute";
  517. abs_x = GET_ABS_X(packet);
  518. abs_y = GET_ABS_Y(packet);
  519. break;
  520. case FSP_PKT_TYPE_NORMAL:
  521. packet_type = "Normal";
  522. break;
  523. case FSP_PKT_TYPE_NOTIFY:
  524. packet_type = "Notify";
  525. break;
  526. case FSP_PKT_TYPE_NORMAL_OPC:
  527. packet_type = "Normal-OPC";
  528. break;
  529. }
  530. ps2_packet_cnt++;
  531. jiffies_msec = jiffies_to_msecs(jiffies);
  532. psmouse_dbg(psmouse,
  533. "%08dms %s packets: %02x, %02x, %02x, %02x; "
  534. "abs_x: %d, abs_y: %d\n",
  535. jiffies_msec, packet_type,
  536. packet[0], packet[1], packet[2], packet[3], abs_x, abs_y);
  537. if (jiffies_msec - ps2_last_second > 1000) {
  538. psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt);
  539. ps2_packet_cnt = 0;
  540. ps2_last_second = jiffies_msec;
  541. }
  542. }
  543. #else
  544. static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
  545. {
  546. }
  547. #endif
  548. static void fsp_set_slot(struct input_dev *dev, int slot, bool active,
  549. unsigned int x, unsigned int y)
  550. {
  551. input_mt_slot(dev, slot);
  552. input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
  553. if (active) {
  554. input_report_abs(dev, ABS_MT_POSITION_X, x);
  555. input_report_abs(dev, ABS_MT_POSITION_Y, y);
  556. }
  557. }
  558. static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
  559. {
  560. struct input_dev *dev = psmouse->dev;
  561. struct fsp_data *ad = psmouse->private;
  562. unsigned char *packet = psmouse->packet;
  563. unsigned char button_status = 0, lscroll = 0, rscroll = 0;
  564. unsigned short abs_x, abs_y, fgrs = 0;
  565. if (psmouse->pktcnt < 4)
  566. return PSMOUSE_GOOD_DATA;
  567. /*
  568. * Full packet accumulated, process it
  569. */
  570. fsp_packet_debug(psmouse, packet);
  571. switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
  572. case FSP_PKT_TYPE_ABS:
  573. if ((packet[0] == 0x48 || packet[0] == 0x49) &&
  574. packet[1] == 0 && packet[2] == 0) {
  575. /*
  576. * Ignore coordinate noise when finger leaving the
  577. * surface, otherwise cursor may jump to upper-left
  578. * corner.
  579. */
  580. packet[3] &= 0xf0;
  581. }
  582. abs_x = GET_ABS_X(packet);
  583. abs_y = GET_ABS_Y(packet);
  584. if (packet[0] & FSP_PB0_MFMC) {
  585. /*
  586. * MFMC packet: assume that there are two fingers on
  587. * pad
  588. */
  589. fgrs = 2;
  590. /* MFMC packet */
  591. if (packet[0] & FSP_PB0_MFMC_FGR2) {
  592. /* 2nd finger */
  593. if (ad->last_mt_fgr == 2) {
  594. /*
  595. * workaround for buggy firmware
  596. * which doesn't clear MFMC bit if
  597. * the 1st finger is up
  598. */
  599. fgrs = 1;
  600. fsp_set_slot(dev, 0, false, 0, 0);
  601. }
  602. ad->last_mt_fgr = 2;
  603. fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y);
  604. } else {
  605. /* 1st finger */
  606. if (ad->last_mt_fgr == 1) {
  607. /*
  608. * workaround for buggy firmware
  609. * which doesn't clear MFMC bit if
  610. * the 2nd finger is up
  611. */
  612. fgrs = 1;
  613. fsp_set_slot(dev, 1, false, 0, 0);
  614. }
  615. ad->last_mt_fgr = 1;
  616. fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y);
  617. }
  618. } else {
  619. /* SFAC packet */
  620. if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
  621. FSP_PB0_LBTN) {
  622. /* On-pad click in SFAC mode should be handled
  623. * by userspace. On-pad clicks in MFMC mode
  624. * are real clickpad clicks, and not ignored.
  625. */
  626. packet[0] &= ~FSP_PB0_LBTN;
  627. }
  628. /* no multi-finger information */
  629. ad->last_mt_fgr = 0;
  630. if (abs_x != 0 && abs_y != 0)
  631. fgrs = 1;
  632. fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
  633. fsp_set_slot(dev, 1, false, 0, 0);
  634. }
  635. if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) {
  636. input_report_abs(dev, ABS_X, abs_x);
  637. input_report_abs(dev, ABS_Y, abs_y);
  638. }
  639. input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
  640. input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
  641. input_report_key(dev, BTN_TOUCH, fgrs);
  642. input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1);
  643. input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2);
  644. break;
  645. case FSP_PKT_TYPE_NORMAL_OPC:
  646. /* on-pad click, filter it if necessary */
  647. if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
  648. packet[0] &= ~FSP_PB0_LBTN;
  649. fallthrough;
  650. case FSP_PKT_TYPE_NORMAL:
  651. /* normal packet */
  652. /* special packet data translation from on-pad packets */
  653. if (packet[3] != 0) {
  654. if (packet[3] & BIT(0))
  655. button_status |= 0x01; /* wheel down */
  656. if (packet[3] & BIT(1))
  657. button_status |= 0x0f; /* wheel up */
  658. if (packet[3] & BIT(2))
  659. button_status |= BIT(4);/* horizontal left */
  660. if (packet[3] & BIT(3))
  661. button_status |= BIT(5);/* horizontal right */
  662. /* push back to packet queue */
  663. if (button_status != 0)
  664. packet[3] = button_status;
  665. rscroll = (packet[3] >> 4) & 1;
  666. lscroll = (packet[3] >> 5) & 1;
  667. }
  668. /*
  669. * Processing wheel up/down and extra button events
  670. */
  671. input_report_rel(dev, REL_WHEEL,
  672. (int)(packet[3] & 8) - (int)(packet[3] & 7));
  673. input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
  674. input_report_key(dev, BTN_BACK, lscroll);
  675. input_report_key(dev, BTN_FORWARD, rscroll);
  676. /*
  677. * Standard PS/2 Mouse
  678. */
  679. psmouse_report_standard_packet(dev, packet);
  680. break;
  681. }
  682. input_sync(dev);
  683. return PSMOUSE_FULL_PACKET;
  684. }
  685. static int fsp_activate_protocol(struct psmouse *psmouse)
  686. {
  687. struct fsp_data *pad = psmouse->private;
  688. struct ps2dev *ps2dev = &psmouse->ps2dev;
  689. unsigned char param[2];
  690. int val;
  691. /*
  692. * Standard procedure to enter FSP Intellimouse mode
  693. * (scrolling wheel, 4th and 5th buttons)
  694. */
  695. param[0] = 200;
  696. ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
  697. param[0] = 200;
  698. ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
  699. param[0] = 80;
  700. ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
  701. ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
  702. if (param[0] != 0x04) {
  703. psmouse_err(psmouse,
  704. "Unable to enable 4 bytes packet format.\n");
  705. return -EIO;
  706. }
  707. if (pad->ver < FSP_VER_STL3888_C0) {
  708. /* Preparing relative coordinates output for older hardware */
  709. if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
  710. psmouse_err(psmouse,
  711. "Unable to read SYSCTL5 register.\n");
  712. return -EIO;
  713. }
  714. if (fsp_get_buttons(psmouse, &pad->buttons)) {
  715. psmouse_err(psmouse,
  716. "Unable to retrieve number of buttons.\n");
  717. return -EIO;
  718. }
  719. val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
  720. /* Ensure we are not in absolute mode */
  721. val &= ~FSP_BIT_EN_PKT_G0;
  722. if (pad->buttons == 0x06) {
  723. /* Left/Middle/Right & Scroll Up/Down/Right/Left */
  724. val |= FSP_BIT_EN_MSID6;
  725. }
  726. if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
  727. psmouse_err(psmouse,
  728. "Unable to set up required mode bits.\n");
  729. return -EIO;
  730. }
  731. /*
  732. * Enable OPC tags such that driver can tell the difference
  733. * between on-pad and real button click
  734. */
  735. if (fsp_opc_tag_enable(psmouse, true))
  736. psmouse_warn(psmouse,
  737. "Failed to enable OPC tag mode.\n");
  738. /* enable on-pad click by default */
  739. pad->flags |= FSPDRV_FLAG_EN_OPC;
  740. /* Enable on-pad vertical and horizontal scrolling */
  741. fsp_onpad_vscr(psmouse, true);
  742. fsp_onpad_hscr(psmouse, true);
  743. } else {
  744. /* Enable absolute coordinates output for Cx/Dx hardware */
  745. if (fsp_reg_write(psmouse, FSP_REG_SWC1,
  746. FSP_BIT_SWC1_EN_ABS_1F |
  747. FSP_BIT_SWC1_EN_ABS_2F |
  748. FSP_BIT_SWC1_EN_FUP_OUT |
  749. FSP_BIT_SWC1_EN_ABS_CON)) {
  750. psmouse_err(psmouse,
  751. "Unable to enable absolute coordinates output.\n");
  752. return -EIO;
  753. }
  754. }
  755. return 0;
  756. }
  757. static int fsp_set_input_params(struct psmouse *psmouse)
  758. {
  759. struct input_dev *dev = psmouse->dev;
  760. struct fsp_data *pad = psmouse->private;
  761. if (pad->ver < FSP_VER_STL3888_C0) {
  762. __set_bit(BTN_MIDDLE, dev->keybit);
  763. __set_bit(BTN_BACK, dev->keybit);
  764. __set_bit(BTN_FORWARD, dev->keybit);
  765. __set_bit(REL_WHEEL, dev->relbit);
  766. __set_bit(REL_HWHEEL, dev->relbit);
  767. } else {
  768. /*
  769. * Hardware prior to Cx performs much better in relative mode;
  770. * hence, only enable absolute coordinates output as well as
  771. * multi-touch output for the newer hardware.
  772. *
  773. * Maximum coordinates can be computed as:
  774. *
  775. * number of scanlines * 64 - 57
  776. *
  777. * where number of X/Y scanline lines are 16/12.
  778. */
  779. int abs_x = 967, abs_y = 711;
  780. __set_bit(EV_ABS, dev->evbit);
  781. __clear_bit(EV_REL, dev->evbit);
  782. __set_bit(BTN_TOUCH, dev->keybit);
  783. __set_bit(BTN_TOOL_FINGER, dev->keybit);
  784. __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
  785. __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
  786. input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0);
  787. input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0);
  788. input_mt_init_slots(dev, 2, 0);
  789. input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0);
  790. input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0);
  791. }
  792. return 0;
  793. }
  794. int fsp_detect(struct psmouse *psmouse, bool set_properties)
  795. {
  796. int id;
  797. if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
  798. return -EIO;
  799. if (id != 0x01)
  800. return -ENODEV;
  801. if (set_properties) {
  802. psmouse->vendor = "Sentelic";
  803. psmouse->name = "FingerSensingPad";
  804. }
  805. return 0;
  806. }
  807. static void fsp_reset(struct psmouse *psmouse)
  808. {
  809. fsp_opc_tag_enable(psmouse, false);
  810. fsp_onpad_vscr(psmouse, false);
  811. fsp_onpad_hscr(psmouse, false);
  812. }
  813. static void fsp_disconnect(struct psmouse *psmouse)
  814. {
  815. sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
  816. &fsp_attribute_group);
  817. fsp_reset(psmouse);
  818. kfree(psmouse->private);
  819. }
  820. static int fsp_reconnect(struct psmouse *psmouse)
  821. {
  822. int version;
  823. if (fsp_detect(psmouse, 0))
  824. return -ENODEV;
  825. if (fsp_get_version(psmouse, &version))
  826. return -ENODEV;
  827. if (fsp_activate_protocol(psmouse))
  828. return -EIO;
  829. return 0;
  830. }
  831. int fsp_init(struct psmouse *psmouse)
  832. {
  833. struct fsp_data *priv;
  834. int ver, rev, sn = 0;
  835. int error;
  836. if (fsp_get_version(psmouse, &ver) ||
  837. fsp_get_revision(psmouse, &rev)) {
  838. return -ENODEV;
  839. }
  840. if (ver >= FSP_VER_STL3888_C0) {
  841. /* firmware information is only available since C0 */
  842. fsp_get_sn(psmouse, &sn);
  843. }
  844. psmouse_info(psmouse,
  845. "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n",
  846. ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver);
  847. psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
  848. if (!priv)
  849. return -ENOMEM;
  850. priv->ver = ver;
  851. priv->rev = rev;
  852. psmouse->protocol_handler = fsp_process_byte;
  853. psmouse->disconnect = fsp_disconnect;
  854. psmouse->reconnect = fsp_reconnect;
  855. psmouse->cleanup = fsp_reset;
  856. psmouse->pktsize = 4;
  857. error = fsp_activate_protocol(psmouse);
  858. if (error)
  859. goto err_out;
  860. /* Set up various supported input event bits */
  861. error = fsp_set_input_params(psmouse);
  862. if (error)
  863. goto err_out;
  864. error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
  865. &fsp_attribute_group);
  866. if (error) {
  867. psmouse_err(psmouse,
  868. "Failed to create sysfs attributes (%d)", error);
  869. goto err_out;
  870. }
  871. return 0;
  872. err_out:
  873. kfree(psmouse->private);
  874. psmouse->private = NULL;
  875. return error;
  876. }