bcm2079x-i2c.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*
  2. * Copyright (C) 2012 Broadcom Corporation.
  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. *
  18. */
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/fs.h>
  22. #include <linux/slab.h>
  23. #include <linux/init.h>
  24. #include <linux/list.h>
  25. #include <linux/i2c.h>
  26. #include <linux/irq.h>
  27. #include <linux/jiffies.h>
  28. #include <linux/uaccess.h>
  29. #include <linux/delay.h>
  30. #include <linux/interrupt.h>
  31. #include <linux/io.h>
  32. #include <linux/platform_device.h>
  33. #include <linux/gpio.h>
  34. #include <linux/miscdevice.h>
  35. #include <linux/spinlock.h>
  36. #include <linux/poll.h>
  37. #include <linux/version.h>
  38. #include <linux/wakelock.h>
  39. #include <linux/of_gpio.h>
  40. #include <linux/regulator/consumer.h>
  41. #include <linux/nfc/bcm2079x.h>
  42. #undef DEBUG_BCM2079X_I2C_IRQ
  43. #define TRUE 1
  44. #define FALSE 0
  45. #define STATE_HIGH 1
  46. #define STATE_LOW 0
  47. /* end of compile options */
  48. /* do not change below */
  49. #define MAX_BUFFER_SIZE 780
  50. /* Read data */
  51. #define PACKET_HEADER_SIZE_NCI (4)
  52. #define PACKET_HEADER_SIZE_HCI (3)
  53. #define PACKET_TYPE_NCI (16)
  54. #define PACKET_TYPE_HCIEV (4)
  55. #define MAX_PACKET_SIZE (PACKET_HEADER_SIZE_NCI + 255)
  56. #ifdef CONFIG_MACH_VICTORLTE_CTC
  57. extern unsigned int system_rev;
  58. #endif
  59. struct bcm2079x_dev {
  60. wait_queue_head_t read_wq;
  61. struct mutex read_mutex;
  62. struct i2c_client *client;
  63. struct miscdevice bcm2079x_device;
  64. struct wake_lock nfc_wake_lock;
  65. unsigned int wake_gpio;
  66. unsigned int en_gpio;
  67. unsigned int irq_gpio;
  68. bool irq_enabled;
  69. spinlock_t irq_enabled_lock;
  70. unsigned int error_write;
  71. unsigned int error_read;
  72. unsigned int count_read;
  73. unsigned int count_irq;
  74. };
  75. static void bcm2079x_init_stat(struct bcm2079x_dev *bcm2079x_dev)
  76. {
  77. bcm2079x_dev->error_write = 0;
  78. bcm2079x_dev->error_read = 0;
  79. bcm2079x_dev->count_read = 0;
  80. bcm2079x_dev->count_irq = 0;
  81. }
  82. #ifndef DEBUG_BCM2079X_I2C_IRQ
  83. /*static void bcm2079x_disable_irq(struct bcm2079x_dev *bcm2079x_dev)
  84. {
  85. unsigned long flags;
  86. spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
  87. if (bcm2079x_dev->irq_enabled) {
  88. disable_irq_wake(bcm2079x_dev->client->irq);
  89. disable_irq_nosync(bcm2079x_dev->client->irq);
  90. bcm2079x_dev->irq_enabled = false;
  91. }
  92. spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
  93. }*/
  94. #endif
  95. static void bcm2079x_enable_irq(struct bcm2079x_dev *bcm2079x_dev)
  96. {
  97. unsigned long flags;
  98. spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
  99. if (!bcm2079x_dev->irq_enabled) {
  100. bcm2079x_dev->irq_enabled = true;
  101. enable_irq(bcm2079x_dev->client->irq);
  102. enable_irq_wake(bcm2079x_dev->client->irq);
  103. }
  104. spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
  105. }
  106. /*
  107. The alias address 0x79, when sent as a 7-bit address from the host processor
  108. will match the first byte (highest 2 bits) of the default client address
  109. (0x1FA) that is programmed in bcm20791.
  110. When used together with the first byte (0xFA) of the byte sequence below,
  111. it can be used to address the bcm20791 in a system that does not support
  112. 10-bit address and change the default address to 0x38.
  113. the new address can be changed by changing the CLIENT_ADDRESS below if 0x38
  114. conflicts with other device on the same i2c bus.
  115. */
  116. #define ALIAS_ADDRESS 0x79
  117. /*
  118. static void set_client_addr(struct bcm2079x_dev *bcm2079x_dev, int addr)
  119. {
  120. struct i2c_client *client = bcm2079x_dev->client;
  121. client->addr = addr;
  122. if (addr > 0x7F)
  123. client->flags |= I2C_CLIENT_TEN;
  124. dev_info(&client->dev,
  125. "Set client device changed to (0x%04X) flag = %04x\n",
  126. client->addr, client->flags);
  127. }
  128. */
  129. static void change_client_addr(struct bcm2079x_dev *bcm2079x_dev, int addr)
  130. {
  131. struct i2c_client *client;
  132. int ret;
  133. int i;
  134. int offset = 1;
  135. char addr_data[] = {
  136. 0xFA, 0xF2, 0x00, 0x00,
  137. 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A
  138. };
  139. client = bcm2079x_dev->client;
  140. if ((client->flags & I2C_CLIENT_TEN) == I2C_CLIENT_TEN) {
  141. client->addr = ALIAS_ADDRESS;
  142. client->flags &= ~I2C_CLIENT_TEN;
  143. offset = 0;
  144. }
  145. addr_data[5] = addr & 0xFF;
  146. ret = 0;
  147. for (i = 1; i < sizeof(addr_data) - 1; ++i)
  148. ret += addr_data[i];
  149. addr_data[sizeof(addr_data) - 1] = (ret & 0xFF);
  150. dev_info(&client->dev,
  151. "Change client device from (0x%04X) flag = "\
  152. "%04x, addr_data[%d] = %02x\n",
  153. client->addr, client->flags, sizeof(addr_data) - 1,
  154. addr_data[sizeof(addr_data) - 1]);
  155. ret = i2c_master_send(client, addr_data+offset,
  156. sizeof(addr_data)-offset);
  157. if (ret != sizeof(addr_data)-offset) {
  158. client->addr = ALIAS_ADDRESS;
  159. client->flags &= ~I2C_CLIENT_TEN;
  160. dev_info(&client->dev,
  161. "Change client device from (0x%04X) flag = "\
  162. "%04x, addr_data[%d] = %02x\n",
  163. client->addr, client->flags, sizeof(addr_data) - 1,
  164. addr_data[sizeof(addr_data) - 1]);
  165. ret = i2c_master_send(client, addr_data, sizeof(addr_data));
  166. }
  167. client->addr = addr_data[5];
  168. dev_info(&client->dev,
  169. "Change client device changed to (0x%04X) flag = %04x, ret = %d\n",
  170. client->addr, client->flags, ret);
  171. }
  172. static irqreturn_t bcm2079x_dev_irq_handler(int irq, void *dev_id)
  173. {
  174. struct bcm2079x_dev *bcm2079x_dev = dev_id;
  175. unsigned long flags;
  176. #ifdef DEBUG_BCM2079X_I2C_IRQ
  177. pr_info("%s, irq is handled!!!!!!!!\n", __func__);
  178. #endif
  179. spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
  180. bcm2079x_dev->count_irq++;
  181. spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
  182. wake_up(&bcm2079x_dev->read_wq);
  183. wake_lock_timeout(&bcm2079x_dev->nfc_wake_lock, 2 * HZ);
  184. return IRQ_HANDLED;
  185. }
  186. static unsigned int bcm2079x_dev_poll(struct file *filp, poll_table *wait)
  187. {
  188. struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
  189. unsigned int mask = 0;
  190. unsigned long flags;
  191. poll_wait(filp, &bcm2079x_dev->read_wq, wait);
  192. spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
  193. if (bcm2079x_dev->count_irq > 0)
  194. mask |= POLLIN | POLLRDNORM;
  195. spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
  196. return mask;
  197. }
  198. static ssize_t bcm2079x_dev_read(struct file *filp, char __user *buf,
  199. size_t count, loff_t *offset)
  200. {
  201. struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
  202. unsigned char tmp[MAX_BUFFER_SIZE];
  203. int total, len, ret;
  204. total = 0;
  205. len = 0;
  206. if (bcm2079x_dev->count_irq > 0)
  207. bcm2079x_dev->count_irq--;
  208. bcm2079x_dev->count_read++;
  209. if (count > MAX_BUFFER_SIZE)
  210. count = MAX_BUFFER_SIZE;
  211. mutex_lock(&bcm2079x_dev->read_mutex);
  212. /** Read the first 4 bytes to include the length of the NCI or HCI.
  213. **/
  214. ret = i2c_master_recv(bcm2079x_dev->client, tmp, 4);
  215. if (ret == 4) {
  216. total = ret;
  217. /** First byte is the packet type
  218. **/
  219. switch (tmp[0]) {
  220. case PACKET_TYPE_NCI:
  221. len = tmp[PACKET_HEADER_SIZE_NCI-1];
  222. break;
  223. case PACKET_TYPE_HCIEV:
  224. len = tmp[PACKET_HEADER_SIZE_HCI-1];
  225. if (len == 0)
  226. /* Since payload is 0, decrement total size
  227. (from 4 to 3) */
  228. total--;
  229. else
  230. /*First byte of payload is in tmp[3] already */
  231. len--;
  232. break;
  233. default:
  234. /*Unknown packet byte */
  235. len = 0;
  236. break;
  237. } /* switch*/
  238. /** make sure full packet fits in the buffer **/
  239. if (len > 0 && (len + total) <= count) {
  240. /** read the remainder of the packet. **/
  241. ret = i2c_master_recv(bcm2079x_dev->client, tmp+total, len);
  242. if (ret == len)
  243. total += len;
  244. } /* if */
  245. } /* if */
  246. mutex_unlock(&bcm2079x_dev->read_mutex);
  247. if (total > count || copy_to_user(buf, tmp, total)) {
  248. dev_err(&bcm2079x_dev->client->dev,
  249. "failed to copy to user space, total = %d\n", total);
  250. total = -EFAULT;
  251. bcm2079x_dev->error_read++;
  252. }
  253. return total;
  254. }
  255. static ssize_t bcm2079x_dev_write(struct file *filp, const char __user *buf,
  256. size_t count, loff_t *offset)
  257. {
  258. struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
  259. char tmp[MAX_BUFFER_SIZE];
  260. int ret;
  261. if (count > MAX_BUFFER_SIZE) {
  262. dev_err(&bcm2079x_dev->client->dev, "out of memory\n");
  263. return -ENOMEM;
  264. }
  265. if (copy_from_user(tmp, buf, count)) {
  266. dev_err(&bcm2079x_dev->client->dev,
  267. "failed to copy from user space\n");
  268. return -EFAULT;
  269. }
  270. mutex_lock(&bcm2079x_dev->read_mutex);
  271. /* Write data */
  272. ret = i2c_master_send(bcm2079x_dev->client, tmp, count);
  273. if (ret != count) {
  274. dev_err(&bcm2079x_dev->client->dev,
  275. "failed to write %d\n", ret);
  276. ret = -EIO;
  277. bcm2079x_dev->error_write++;
  278. }
  279. mutex_unlock(&bcm2079x_dev->read_mutex);
  280. return ret;
  281. }
  282. static int bcm2079x_dev_open(struct inode *inode, struct file *filp)
  283. {
  284. int ret = 0;
  285. struct bcm2079x_dev *bcm2079x_dev = container_of(filp->private_data,
  286. struct bcm2079x_dev,
  287. bcm2079x_device);
  288. filp->private_data = bcm2079x_dev;
  289. bcm2079x_init_stat(bcm2079x_dev);
  290. bcm2079x_enable_irq(bcm2079x_dev);
  291. dev_info(&bcm2079x_dev->client->dev,
  292. "dev node major=%d, minor=%d\n", imajor(inode), iminor(inode));
  293. return ret;
  294. }
  295. static long bcm2079x_dev_unlocked_ioctl(struct file *filp,
  296. unsigned int cmd, unsigned long arg)
  297. {
  298. struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
  299. switch (cmd) {
  300. case BCMNFC_READ_FULL_PACKET:
  301. break;
  302. case BCMNFC_READ_MULTI_PACKETS:
  303. break;
  304. case BCMNFC_CHANGE_ADDR:
  305. dev_info(&bcm2079x_dev->client->dev,
  306. "%s, BCMNFC_CHANGE_ADDR (%x, %lx):\n", __func__, cmd,
  307. arg);
  308. change_client_addr(bcm2079x_dev, arg);
  309. break;
  310. case BCMNFC_POWER_CTL:
  311. dev_info(&bcm2079x_dev->client->dev,
  312. "%s, BCMNFC_POWER_CTL (%x, %lx):\n", __func__, cmd,
  313. arg);
  314. gpio_set_value(bcm2079x_dev->en_gpio, arg);
  315. break;
  316. case BCMNFC_WAKE_CTL:
  317. dev_info(&bcm2079x_dev->client->dev,
  318. "%s, BCMNFC_WAKE_CTL (%x, %lx):\n", __func__, cmd,
  319. arg);
  320. gpio_set_value(bcm2079x_dev->wake_gpio, arg);
  321. break;
  322. default:
  323. dev_err(&bcm2079x_dev->client->dev,
  324. "%s, unknown cmd (%x, %lx)\n", __func__, cmd, arg);
  325. return 0;
  326. }
  327. return 0;
  328. }
  329. static const struct file_operations bcm2079x_dev_fops = {
  330. .owner = THIS_MODULE,
  331. .llseek = no_llseek,
  332. .poll = bcm2079x_dev_poll,
  333. .read = bcm2079x_dev_read,
  334. .write = bcm2079x_dev_write,
  335. .open = bcm2079x_dev_open,
  336. .unlocked_ioctl = bcm2079x_dev_unlocked_ioctl
  337. };
  338. #ifdef CONFIG_OF
  339. /*device tree parsing*/
  340. static int bcm2079x_parse_dt(struct device *dev,
  341. struct bcm2079x_platform_data *pdata)
  342. {
  343. struct device_node *np = dev->of_node;
  344. pdata->irq_gpio = of_get_named_gpio_flags(np, "bcm2079x-i2c,irq-gpio",
  345. 0, &pdata->irq_gpio_flags);
  346. pdata->en_gpio = of_get_named_gpio_flags(np, "bcm2079x-i2c,en-gpio",
  347. 0, &pdata->en_gpio_flags);
  348. pdata->wake_gpio = of_get_named_gpio_flags(np, "bcm2079x-i2c,wake-gpio",
  349. 0, &pdata->wake_gpio_flags);
  350. if (pdata->wake_gpio < 0)
  351. of_property_read_u32(np, "bcm2079x-i2c,wake-expander-gpio",
  352. &pdata->wake_gpio);
  353. return 0;
  354. }
  355. #else
  356. static int bcm2079x_parse_dt(struct device *dev,
  357. struct bcm2079x_platform_data *pdata)
  358. {
  359. return -ENODEV;
  360. }
  361. #endif
  362. static int bcm2079x_probe(struct i2c_client *client,
  363. const struct i2c_device_id *id)
  364. {
  365. int ret;
  366. int err;
  367. struct bcm2079x_platform_data *platform_data;
  368. struct bcm2079x_dev *bcm2079x_dev;
  369. #ifdef DEBUG_BCM2079X_I2C_IRQ
  370. char tmp[5] = {0x10, 0x20, 0x00, 0x01, 0x00};
  371. #endif
  372. #ifdef CONFIG_MACH_VICTORLTE_CTC
  373. pr_info("%s : start system_rev : %d\n", __func__,system_rev);
  374. if (system_rev > 2)
  375. {
  376. pr_info("%s : probe fail \n", __func__);
  377. return -ENODEV;
  378. }
  379. #endif
  380. if (client->dev.of_node) {
  381. platform_data = devm_kzalloc(&client->dev,
  382. sizeof(struct bcm2079x_platform_data), GFP_KERNEL);
  383. if (!platform_data) {
  384. dev_err(&client->dev, "Failed to allocate memory\n");
  385. return -ENOMEM;
  386. }
  387. err = bcm2079x_parse_dt(&client->dev, platform_data);
  388. if (err)
  389. return err;
  390. } else {
  391. platform_data = client->dev.platform_data;
  392. }
  393. dev_info(&client->dev, "%s, probing bcm2079x driver flags = %x\n",
  394. __func__, client->flags);
  395. if (platform_data == NULL) {
  396. dev_err(&client->dev, "nfc probe fail\n");
  397. return -ENODEV;
  398. }
  399. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  400. dev_err(&client->dev, "need I2C_FUNC_I2C\n");
  401. return -ENODEV;
  402. }
  403. ret = gpio_request(platform_data->irq_gpio, "nfc_int");
  404. if (ret)
  405. return -ENODEV;
  406. gpio_direction_input(platform_data->irq_gpio);
  407. ret = gpio_request(platform_data->en_gpio, "nfc_en");
  408. if (ret)
  409. goto err_en;
  410. gpio_direction_output(platform_data->en_gpio, 0);
  411. ret = gpio_request(platform_data->wake_gpio, "nfc_wake");
  412. if (ret)
  413. goto err_firm;
  414. gpio_direction_output(platform_data->wake_gpio, 0);
  415. #ifdef DEBUG_BCM2079X_I2C_IRQ
  416. msleep(100);
  417. gpio_set_value_cansleep(platform_data->en_gpio, 1);
  418. msleep(100);
  419. #else
  420. gpio_set_value_cansleep(platform_data->en_gpio, 0);
  421. #endif
  422. gpio_set_value_cansleep(platform_data->wake_gpio, 1);
  423. bcm2079x_dev = kzalloc(sizeof(*bcm2079x_dev), GFP_KERNEL);
  424. if (bcm2079x_dev == NULL) {
  425. dev_err(&client->dev,
  426. "failed to allocate memory for module data\n");
  427. ret = -ENOMEM;
  428. goto err_exit;
  429. }
  430. bcm2079x_dev->wake_gpio = platform_data->wake_gpio;
  431. bcm2079x_dev->irq_gpio = platform_data->irq_gpio;
  432. bcm2079x_dev->en_gpio = platform_data->en_gpio;
  433. bcm2079x_dev->client = client;
  434. /* init mutex and queues */
  435. init_waitqueue_head(&bcm2079x_dev->read_wq);
  436. mutex_init(&bcm2079x_dev->read_mutex);
  437. spin_lock_init(&bcm2079x_dev->irq_enabled_lock);
  438. bcm2079x_dev->bcm2079x_device.minor = MISC_DYNAMIC_MINOR;
  439. bcm2079x_dev->bcm2079x_device.name = "bcm2079x";
  440. bcm2079x_dev->bcm2079x_device.fops = &bcm2079x_dev_fops;
  441. ret = misc_register(&bcm2079x_dev->bcm2079x_device);
  442. if (ret) {
  443. dev_err(&client->dev, "misc_register failed\n");
  444. goto err_misc_register;
  445. }
  446. /* wake lock init */
  447. wake_lock_init(&bcm2079x_dev->nfc_wake_lock,
  448. WAKE_LOCK_SUSPEND, "nfc_wake_lock");
  449. /* request irq. the irq is set whenever the chip has data available
  450. * for reading. it is cleared when all data has been read.
  451. */
  452. pr_info("\n client irq is %d\n",client->irq);
  453. dev_info(&client->dev, "requesting IRQ %d with IRQF_NO_SUSPEND\n",
  454. client->irq);
  455. ret = request_irq(client->irq, bcm2079x_dev_irq_handler,
  456. IRQF_TRIGGER_RISING|IRQF_NO_SUSPEND, client->name,
  457. bcm2079x_dev);
  458. if (ret) {
  459. dev_err(&client->dev, "request_irq failed\n");
  460. goto err_request_irq_failed;
  461. }
  462. i2c_set_clientdata(client, bcm2079x_dev);
  463. #ifndef DEBUG_BCM2079X_I2C_IRQ
  464. bcm2079x_dev->irq_enabled = false;
  465. disable_irq_nosync(bcm2079x_dev->client->irq);
  466. #else
  467. /* NCI reset test */
  468. ret = i2c_master_send(bcm2079x_dev->client, tmp, sizeof(tmp));
  469. if (ret != 5)
  470. pr_err("%s, i2c write error, NCI rest cmd err = %d\n",
  471. __func__, ret);
  472. else
  473. pr_info("%s, i2c write success!!! ret = %d\n",
  474. __func__, ret);
  475. #endif
  476. dev_info(&client->dev,
  477. "%s, probing bcm2079x driver exited successfully\n",
  478. __func__);
  479. return 0;
  480. err_request_irq_failed:
  481. wake_lock_destroy(&bcm2079x_dev->nfc_wake_lock);
  482. misc_deregister(&bcm2079x_dev->bcm2079x_device);
  483. err_misc_register:
  484. mutex_destroy(&bcm2079x_dev->read_mutex);
  485. kfree(bcm2079x_dev);
  486. err_exit:
  487. gpio_free(platform_data->wake_gpio);
  488. err_firm:
  489. gpio_free(platform_data->en_gpio);
  490. err_en:
  491. gpio_free(platform_data->irq_gpio);
  492. return ret;
  493. }
  494. static int bcm2079x_remove(struct i2c_client *client)
  495. {
  496. struct bcm2079x_dev *bcm2079x_dev;
  497. bcm2079x_dev = i2c_get_clientdata(client);
  498. wake_lock_destroy(&bcm2079x_dev->nfc_wake_lock);
  499. free_irq(client->irq, bcm2079x_dev);
  500. misc_deregister(&bcm2079x_dev->bcm2079x_device);
  501. mutex_destroy(&bcm2079x_dev->read_mutex);
  502. gpio_free(bcm2079x_dev->irq_gpio);
  503. gpio_free(bcm2079x_dev->en_gpio);
  504. gpio_free(bcm2079x_dev->wake_gpio);
  505. kfree(bcm2079x_dev);
  506. return 0;
  507. }
  508. static const struct i2c_device_id bcm2079x_id[] = {
  509. {"bcm2079x-i2c", 0},
  510. {}
  511. };
  512. #ifdef CONFIG_OF
  513. static struct of_device_id nfc_match_table[] = {
  514. { .compatible = "nfc,bcm2079x-i2c",},
  515. {},
  516. };
  517. #else
  518. #define nfc_match_table NULL
  519. #endif
  520. static struct i2c_driver bcm2079x_driver = {
  521. .id_table = bcm2079x_id,
  522. .probe = bcm2079x_probe,
  523. .remove = bcm2079x_remove,
  524. .driver = {
  525. .owner = THIS_MODULE,
  526. .name = "bcm2079x-i2c",
  527. .of_match_table = nfc_match_table,
  528. },
  529. };
  530. /*
  531. * module load/unload record keeping
  532. */
  533. static int __init bcm2079x_dev_init(void)
  534. {
  535. return i2c_add_driver(&bcm2079x_driver);
  536. }
  537. module_init(bcm2079x_dev_init);
  538. static void __exit bcm2079x_dev_exit(void)
  539. {
  540. i2c_del_driver(&bcm2079x_driver);
  541. }
  542. module_exit(bcm2079x_dev_exit);
  543. MODULE_AUTHOR("Broadcom");
  544. MODULE_DESCRIPTION("NFC bcm2079x driver");
  545. MODULE_LICENSE("GPL");