mt6397-core.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. * Copyright (c) 2014 MediaTek Inc.
  3. * Author: Flora Fu, MediaTek
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  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. #include <linux/interrupt.h>
  15. #include <linux/module.h>
  16. #include <linux/of_device.h>
  17. #include <linux/of_irq.h>
  18. #include <linux/regmap.h>
  19. #include <linux/mfd/core.h>
  20. #include <linux/mfd/mt6397/core.h>
  21. #include <linux/mfd/mt6323/core.h>
  22. #include <linux/mfd/mt6397/registers.h>
  23. #include <linux/mfd/mt6323/registers.h>
  24. #define MT6397_RTC_BASE 0xe000
  25. #define MT6397_RTC_SIZE 0x3e
  26. #define MT6323_CID_CODE 0x23
  27. #define MT6391_CID_CODE 0x91
  28. #define MT6397_CID_CODE 0x97
  29. static const struct resource mt6397_rtc_resources[] = {
  30. {
  31. .start = MT6397_RTC_BASE,
  32. .end = MT6397_RTC_BASE + MT6397_RTC_SIZE,
  33. .flags = IORESOURCE_MEM,
  34. },
  35. {
  36. .start = MT6397_IRQ_RTC,
  37. .end = MT6397_IRQ_RTC,
  38. .flags = IORESOURCE_IRQ,
  39. },
  40. };
  41. static const struct mfd_cell mt6323_devs[] = {
  42. {
  43. .name = "mt6323-regulator",
  44. .of_compatible = "mediatek,mt6323-regulator"
  45. },
  46. };
  47. static const struct mfd_cell mt6397_devs[] = {
  48. {
  49. .name = "mt6397-rtc",
  50. .num_resources = ARRAY_SIZE(mt6397_rtc_resources),
  51. .resources = mt6397_rtc_resources,
  52. .of_compatible = "mediatek,mt6397-rtc",
  53. }, {
  54. .name = "mt6397-regulator",
  55. .of_compatible = "mediatek,mt6397-regulator",
  56. }, {
  57. .name = "mt6397-codec",
  58. .of_compatible = "mediatek,mt6397-codec",
  59. }, {
  60. .name = "mt6397-clk",
  61. .of_compatible = "mediatek,mt6397-clk",
  62. }, {
  63. .name = "mt6397-pinctrl",
  64. .of_compatible = "mediatek,mt6397-pinctrl",
  65. },
  66. };
  67. static void mt6397_irq_lock(struct irq_data *data)
  68. {
  69. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  70. mutex_lock(&mt6397->irqlock);
  71. }
  72. static void mt6397_irq_sync_unlock(struct irq_data *data)
  73. {
  74. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  75. regmap_write(mt6397->regmap, mt6397->int_con[0],
  76. mt6397->irq_masks_cur[0]);
  77. regmap_write(mt6397->regmap, mt6397->int_con[1],
  78. mt6397->irq_masks_cur[1]);
  79. mutex_unlock(&mt6397->irqlock);
  80. }
  81. static void mt6397_irq_disable(struct irq_data *data)
  82. {
  83. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  84. int shift = data->hwirq & 0xf;
  85. int reg = data->hwirq >> 4;
  86. mt6397->irq_masks_cur[reg] &= ~BIT(shift);
  87. }
  88. static void mt6397_irq_enable(struct irq_data *data)
  89. {
  90. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  91. int shift = data->hwirq & 0xf;
  92. int reg = data->hwirq >> 4;
  93. mt6397->irq_masks_cur[reg] |= BIT(shift);
  94. }
  95. #ifdef CONFIG_PM_SLEEP
  96. static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
  97. {
  98. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
  99. int shift = irq_data->hwirq & 0xf;
  100. int reg = irq_data->hwirq >> 4;
  101. if (on)
  102. mt6397->wake_mask[reg] |= BIT(shift);
  103. else
  104. mt6397->wake_mask[reg] &= ~BIT(shift);
  105. return 0;
  106. }
  107. #else
  108. #define mt6397_irq_set_wake NULL
  109. #endif
  110. static struct irq_chip mt6397_irq_chip = {
  111. .name = "mt6397-irq",
  112. .irq_bus_lock = mt6397_irq_lock,
  113. .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
  114. .irq_enable = mt6397_irq_enable,
  115. .irq_disable = mt6397_irq_disable,
  116. .irq_set_wake = mt6397_irq_set_wake,
  117. };
  118. static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
  119. int irqbase)
  120. {
  121. unsigned int status;
  122. int i, irq, ret;
  123. ret = regmap_read(mt6397->regmap, reg, &status);
  124. if (ret) {
  125. dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
  126. return;
  127. }
  128. for (i = 0; i < 16; i++) {
  129. if (status & BIT(i)) {
  130. irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
  131. if (irq)
  132. handle_nested_irq(irq);
  133. }
  134. }
  135. regmap_write(mt6397->regmap, reg, status);
  136. }
  137. static irqreturn_t mt6397_irq_thread(int irq, void *data)
  138. {
  139. struct mt6397_chip *mt6397 = data;
  140. mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
  141. mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
  142. return IRQ_HANDLED;
  143. }
  144. static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
  145. irq_hw_number_t hw)
  146. {
  147. struct mt6397_chip *mt6397 = d->host_data;
  148. irq_set_chip_data(irq, mt6397);
  149. irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
  150. irq_set_nested_thread(irq, 1);
  151. irq_set_noprobe(irq);
  152. return 0;
  153. }
  154. static const struct irq_domain_ops mt6397_irq_domain_ops = {
  155. .map = mt6397_irq_domain_map,
  156. };
  157. static int mt6397_irq_init(struct mt6397_chip *mt6397)
  158. {
  159. int ret;
  160. mutex_init(&mt6397->irqlock);
  161. /* Mask all interrupt sources */
  162. regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
  163. regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
  164. mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
  165. MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
  166. if (!mt6397->irq_domain) {
  167. dev_err(mt6397->dev, "could not create irq domain\n");
  168. return -ENOMEM;
  169. }
  170. ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
  171. mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
  172. if (ret) {
  173. dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
  174. mt6397->irq, ret);
  175. return ret;
  176. }
  177. return 0;
  178. }
  179. #ifdef CONFIG_PM_SLEEP
  180. static int mt6397_irq_suspend(struct device *dev)
  181. {
  182. struct mt6397_chip *chip = dev_get_drvdata(dev);
  183. regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
  184. regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
  185. enable_irq_wake(chip->irq);
  186. return 0;
  187. }
  188. static int mt6397_irq_resume(struct device *dev)
  189. {
  190. struct mt6397_chip *chip = dev_get_drvdata(dev);
  191. regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
  192. regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
  193. disable_irq_wake(chip->irq);
  194. return 0;
  195. }
  196. #endif
  197. static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
  198. mt6397_irq_resume);
  199. static int mt6397_probe(struct platform_device *pdev)
  200. {
  201. int ret;
  202. unsigned int id;
  203. struct mt6397_chip *pmic;
  204. pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
  205. if (!pmic)
  206. return -ENOMEM;
  207. pmic->dev = &pdev->dev;
  208. /*
  209. * mt6397 MFD is child device of soc pmic wrapper.
  210. * Regmap is set from its parent.
  211. */
  212. pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  213. if (!pmic->regmap)
  214. return -ENODEV;
  215. platform_set_drvdata(pdev, pmic);
  216. ret = regmap_read(pmic->regmap, MT6397_CID, &id);
  217. if (ret) {
  218. dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
  219. return ret;
  220. }
  221. pmic->irq = platform_get_irq(pdev, 0);
  222. if (pmic->irq <= 0)
  223. return pmic->irq;
  224. switch (id & 0xff) {
  225. case MT6323_CID_CODE:
  226. pmic->int_con[0] = MT6323_INT_CON0;
  227. pmic->int_con[1] = MT6323_INT_CON1;
  228. pmic->int_status[0] = MT6323_INT_STATUS0;
  229. pmic->int_status[1] = MT6323_INT_STATUS1;
  230. ret = mt6397_irq_init(pmic);
  231. if (ret)
  232. return ret;
  233. ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
  234. ARRAY_SIZE(mt6323_devs), NULL,
  235. 0, NULL);
  236. break;
  237. case MT6397_CID_CODE:
  238. case MT6391_CID_CODE:
  239. pmic->int_con[0] = MT6397_INT_CON0;
  240. pmic->int_con[1] = MT6397_INT_CON1;
  241. pmic->int_status[0] = MT6397_INT_STATUS0;
  242. pmic->int_status[1] = MT6397_INT_STATUS1;
  243. ret = mt6397_irq_init(pmic);
  244. if (ret)
  245. return ret;
  246. ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
  247. ARRAY_SIZE(mt6397_devs), NULL,
  248. 0, NULL);
  249. break;
  250. default:
  251. dev_err(&pdev->dev, "unsupported chip: %d\n", id);
  252. ret = -ENODEV;
  253. break;
  254. }
  255. if (ret) {
  256. irq_domain_remove(pmic->irq_domain);
  257. dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
  258. }
  259. return ret;
  260. }
  261. static const struct of_device_id mt6397_of_match[] = {
  262. { .compatible = "mediatek,mt6397" },
  263. { .compatible = "mediatek,mt6323" },
  264. { }
  265. };
  266. MODULE_DEVICE_TABLE(of, mt6397_of_match);
  267. static const struct platform_device_id mt6397_id[] = {
  268. { "mt6397", 0 },
  269. { },
  270. };
  271. MODULE_DEVICE_TABLE(platform, mt6397_id);
  272. static struct platform_driver mt6397_driver = {
  273. .probe = mt6397_probe,
  274. .driver = {
  275. .name = "mt6397",
  276. .of_match_table = of_match_ptr(mt6397_of_match),
  277. .pm = &mt6397_pm_ops,
  278. },
  279. .id_table = mt6397_id,
  280. };
  281. module_platform_driver(mt6397_driver);
  282. MODULE_AUTHOR("Flora Fu, MediaTek");
  283. MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
  284. MODULE_LICENSE("GPL");