tc3589x.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2010
  3. *
  4. * License Terms: GNU General Public License, version 2
  5. * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
  6. * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
  7. */
  8. #include <linux/module.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/irq.h>
  11. #include <linux/irqdomain.h>
  12. #include <linux/slab.h>
  13. #include <linux/i2c.h>
  14. #include <linux/of.h>
  15. #include <linux/mfd/core.h>
  16. #include <linux/mfd/tc3589x.h>
  17. #define TC3589x_CLKMODE_MODCTL_SLEEP 0x0
  18. #define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0)
  19. /**
  20. * tc3589x_reg_read() - read a single TC3589x register
  21. * @tc3589x: Device to read from
  22. * @reg: Register to read
  23. */
  24. int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg)
  25. {
  26. int ret;
  27. ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg);
  28. if (ret < 0)
  29. dev_err(tc3589x->dev, "failed to read reg %#x: %d\n",
  30. reg, ret);
  31. return ret;
  32. }
  33. EXPORT_SYMBOL_GPL(tc3589x_reg_read);
  34. /**
  35. * tc3589x_reg_read() - write a single TC3589x register
  36. * @tc3589x: Device to write to
  37. * @reg: Register to read
  38. * @data: Value to write
  39. */
  40. int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data)
  41. {
  42. int ret;
  43. ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data);
  44. if (ret < 0)
  45. dev_err(tc3589x->dev, "failed to write reg %#x: %d\n",
  46. reg, ret);
  47. return ret;
  48. }
  49. EXPORT_SYMBOL_GPL(tc3589x_reg_write);
  50. /**
  51. * tc3589x_block_read() - read multiple TC3589x registers
  52. * @tc3589x: Device to read from
  53. * @reg: First register
  54. * @length: Number of registers
  55. * @values: Buffer to write to
  56. */
  57. int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values)
  58. {
  59. int ret;
  60. ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values);
  61. if (ret < 0)
  62. dev_err(tc3589x->dev, "failed to read regs %#x: %d\n",
  63. reg, ret);
  64. return ret;
  65. }
  66. EXPORT_SYMBOL_GPL(tc3589x_block_read);
  67. /**
  68. * tc3589x_block_write() - write multiple TC3589x registers
  69. * @tc3589x: Device to write to
  70. * @reg: First register
  71. * @length: Number of registers
  72. * @values: Values to write
  73. */
  74. int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length,
  75. const u8 *values)
  76. {
  77. int ret;
  78. ret = i2c_smbus_write_i2c_block_data(tc3589x->i2c, reg, length,
  79. values);
  80. if (ret < 0)
  81. dev_err(tc3589x->dev, "failed to write regs %#x: %d\n",
  82. reg, ret);
  83. return ret;
  84. }
  85. EXPORT_SYMBOL_GPL(tc3589x_block_write);
  86. /**
  87. * tc3589x_set_bits() - set the value of a bitfield in a TC3589x register
  88. * @tc3589x: Device to write to
  89. * @reg: Register to write
  90. * @mask: Mask of bits to set
  91. * @values: Value to set
  92. */
  93. int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val)
  94. {
  95. int ret;
  96. mutex_lock(&tc3589x->lock);
  97. ret = tc3589x_reg_read(tc3589x, reg);
  98. if (ret < 0)
  99. goto out;
  100. ret &= ~mask;
  101. ret |= val;
  102. ret = tc3589x_reg_write(tc3589x, reg, ret);
  103. out:
  104. mutex_unlock(&tc3589x->lock);
  105. return ret;
  106. }
  107. EXPORT_SYMBOL_GPL(tc3589x_set_bits);
  108. static struct resource gpio_resources[] = {
  109. {
  110. .start = TC3589x_INT_GPIIRQ,
  111. .end = TC3589x_INT_GPIIRQ,
  112. .flags = IORESOURCE_IRQ,
  113. },
  114. };
  115. static struct resource keypad_resources[] = {
  116. {
  117. .start = TC3589x_INT_KBDIRQ,
  118. .end = TC3589x_INT_KBDIRQ,
  119. .flags = IORESOURCE_IRQ,
  120. },
  121. };
  122. static struct mfd_cell tc3589x_dev_gpio[] = {
  123. {
  124. .name = "tc3589x-gpio",
  125. .num_resources = ARRAY_SIZE(gpio_resources),
  126. .resources = &gpio_resources[0],
  127. .of_compatible = "tc3589x-gpio",
  128. },
  129. };
  130. static struct mfd_cell tc3589x_dev_keypad[] = {
  131. {
  132. .name = "tc3589x-keypad",
  133. .num_resources = ARRAY_SIZE(keypad_resources),
  134. .resources = &keypad_resources[0],
  135. .of_compatible = "tc3589x-keypad",
  136. },
  137. };
  138. static irqreturn_t tc3589x_irq(int irq, void *data)
  139. {
  140. struct tc3589x *tc3589x = data;
  141. int status;
  142. again:
  143. status = tc3589x_reg_read(tc3589x, TC3589x_IRQST);
  144. if (status < 0)
  145. return IRQ_NONE;
  146. while (status) {
  147. int bit = __ffs(status);
  148. int virq = irq_create_mapping(tc3589x->domain, bit);
  149. handle_nested_irq(virq);
  150. status &= ~(1 << bit);
  151. }
  152. /*
  153. * A dummy read or write (to any register) appears to be necessary to
  154. * have the last interrupt clear (for example, GPIO IC write) take
  155. * effect. In such a case, recheck for any interrupt which is still
  156. * pending.
  157. */
  158. status = tc3589x_reg_read(tc3589x, TC3589x_IRQST);
  159. if (status)
  160. goto again;
  161. return IRQ_HANDLED;
  162. }
  163. static int tc3589x_irq_map(struct irq_domain *d, unsigned int virq,
  164. irq_hw_number_t hwirq)
  165. {
  166. struct tc3589x *tc3589x = d->host_data;
  167. irq_set_chip_data(virq, tc3589x);
  168. irq_set_chip_and_handler(virq, &dummy_irq_chip,
  169. handle_edge_irq);
  170. irq_set_nested_thread(virq, 1);
  171. #ifdef CONFIG_ARM
  172. set_irq_flags(virq, IRQF_VALID);
  173. #else
  174. irq_set_noprobe(virq);
  175. #endif
  176. return 0;
  177. }
  178. static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
  179. {
  180. #ifdef CONFIG_ARM
  181. set_irq_flags(virq, 0);
  182. #endif
  183. irq_set_chip_and_handler(virq, NULL, NULL);
  184. irq_set_chip_data(virq, NULL);
  185. }
  186. static struct irq_domain_ops tc3589x_irq_ops = {
  187. .map = tc3589x_irq_map,
  188. .unmap = tc3589x_irq_unmap,
  189. .xlate = irq_domain_xlate_twocell,
  190. };
  191. static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
  192. {
  193. int base = tc3589x->irq_base;
  194. tc3589x->domain = irq_domain_add_simple(
  195. np, TC3589x_NR_INTERNAL_IRQS, base,
  196. &tc3589x_irq_ops, tc3589x);
  197. if (!tc3589x->domain) {
  198. dev_err(tc3589x->dev, "Failed to create irqdomain\n");
  199. return -ENOSYS;
  200. }
  201. return 0;
  202. }
  203. static int tc3589x_chip_init(struct tc3589x *tc3589x)
  204. {
  205. int manf, ver, ret;
  206. manf = tc3589x_reg_read(tc3589x, TC3589x_MANFCODE);
  207. if (manf < 0)
  208. return manf;
  209. ver = tc3589x_reg_read(tc3589x, TC3589x_VERSION);
  210. if (ver < 0)
  211. return ver;
  212. if (manf != TC3589x_MANFCODE_MAGIC) {
  213. dev_err(tc3589x->dev, "unknown manufacturer: %#x\n", manf);
  214. return -EINVAL;
  215. }
  216. dev_info(tc3589x->dev, "manufacturer: %#x, version: %#x\n", manf, ver);
  217. /*
  218. * Put everything except the IRQ module into reset;
  219. * also spare the GPIO module for any pin initialization
  220. * done during pre-kernel boot
  221. */
  222. ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL,
  223. TC3589x_RSTCTRL_TIMRST
  224. | TC3589x_RSTCTRL_ROTRST
  225. | TC3589x_RSTCTRL_KBDRST);
  226. if (ret < 0)
  227. return ret;
  228. /* Clear the reset interrupt. */
  229. return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1);
  230. }
  231. static int tc3589x_device_init(struct tc3589x *tc3589x)
  232. {
  233. int ret = 0;
  234. unsigned int blocks = tc3589x->pdata->block;
  235. if (blocks & TC3589x_BLOCK_GPIO) {
  236. ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio,
  237. ARRAY_SIZE(tc3589x_dev_gpio), NULL,
  238. tc3589x->irq_base, tc3589x->domain);
  239. if (ret) {
  240. dev_err(tc3589x->dev, "failed to add gpio child\n");
  241. return ret;
  242. }
  243. dev_info(tc3589x->dev, "added gpio block\n");
  244. }
  245. if (blocks & TC3589x_BLOCK_KEYPAD) {
  246. ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad,
  247. ARRAY_SIZE(tc3589x_dev_keypad), NULL,
  248. tc3589x->irq_base, tc3589x->domain);
  249. if (ret) {
  250. dev_err(tc3589x->dev, "failed to keypad child\n");
  251. return ret;
  252. }
  253. dev_info(tc3589x->dev, "added keypad block\n");
  254. }
  255. return ret;
  256. }
  257. static int tc3589x_of_probe(struct device_node *np,
  258. struct tc3589x_platform_data *pdata)
  259. {
  260. struct device_node *child;
  261. for_each_child_of_node(np, child) {
  262. if (!strcmp(child->name, "tc3589x_gpio")) {
  263. pdata->block |= TC3589x_BLOCK_GPIO;
  264. }
  265. if (!strcmp(child->name, "tc3589x_keypad")) {
  266. pdata->block |= TC3589x_BLOCK_KEYPAD;
  267. }
  268. }
  269. return 0;
  270. }
  271. static int tc3589x_probe(struct i2c_client *i2c,
  272. const struct i2c_device_id *id)
  273. {
  274. struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
  275. struct device_node *np = i2c->dev.of_node;
  276. struct tc3589x *tc3589x;
  277. int ret;
  278. if (!pdata) {
  279. if (np) {
  280. pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
  281. if (!pdata)
  282. return -ENOMEM;
  283. ret = tc3589x_of_probe(np, pdata);
  284. if (ret)
  285. return ret;
  286. }
  287. else {
  288. dev_err(&i2c->dev, "No platform data or DT found\n");
  289. return -EINVAL;
  290. }
  291. }
  292. if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
  293. | I2C_FUNC_SMBUS_I2C_BLOCK))
  294. return -EIO;
  295. tc3589x = kzalloc(sizeof(struct tc3589x), GFP_KERNEL);
  296. if (!tc3589x)
  297. return -ENOMEM;
  298. mutex_init(&tc3589x->lock);
  299. tc3589x->dev = &i2c->dev;
  300. tc3589x->i2c = i2c;
  301. tc3589x->pdata = pdata;
  302. tc3589x->irq_base = pdata->irq_base;
  303. tc3589x->num_gpio = id->driver_data;
  304. i2c_set_clientdata(i2c, tc3589x);
  305. ret = tc3589x_chip_init(tc3589x);
  306. if (ret)
  307. goto out_free;
  308. ret = tc3589x_irq_init(tc3589x, np);
  309. if (ret)
  310. goto out_free;
  311. ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq,
  312. IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  313. "tc3589x", tc3589x);
  314. if (ret) {
  315. dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
  316. goto out_free;
  317. }
  318. ret = tc3589x_device_init(tc3589x);
  319. if (ret) {
  320. dev_err(tc3589x->dev, "failed to add child devices\n");
  321. goto out_freeirq;
  322. }
  323. return 0;
  324. out_freeirq:
  325. free_irq(tc3589x->i2c->irq, tc3589x);
  326. out_free:
  327. kfree(tc3589x);
  328. return ret;
  329. }
  330. static int tc3589x_remove(struct i2c_client *client)
  331. {
  332. struct tc3589x *tc3589x = i2c_get_clientdata(client);
  333. mfd_remove_devices(tc3589x->dev);
  334. free_irq(tc3589x->i2c->irq, tc3589x);
  335. kfree(tc3589x);
  336. return 0;
  337. }
  338. #ifdef CONFIG_PM_SLEEP
  339. static int tc3589x_suspend(struct device *dev)
  340. {
  341. struct tc3589x *tc3589x = dev_get_drvdata(dev);
  342. struct i2c_client *client = tc3589x->i2c;
  343. int ret = 0;
  344. /* put the system to sleep mode */
  345. if (!device_may_wakeup(&client->dev))
  346. ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE,
  347. TC3589x_CLKMODE_MODCTL_SLEEP);
  348. return ret;
  349. }
  350. static int tc3589x_resume(struct device *dev)
  351. {
  352. struct tc3589x *tc3589x = dev_get_drvdata(dev);
  353. struct i2c_client *client = tc3589x->i2c;
  354. int ret = 0;
  355. /* enable the system into operation */
  356. if (!device_may_wakeup(&client->dev))
  357. ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE,
  358. TC3589x_CLKMODE_MODCTL_OPERATION);
  359. return ret;
  360. }
  361. #endif
  362. static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume);
  363. static const struct i2c_device_id tc3589x_id[] = {
  364. { "tc3589x", 24 },
  365. { }
  366. };
  367. MODULE_DEVICE_TABLE(i2c, tc3589x_id);
  368. static struct i2c_driver tc3589x_driver = {
  369. .driver.name = "tc3589x",
  370. .driver.owner = THIS_MODULE,
  371. .driver.pm = &tc3589x_dev_pm_ops,
  372. .probe = tc3589x_probe,
  373. .remove = tc3589x_remove,
  374. .id_table = tc3589x_id,
  375. };
  376. static int __init tc3589x_init(void)
  377. {
  378. return i2c_add_driver(&tc3589x_driver);
  379. }
  380. subsys_initcall(tc3589x_init);
  381. static void __exit tc3589x_exit(void)
  382. {
  383. i2c_del_driver(&tc3589x_driver);
  384. }
  385. module_exit(tc3589x_exit);
  386. MODULE_LICENSE("GPL v2");
  387. MODULE_DESCRIPTION("TC3589x MFD core driver");
  388. MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");