common.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /******************************************************************************
  2. * Copyright (C) 2019-2020 NXP
  3. * *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. ******************************************************************************/
  19. #include <linux/of_gpio.h>
  20. #include <linux/of_device.h>
  21. #include <linux/delay.h>
  22. #include <linux/version.h>
  23. #include "common.h"
  24. #include "common_ese.h"
  25. int nfc_parse_dt(struct device *dev, platform_gpio_t * nfc_gpio,
  26. uint8_t interface)
  27. {
  28. struct device_node *np = dev->of_node;
  29. if (!np) {
  30. pr_err("nfc of_node NULL\n");
  31. return -EINVAL;
  32. }
  33. nfc_gpio->irq = -EINVAL;
  34. nfc_gpio->dwl_req = -EINVAL;
  35. nfc_gpio->ven = -EINVAL;
  36. //required for i2c based chips only
  37. if (interface == PLATFORM_IF_I2C) {
  38. nfc_gpio->irq = of_get_named_gpio(np, DTS_IRQ_GPIO_STR, 0);
  39. if ((!gpio_is_valid(nfc_gpio->irq))) {
  40. pr_err("nfc irq gpio invalid %d\n", nfc_gpio->irq);
  41. return -EINVAL;
  42. }
  43. pr_info("%s: irq %d\n", __func__, nfc_gpio->irq);
  44. nfc_gpio->dwl_req = of_get_named_gpio(np, DTS_FWDN_GPIO_STR, 0);
  45. if ((!gpio_is_valid(nfc_gpio->dwl_req))) {
  46. pr_err("nfc dwl_req gpio invalid %d\n", nfc_gpio->dwl_req);
  47. }
  48. }
  49. nfc_gpio->ven = of_get_named_gpio(np, DTS_VEN_GPIO_STR, 0);
  50. if ((!gpio_is_valid(nfc_gpio->ven))) {
  51. pr_err("nfc ven gpio invalid %d\n", nfc_gpio->ven);
  52. return -EINVAL;
  53. }
  54. pr_info("%s: %d, %d, %d, %d\n", __func__, nfc_gpio->irq, nfc_gpio->ven,
  55. nfc_gpio->dwl_req);
  56. return 0;
  57. }
  58. void set_valid_gpio(int gpio, int value)
  59. {
  60. if (gpio_is_valid(gpio)) {
  61. pr_debug("%s gpio %d value %d\n", __func__, gpio, value);
  62. gpio_set_value(gpio, value);
  63. // hardware dependent delay
  64. usleep_range(10000, 10100);
  65. }
  66. }
  67. int get_valid_gpio(int gpio)
  68. {
  69. int value = -1;
  70. if (gpio_is_valid(gpio)) {
  71. value = gpio_get_value(gpio);
  72. pr_debug("%s gpio %d value %d\n", __func__, gpio, value);
  73. }
  74. return value;
  75. }
  76. void gpio_set_ven(struct nfc_dev *nfc_dev, int value)
  77. {
  78. if (gpio_get_value(nfc_dev->gpio.ven) != value) {
  79. pr_debug("%s: gpio_set_ven %d\n", __func__, value);
  80. /*reset on change in level from high to low */
  81. if (value) {
  82. common_ese_on_hard_reset(nfc_dev);
  83. }
  84. gpio_set_value(nfc_dev->gpio.ven, value);
  85. // hardware dependent delay
  86. usleep_range(10000, 10100);
  87. }
  88. }
  89. int configure_gpio(unsigned int gpio, int flag)
  90. {
  91. int ret;
  92. pr_debug("%s: nfc gpio [%d] flag [%01x]\n", __func__, gpio, flag);
  93. if (gpio_is_valid(gpio)) {
  94. ret = gpio_request(gpio, "nfc_gpio");
  95. if (ret) {
  96. pr_err("%s: unable to request nfc gpio [%d]\n", __func__, gpio);
  97. return ret;
  98. }
  99. /*set direction and value for output pin */
  100. if (flag & GPIO_OUTPUT) {
  101. ret = gpio_direction_output(gpio, (GPIO_HIGH & flag));
  102. pr_debug("nfc o/p gpio %d level %d\n", gpio, gpio_get_value(gpio));
  103. } else {
  104. ret = gpio_direction_input(gpio);
  105. pr_debug("nfc i/p gpio %d\n", gpio);
  106. }
  107. if (ret) {
  108. pr_err("%s: unable to set direction for nfc gpio [%d]\n", __func__, gpio);
  109. gpio_free(gpio);
  110. return ret;
  111. }
  112. /*Consider value as control for input IRQ pin */
  113. if (flag & GPIO_IRQ) {
  114. ret = gpio_to_irq(gpio);
  115. if (ret < 0) {
  116. pr_err("%s: unable to set irq for nfc gpio [%d]\n", __func__, gpio);
  117. gpio_free(gpio);
  118. return ret;
  119. }
  120. pr_debug("%s: gpio_to_irq successful [%d]\n", __func__, gpio);
  121. return ret;
  122. }
  123. } else {
  124. pr_err("%s: invalid gpio\n", __func__);
  125. ret = -EINVAL;
  126. }
  127. return ret;
  128. }
  129. void gpio_free_all(nfc_dev_t *nfc_dev)
  130. {
  131. if (gpio_is_valid(nfc_dev->gpio.dwl_req)) {
  132. gpio_free(nfc_dev->gpio.dwl_req);
  133. }
  134. if (gpio_is_valid(nfc_dev->gpio.irq)) {
  135. gpio_free(nfc_dev->gpio.irq);
  136. }
  137. if (gpio_is_valid(nfc_dev->gpio.ven)) {
  138. gpio_free(nfc_dev->gpio.ven);
  139. }
  140. }
  141. void nfc_misc_unregister(nfc_dev_t *nfc_dev, int count)
  142. {
  143. pr_debug("%s: entry\n", __func__);
  144. device_destroy(nfc_dev->nfc_class, nfc_dev->devno);
  145. cdev_del(&nfc_dev->c_dev);
  146. class_destroy(nfc_dev->nfc_class);
  147. unregister_chrdev_region(nfc_dev->devno, count);
  148. }
  149. int nfc_misc_register(nfc_dev_t *nfc_dev,
  150. const struct file_operations *nfc_fops,
  151. int count, char *devname, char *classname)
  152. {
  153. int ret = 0;
  154. ret = alloc_chrdev_region(&nfc_dev->devno, 0, count, devname);
  155. if (ret < 0) {
  156. pr_err("%s: failed to alloc chrdev region ret %d\n", __func__, ret);
  157. return ret;
  158. }
  159. nfc_dev->nfc_class = class_create(THIS_MODULE, classname);
  160. if (IS_ERR(nfc_dev->nfc_class)) {
  161. ret = PTR_ERR(nfc_dev->nfc_class);
  162. pr_err("%s: failed to register device class ret %d\n", __func__, ret);
  163. unregister_chrdev_region(nfc_dev->devno, count);
  164. return ret;
  165. }
  166. cdev_init(&nfc_dev->c_dev, nfc_fops);
  167. ret = cdev_add(&nfc_dev->c_dev, nfc_dev->devno, count);
  168. if (ret < 0) {
  169. pr_err("%s: failed to add cdev ret %d\n", __func__, ret);
  170. class_destroy(nfc_dev->nfc_class);
  171. unregister_chrdev_region(nfc_dev->devno, count);
  172. return ret;
  173. }
  174. nfc_dev->nfc_device = device_create(nfc_dev->nfc_class, NULL,
  175. nfc_dev->devno, nfc_dev, devname);
  176. if (IS_ERR(nfc_dev->nfc_device)) {
  177. ret = PTR_ERR(nfc_dev->nfc_device);
  178. pr_err("%s: failed to create the device ret %d\n", __func__, ret);
  179. cdev_del(&nfc_dev->c_dev);
  180. class_destroy(nfc_dev->nfc_class);
  181. unregister_chrdev_region(nfc_dev->devno, count);
  182. return ret;
  183. }
  184. return 0;
  185. }
  186. /*
  187. * nfc_ioctl_power_states() - power control
  188. * @nfc_dev: nfc device data structure
  189. * @arg: mode that we want to move to
  190. *
  191. * Device power control. Depending on the arg value, device moves to
  192. * different states, refer common.h for args
  193. *
  194. * Return: -ENOIOCTLCMD if arg is not supported, 0 in any other case
  195. */
  196. static int nfc_ioctl_power_states(nfc_dev_t *nfc_dev, unsigned long arg)
  197. {
  198. int ret = 0;
  199. if (arg == NFC_POWER_OFF) {
  200. /*
  201. * We are attempting a hardware reset so let us disable
  202. * interrupts to avoid spurious notifications to upper
  203. * layers.
  204. */
  205. nfc_dev->nfc_disable_intr(nfc_dev);
  206. set_valid_gpio(nfc_dev->gpio.dwl_req, 0);
  207. gpio_set_ven(nfc_dev, 0);
  208. nfc_dev->nfc_ven_enabled = false;
  209. } else if (arg == NFC_POWER_ON) {
  210. nfc_dev->nfc_enable_intr(nfc_dev);
  211. set_valid_gpio(nfc_dev->gpio.dwl_req, 0);
  212. gpio_set_ven(nfc_dev, 1);
  213. nfc_dev->nfc_ven_enabled = true;
  214. } else if (arg == NFC_FW_DWL_VEN_TOGGLE) {
  215. /*
  216. * We are switching to download Mode, toggle the enable pin
  217. * in order to set the NFCC in the new mode
  218. */
  219. nfc_dev->nfc_disable_intr(nfc_dev);
  220. set_valid_gpio(nfc_dev->gpio.dwl_req, 1);
  221. if (nfc_dev->interface == PLATFORM_IF_I2C) {
  222. nfc_dev->nfc_state = NFC_STATE_FW_DWL;
  223. }
  224. gpio_set_ven(nfc_dev, 0);
  225. gpio_set_ven(nfc_dev, 1);
  226. nfc_dev->nfc_enable_intr(nfc_dev);
  227. } else if (arg == NFC_FW_DWL_HIGH) {
  228. /*
  229. * Setting firmware download gpio to HIGH
  230. * before FW download start
  231. */
  232. set_valid_gpio(nfc_dev->gpio.dwl_req, 1);
  233. if (nfc_dev->interface == PLATFORM_IF_I2C) {
  234. nfc_dev->nfc_state = NFC_STATE_FW_DWL;
  235. }
  236. } else if (arg == NFC_VEN_FORCED_HARD_RESET) {
  237. nfc_dev->nfc_disable_intr(nfc_dev);
  238. gpio_set_ven(nfc_dev, 0);
  239. gpio_set_ven(nfc_dev, 1);
  240. nfc_dev->nfc_enable_intr(nfc_dev);
  241. } else if (arg == NFC_FW_DWL_LOW) {
  242. /*
  243. * Setting firmware download gpio to LOW
  244. * FW download finished
  245. */
  246. set_valid_gpio(nfc_dev->gpio.dwl_req, 0);
  247. if (nfc_dev->interface == PLATFORM_IF_I2C) {
  248. nfc_dev->nfc_state = NFC_STATE_NCI;
  249. }
  250. } else {
  251. pr_err("%s bad arg %lu\n", __func__, arg);
  252. ret = -ENOIOCTLCMD;
  253. }
  254. return ret;
  255. }
  256. /** @brief IOCTL function to be used to set or get data from upper layer.
  257. *
  258. * @param pfile fil node for opened device.
  259. * @cmd IOCTL type from upper layer.
  260. * @arg IOCTL arg from upper layer.
  261. *
  262. * @return 0 on success, error code for failures.
  263. */
  264. long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
  265. {
  266. int ret = 0;
  267. struct nfc_dev *nfc_dev = pfile->private_data;
  268. if (!nfc_dev)
  269. return -ENODEV;
  270. pr_debug("%s cmd = %x arg = %zx\n", __func__, cmd, arg);
  271. switch (cmd) {
  272. case NFC_SET_PWR:
  273. ret = nfc_ioctl_power_states(nfc_dev, arg);
  274. break;
  275. case ESE_SET_PWR:
  276. ret = nfc_ese_pwr(nfc_dev, arg);
  277. break;
  278. case ESE_GET_PWR:
  279. ret = nfc_ese_pwr(nfc_dev, ESE_POWER_STATE);
  280. break;
  281. case NFC_GET_PLATFORM_TYPE:
  282. ret = nfc_dev->interface;
  283. break;
  284. case NFC_GET_NFC_STATE:
  285. ret = nfc_dev->nfc_state;
  286. pr_debug("nfc get state %d\n", ret);
  287. break;
  288. case NFC_GET_IRQ_STATE:
  289. ret = 0;
  290. ret = gpio_get_value(nfc_dev->gpio.irq);
  291. break;
  292. default:
  293. pr_err("%s bad cmd %lu\n", __func__, arg);
  294. ret = -ENOIOCTLCMD;
  295. };
  296. return ret;
  297. }
  298. int nfc_dev_open(struct inode *inode, struct file *filp)
  299. {
  300. nfc_dev_t *nfc_dev = container_of(inode->i_cdev, nfc_dev_t, c_dev);
  301. pr_debug("%s: %d, %d\n", __func__, imajor(inode), iminor(inode));
  302. mutex_lock(&nfc_dev->dev_ref_mutex);
  303. filp->private_data = nfc_dev;
  304. if (nfc_dev->dev_ref_count == 0) {
  305. set_valid_gpio(nfc_dev->gpio.dwl_req, 0);
  306. nfc_dev->nfc_enable_intr(nfc_dev);
  307. }
  308. nfc_dev->dev_ref_count = nfc_dev->dev_ref_count + 1;
  309. mutex_unlock(&nfc_dev->dev_ref_mutex);
  310. return 0;
  311. }
  312. int nfc_dev_close(struct inode *inode, struct file *filp)
  313. {
  314. nfc_dev_t *nfc_dev = container_of(inode->i_cdev, nfc_dev_t, c_dev);
  315. pr_debug("%s: %d, %d\n", __func__, imajor(inode), iminor(inode));
  316. mutex_lock(&nfc_dev->dev_ref_mutex);
  317. if (nfc_dev->dev_ref_count == 1) {
  318. nfc_dev->nfc_disable_intr(nfc_dev);
  319. set_valid_gpio(nfc_dev->gpio.dwl_req, 0);
  320. }
  321. if (nfc_dev->dev_ref_count > 0)
  322. nfc_dev->dev_ref_count = nfc_dev->dev_ref_count - 1;
  323. else {
  324. nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS_NFC);
  325. /* Uncomment below line incase of eSE calls flow is via NFC driver
  326. * i.e. direct calls from SPI HAL to NFC driver*/
  327. //nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS);
  328. }
  329. filp->private_data = NULL;
  330. mutex_unlock(&nfc_dev->dev_ref_mutex);
  331. return 0;
  332. }
  333. static int get_nfcc_boot_state(struct nfc_dev *nfc_dev)
  334. {
  335. int ret = 0;
  336. char get_version_cmd[] = { 0x00, 0x04, 0xF1, 0x00, 0x00, 0x00, 0x6E, 0xEF };
  337. char get_session_state_cmd[] = { 0x00, 0x04, 0xF2, 0x00, 0x00, 0x00, 0xF5, 0x33 };
  338. char rsp_buf[MAX_BUFFER_SIZE];
  339. /*clearing any data in the kbuf store */
  340. do {
  341. ret = nfc_dev->nfc_read(nfc_dev, rsp_buf, MAX_BUFFER_SIZE);
  342. if (ret < 0) {
  343. pr_err("%s: - nfc read ret %d\n", __func__, ret);
  344. }
  345. pr_info("%s: - nfc read ret %d\n", __func__, ret);
  346. } while (ret > 0);
  347. pr_debug("%s:Sending GET_VERSION cmd\n", __func__);
  348. ret = nfc_dev->nfc_write(nfc_dev, get_version_cmd,
  349. sizeof(get_version_cmd), MAX_RETRY_COUNT);
  350. if (ret <= 0) {
  351. pr_err("%s: - nfc get version cmd error ret %d\n", __func__, ret);
  352. goto err;
  353. }
  354. memset(rsp_buf, 0x00, MAX_BUFFER_SIZE);
  355. pr_debug("%s:Reading response of GET_VERSION cmd\n", __func__);
  356. ret = nfc_dev->nfc_read(nfc_dev, rsp_buf, MAX_BUFFER_SIZE);
  357. if (ret <= 0) {
  358. pr_err("%s: - nfc get version rsp error ret %d\n", __func__, ret);
  359. goto err;
  360. } else if (rsp_buf[0] == 0x0
  361. && ret == (FW_HDR_LEN + rsp_buf[FW_PAYLOAD_LEN_IDX] + FW_CRC_LEN)
  362. && (ret == DL_GET_VERSION_RSP_LEN_1 || ret == DL_GET_VERSION_RSP_LEN_2)) {
  363. pr_info("%s:NFC chip_type 0x%02x rom_version 0x%02x fw_minor 0x%02x fw_major 0x%02x\n",
  364. __func__, rsp_buf[3], rsp_buf[4], rsp_buf[6], rsp_buf[7]);
  365. } else if (rsp_buf[0] != 0x0
  366. && ret == (NCI_HDR_LEN + rsp_buf[NCI_PAYLOAD_LEN_IDX])) {
  367. pr_info("%s:NFC response bytes 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__,
  368. rsp_buf[0], rsp_buf[1], rsp_buf[2], rsp_buf[3], rsp_buf[3]);
  369. pr_debug("%s NFCC booted in NCI mode %d\n", __func__, __LINE__);
  370. return NFC_STATE_NCI;
  371. }
  372. pr_debug("%s:Sending GET_SESSION_STATE cmd \n", __func__);
  373. ret = nfc_dev->nfc_write(nfc_dev, get_session_state_cmd,
  374. sizeof(get_session_state_cmd),
  375. MAX_RETRY_COUNT);
  376. if (ret <= 0) {
  377. pr_err("%s: - nfc get session state cmd err ret %d\n", __func__, ret);
  378. goto err;
  379. }
  380. memset(rsp_buf, 0x00, DL_GET_SESSION_STATE_RSP_LEN);
  381. pr_debug("%s:Reading response of GET_SESSION_STATE cmd\n", __func__);
  382. ret = nfc_dev->nfc_read(nfc_dev, rsp_buf, DL_GET_SESSION_STATE_RSP_LEN);
  383. if (ret <= 0) {
  384. pr_err("%s: - nfc get session state rsp err %d\n", __func__, ret);
  385. goto err;
  386. }
  387. pr_debug("Response bytes are %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x",
  388. rsp_buf[0], rsp_buf[1], rsp_buf[2], rsp_buf[3], rsp_buf[4], rsp_buf[5],
  389. rsp_buf[6], rsp_buf[7]);
  390. /*verify fw in non-teared state */
  391. if (rsp_buf[GET_SESSION_STS_OFF] != NFCC_SESSION_STS_CLOSED) {
  392. pr_debug("%s NFCC booted in teared fw state %d\n", __func__, __LINE__);
  393. return NFC_STATE_FW_TEARED;
  394. }
  395. pr_debug("%s NFCC booted in FW DN mode %d\n", __func__, __LINE__);
  396. return NFC_STATE_FW_DWL;
  397. err:
  398. pr_err("%s Unlikely NFCC not booted in FW DN mode %d\n", __func__, __LINE__);
  399. return NFC_STATE_UNKNOWN;
  400. }
  401. int validate_nfc_state_nci(nfc_dev_t *nfc_dev)
  402. {
  403. if (!gpio_get_value(nfc_dev->gpio.ven)) {
  404. pr_err("VEN LOW - NFCC powered off\n");
  405. return -ENODEV;
  406. } else {
  407. if (get_valid_gpio(nfc_dev->gpio.dwl_req) == 1) {
  408. pr_err("FW download in-progress\n");
  409. return -EBUSY;
  410. } else if (nfc_dev->nfc_state == NFC_STATE_FW_DWL) {
  411. pr_err("FW download state \n");
  412. return -EBUSY;
  413. }
  414. }
  415. return 0;
  416. }