max8925-core.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. * Base driver for Maxim MAX8925
  3. *
  4. * Copyright (C) 2009 Marvell International Ltd.
  5. * Haojian Zhuang <haojian.zhuang@marvell.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/i2c.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/mfd/core.h>
  17. #include <linux/mfd/max8925.h>
  18. #define IRQ_MODE_STATUS 0
  19. #define IRQ_MODE_MASK 1
  20. static struct resource backlight_resources[] = {
  21. {
  22. .name = "max8925-backlight",
  23. .start = MAX8925_WLED_MODE_CNTL,
  24. .end = MAX8925_WLED_CNTL,
  25. .flags = IORESOURCE_IO,
  26. },
  27. };
  28. static struct mfd_cell backlight_devs[] = {
  29. {
  30. .name = "max8925-backlight",
  31. .num_resources = 1,
  32. .resources = &backlight_resources[0],
  33. .id = -1,
  34. },
  35. };
  36. static struct resource touch_resources[] = {
  37. {
  38. .name = "max8925-tsc",
  39. .start = MAX8925_TSC_IRQ,
  40. .end = MAX8925_ADC_RES_END,
  41. .flags = IORESOURCE_IO,
  42. },
  43. };
  44. static struct mfd_cell touch_devs[] = {
  45. {
  46. .name = "max8925-touch",
  47. .num_resources = 1,
  48. .resources = &touch_resources[0],
  49. .id = -1,
  50. },
  51. };
  52. #define MAX8925_REG_RESOURCE(_start, _end) \
  53. { \
  54. .start = MAX8925_##_start, \
  55. .end = MAX8925_##_end, \
  56. .flags = IORESOURCE_IO, \
  57. }
  58. static struct resource regulator_resources[] = {
  59. MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
  60. MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
  61. MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
  62. MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
  63. MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
  64. MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
  65. MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
  66. MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
  67. MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
  68. MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
  69. MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
  70. MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
  71. MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
  72. MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
  73. MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
  74. MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
  75. MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
  76. MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
  77. MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
  78. MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
  79. MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
  80. MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
  81. MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
  82. };
  83. #define MAX8925_REG_DEVS(_id) \
  84. { \
  85. .name = "max8925-regulator", \
  86. .num_resources = 1, \
  87. .resources = &regulator_resources[MAX8925_ID_##_id], \
  88. .id = MAX8925_ID_##_id, \
  89. }
  90. static struct mfd_cell regulator_devs[] = {
  91. MAX8925_REG_DEVS(SD1),
  92. MAX8925_REG_DEVS(SD2),
  93. MAX8925_REG_DEVS(SD3),
  94. MAX8925_REG_DEVS(LDO1),
  95. MAX8925_REG_DEVS(LDO2),
  96. MAX8925_REG_DEVS(LDO3),
  97. MAX8925_REG_DEVS(LDO4),
  98. MAX8925_REG_DEVS(LDO5),
  99. MAX8925_REG_DEVS(LDO6),
  100. MAX8925_REG_DEVS(LDO7),
  101. MAX8925_REG_DEVS(LDO8),
  102. MAX8925_REG_DEVS(LDO9),
  103. MAX8925_REG_DEVS(LDO10),
  104. MAX8925_REG_DEVS(LDO11),
  105. MAX8925_REG_DEVS(LDO12),
  106. MAX8925_REG_DEVS(LDO13),
  107. MAX8925_REG_DEVS(LDO14),
  108. MAX8925_REG_DEVS(LDO15),
  109. MAX8925_REG_DEVS(LDO16),
  110. MAX8925_REG_DEVS(LDO17),
  111. MAX8925_REG_DEVS(LDO18),
  112. MAX8925_REG_DEVS(LDO19),
  113. MAX8925_REG_DEVS(LDO20),
  114. };
  115. static int __get_irq_offset(struct max8925_chip *chip, int irq, int mode,
  116. int *offset, int *bit)
  117. {
  118. if (!offset || !bit)
  119. return -EINVAL;
  120. switch (chip->chip_id) {
  121. case MAX8925_GPM:
  122. *bit = irq % BITS_PER_BYTE;
  123. if (irq < (BITS_PER_BYTE << 1)) { /* irq = [0,15] */
  124. *offset = (mode) ? MAX8925_CHG_IRQ1_MASK
  125. : MAX8925_CHG_IRQ1;
  126. if (irq >= BITS_PER_BYTE)
  127. (*offset)++;
  128. } else { /* irq = [16,31] */
  129. *offset = (mode) ? MAX8925_ON_OFF_IRQ1_MASK
  130. : MAX8925_ON_OFF_IRQ1;
  131. if (irq >= (BITS_PER_BYTE * 3))
  132. (*offset)++;
  133. }
  134. break;
  135. case MAX8925_ADC:
  136. *bit = irq % BITS_PER_BYTE;
  137. *offset = (mode) ? MAX8925_TSC_IRQ_MASK : MAX8925_TSC_IRQ;
  138. break;
  139. default:
  140. goto out;
  141. }
  142. return 0;
  143. out:
  144. dev_err(chip->dev, "Wrong irq #%d is assigned\n", irq);
  145. return -EINVAL;
  146. }
  147. static int __check_irq(int irq)
  148. {
  149. if ((irq < 0) || (irq >= MAX8925_NUM_IRQ))
  150. return -EINVAL;
  151. return 0;
  152. }
  153. int max8925_mask_irq(struct max8925_chip *chip, int irq)
  154. {
  155. int offset, bit, ret;
  156. ret = __get_irq_offset(chip, irq, IRQ_MODE_MASK, &offset, &bit);
  157. if (ret < 0)
  158. return ret;
  159. ret = max8925_set_bits(chip->i2c, offset, 1 << bit, 1 << bit);
  160. return ret;
  161. }
  162. int max8925_unmask_irq(struct max8925_chip *chip, int irq)
  163. {
  164. int offset, bit, ret;
  165. ret = __get_irq_offset(chip, irq, IRQ_MODE_MASK, &offset, &bit);
  166. if (ret < 0)
  167. return ret;
  168. ret = max8925_set_bits(chip->i2c, offset, 1 << bit, 0);
  169. return ret;
  170. }
  171. #define INT_STATUS_NUM (MAX8925_NUM_IRQ / BITS_PER_BYTE)
  172. static irqreturn_t max8925_irq_thread(int irq, void *data)
  173. {
  174. struct max8925_chip *chip = data;
  175. unsigned long irq_status[INT_STATUS_NUM];
  176. unsigned char status_buf[INT_STATUS_NUM << 1];
  177. int i, ret;
  178. memset(irq_status, 0, sizeof(unsigned long) * INT_STATUS_NUM);
  179. /* all these interrupt status registers are read-only */
  180. switch (chip->chip_id) {
  181. case MAX8925_GPM:
  182. ret = max8925_bulk_read(chip->i2c, MAX8925_CHG_IRQ1,
  183. 4, status_buf);
  184. if (ret < 0)
  185. goto out;
  186. ret = max8925_bulk_read(chip->i2c, MAX8925_ON_OFF_IRQ1,
  187. 2, &status_buf[4]);
  188. if (ret < 0)
  189. goto out;
  190. ret = max8925_bulk_read(chip->i2c, MAX8925_ON_OFF_IRQ2,
  191. 2, &status_buf[6]);
  192. if (ret < 0)
  193. goto out;
  194. /* clear masked interrupt status */
  195. status_buf[0] &= (~status_buf[2] & CHG_IRQ1_MASK);
  196. irq_status[0] |= status_buf[0];
  197. status_buf[1] &= (~status_buf[3] & CHG_IRQ2_MASK);
  198. irq_status[0] |= (status_buf[1] << BITS_PER_BYTE);
  199. status_buf[4] &= (~status_buf[5] & ON_OFF_IRQ1_MASK);
  200. irq_status[0] |= (status_buf[4] << (BITS_PER_BYTE * 2));
  201. status_buf[6] &= (~status_buf[7] & ON_OFF_IRQ2_MASK);
  202. irq_status[0] |= (status_buf[6] << (BITS_PER_BYTE * 3));
  203. break;
  204. case MAX8925_ADC:
  205. ret = max8925_bulk_read(chip->i2c, MAX8925_TSC_IRQ,
  206. 2, status_buf);
  207. if (ret < 0)
  208. goto out;
  209. /* clear masked interrupt status */
  210. status_buf[0] &= (~status_buf[1] & TSC_IRQ_MASK);
  211. irq_status[0] |= status_buf[0];
  212. break;
  213. default:
  214. goto out;
  215. }
  216. for_each_bit(i, &irq_status[0], MAX8925_NUM_IRQ) {
  217. clear_bit(i, irq_status);
  218. dev_dbg(chip->dev, "Servicing IRQ #%d in %s\n", i, chip->name);
  219. mutex_lock(&chip->irq_lock);
  220. if (chip->irq[i].handler)
  221. chip->irq[i].handler(i, chip->irq[i].data);
  222. else {
  223. max8925_mask_irq(chip, i);
  224. dev_err(chip->dev, "Noboday cares IRQ #%d in %s. "
  225. "Now mask it.\n", i, chip->name);
  226. }
  227. mutex_unlock(&chip->irq_lock);
  228. }
  229. out:
  230. return IRQ_HANDLED;
  231. }
  232. int max8925_request_irq(struct max8925_chip *chip, int irq,
  233. irq_handler_t handler, void *data)
  234. {
  235. if ((__check_irq(irq) < 0) || !handler)
  236. return -EINVAL;
  237. mutex_lock(&chip->irq_lock);
  238. chip->irq[irq].handler = handler;
  239. chip->irq[irq].data = data;
  240. mutex_unlock(&chip->irq_lock);
  241. return 0;
  242. }
  243. EXPORT_SYMBOL(max8925_request_irq);
  244. int max8925_free_irq(struct max8925_chip *chip, int irq)
  245. {
  246. if (__check_irq(irq) < 0)
  247. return -EINVAL;
  248. mutex_lock(&chip->irq_lock);
  249. chip->irq[irq].handler = NULL;
  250. chip->irq[irq].data = NULL;
  251. mutex_unlock(&chip->irq_lock);
  252. return 0;
  253. }
  254. EXPORT_SYMBOL(max8925_free_irq);
  255. static int __devinit device_gpm_init(struct max8925_chip *chip,
  256. struct i2c_client *i2c,
  257. struct max8925_platform_data *pdata)
  258. {
  259. int ret;
  260. /* mask all IRQs */
  261. ret = max8925_set_bits(i2c, MAX8925_CHG_IRQ1_MASK, 0x7, 0x7);
  262. if (ret < 0)
  263. goto out;
  264. ret = max8925_set_bits(i2c, MAX8925_CHG_IRQ2_MASK, 0xff, 0xff);
  265. if (ret < 0)
  266. goto out;
  267. ret = max8925_set_bits(i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff, 0xff);
  268. if (ret < 0)
  269. goto out;
  270. ret = max8925_set_bits(i2c, MAX8925_ON_OFF_IRQ2_MASK, 0x3, 0x3);
  271. if (ret < 0)
  272. goto out;
  273. chip->name = "GPM";
  274. memset(chip->irq, 0, sizeof(struct max8925_irq) * MAX8925_NUM_IRQ);
  275. ret = request_threaded_irq(i2c->irq, NULL, max8925_irq_thread,
  276. IRQF_ONESHOT | IRQF_TRIGGER_LOW,
  277. "max8925-gpm", chip);
  278. if (ret < 0) {
  279. dev_err(chip->dev, "Failed to request IRQ #%d.\n", i2c->irq);
  280. goto out;
  281. }
  282. chip->chip_irq = i2c->irq;
  283. /* enable hard-reset for ONKEY power-off */
  284. max8925_set_bits(i2c, MAX8925_SYSENSEL, 0x80, 0x80);
  285. ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
  286. ARRAY_SIZE(regulator_devs),
  287. &regulator_resources[0], 0);
  288. if (ret < 0) {
  289. dev_err(chip->dev, "Failed to add regulator subdev\n");
  290. goto out_irq;
  291. }
  292. if (pdata && pdata->backlight) {
  293. ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
  294. ARRAY_SIZE(backlight_devs),
  295. &backlight_resources[0], 0);
  296. if (ret < 0) {
  297. dev_err(chip->dev, "Failed to add backlight subdev\n");
  298. goto out_dev;
  299. }
  300. }
  301. return 0;
  302. out_dev:
  303. mfd_remove_devices(chip->dev);
  304. out_irq:
  305. if (chip->chip_irq)
  306. free_irq(chip->chip_irq, chip);
  307. out:
  308. return ret;
  309. }
  310. static int __devinit device_adc_init(struct max8925_chip *chip,
  311. struct i2c_client *i2c,
  312. struct max8925_platform_data *pdata)
  313. {
  314. int ret;
  315. /* mask all IRQs */
  316. ret = max8925_set_bits(i2c, MAX8925_TSC_IRQ_MASK, 3, 3);
  317. chip->name = "ADC";
  318. memset(chip->irq, 0, sizeof(struct max8925_irq) * MAX8925_NUM_IRQ);
  319. ret = request_threaded_irq(i2c->irq, NULL, max8925_irq_thread,
  320. IRQF_ONESHOT | IRQF_TRIGGER_LOW,
  321. "max8925-adc", chip);
  322. if (ret < 0) {
  323. dev_err(chip->dev, "Failed to request IRQ #%d.\n", i2c->irq);
  324. goto out;
  325. }
  326. chip->chip_irq = i2c->irq;
  327. if (pdata && pdata->touch) {
  328. ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
  329. ARRAY_SIZE(touch_devs),
  330. &touch_resources[0], 0);
  331. if (ret < 0) {
  332. dev_err(chip->dev, "Failed to add touch subdev\n");
  333. goto out_irq;
  334. }
  335. }
  336. return 0;
  337. out_irq:
  338. if (chip->chip_irq)
  339. free_irq(chip->chip_irq, chip);
  340. out:
  341. return ret;
  342. }
  343. int __devinit max8925_device_init(struct max8925_chip *chip,
  344. struct max8925_platform_data *pdata)
  345. {
  346. switch (chip->chip_id) {
  347. case MAX8925_GPM:
  348. device_gpm_init(chip, chip->i2c, pdata);
  349. break;
  350. case MAX8925_ADC:
  351. device_adc_init(chip, chip->i2c, pdata);
  352. break;
  353. }
  354. return 0;
  355. }
  356. void max8925_device_exit(struct max8925_chip *chip)
  357. {
  358. if (chip->chip_irq >= 0)
  359. free_irq(chip->chip_irq, chip);
  360. mfd_remove_devices(chip->dev);
  361. }
  362. MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
  363. MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
  364. MODULE_LICENSE("GPL");