as3722.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Core driver for ams AS3722 PMICs
  4. *
  5. * Copyright (C) 2013 AMS AG
  6. * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
  7. *
  8. * Author: Florian Lobmaier <[email protected]>
  9. * Author: Laxman Dewangan <[email protected]>
  10. */
  11. #include <linux/err.h>
  12. #include <linux/i2c.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/irq.h>
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/mfd/core.h>
  18. #include <linux/mfd/as3722.h>
  19. #include <linux/of.h>
  20. #include <linux/regmap.h>
  21. #include <linux/slab.h>
  22. #define AS3722_DEVICE_ID 0x0C
  23. static const struct resource as3722_rtc_resource[] = {
  24. DEFINE_RES_IRQ_NAMED(AS3722_IRQ_RTC_ALARM, "as3722-rtc-alarm"),
  25. };
  26. static const struct resource as3722_adc_resource[] = {
  27. DEFINE_RES_IRQ_NAMED(AS3722_IRQ_ADC, "as3722-adc"),
  28. };
  29. static const struct mfd_cell as3722_devs[] = {
  30. {
  31. .name = "as3722-pinctrl",
  32. },
  33. {
  34. .name = "as3722-regulator",
  35. },
  36. {
  37. .name = "as3722-rtc",
  38. .num_resources = ARRAY_SIZE(as3722_rtc_resource),
  39. .resources = as3722_rtc_resource,
  40. },
  41. {
  42. .name = "as3722-adc",
  43. .num_resources = ARRAY_SIZE(as3722_adc_resource),
  44. .resources = as3722_adc_resource,
  45. },
  46. {
  47. .name = "as3722-power-off",
  48. },
  49. {
  50. .name = "as3722-wdt",
  51. },
  52. };
  53. static const struct regmap_irq as3722_irqs[] = {
  54. /* INT1 IRQs */
  55. [AS3722_IRQ_LID] = {
  56. .mask = AS3722_INTERRUPT_MASK1_LID,
  57. },
  58. [AS3722_IRQ_ACOK] = {
  59. .mask = AS3722_INTERRUPT_MASK1_ACOK,
  60. },
  61. [AS3722_IRQ_ENABLE1] = {
  62. .mask = AS3722_INTERRUPT_MASK1_ENABLE1,
  63. },
  64. [AS3722_IRQ_OCCUR_ALARM_SD0] = {
  65. .mask = AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0,
  66. },
  67. [AS3722_IRQ_ONKEY_LONG_PRESS] = {
  68. .mask = AS3722_INTERRUPT_MASK1_ONKEY_LONG,
  69. },
  70. [AS3722_IRQ_ONKEY] = {
  71. .mask = AS3722_INTERRUPT_MASK1_ONKEY,
  72. },
  73. [AS3722_IRQ_OVTMP] = {
  74. .mask = AS3722_INTERRUPT_MASK1_OVTMP,
  75. },
  76. [AS3722_IRQ_LOWBAT] = {
  77. .mask = AS3722_INTERRUPT_MASK1_LOWBAT,
  78. },
  79. /* INT2 IRQs */
  80. [AS3722_IRQ_SD0_LV] = {
  81. .mask = AS3722_INTERRUPT_MASK2_SD0_LV,
  82. .reg_offset = 1,
  83. },
  84. [AS3722_IRQ_SD1_LV] = {
  85. .mask = AS3722_INTERRUPT_MASK2_SD1_LV,
  86. .reg_offset = 1,
  87. },
  88. [AS3722_IRQ_SD2_LV] = {
  89. .mask = AS3722_INTERRUPT_MASK2_SD2345_LV,
  90. .reg_offset = 1,
  91. },
  92. [AS3722_IRQ_PWM1_OV_PROT] = {
  93. .mask = AS3722_INTERRUPT_MASK2_PWM1_OV_PROT,
  94. .reg_offset = 1,
  95. },
  96. [AS3722_IRQ_PWM2_OV_PROT] = {
  97. .mask = AS3722_INTERRUPT_MASK2_PWM2_OV_PROT,
  98. .reg_offset = 1,
  99. },
  100. [AS3722_IRQ_ENABLE2] = {
  101. .mask = AS3722_INTERRUPT_MASK2_ENABLE2,
  102. .reg_offset = 1,
  103. },
  104. [AS3722_IRQ_SD6_LV] = {
  105. .mask = AS3722_INTERRUPT_MASK2_SD6_LV,
  106. .reg_offset = 1,
  107. },
  108. [AS3722_IRQ_RTC_REP] = {
  109. .mask = AS3722_INTERRUPT_MASK2_RTC_REP,
  110. .reg_offset = 1,
  111. },
  112. /* INT3 IRQs */
  113. [AS3722_IRQ_RTC_ALARM] = {
  114. .mask = AS3722_INTERRUPT_MASK3_RTC_ALARM,
  115. .reg_offset = 2,
  116. },
  117. [AS3722_IRQ_GPIO1] = {
  118. .mask = AS3722_INTERRUPT_MASK3_GPIO1,
  119. .reg_offset = 2,
  120. },
  121. [AS3722_IRQ_GPIO2] = {
  122. .mask = AS3722_INTERRUPT_MASK3_GPIO2,
  123. .reg_offset = 2,
  124. },
  125. [AS3722_IRQ_GPIO3] = {
  126. .mask = AS3722_INTERRUPT_MASK3_GPIO3,
  127. .reg_offset = 2,
  128. },
  129. [AS3722_IRQ_GPIO4] = {
  130. .mask = AS3722_INTERRUPT_MASK3_GPIO4,
  131. .reg_offset = 2,
  132. },
  133. [AS3722_IRQ_GPIO5] = {
  134. .mask = AS3722_INTERRUPT_MASK3_GPIO5,
  135. .reg_offset = 2,
  136. },
  137. [AS3722_IRQ_WATCHDOG] = {
  138. .mask = AS3722_INTERRUPT_MASK3_WATCHDOG,
  139. .reg_offset = 2,
  140. },
  141. [AS3722_IRQ_ENABLE3] = {
  142. .mask = AS3722_INTERRUPT_MASK3_ENABLE3,
  143. .reg_offset = 2,
  144. },
  145. /* INT4 IRQs */
  146. [AS3722_IRQ_TEMP_SD0_SHUTDOWN] = {
  147. .mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN,
  148. .reg_offset = 3,
  149. },
  150. [AS3722_IRQ_TEMP_SD1_SHUTDOWN] = {
  151. .mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN,
  152. .reg_offset = 3,
  153. },
  154. [AS3722_IRQ_TEMP_SD2_SHUTDOWN] = {
  155. .mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN,
  156. .reg_offset = 3,
  157. },
  158. [AS3722_IRQ_TEMP_SD0_ALARM] = {
  159. .mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM,
  160. .reg_offset = 3,
  161. },
  162. [AS3722_IRQ_TEMP_SD1_ALARM] = {
  163. .mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM,
  164. .reg_offset = 3,
  165. },
  166. [AS3722_IRQ_TEMP_SD6_ALARM] = {
  167. .mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM,
  168. .reg_offset = 3,
  169. },
  170. [AS3722_IRQ_OCCUR_ALARM_SD6] = {
  171. .mask = AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6,
  172. .reg_offset = 3,
  173. },
  174. [AS3722_IRQ_ADC] = {
  175. .mask = AS3722_INTERRUPT_MASK4_ADC,
  176. .reg_offset = 3,
  177. },
  178. };
  179. static const struct regmap_irq_chip as3722_irq_chip = {
  180. .name = "as3722",
  181. .irqs = as3722_irqs,
  182. .num_irqs = ARRAY_SIZE(as3722_irqs),
  183. .num_regs = 4,
  184. .status_base = AS3722_INTERRUPT_STATUS1_REG,
  185. .mask_base = AS3722_INTERRUPT_MASK1_REG,
  186. };
  187. static int as3722_check_device_id(struct as3722 *as3722)
  188. {
  189. u32 val;
  190. int ret;
  191. /* Check that this is actually a AS3722 */
  192. ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val);
  193. if (ret < 0) {
  194. dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret);
  195. return ret;
  196. }
  197. if (val != AS3722_DEVICE_ID) {
  198. dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val);
  199. return -ENODEV;
  200. }
  201. ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val);
  202. if (ret < 0) {
  203. dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret);
  204. return ret;
  205. }
  206. dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val);
  207. return 0;
  208. }
  209. static int as3722_configure_pullups(struct as3722 *as3722)
  210. {
  211. int ret;
  212. u32 val = 0;
  213. if (as3722->en_intern_int_pullup)
  214. val |= AS3722_INT_PULL_UP;
  215. if (as3722->en_intern_i2c_pullup)
  216. val |= AS3722_I2C_PULL_UP;
  217. ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG,
  218. AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val);
  219. if (ret < 0)
  220. dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret);
  221. return ret;
  222. }
  223. static const struct regmap_range as3722_readable_ranges[] = {
  224. regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
  225. regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
  226. regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_REG_SEQU_MOD3_REG),
  227. regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
  228. regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
  229. regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
  230. AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
  231. regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
  232. regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
  233. regmap_reg_range(AS3722_RTC_ACCESS_REG, AS3722_RTC_ACCESS_REG),
  234. regmap_reg_range(AS3722_RTC_STATUS_REG, AS3722_TEMP_STATUS_REG),
  235. regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
  236. regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
  237. regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
  238. regmap_reg_range(AS3722_FUSE7_REG, AS3722_FUSE7_REG),
  239. };
  240. static const struct regmap_access_table as3722_readable_table = {
  241. .yes_ranges = as3722_readable_ranges,
  242. .n_yes_ranges = ARRAY_SIZE(as3722_readable_ranges),
  243. };
  244. static const struct regmap_range as3722_writable_ranges[] = {
  245. regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
  246. regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
  247. regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_GPIO_SIGNAL_OUT_REG),
  248. regmap_reg_range(AS3722_REG_SEQU_MOD1_REG, AS3722_REG_SEQU_MOD3_REG),
  249. regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
  250. regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
  251. regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
  252. AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
  253. regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
  254. regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
  255. regmap_reg_range(AS3722_INTERRUPT_MASK1_REG, AS3722_TEMP_STATUS_REG),
  256. regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC1_CONTROL_REG),
  257. regmap_reg_range(AS3722_ADC1_THRESHOLD_HI_MSB_REG,
  258. AS3722_ADC_CONFIGURATION_REG),
  259. regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
  260. };
  261. static const struct regmap_access_table as3722_writable_table = {
  262. .yes_ranges = as3722_writable_ranges,
  263. .n_yes_ranges = ARRAY_SIZE(as3722_writable_ranges),
  264. };
  265. static const struct regmap_range as3722_cacheable_ranges[] = {
  266. regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_LDO11_VOLTAGE_REG),
  267. regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_LDOCONTROL1_REG),
  268. };
  269. static const struct regmap_access_table as3722_volatile_table = {
  270. .no_ranges = as3722_cacheable_ranges,
  271. .n_no_ranges = ARRAY_SIZE(as3722_cacheable_ranges),
  272. };
  273. static const struct regmap_config as3722_regmap_config = {
  274. .reg_bits = 8,
  275. .val_bits = 8,
  276. .max_register = AS3722_MAX_REGISTER,
  277. .cache_type = REGCACHE_RBTREE,
  278. .rd_table = &as3722_readable_table,
  279. .wr_table = &as3722_writable_table,
  280. .volatile_table = &as3722_volatile_table,
  281. };
  282. static int as3722_i2c_of_probe(struct i2c_client *i2c,
  283. struct as3722 *as3722)
  284. {
  285. struct device_node *np = i2c->dev.of_node;
  286. struct irq_data *irq_data;
  287. if (!np) {
  288. dev_err(&i2c->dev, "Device Tree not found\n");
  289. return -EINVAL;
  290. }
  291. irq_data = irq_get_irq_data(i2c->irq);
  292. if (!irq_data) {
  293. dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
  294. return -EINVAL;
  295. }
  296. as3722->en_intern_int_pullup = of_property_read_bool(np,
  297. "ams,enable-internal-int-pullup");
  298. as3722->en_intern_i2c_pullup = of_property_read_bool(np,
  299. "ams,enable-internal-i2c-pullup");
  300. as3722->en_ac_ok_pwr_on = of_property_read_bool(np,
  301. "ams,enable-ac-ok-power-on");
  302. as3722->irq_flags = irqd_get_trigger_type(irq_data);
  303. dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags);
  304. return 0;
  305. }
  306. static int as3722_i2c_probe(struct i2c_client *i2c,
  307. const struct i2c_device_id *id)
  308. {
  309. struct as3722 *as3722;
  310. unsigned long irq_flags;
  311. int ret;
  312. u8 val = 0;
  313. as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL);
  314. if (!as3722)
  315. return -ENOMEM;
  316. as3722->dev = &i2c->dev;
  317. as3722->chip_irq = i2c->irq;
  318. i2c_set_clientdata(i2c, as3722);
  319. ret = as3722_i2c_of_probe(i2c, as3722);
  320. if (ret < 0)
  321. return ret;
  322. as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config);
  323. if (IS_ERR(as3722->regmap)) {
  324. ret = PTR_ERR(as3722->regmap);
  325. dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
  326. return ret;
  327. }
  328. ret = as3722_check_device_id(as3722);
  329. if (ret < 0)
  330. return ret;
  331. irq_flags = as3722->irq_flags | IRQF_ONESHOT;
  332. ret = devm_regmap_add_irq_chip(as3722->dev, as3722->regmap,
  333. as3722->chip_irq,
  334. irq_flags, -1, &as3722_irq_chip,
  335. &as3722->irq_data);
  336. if (ret < 0) {
  337. dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret);
  338. return ret;
  339. }
  340. ret = as3722_configure_pullups(as3722);
  341. if (ret < 0)
  342. return ret;
  343. if (as3722->en_ac_ok_pwr_on)
  344. val = AS3722_CTRL_SEQU1_AC_OK_PWR_ON;
  345. ret = as3722_update_bits(as3722, AS3722_CTRL_SEQU1_REG,
  346. AS3722_CTRL_SEQU1_AC_OK_PWR_ON, val);
  347. if (ret < 0) {
  348. dev_err(as3722->dev, "CTRLsequ1 update failed: %d\n", ret);
  349. return ret;
  350. }
  351. ret = devm_mfd_add_devices(&i2c->dev, -1, as3722_devs,
  352. ARRAY_SIZE(as3722_devs), NULL, 0,
  353. regmap_irq_get_domain(as3722->irq_data));
  354. if (ret) {
  355. dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret);
  356. return ret;
  357. }
  358. device_init_wakeup(as3722->dev, true);
  359. dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n");
  360. return 0;
  361. }
  362. static int __maybe_unused as3722_i2c_suspend(struct device *dev)
  363. {
  364. struct as3722 *as3722 = dev_get_drvdata(dev);
  365. if (device_may_wakeup(dev))
  366. enable_irq_wake(as3722->chip_irq);
  367. disable_irq(as3722->chip_irq);
  368. return 0;
  369. }
  370. static int __maybe_unused as3722_i2c_resume(struct device *dev)
  371. {
  372. struct as3722 *as3722 = dev_get_drvdata(dev);
  373. enable_irq(as3722->chip_irq);
  374. if (device_may_wakeup(dev))
  375. disable_irq_wake(as3722->chip_irq);
  376. return 0;
  377. }
  378. static const struct of_device_id as3722_of_match[] = {
  379. { .compatible = "ams,as3722", },
  380. {},
  381. };
  382. MODULE_DEVICE_TABLE(of, as3722_of_match);
  383. static const struct i2c_device_id as3722_i2c_id[] = {
  384. { "as3722", 0 },
  385. {},
  386. };
  387. MODULE_DEVICE_TABLE(i2c, as3722_i2c_id);
  388. static const struct dev_pm_ops as3722_pm_ops = {
  389. SET_SYSTEM_SLEEP_PM_OPS(as3722_i2c_suspend, as3722_i2c_resume)
  390. };
  391. static struct i2c_driver as3722_i2c_driver = {
  392. .driver = {
  393. .name = "as3722",
  394. .of_match_table = as3722_of_match,
  395. .pm = &as3722_pm_ops,
  396. },
  397. .probe = as3722_i2c_probe,
  398. .id_table = as3722_i2c_id,
  399. };
  400. module_i2c_driver(as3722_i2c_driver);
  401. MODULE_DESCRIPTION("I2C support for AS3722 PMICs");
  402. MODULE_AUTHOR("Florian Lobmaier <[email protected]>");
  403. MODULE_AUTHOR("Laxman Dewangan <[email protected]>");
  404. MODULE_LICENSE("GPL");