qfs4008_common.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359
  1. /*
  2. * Copyright (C) 2018 Samsung Electronics. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. */
  13. #include "fingerprint.h"
  14. #include "qfs4008_common.h"
  15. /*
  16. * struct ipc_msg_type_to_fw_event -
  17. * entry in mapping between an IPC message type to a firmware event
  18. * @msg_type - IPC message type, as reported by firmware
  19. * @fw_event - corresponding firmware event code to report to driver client
  20. */
  21. struct ipc_msg_type_to_fw_event {
  22. uint32_t msg_type;
  23. enum qfs4008_fw_event fw_event;
  24. };
  25. /* mapping between firmware IPC message types to HLOS firmware events */
  26. struct ipc_msg_type_to_fw_event g_msg_to_event[] = {
  27. {IPC_MSG_ID_CBGE_REQUIRED, FW_EVENT_CBGE_REQUIRED},
  28. {IPC_MSG_ID_FINGER_ON_SENSOR, FW_EVENT_FINGER_DOWN},
  29. {IPC_MSG_ID_FINGER_OFF_SENSOR, FW_EVENT_FINGER_UP},
  30. };
  31. static ssize_t vendor_show(struct device *dev,
  32. struct device_attribute *attr, char *buf)
  33. {
  34. return snprintf(buf, PAGE_SIZE, "%s\n", VENDOR);
  35. }
  36. static ssize_t name_show(struct device *dev,
  37. struct device_attribute *attr, char *buf)
  38. {
  39. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  40. return snprintf(buf, PAGE_SIZE, "%s\n", drvdata->chipid);
  41. }
  42. static ssize_t adm_show(struct device *dev,
  43. struct device_attribute *attr, char *buf)
  44. {
  45. return snprintf(buf, PAGE_SIZE, "%d\n", DETECT_ADM);
  46. }
  47. static ssize_t bfs_values_show(struct device *dev,
  48. struct device_attribute *attr, char *buf)
  49. {
  50. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  51. return snprintf(buf, PAGE_SIZE, "\"FP_SPICLK\":\"%d\"\n",
  52. drvdata->clk_setting->spi_speed);
  53. }
  54. static ssize_t type_check_show(struct device *dev,
  55. struct device_attribute *attr, char *buf)
  56. {
  57. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  58. pr_info("%s\n", drvdata->sensortype > 0 ? drvdata->chipid : sensor_status[drvdata->sensortype + 2]);
  59. return snprintf(buf, PAGE_SIZE, "%d\n", drvdata->sensortype);
  60. }
  61. static ssize_t position_show(struct device *dev,
  62. struct device_attribute *attr, char *buf)
  63. {
  64. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  65. return snprintf(buf, PAGE_SIZE, "%s\n", drvdata->sensor_position);
  66. }
  67. static ssize_t cbgecnt_show(struct device *dev,
  68. struct device_attribute *attr, char *buf)
  69. {
  70. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  71. return snprintf(buf, PAGE_SIZE, "%d\n", drvdata->cbge_count);
  72. }
  73. static ssize_t cbgecnt_store(struct device *dev,
  74. struct device_attribute *attr, const char *buf,
  75. size_t size)
  76. {
  77. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  78. if (sysfs_streq(buf, "c")) {
  79. drvdata->cbge_count = 0;
  80. pr_info("initialization is done\n");
  81. }
  82. return size;
  83. }
  84. static ssize_t intcnt_show(struct device *dev,
  85. struct device_attribute *attr, char *buf)
  86. {
  87. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  88. return snprintf(buf, PAGE_SIZE, "%d\n", drvdata->wuhb_count);
  89. }
  90. static ssize_t intcnt_store(struct device *dev,
  91. struct device_attribute *attr, const char *buf,
  92. size_t size)
  93. {
  94. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  95. if (sysfs_streq(buf, "c")) {
  96. drvdata->wuhb_count = 0;
  97. pr_info("initialization is done\n");
  98. }
  99. return size;
  100. }
  101. static ssize_t resetcnt_show(struct device *dev,
  102. struct device_attribute *attr, char *buf)
  103. {
  104. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  105. return snprintf(buf, PAGE_SIZE, "%d\n", drvdata->reset_count);
  106. }
  107. static ssize_t resetcnt_store(struct device *dev,
  108. struct device_attribute *attr, const char *buf,
  109. size_t size)
  110. {
  111. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  112. if (sysfs_streq(buf, "c")) {
  113. drvdata->reset_count = 0;
  114. pr_info("initialization is done\n");
  115. }
  116. return size;
  117. }
  118. static ssize_t wuhbtest_show(struct device *dev,
  119. struct device_attribute *attr, char *buf)
  120. {
  121. struct qfs4008_drvdata *drvdata = dev_get_drvdata(dev);
  122. int rc = 0;
  123. int gpio_value = 0;
  124. gpio_value = gpio_get_value(drvdata->fd_gpio.gpio);
  125. if (gpio_value == 0) { /* Finger Leave */
  126. pr_info("wuhbtest Finger Leave Ok\n");
  127. rc = 1;
  128. } else { /* Finger Down */
  129. pr_err("wuhbtest Finger Leave NG\n");
  130. rc = 0;
  131. }
  132. return snprintf(buf, PAGE_SIZE, "%d\n", rc);
  133. }
  134. static DEVICE_ATTR_RO(bfs_values);
  135. static DEVICE_ATTR_RO(type_check);
  136. static DEVICE_ATTR_RO(vendor);
  137. static DEVICE_ATTR_RO(name);
  138. static DEVICE_ATTR_RO(adm);
  139. static DEVICE_ATTR_RO(position);
  140. static DEVICE_ATTR_RW(cbgecnt);
  141. static DEVICE_ATTR_RW(intcnt);
  142. static DEVICE_ATTR_RW(resetcnt);
  143. static DEVICE_ATTR_RO(wuhbtest);
  144. static struct device_attribute *fp_attrs[] = {
  145. &dev_attr_bfs_values,
  146. &dev_attr_type_check,
  147. &dev_attr_vendor,
  148. &dev_attr_name,
  149. &dev_attr_adm,
  150. &dev_attr_position,
  151. &dev_attr_cbgecnt,
  152. &dev_attr_intcnt,
  153. &dev_attr_resetcnt,
  154. &dev_attr_wuhbtest,
  155. NULL,
  156. };
  157. int qfs4008_pinctrl_register(struct qfs4008_drvdata *drvdata)
  158. {
  159. drvdata->p = devm_pinctrl_get(drvdata->dev);
  160. if (IS_ERR(drvdata->p)) {
  161. pr_err("failed pinctrl_get\n");
  162. goto pinctrl_get_exit;
  163. }
  164. #if !defined(ENABLE_SENSORS_FPRINT_SECURE) || defined(DISABLED_GPIO_PROTECTION)
  165. drvdata->pins_poweroff = pinctrl_lookup_state(drvdata->p, "pins_poweroff");
  166. if (IS_ERR(drvdata->pins_poweroff)) {
  167. pr_err("could not get pins sleep_state (%li)\n",
  168. PTR_ERR(drvdata->pins_poweroff));
  169. goto pinctrl_register_exit;
  170. }
  171. drvdata->pins_poweron = pinctrl_lookup_state(drvdata->p, "pins_poweron");
  172. if (IS_ERR(drvdata->pins_poweron)) {
  173. pr_err("could not get pins idle_state (%li)\n",
  174. PTR_ERR(drvdata->pins_poweron));
  175. goto pinctrl_register_exit;
  176. }
  177. #endif
  178. pr_info("finished\n");
  179. return 0;
  180. #if !defined(ENABLE_SENSORS_FPRINT_SECURE) || defined(DISABLED_GPIO_PROTECTION)
  181. pinctrl_register_exit:
  182. drvdata->pins_poweron = NULL;
  183. drvdata->pins_poweroff = NULL;
  184. #endif
  185. pinctrl_get_exit:
  186. pr_err("failed\n");
  187. return -ENODEV;
  188. }
  189. static int qfs4008_power_control(struct qfs4008_drvdata *drvdata, int onoff)
  190. {
  191. int rc = 0;
  192. if (regulator_is_enabled(drvdata->regulator_1p8) == onoff &&
  193. regulator_is_enabled(drvdata->regulator_3p0) == onoff) {
  194. pr_err("regulator already turned %s\n", onoff ? "on" : "off");
  195. } else {
  196. if (onoff) {
  197. rc = regulator_enable(drvdata->regulator_3p0);
  198. if (rc)
  199. pr_err("regulator_3p0 enable failed, rc=%d\n", rc);
  200. usleep_range(2000, 2050);
  201. rc = regulator_enable(drvdata->regulator_1p8);
  202. if (rc)
  203. pr_err("regulator_1p8 enable failed, rc=%d\n", rc);
  204. usleep_range(2000, 2050);
  205. } else {
  206. rc = regulator_disable(drvdata->regulator_1p8);
  207. if (rc)
  208. pr_err("regulator_1p8 disable failed, rc=%d\n", rc);
  209. rc = regulator_disable(drvdata->regulator_3p0);
  210. if (rc)
  211. pr_err("regulator_3p0 disable failed, rc=%d\n", rc);
  212. }
  213. }
  214. if (!rc) {
  215. #if !defined(ENABLE_SENSORS_FPRINT_SECURE) || defined(DISABLED_GPIO_PROTECTION)
  216. if (onoff) {
  217. if (drvdata->pins_poweron) {
  218. rc = pinctrl_select_state(drvdata->p, drvdata->pins_poweron);
  219. pr_debug("pinctrl for poweron. rc=%d\n", rc);
  220. }
  221. } else {
  222. if (drvdata->pins_poweroff) {
  223. rc = pinctrl_select_state(drvdata->p, drvdata->pins_poweroff);
  224. pr_debug("pinctrl for poweroff. rc=%d\n", rc);
  225. }
  226. }
  227. #endif
  228. drvdata->enabled_ldo = onoff;
  229. }
  230. pr_info("%s, rc=%d\n", onoff ? "ON" : "OFF", rc);
  231. return rc;
  232. }
  233. static int qfs4008_enable_spi_clock(struct qfs4008_drvdata *drvdata)
  234. {
  235. int rc = 0;
  236. #if !defined(ENABLE_SENSORS_FPRINT_SECURE) || defined(DISABLED_GPIO_PROTECTION)
  237. if (drvdata->pins_poweron) {
  238. rc = pinctrl_select_state(drvdata->p, drvdata->pins_poweron);
  239. pr_info("pinctrl for spi_active. rc=%d\n", rc);
  240. }
  241. #endif
  242. rc = spi_clk_enable(drvdata->clk_setting);
  243. return rc;
  244. }
  245. static int qfs4008_disable_spi_clock(struct qfs4008_drvdata *drvdata)
  246. {
  247. int rc = 0;
  248. #if !defined(ENABLE_SENSORS_FPRINT_SECURE) || defined(DISABLED_GPIO_PROTECTION)
  249. if (drvdata->pins_poweroff) {
  250. rc = pinctrl_select_state(drvdata->p, drvdata->pins_poweroff);
  251. pr_info("pinctrl for spi_inactive. rc=%d\n", rc);
  252. }
  253. #endif
  254. rc = spi_clk_disable(drvdata->clk_setting);
  255. return rc;
  256. }
  257. static int qfs4008_enable_ipc(struct qfs4008_drvdata *drvdata)
  258. {
  259. int rc = 0;
  260. if (drvdata->fw_ipc.gpio) {
  261. if (drvdata->enabled_ipc) {
  262. rc = -EINVAL;
  263. pr_err("already enabled ipc\n");
  264. } else {
  265. enable_irq(drvdata->fw_ipc.irq);
  266. enable_irq_wake(drvdata->fw_ipc.irq);
  267. drvdata->enabled_ipc = true;
  268. }
  269. }
  270. return rc;
  271. }
  272. static int qfs4008_disable_ipc(struct qfs4008_drvdata *drvdata)
  273. {
  274. int rc = 0;
  275. if (drvdata->fw_ipc.gpio) {
  276. if (drvdata->enabled_ipc) {
  277. disable_irq_wake(drvdata->fw_ipc.irq);
  278. disable_irq(drvdata->fw_ipc.irq);
  279. drvdata->enabled_ipc = false;
  280. } else {
  281. rc = -EINVAL;
  282. pr_err("already disabled ipc\n");
  283. }
  284. }
  285. return rc;
  286. }
  287. static int qfs4008_enable_wuhb(struct qfs4008_drvdata *drvdata)
  288. {
  289. int rc = 0;
  290. int gpio = 0;
  291. if (drvdata->fd_gpio.gpio) {
  292. if (drvdata->enabled_wuhb) {
  293. rc = -EINVAL;
  294. pr_err("already enabled wuhb\n");
  295. } else {
  296. enable_irq(drvdata->fd_gpio.irq);
  297. enable_irq_wake(drvdata->fd_gpio.irq);
  298. drvdata->enabled_wuhb = true;
  299. /* To prevent FingerUp Missing issue. */
  300. gpio = gpio_get_value(drvdata->fd_gpio.gpio);
  301. if (drvdata->fd_gpio.last_gpio_state == FINGER_DOWN_GPIO_STATE &&
  302. gpio == FINGER_LEAVE_GPIO_STATE) {
  303. pr_info("Finger leave event already occurred. %d, %d\n",
  304. drvdata->fd_gpio.last_gpio_state, gpio);
  305. __pm_wakeup_event(drvdata->fp_signal_lock,
  306. msecs_to_jiffies(QFS4008_WAKELOCK_HOLD_TIME));
  307. schedule_work(&drvdata->fd_gpio.work);
  308. }
  309. }
  310. }
  311. return rc;
  312. }
  313. static int qfs4008_disable_wuhb(struct qfs4008_drvdata *drvdata)
  314. {
  315. int rc = 0;
  316. if (drvdata->fd_gpio.gpio) {
  317. if (drvdata->enabled_wuhb) {
  318. disable_irq(drvdata->fd_gpio.irq);
  319. disable_irq_wake(drvdata->fd_gpio.irq);
  320. drvdata->enabled_wuhb = false;
  321. } else {
  322. rc = -EINVAL;
  323. pr_err("already disabled wuhb\n");
  324. }
  325. }
  326. return rc;
  327. }
  328. /**
  329. * qfs4008_open() - Function called when user space opens device.
  330. * Successful if driver not currently open.
  331. * @inode: ptr to inode object
  332. * @file: ptr to file object
  333. *
  334. * Return: 0 on success. Error code on failure.
  335. */
  336. static int qfs4008_open(struct inode *inode, struct file *file)
  337. {
  338. struct qfs4008_drvdata *drvdata = NULL;
  339. int rc = 0;
  340. int minor_no = iminor(inode);
  341. if (minor_no == MINOR_NUM_FD) {
  342. drvdata = container_of(inode->i_cdev, struct qfs4008_drvdata,
  343. qfs4008_fd_cdev);
  344. } else if (minor_no == MINOR_NUM_IPC) {
  345. drvdata = container_of(inode->i_cdev, struct qfs4008_drvdata,
  346. qfs4008_ipc_cdev);
  347. } else {
  348. pr_err("Invalid minor number\n");
  349. return -EINVAL;
  350. }
  351. file->private_data = drvdata;
  352. /* disallowing concurrent opens */
  353. if (minor_no == MINOR_NUM_FD && !atomic_dec_and_test(&drvdata->fd_available)) {
  354. atomic_inc(&drvdata->fd_available);
  355. pr_err("fd_unavailable\n");
  356. rc = -EBUSY;
  357. } else if (minor_no == MINOR_NUM_IPC && !atomic_dec_and_test(&drvdata->ipc_available)) {
  358. atomic_inc(&drvdata->ipc_available);
  359. pr_err("ipc_unavailable\n");
  360. rc = -EBUSY;
  361. }
  362. pr_debug("minor_no=%d, rc=%d,%d,%d\n", minor_no, rc,
  363. atomic_read(&drvdata->fd_available),
  364. atomic_read(&drvdata->ipc_available));
  365. return rc;
  366. }
  367. /**
  368. * qfs4008_release() - Function called when user space closes device.
  369. * @inode: ptr to inode object
  370. * @file: ptr to file object
  371. *
  372. * Return: 0 on success. Error code on failure.
  373. */
  374. static int qfs4008_release(struct inode *inode, struct file *file)
  375. {
  376. struct qfs4008_drvdata *drvdata;
  377. int minor_no;
  378. int rc = 0;
  379. if (!file || !file->private_data) {
  380. pr_err("%s: NULL pointer passed\n", __func__);
  381. return -EINVAL;
  382. }
  383. drvdata = file->private_data;
  384. minor_no = iminor(inode);
  385. if (minor_no == MINOR_NUM_FD) {
  386. atomic_inc(&drvdata->fd_available);
  387. } else if (minor_no == MINOR_NUM_IPC) {
  388. atomic_inc(&drvdata->ipc_available);
  389. } else {
  390. pr_err("Invalid minor number\n");
  391. rc = -EINVAL;
  392. }
  393. pr_debug("minor_no=%d, rc=%d,%d,%d\n", minor_no, rc,
  394. atomic_read(&drvdata->fd_available),
  395. atomic_read(&drvdata->ipc_available));
  396. return rc;
  397. }
  398. /**
  399. * qfs4008_ioctl() - Function called when user space calls ioctl.
  400. * @file: struct file - not used
  401. * @cmd: cmd identifier:QFS4008_LOAD_APP,QFS4008_UNLOAD_APP,
  402. * QFS4008_SEND_TZCMD
  403. * @arg: ptr to relevant structe: either qfs4008_app or
  404. * qfs4008_send_tz_cmd depending on which cmd is passed
  405. *
  406. * Return: 0 on success. Error code on failure.
  407. */
  408. static long qfs4008_ioctl(
  409. struct file *file, unsigned int cmd, unsigned long arg)
  410. {
  411. int rc = 0;
  412. int data = 0;
  413. void __user *priv_arg = (void __user *)arg;
  414. struct qfs4008_drvdata *drvdata;
  415. if (!file || !file->private_data) {
  416. pr_err("%s: NULL pointer passed\n", __func__);
  417. return -EINVAL;
  418. }
  419. drvdata = file->private_data;
  420. if (IS_ERR(priv_arg)) {
  421. pr_err("invalid user space pointer %lu\n", arg);
  422. return -EINVAL;
  423. }
  424. mutex_lock(&drvdata->ioctl_mutex);
  425. switch (cmd) {
  426. case QFS4008_IS_WHUB_CONNECTED:
  427. break;
  428. case QFS4008_POWER_CONTROL:
  429. if (copy_from_user(&data, (void *)arg, sizeof(int)) != 0) {
  430. pr_err("Failed copy from user.(POWER_CONTROL)\n");
  431. rc = -EFAULT;
  432. goto ioctl_failed;
  433. }
  434. if (drvdata->enabled_ldo != data) {
  435. pr_debug("POWER_CONTROL\n");
  436. qfs4008_power_control(drvdata, data);
  437. }
  438. break;
  439. case QFS4008_ENABLE_SPI_CLOCK:
  440. pr_info("ENABLE_SPI_CLOCK\n");
  441. rc = qfs4008_enable_spi_clock(drvdata);
  442. break;
  443. case QFS4008_DISABLE_SPI_CLOCK:
  444. pr_info("DISABLE_SPI_CLOCK\n");
  445. rc = qfs4008_disable_spi_clock(drvdata);
  446. break;
  447. case QFS4008_ENABLE_IPC:
  448. pr_info("ENABLE_IPC\n");
  449. rc = qfs4008_enable_ipc(drvdata);
  450. break;
  451. case QFS4008_DISABLE_IPC:
  452. pr_info("DISABLE_IPC\n");
  453. rc = qfs4008_disable_ipc(drvdata);
  454. break;
  455. case QFS4008_ENABLE_WUHB:
  456. pr_info("ENABLE_WUHB\n");
  457. rc = qfs4008_enable_wuhb(drvdata);
  458. break;
  459. case QFS4008_DISABLE_WUHB:
  460. pr_info("DISABLE_WUHB\n");
  461. rc = qfs4008_disable_wuhb(drvdata);
  462. break;
  463. case QFS4008_CPU_SPEEDUP:
  464. if (copy_from_user(&data, (void *)arg, sizeof(int)) != 0) {
  465. pr_err("Failed copy from user.(SPEEDUP)\n");
  466. rc = -EFAULT;
  467. goto ioctl_failed;
  468. }
  469. if (data)
  470. rc = cpu_speedup_enable(drvdata->boosting);
  471. else
  472. rc = cpu_speedup_disable(drvdata->boosting);
  473. break;
  474. case QFS4008_SET_SENSOR_TYPE:
  475. if (copy_from_user(&data, (void *)arg, sizeof(int)) != 0) {
  476. pr_err("Failed to copy sensor type from user to kernel\n");
  477. rc = -EFAULT;
  478. goto ioctl_failed;
  479. }
  480. set_sensor_type(data, &drvdata->sensortype);
  481. break;
  482. case QFS4008_SET_LOCKSCREEN:
  483. break;
  484. case QFS4008_SENSOR_RESET:
  485. drvdata->reset_count++;
  486. pr_err("SENSOR_RESET\n");
  487. break;
  488. case QFS4008_SENSOR_TEST:
  489. if (copy_from_user(&data, (void *)arg, sizeof(int)) != 0) {
  490. pr_err("Failed to copy BGECAL from user to kernel\n");
  491. rc = -EFAULT;
  492. goto ioctl_failed;
  493. }
  494. #ifndef ENABLE_SENSORS_FPRINT_SECURE //only for factory
  495. if (data == QFS4008_SENSORTEST_DONE)
  496. pr_info("SENSORTEST Finished\n");
  497. else
  498. pr_info("SENSORTEST Start : 0x%x\n", data);
  499. #endif
  500. break;
  501. case QFS4008_GET_MODELINFO:
  502. pr_info("QFS4008_GET_MODELINFO : %s\n", drvdata->model_info);
  503. if (copy_to_user((void __user *)priv_arg, drvdata->model_info, 10)) {
  504. pr_err("Failed to copy GET_MODELINFO to user\n");
  505. rc = -EFAULT;
  506. }
  507. break;
  508. case QFS4008_SET_TOUCH_IGNORE:
  509. if (copy_from_user(&data, (void *)arg, sizeof(int)) != 0) {
  510. pr_err("Failed copy from user.(TOUCH_IGNORE)\n");
  511. rc = -EFAULT;
  512. goto ioctl_failed;
  513. }
  514. drvdata->touch_ignore = data;
  515. pr_info("QFS4008_SET_TOUCH_IGNORE : %d, %d\n", drvdata->touch_ignore, data);
  516. break;
  517. default:
  518. pr_err("invalid cmd %d\n", cmd);
  519. rc = -ENOIOCTLCMD;
  520. }
  521. ioctl_failed:
  522. mutex_unlock(&drvdata->ioctl_mutex);
  523. return rc;
  524. }
  525. static int get_events_fifo_len_locked(struct qfs4008_drvdata *drvdata, int minor_no)
  526. {
  527. int len = 0;
  528. if (minor_no == MINOR_NUM_FD) {
  529. mutex_lock(&drvdata->fd_events_mutex);
  530. len = kfifo_len(&drvdata->fd_events);
  531. mutex_unlock(&drvdata->fd_events_mutex);
  532. } else if (minor_no == MINOR_NUM_IPC) {
  533. mutex_lock(&drvdata->ipc_events_mutex);
  534. len = kfifo_len(&drvdata->ipc_events);
  535. mutex_unlock(&drvdata->ipc_events_mutex);
  536. }
  537. return len;
  538. }
  539. static ssize_t qfs4008_read(struct file *filp, char __user *ubuf,
  540. size_t cnt, loff_t *ppos)
  541. {
  542. struct fw_event_desc fw_event;
  543. struct qfs4008_drvdata *drvdata = filp->private_data;
  544. wait_queue_head_t *read_wait_queue = NULL;
  545. int rc = 0;
  546. int minor_no = iminor(filp->f_path.dentry->d_inode);
  547. int fifo_len = get_events_fifo_len_locked(drvdata, minor_no);
  548. if (cnt < sizeof(fw_event.ev)) {
  549. pr_err("Num bytes to read is too small, numBytes=%zd\n", cnt);
  550. return -EINVAL;
  551. }
  552. if (minor_no == MINOR_NUM_FD) {
  553. read_wait_queue = &drvdata->read_wait_queue_fd;
  554. } else if (minor_no == MINOR_NUM_IPC) {
  555. read_wait_queue = &drvdata->read_wait_queue_ipc;
  556. } else {
  557. pr_err("Invalid minor number\n");
  558. return -EINVAL;
  559. }
  560. while (fifo_len == 0) {
  561. if (filp->f_flags & O_NONBLOCK) {
  562. pr_debug("fw_events fifo: empty, returning\n");
  563. return -EAGAIN;
  564. }
  565. pr_debug("fw_events fifo: empty, waiting\n");
  566. if (wait_event_interruptible(*read_wait_queue,
  567. (get_events_fifo_len_locked(drvdata, minor_no) > 0)))
  568. return -ERESTARTSYS;
  569. fifo_len = get_events_fifo_len_locked(drvdata, minor_no);
  570. }
  571. if (minor_no == MINOR_NUM_FD) {
  572. mutex_lock(&drvdata->fd_events_mutex);
  573. rc = kfifo_get(&drvdata->fd_events, &fw_event);
  574. mutex_unlock(&drvdata->fd_events_mutex);
  575. } else if (minor_no == MINOR_NUM_IPC) {
  576. mutex_lock(&drvdata->ipc_events_mutex);
  577. rc = kfifo_get(&drvdata->ipc_events, &fw_event);
  578. mutex_unlock(&drvdata->ipc_events_mutex);
  579. } else {
  580. pr_err("Invalid minor number\n");
  581. }
  582. if (!rc) {
  583. pr_err("fw_events fifo: unexpectedly empty\n");
  584. return -EINVAL;
  585. }
  586. rc = copy_to_user(ubuf, &fw_event.ev, sizeof(fw_event.ev));
  587. if (rc != 0) {
  588. pr_err("Failed to copy_to_user:%d - event:%d, minor:%d\n",
  589. rc, (int)fw_event.ev, minor_no);
  590. } else {
  591. if (minor_no == MINOR_NUM_FD) {
  592. pr_info("Firmware event %d at minor no %d read at time %lu uS, mutex_unlock\n",
  593. (int)fw_event.ev, minor_no,
  594. (unsigned long)ktime_to_us(ktime_get()));
  595. } else {
  596. pr_info("Firmware event %d at minor no %d read at time %lu uS\n",
  597. (int)fw_event.ev, minor_no,
  598. (unsigned long)ktime_to_us(ktime_get()));
  599. }
  600. }
  601. return rc;
  602. }
  603. static unsigned int qfs4008_poll(struct file *filp,
  604. struct poll_table_struct *wait)
  605. {
  606. struct qfs4008_drvdata *drvdata = filp->private_data;
  607. unsigned int mask = 0;
  608. int minor_no = iminor(filp->f_path.dentry->d_inode);
  609. if (minor_no == MINOR_NUM_FD) {
  610. poll_wait(filp, &drvdata->read_wait_queue_fd, wait);
  611. if (kfifo_len(&drvdata->fd_events) > 0)
  612. mask |= (POLLIN | POLLRDNORM);
  613. } else if (minor_no == MINOR_NUM_IPC) {
  614. poll_wait(filp, &drvdata->read_wait_queue_ipc, wait);
  615. if (kfifo_len(&drvdata->ipc_events) > 0)
  616. mask |= (POLLIN | POLLRDNORM);
  617. } else {
  618. pr_err("Invalid minor number\n");
  619. return -EINVAL;
  620. }
  621. return mask;
  622. }
  623. static const struct file_operations qfs4008_fops = {
  624. .owner = THIS_MODULE,
  625. .unlocked_ioctl = qfs4008_ioctl,
  626. .open = qfs4008_open,
  627. .release = qfs4008_release,
  628. .read = qfs4008_read,
  629. .poll = qfs4008_poll
  630. };
  631. static int qfs4008_dev_register(struct qfs4008_drvdata *drvdata)
  632. {
  633. dev_t dev_no, major_no;
  634. int rc = 0;
  635. struct device *dev = drvdata->dev;
  636. rc = alloc_chrdev_region(&dev_no, 0, 2, QFS4008_DEV);
  637. if (rc) {
  638. pr_err("alloc_chrdev_region failed %d\n", rc);
  639. goto err_alloc;
  640. }
  641. major_no = MAJOR(dev_no);
  642. cdev_init(&drvdata->qfs4008_fd_cdev, &qfs4008_fops);
  643. drvdata->qfs4008_fd_cdev.owner = THIS_MODULE;
  644. rc = cdev_add(&drvdata->qfs4008_fd_cdev,
  645. MKDEV(major_no, MINOR_NUM_FD), 1);
  646. if (rc) {
  647. pr_err("cdev_add failed for fd %d\n", rc);
  648. goto err_cdev_add;
  649. }
  650. cdev_init(&drvdata->qfs4008_ipc_cdev, &qfs4008_fops);
  651. drvdata->qfs4008_ipc_cdev.owner = THIS_MODULE;
  652. rc = cdev_add(&drvdata->qfs4008_ipc_cdev,
  653. MKDEV(major_no, MINOR_NUM_IPC), 1);
  654. if (rc) {
  655. pr_err("cdev_add failed for ipc %d\n", rc);
  656. goto err_cdev_add;
  657. }
  658. #if (KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE)
  659. drvdata->qfs4008_class = class_create(QFS4008_DEV);
  660. #else
  661. drvdata->qfs4008_class = class_create(THIS_MODULE, QFS4008_DEV);
  662. #endif
  663. if (IS_ERR(drvdata->qfs4008_class)) {
  664. rc = PTR_ERR(drvdata->qfs4008_class);
  665. pr_err("class_create failed %d\n", rc);
  666. goto err_class_create;
  667. }
  668. dev = device_create(drvdata->qfs4008_class, NULL,
  669. drvdata->qfs4008_fd_cdev.dev,
  670. drvdata, "%s_fd", QFS4008_DEV);
  671. if (IS_ERR(dev)) {
  672. rc = PTR_ERR(dev);
  673. pr_err("fd device_create failed %d\n", rc);
  674. goto err_dev_create_fd;
  675. }
  676. dev = device_create(drvdata->qfs4008_class, NULL,
  677. drvdata->qfs4008_ipc_cdev.dev,
  678. drvdata, "%s_ipc", QFS4008_DEV);
  679. if (IS_ERR(dev)) {
  680. rc = PTR_ERR(dev);
  681. pr_err("ipc device_create failed %d\n", rc);
  682. goto err_dev_create_ipc;
  683. }
  684. pr_info("finished\n");
  685. return 0;
  686. err_dev_create_ipc:
  687. device_destroy(drvdata->qfs4008_class, drvdata->qfs4008_fd_cdev.dev);
  688. err_dev_create_fd:
  689. class_destroy(drvdata->qfs4008_class);
  690. err_class_create:
  691. cdev_del(&drvdata->qfs4008_fd_cdev);
  692. cdev_del(&drvdata->qfs4008_ipc_cdev);
  693. err_cdev_add:
  694. unregister_chrdev_region(drvdata->qfs4008_fd_cdev.dev, 1);
  695. unregister_chrdev_region(drvdata->qfs4008_ipc_cdev.dev, 1);
  696. err_alloc:
  697. return rc;
  698. }
  699. static void qfs4008_gpio_report_event(struct qfs4008_drvdata *drvdata)
  700. {
  701. int state;
  702. struct fw_event_desc fw_event;
  703. state = (gpio_get_value(drvdata->fd_gpio.gpio) ? FINGER_DOWN_GPIO_STATE : FINGER_LEAVE_GPIO_STATE)
  704. ^ drvdata->fd_gpio.active_low;
  705. if (state == drvdata->fd_gpio.last_gpio_state) {
  706. pr_err("skip the report_event. this event already reported, last_gpio:%d\n", state);
  707. return;
  708. }
  709. if (drvdata->touch_ignore && state == FINGER_DOWN_GPIO_STATE) {
  710. pr_info("touch ignored. %s state, %d \n", (state ? "Finger Down" : "Finger Leave"), drvdata->touch_ignore);
  711. return;
  712. }
  713. drvdata->fd_gpio.last_gpio_state = state;
  714. fw_event.ev = (state ? FW_EVENT_FINGER_DOWN : FW_EVENT_FINGER_UP);
  715. mutex_lock(&drvdata->fd_events_mutex);
  716. kfifo_reset(&drvdata->fd_events);
  717. if (!kfifo_put(&drvdata->fd_events, fw_event))
  718. pr_err("fw events fifo: error adding item\n");
  719. mutex_unlock(&drvdata->fd_events_mutex);
  720. wake_up_interruptible(&drvdata->read_wait_queue_fd);
  721. pr_info("state: %s\n", state ? "Finger Down" : "Finger Leave");
  722. }
  723. static void qfs4008_wuhb_work_func(struct work_struct *work)
  724. {
  725. struct qfs4008_drvdata *drvdata = container_of(work,
  726. struct qfs4008_drvdata, fd_gpio.work);
  727. qfs4008_gpio_report_event(drvdata);
  728. }
  729. static irqreturn_t qfs4008_wuhb_irq_handler(int irq, void *dev_id)
  730. {
  731. struct qfs4008_drvdata *drvdata = dev_id;
  732. if (irq != drvdata->fd_gpio.irq) {
  733. pr_warn("invalid irq %d (expected %d)\n", irq,
  734. drvdata->fd_gpio.irq);
  735. return IRQ_HANDLED;
  736. }
  737. drvdata->wuhb_count++;
  738. __pm_wakeup_event(drvdata->fp_signal_lock,
  739. msecs_to_jiffies(QFS4008_WAKELOCK_HOLD_TIME));
  740. schedule_work(&drvdata->fd_gpio.work);
  741. return IRQ_HANDLED;
  742. }
  743. /*
  744. * qfs4008_ipc_irq_handler() - function processes IPC
  745. * interrupts on its own thread
  746. * @irq: the interrupt that occurred
  747. * @dev_id: pointer to the qfs4008_drvdata
  748. *
  749. * Return: IRQ_HANDLED when complete
  750. */
  751. static irqreturn_t qfs4008_ipc_irq_handler(int irq, void *dev_id)
  752. {
  753. struct qfs4008_drvdata *drvdata = (struct qfs4008_drvdata *)dev_id;
  754. enum qfs4008_fw_event ev = FW_EVENT_CBGE_REQUIRED;
  755. struct fw_event_desc fw_ev_des;
  756. __pm_wakeup_event(drvdata->fp_signal_lock,
  757. msecs_to_jiffies(QFS4008_WAKELOCK_HOLD_TIME));
  758. mutex_lock(&drvdata->mutex);
  759. if (irq != drvdata->fw_ipc.irq) {
  760. pr_warn("invalid irq %d (expected %d)\n", irq,
  761. drvdata->fw_ipc.irq);
  762. goto ipc_irq_failed;
  763. }
  764. mutex_lock(&drvdata->ipc_events_mutex);
  765. fw_ev_des.ev = ev;
  766. if (!kfifo_put(&drvdata->ipc_events, fw_ev_des))
  767. pr_err("fw events: fifo full, drop event %d\n", (int) ev);
  768. drvdata->cbge_count++;
  769. mutex_unlock(&drvdata->ipc_events_mutex);
  770. wake_up_interruptible(&drvdata->read_wait_queue_ipc);
  771. pr_debug("ipc interrupt received, irq=%d, event=%d\n", irq, (int)ev);
  772. ipc_irq_failed:
  773. mutex_unlock(&drvdata->mutex);
  774. return IRQ_HANDLED;
  775. }
  776. static int qfs4008_setup_fd_gpio_irq(struct platform_device *pdev,
  777. struct qfs4008_drvdata *drvdata)
  778. {
  779. int rc = 0;
  780. int irq;
  781. const char *desc = "qbt_finger_detect";
  782. rc = devm_gpio_request_one(&pdev->dev, drvdata->fd_gpio.gpio,
  783. GPIOF_IN, desc);
  784. if (rc < 0) {
  785. pr_err("failed to request gpio %d, error %d\n",
  786. drvdata->fd_gpio.gpio, rc);
  787. goto fd_gpio_failed;
  788. }
  789. irq = gpio_to_irq(drvdata->fd_gpio.gpio);
  790. if (irq < 0) {
  791. rc = irq;
  792. pr_err("unable to get irq number for gpio %d, error %d\n",
  793. drvdata->fd_gpio.gpio, rc);
  794. goto fd_gpio_failed_request;
  795. }
  796. drvdata->fd_gpio.irq = irq;
  797. INIT_WORK(&drvdata->fd_gpio.work, qfs4008_wuhb_work_func);
  798. rc = devm_request_any_context_irq(&pdev->dev, drvdata->fd_gpio.irq,
  799. qfs4008_wuhb_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  800. desc, drvdata);
  801. if (rc < 0) {
  802. pr_err("unable to claim irq %d; error %d\n",
  803. drvdata->fd_gpio.irq, rc);
  804. goto fd_gpio_failed_request;
  805. }
  806. enable_irq_wake(drvdata->fd_gpio.irq);
  807. drvdata->enabled_wuhb = true;
  808. qfs4008_disable_wuhb(drvdata);
  809. pr_debug("irq=%d,gpio=%d,rc=%d\n", drvdata->fd_gpio.irq, drvdata->fd_gpio.gpio, rc);
  810. fd_gpio_failed_request:
  811. gpio_free(drvdata->fd_gpio.gpio);
  812. fd_gpio_failed:
  813. return rc;
  814. }
  815. static int qfs4008_setup_ipc_irq(struct platform_device *pdev,
  816. struct qfs4008_drvdata *drvdata)
  817. {
  818. int rc = 0;
  819. const char *desc = "qbt_ipc";
  820. drvdata->fw_ipc.irq = gpio_to_irq(drvdata->fw_ipc.gpio);
  821. if (drvdata->fw_ipc.irq < 0) {
  822. rc = drvdata->fw_ipc.irq;
  823. pr_err("no irq for gpio %d, error=%d\n",
  824. drvdata->fw_ipc.gpio, rc);
  825. goto ipc_gpio_failed;
  826. }
  827. rc = devm_gpio_request_one(&pdev->dev, drvdata->fw_ipc.gpio,
  828. GPIOF_IN, desc);
  829. if (rc < 0) {
  830. pr_err("failed to request gpio %d, error %d\n",
  831. drvdata->fw_ipc.gpio, rc);
  832. goto ipc_gpio_failed;
  833. }
  834. rc = devm_request_threaded_irq(&pdev->dev,
  835. drvdata->fw_ipc.irq, NULL, qfs4008_ipc_irq_handler,
  836. IRQF_ONESHOT | IRQF_TRIGGER_FALLING, desc, drvdata);
  837. if (rc < 0) {
  838. pr_err("failed to register for ipc irq %d, rc = %d\n",
  839. drvdata->fw_ipc.irq, rc);
  840. goto ipc_gpio_failed_request;
  841. }
  842. enable_irq_wake(drvdata->fw_ipc.irq);
  843. drvdata->enabled_ipc = true;
  844. qfs4008_disable_ipc(drvdata);
  845. pr_debug("irq=%d,gpio=%d,rc=%d\n", drvdata->fw_ipc.irq,
  846. drvdata->fw_ipc.gpio, rc);
  847. ipc_gpio_failed_request:
  848. gpio_free(drvdata->fw_ipc.gpio);
  849. ipc_gpio_failed:
  850. return rc;
  851. }
  852. /**
  853. * qfs4008_read_device_tree() - Function reads device tree
  854. * properties into driver data
  855. * @pdev: ptr to platform device object
  856. * @drvdata: ptr to driver data
  857. *
  858. * Return: 0 on success. Error code on failure.
  859. */
  860. static int qfs4008_read_device_tree(struct platform_device *pdev,
  861. struct qfs4008_drvdata *drvdata)
  862. {
  863. int rc = 0;
  864. /* read IPC gpio */
  865. drvdata->fw_ipc.gpio = of_get_named_gpio(pdev->dev.of_node,
  866. "qcom,ipc-gpio", 0);
  867. if (drvdata->fw_ipc.gpio < 0) {
  868. rc = drvdata->fw_ipc.gpio;
  869. pr_err("ipc gpio not found, error=%d\n", rc);
  870. goto dt_failed;
  871. }
  872. /* read WUHB gpio */
  873. drvdata->fd_gpio.gpio = of_get_named_gpio(pdev->dev.of_node,
  874. "qcom,wuhb-gpio", 0);
  875. if (drvdata->fd_gpio.gpio < 0) {
  876. rc = drvdata->fd_gpio.gpio;
  877. pr_err("wuhb gpio not found, error=%d\n", rc);
  878. goto dt_failed;
  879. } else {
  880. drvdata->fd_gpio.active_low = 0x0;
  881. }
  882. rc = of_property_read_string(pdev->dev.of_node, "qcom,btp-regulator-1p8", &drvdata->btp_vdd_1p8);
  883. if (rc < 0) {
  884. pr_err("not set btp_regulator_1p8\n");
  885. drvdata->btp_vdd_1p8 = NULL;
  886. goto dt_failed;
  887. } else {
  888. drvdata->regulator_1p8 = regulator_get(&pdev->dev, drvdata->btp_vdd_1p8);
  889. if (IS_ERR(drvdata->regulator_1p8) || (drvdata->regulator_1p8) == NULL) {
  890. pr_err("not set regulator_1p8\n");
  891. drvdata->regulator_1p8 = NULL;
  892. goto dt_failed;
  893. } else {
  894. pr_info("btp_regulator_1p8 ok\n");
  895. drvdata->enabled_ldo = 0;
  896. rc = regulator_set_load(drvdata->regulator_1p8, 500000);
  897. if (rc)
  898. pr_err("regulator_1p8 set_load failed, rc=%d\n", rc);
  899. }
  900. }
  901. rc = of_property_read_string(pdev->dev.of_node, "qcom,btp-regulator-3p0", &drvdata->btp_vdd_3p0);
  902. if (rc < 0) {
  903. pr_err("not set btp_regulator_3p0\n");
  904. drvdata->btp_vdd_3p0 = NULL;
  905. goto dt_failed;
  906. } else {
  907. drvdata->regulator_3p0 = regulator_get(&pdev->dev, drvdata->btp_vdd_3p0);
  908. if (IS_ERR(drvdata->regulator_3p0) || (drvdata->regulator_3p0) == NULL) {
  909. pr_err("not set regulator_3p0\n");
  910. drvdata->regulator_3p0 = NULL;
  911. goto dt_failed;
  912. } else {
  913. pr_info("btp_regulator_3p0 ok\n");
  914. drvdata->enabled_ldo = 0;
  915. rc = regulator_set_load(drvdata->regulator_3p0, 500000);
  916. if (rc)
  917. pr_err("regulator_3p0 set_load failed, rc=%d\n", rc);
  918. }
  919. }
  920. if (of_property_read_u32(pdev->dev.of_node, "qcom,min_cpufreq_limit",
  921. &drvdata->boosting->min_cpufreq_limit))
  922. drvdata->boosting->min_cpufreq_limit = 0;
  923. if (of_property_read_string_index(pdev->dev.of_node, "qcom,position", 0,
  924. (const char **)&drvdata->sensor_position))
  925. drvdata->sensor_position = "32.48,0.00,7.50,8.25,14.80,14.80,13.00,13.00,5.00";
  926. pr_info("Sensor Position: %s\n", drvdata->sensor_position);
  927. if (of_property_read_string_index(pdev->dev.of_node, "qcom,modelinfo", 0,
  928. (const char **)&drvdata->model_info)) {
  929. drvdata->model_info = "S92X";
  930. }
  931. pr_info("modelinfo: %s\n", drvdata->model_info);
  932. if (of_property_read_string_index(pdev->dev.of_node, "qcom,chipid", 0,
  933. (const char **)&drvdata->chipid)) {
  934. drvdata->chipid = "QFS4008";
  935. }
  936. pr_info("chipid: %s\n", drvdata->chipid);
  937. pr_info("finished\n");
  938. return rc;
  939. dt_failed:
  940. pr_err("failed:%d\n", rc);
  941. return rc;
  942. }
  943. static void qfs4008_work_func_debug(struct work_struct *work)
  944. {
  945. struct debug_logger *logger;
  946. struct qfs4008_drvdata *drvdata;
  947. logger = container_of(work, struct debug_logger, work_debug);
  948. drvdata = dev_get_drvdata(logger->dev);
  949. pr_info("ldo:%d,ipc:%d,wuhb:%d,tz:%d,type:%s,int:%d,%d,rst:%d\n",
  950. drvdata->enabled_ldo, drvdata->enabled_ipc,
  951. drvdata->enabled_wuhb, drvdata->tz_mode,
  952. drvdata->sensortype > 0 ? drvdata->chipid : sensor_status[drvdata->sensortype + 2],
  953. drvdata->cbge_count, drvdata->wuhb_count,
  954. drvdata->reset_count);
  955. }
  956. /**
  957. * qfs4008_probe() - Function loads hardware config from device tree
  958. * @pdev: ptr to platform device object
  959. *
  960. * Return: 0 on success. Error code on failure.
  961. */
  962. static int qfs4008_probe(struct platform_device *pdev)
  963. {
  964. struct device *dev = &pdev->dev;
  965. struct qfs4008_drvdata *drvdata;
  966. int rc = 0;
  967. pr_info("Start\n");
  968. #ifdef CONFIG_BATTERY_SAMSUNG
  969. if (lpcharge) {
  970. pr_info("Do not load driver due to : lpm %d\n", lpcharge);
  971. return rc;
  972. }
  973. #endif
  974. drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
  975. if (!drvdata)
  976. return -ENOMEM;
  977. drvdata->clk_setting = devm_kzalloc(dev, sizeof(*drvdata->clk_setting),
  978. GFP_KERNEL);
  979. if (drvdata->clk_setting == NULL)
  980. return -ENOMEM;
  981. drvdata->boosting = devm_kzalloc(dev, sizeof(*drvdata->boosting),
  982. GFP_KERNEL);
  983. if (drvdata->boosting == NULL)
  984. return -ENOMEM;
  985. drvdata->logger = devm_kzalloc(dev, sizeof(*drvdata->logger),
  986. GFP_KERNEL);
  987. if (drvdata->logger == NULL)
  988. return -ENOMEM;
  989. drvdata->dev = dev;
  990. drvdata->logger->dev = dev;
  991. platform_set_drvdata(pdev, drvdata);
  992. rc = qfs4008_read_device_tree(pdev, drvdata);
  993. if (rc < 0)
  994. goto probe_failed_dt;
  995. atomic_set(&drvdata->fd_available, 1);
  996. atomic_set(&drvdata->ipc_available, 1);
  997. mutex_init(&drvdata->mutex);
  998. mutex_init(&drvdata->ioctl_mutex);
  999. mutex_init(&drvdata->fd_events_mutex);
  1000. mutex_init(&drvdata->ipc_events_mutex);
  1001. rc = qfs4008_dev_register(drvdata);
  1002. if (rc < 0)
  1003. goto probe_failed_dev_register;
  1004. INIT_KFIFO(drvdata->fd_events);
  1005. INIT_KFIFO(drvdata->ipc_events);
  1006. init_waitqueue_head(&drvdata->read_wait_queue_fd);
  1007. init_waitqueue_head(&drvdata->read_wait_queue_ipc);
  1008. drvdata->clk_setting->spi_wake_lock = wakeup_source_register(dev, "qfs4008_spi_lock");
  1009. drvdata->fp_signal_lock = wakeup_source_register(dev, "qfs4008_signal_lock");
  1010. rc = qfs4008_pinctrl_register(drvdata);
  1011. if (rc < 0)
  1012. pr_err("register pinctrl failed: %d\n", rc);
  1013. rc = qfs4008_setup_fd_gpio_irq(pdev, drvdata);
  1014. if (rc < 0)
  1015. goto probe_failed_fd_gpio;
  1016. rc = qfs4008_setup_ipc_irq(pdev, drvdata);
  1017. if (rc < 0)
  1018. goto probe_failed_ipc_gpio;
  1019. rc = device_init_wakeup(dev, 1);
  1020. if (rc < 0)
  1021. goto probe_failed_device_init_wakeup;
  1022. rc = spi_clk_register(drvdata->clk_setting, dev);
  1023. if (rc < 0)
  1024. goto probe_failed_spi_clk_register;
  1025. rc = fingerprint_register(drvdata->fp_device,
  1026. drvdata, fp_attrs, "fingerprint");
  1027. if (rc) {
  1028. pr_err("sysfs register failed\n");
  1029. goto probe_failed_sysfs_register;
  1030. }
  1031. drvdata->clk_setting->spi_speed = SPI_CLOCK_MAX;
  1032. #ifdef ENABLE_SENSORS_FPRINT_SECURE
  1033. drvdata->sensortype = SENSOR_UNKNOWN;
  1034. #else
  1035. drvdata->sensortype = SENSOR_OK;
  1036. #endif
  1037. drvdata->cbge_count = 0;
  1038. drvdata->wuhb_count = 0;
  1039. drvdata->reset_count = 0;
  1040. drvdata->touch_ignore = 0;
  1041. #ifdef ENABLE_SENSORS_FPRINT_SECURE
  1042. drvdata->clk_setting->enabled_clk = false;
  1043. drvdata->tz_mode = true;
  1044. #else
  1045. drvdata->clk_setting->enabled_clk = true;
  1046. drvdata->tz_mode = false;
  1047. #endif
  1048. g_logger = drvdata->logger;
  1049. set_fp_debug_timer(drvdata->logger, qfs4008_work_func_debug);
  1050. enable_fp_debug_timer(drvdata->logger);
  1051. pr_info("finished\n");
  1052. return 0;
  1053. probe_failed_sysfs_register:
  1054. spi_clk_unregister(drvdata->clk_setting);
  1055. probe_failed_spi_clk_register:
  1056. probe_failed_device_init_wakeup:
  1057. gpio_free(drvdata->fw_ipc.gpio);
  1058. probe_failed_ipc_gpio:
  1059. gpio_free(drvdata->fd_gpio.gpio);
  1060. probe_failed_fd_gpio:
  1061. if (drvdata->p) {
  1062. devm_pinctrl_put(drvdata->p);
  1063. drvdata->p = NULL;
  1064. }
  1065. wakeup_source_unregister(drvdata->clk_setting->spi_wake_lock);
  1066. wakeup_source_unregister(drvdata->fp_signal_lock);
  1067. device_destroy(drvdata->qfs4008_class, drvdata->qfs4008_ipc_cdev.dev);
  1068. device_destroy(drvdata->qfs4008_class, drvdata->qfs4008_fd_cdev.dev);
  1069. class_destroy(drvdata->qfs4008_class);
  1070. cdev_del(&drvdata->qfs4008_fd_cdev);
  1071. cdev_del(&drvdata->qfs4008_ipc_cdev);
  1072. unregister_chrdev_region(drvdata->qfs4008_fd_cdev.dev, 1);
  1073. unregister_chrdev_region(drvdata->qfs4008_ipc_cdev.dev, 1);
  1074. probe_failed_dev_register:
  1075. if (drvdata->regulator_1p8)
  1076. regulator_put(drvdata->regulator_1p8);
  1077. if (drvdata->regulator_3p0)
  1078. regulator_put(drvdata->regulator_3p0);
  1079. probe_failed_dt:
  1080. drvdata = NULL;
  1081. pr_err("failed: %d\n", rc);
  1082. return rc;
  1083. }
  1084. static int qfs4008_remove(struct platform_device *pdev)
  1085. {
  1086. struct qfs4008_drvdata *drvdata = platform_get_drvdata(pdev);
  1087. pr_info("called\n");
  1088. mutex_destroy(&drvdata->mutex);
  1089. mutex_destroy(&drvdata->ioctl_mutex);
  1090. mutex_destroy(&drvdata->fd_events_mutex);
  1091. mutex_destroy(&drvdata->ipc_events_mutex);
  1092. device_destroy(drvdata->qfs4008_class, drvdata->qfs4008_fd_cdev.dev);
  1093. device_destroy(drvdata->qfs4008_class, drvdata->qfs4008_ipc_cdev.dev);
  1094. disable_fp_debug_timer(drvdata->logger);
  1095. if (drvdata->regulator_1p8)
  1096. regulator_put(drvdata->regulator_1p8);
  1097. if (drvdata->regulator_3p0)
  1098. regulator_put(drvdata->regulator_3p0);
  1099. wakeup_source_unregister(drvdata->clk_setting->spi_wake_lock);
  1100. wakeup_source_unregister(drvdata->fp_signal_lock);
  1101. class_destroy(drvdata->qfs4008_class);
  1102. cdev_del(&drvdata->qfs4008_fd_cdev);
  1103. cdev_del(&drvdata->qfs4008_ipc_cdev);
  1104. unregister_chrdev_region(drvdata->qfs4008_fd_cdev.dev, 1);
  1105. unregister_chrdev_region(drvdata->qfs4008_ipc_cdev.dev, 1);
  1106. fingerprint_unregister(drvdata->fp_device, fp_attrs);
  1107. device_init_wakeup(&pdev->dev, 0);
  1108. spi_clk_unregister(drvdata->clk_setting);
  1109. if (drvdata->p) {
  1110. devm_pinctrl_put(drvdata->p);
  1111. drvdata->p = NULL;
  1112. }
  1113. drvdata = NULL;
  1114. return 0;
  1115. }
  1116. static int qfs4008_suspend(struct platform_device *pdev, pm_message_t state)
  1117. {
  1118. int rc = 0;
  1119. struct qfs4008_drvdata *drvdata = platform_get_drvdata(pdev);
  1120. #ifdef CONFIG_BATTERY_SAMSUNG
  1121. if (lpcharge)
  1122. return rc;
  1123. #endif
  1124. /*
  1125. * Returning an error code if driver currently making a TZ call.
  1126. * Note: The purpose of this driver is to ensure that the clocks are on
  1127. * while making a TZ call. Hence the clock check to determine if the
  1128. * driver will allow suspend to occur.
  1129. */
  1130. if (!mutex_trylock(&drvdata->mutex))
  1131. return -EBUSY;
  1132. disable_fp_debug_timer(drvdata->logger);
  1133. pr_info("ret = %d\n", rc);
  1134. mutex_unlock(&drvdata->mutex);
  1135. return 0;
  1136. }
  1137. static int qfs4008_resume(struct platform_device *pdev)
  1138. {
  1139. int rc = 0;
  1140. struct qfs4008_drvdata *drvdata = platform_get_drvdata(pdev);
  1141. #ifdef CONFIG_BATTERY_SAMSUNG
  1142. if (lpcharge)
  1143. return rc;
  1144. #endif
  1145. enable_fp_debug_timer(drvdata->logger);
  1146. pr_info("ret = %d\n", rc);
  1147. return 0;
  1148. }
  1149. static const struct of_device_id qfs4008_match[] = {
  1150. { .compatible = "qcom,qfs4008" },
  1151. {}
  1152. };
  1153. static struct platform_driver qfs4008_plat_driver = {
  1154. .probe = qfs4008_probe,
  1155. .remove = qfs4008_remove,
  1156. .suspend = qfs4008_suspend,
  1157. .resume = qfs4008_resume,
  1158. .driver = {
  1159. .name = QFS4008_DEV,
  1160. .owner = THIS_MODULE,
  1161. .of_match_table = qfs4008_match,
  1162. },
  1163. };
  1164. static int __init qfs4008_init(void)
  1165. {
  1166. int rc = 0;
  1167. rc = platform_driver_register(&qfs4008_plat_driver);
  1168. pr_info("ret : %d\n", rc);
  1169. return rc;
  1170. }
  1171. static void __exit qfs4008_exit(void)
  1172. {
  1173. pr_info("entry\n");
  1174. return platform_driver_unregister(&qfs4008_plat_driver);
  1175. }
  1176. late_initcall(qfs4008_init);
  1177. module_exit(qfs4008_exit);
  1178. MODULE_LICENSE("GPL v2");
  1179. MODULE_AUTHOR("[email protected]");
  1180. MODULE_DESCRIPTION("Samsung Electronics Inc. QFS4008 driver");