max77686.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * max77686.c - mfd core driver for the Maxim 77686/802
  3. *
  4. * Copyright (C) 2012 Samsung Electronics
  5. * Chiwoong Byun <woong.byun@samsung.com>
  6. * Jonghwa Lee <jonghwa3.lee@samsung.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. * This driver is based on max8997.c
  23. */
  24. #include <linux/export.h>
  25. #include <linux/slab.h>
  26. #include <linux/i2c.h>
  27. #include <linux/irq.h>
  28. #include <linux/interrupt.h>
  29. #include <linux/pm_runtime.h>
  30. #include <linux/module.h>
  31. #include <linux/mfd/core.h>
  32. #include <linux/mfd/max77686.h>
  33. #include <linux/mfd/max77686-private.h>
  34. #include <linux/err.h>
  35. #include <linux/of.h>
  36. #include <linux/of_device.h>
  37. static const struct mfd_cell max77686_devs[] = {
  38. { .name = "max77686-pmic", },
  39. { .name = "max77686-rtc", },
  40. { .name = "max77686-clk", },
  41. };
  42. static const struct mfd_cell max77802_devs[] = {
  43. { .name = "max77802-pmic", },
  44. { .name = "max77802-clk", },
  45. { .name = "max77802-rtc", },
  46. };
  47. static bool max77802_pmic_is_accessible_reg(struct device *dev,
  48. unsigned int reg)
  49. {
  50. return reg < MAX77802_REG_PMIC_END;
  51. }
  52. static bool max77802_rtc_is_accessible_reg(struct device *dev,
  53. unsigned int reg)
  54. {
  55. return (reg >= MAX77802_RTC_INT && reg < MAX77802_RTC_END);
  56. }
  57. static bool max77802_is_accessible_reg(struct device *dev, unsigned int reg)
  58. {
  59. return (max77802_pmic_is_accessible_reg(dev, reg) ||
  60. max77802_rtc_is_accessible_reg(dev, reg));
  61. }
  62. static bool max77802_pmic_is_precious_reg(struct device *dev, unsigned int reg)
  63. {
  64. return (reg == MAX77802_REG_INTSRC || reg == MAX77802_REG_INT1 ||
  65. reg == MAX77802_REG_INT2);
  66. }
  67. static bool max77802_rtc_is_precious_reg(struct device *dev, unsigned int reg)
  68. {
  69. return (reg == MAX77802_RTC_INT ||
  70. reg == MAX77802_RTC_UPDATE0 ||
  71. reg == MAX77802_RTC_UPDATE1);
  72. }
  73. static bool max77802_is_precious_reg(struct device *dev, unsigned int reg)
  74. {
  75. return (max77802_pmic_is_precious_reg(dev, reg) ||
  76. max77802_rtc_is_precious_reg(dev, reg));
  77. }
  78. static bool max77802_pmic_is_volatile_reg(struct device *dev, unsigned int reg)
  79. {
  80. return (max77802_is_precious_reg(dev, reg) ||
  81. reg == MAX77802_REG_STATUS1 || reg == MAX77802_REG_STATUS2 ||
  82. reg == MAX77802_REG_PWRON);
  83. }
  84. static bool max77802_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
  85. {
  86. return (max77802_rtc_is_precious_reg(dev, reg) ||
  87. reg == MAX77802_RTC_SEC ||
  88. reg == MAX77802_RTC_MIN ||
  89. reg == MAX77802_RTC_HOUR ||
  90. reg == MAX77802_RTC_WEEKDAY ||
  91. reg == MAX77802_RTC_MONTH ||
  92. reg == MAX77802_RTC_YEAR ||
  93. reg == MAX77802_RTC_DATE);
  94. }
  95. static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg)
  96. {
  97. return (max77802_pmic_is_volatile_reg(dev, reg) ||
  98. max77802_rtc_is_volatile_reg(dev, reg));
  99. }
  100. static const struct regmap_config max77686_regmap_config = {
  101. .reg_bits = 8,
  102. .val_bits = 8,
  103. };
  104. static const struct regmap_config max77802_regmap_config = {
  105. .reg_bits = 8,
  106. .val_bits = 8,
  107. .writeable_reg = max77802_is_accessible_reg,
  108. .readable_reg = max77802_is_accessible_reg,
  109. .precious_reg = max77802_is_precious_reg,
  110. .volatile_reg = max77802_is_volatile_reg,
  111. .name = "max77802-pmic",
  112. .cache_type = REGCACHE_RBTREE,
  113. };
  114. static const struct regmap_irq max77686_irqs[] = {
  115. /* INT1 interrupts */
  116. { .reg_offset = 0, .mask = MAX77686_INT1_PWRONF_MSK, },
  117. { .reg_offset = 0, .mask = MAX77686_INT1_PWRONR_MSK, },
  118. { .reg_offset = 0, .mask = MAX77686_INT1_JIGONBF_MSK, },
  119. { .reg_offset = 0, .mask = MAX77686_INT1_JIGONBR_MSK, },
  120. { .reg_offset = 0, .mask = MAX77686_INT1_ACOKBF_MSK, },
  121. { .reg_offset = 0, .mask = MAX77686_INT1_ACOKBR_MSK, },
  122. { .reg_offset = 0, .mask = MAX77686_INT1_ONKEY1S_MSK, },
  123. { .reg_offset = 0, .mask = MAX77686_INT1_MRSTB_MSK, },
  124. /* INT2 interrupts */
  125. { .reg_offset = 1, .mask = MAX77686_INT2_140C_MSK, },
  126. { .reg_offset = 1, .mask = MAX77686_INT2_120C_MSK, },
  127. };
  128. static const struct regmap_irq_chip max77686_irq_chip = {
  129. .name = "max77686-pmic",
  130. .status_base = MAX77686_REG_INT1,
  131. .mask_base = MAX77686_REG_INT1MSK,
  132. .num_regs = 2,
  133. .irqs = max77686_irqs,
  134. .num_irqs = ARRAY_SIZE(max77686_irqs),
  135. };
  136. static const struct regmap_irq_chip max77802_irq_chip = {
  137. .name = "max77802-pmic",
  138. .status_base = MAX77802_REG_INT1,
  139. .mask_base = MAX77802_REG_INT1MSK,
  140. .num_regs = 2,
  141. .irqs = max77686_irqs, /* same masks as 77686 */
  142. .num_irqs = ARRAY_SIZE(max77686_irqs),
  143. };
  144. static const struct of_device_id max77686_pmic_dt_match[] = {
  145. {
  146. .compatible = "maxim,max77686",
  147. .data = (void *)TYPE_MAX77686,
  148. },
  149. {
  150. .compatible = "maxim,max77802",
  151. .data = (void *)TYPE_MAX77802,
  152. },
  153. { },
  154. };
  155. MODULE_DEVICE_TABLE(of, max77686_pmic_dt_match);
  156. static int max77686_i2c_probe(struct i2c_client *i2c)
  157. {
  158. struct max77686_dev *max77686 = NULL;
  159. unsigned int data;
  160. int ret = 0;
  161. const struct regmap_config *config;
  162. const struct regmap_irq_chip *irq_chip;
  163. const struct mfd_cell *cells;
  164. int n_devs;
  165. max77686 = devm_kzalloc(&i2c->dev,
  166. sizeof(struct max77686_dev), GFP_KERNEL);
  167. if (!max77686)
  168. return -ENOMEM;
  169. i2c_set_clientdata(i2c, max77686);
  170. max77686->type = (unsigned long)of_device_get_match_data(&i2c->dev);
  171. max77686->dev = &i2c->dev;
  172. max77686->i2c = i2c;
  173. max77686->irq = i2c->irq;
  174. if (max77686->type == TYPE_MAX77686) {
  175. config = &max77686_regmap_config;
  176. irq_chip = &max77686_irq_chip;
  177. cells = max77686_devs;
  178. n_devs = ARRAY_SIZE(max77686_devs);
  179. } else {
  180. config = &max77802_regmap_config;
  181. irq_chip = &max77802_irq_chip;
  182. cells = max77802_devs;
  183. n_devs = ARRAY_SIZE(max77802_devs);
  184. }
  185. max77686->regmap = devm_regmap_init_i2c(i2c, config);
  186. if (IS_ERR(max77686->regmap)) {
  187. ret = PTR_ERR(max77686->regmap);
  188. dev_err(max77686->dev, "Failed to allocate register map: %d\n",
  189. ret);
  190. return ret;
  191. }
  192. ret = regmap_read(max77686->regmap, MAX77686_REG_DEVICE_ID, &data);
  193. if (ret < 0) {
  194. dev_err(max77686->dev,
  195. "device not found on this channel (this is not an error)\n");
  196. return -ENODEV;
  197. }
  198. ret = devm_regmap_add_irq_chip(&i2c->dev, max77686->regmap,
  199. max77686->irq,
  200. IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
  201. IRQF_SHARED, 0, irq_chip,
  202. &max77686->irq_data);
  203. if (ret < 0) {
  204. dev_err(&i2c->dev, "failed to add PMIC irq chip: %d\n", ret);
  205. return ret;
  206. }
  207. ret = devm_mfd_add_devices(max77686->dev, -1, cells, n_devs, NULL,
  208. 0, NULL);
  209. if (ret < 0) {
  210. dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
  211. return ret;
  212. }
  213. return 0;
  214. }
  215. #ifdef CONFIG_PM_SLEEP
  216. static int max77686_suspend(struct device *dev)
  217. {
  218. struct i2c_client *i2c = to_i2c_client(dev);
  219. struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
  220. if (device_may_wakeup(dev))
  221. enable_irq_wake(max77686->irq);
  222. /*
  223. * IRQ must be disabled during suspend because if it happens
  224. * while suspended it will be handled before resuming I2C.
  225. *
  226. * When device is woken up from suspend (e.g. by RTC wake alarm),
  227. * an interrupt occurs before resuming I2C bus controller.
  228. * Interrupt handler tries to read registers but this read
  229. * will fail because I2C is still suspended.
  230. */
  231. disable_irq(max77686->irq);
  232. return 0;
  233. }
  234. static int max77686_resume(struct device *dev)
  235. {
  236. struct i2c_client *i2c = to_i2c_client(dev);
  237. struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
  238. if (device_may_wakeup(dev))
  239. disable_irq_wake(max77686->irq);
  240. enable_irq(max77686->irq);
  241. return 0;
  242. }
  243. #endif /* CONFIG_PM_SLEEP */
  244. static SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume);
  245. static struct i2c_driver max77686_i2c_driver = {
  246. .driver = {
  247. .name = "max77686",
  248. .pm = &max77686_pm,
  249. .of_match_table = of_match_ptr(max77686_pmic_dt_match),
  250. },
  251. .probe_new = max77686_i2c_probe,
  252. };
  253. module_i2c_driver(max77686_i2c_driver);
  254. MODULE_DESCRIPTION("MAXIM 77686/802 multi-function core driver");
  255. MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
  256. MODULE_LICENSE("GPL");