intel_soc_pmic_bxtwc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. * MFD core driver for Intel Broxton Whiskey Cove PMIC
  3. *
  4. * Copyright (C) 2015 Intel Corporation. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/acpi.h>
  17. #include <linux/err.h>
  18. #include <linux/delay.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/kernel.h>
  21. #include <linux/mfd/core.h>
  22. #include <linux/mfd/intel_bxtwc.h>
  23. #include <asm/intel_pmc_ipc.h>
  24. /* PMIC device registers */
  25. #define REG_ADDR_MASK 0xFF00
  26. #define REG_ADDR_SHIFT 8
  27. #define REG_OFFSET_MASK 0xFF
  28. /* Interrupt Status Registers */
  29. #define BXTWC_IRQLVL1 0x4E02
  30. #define BXTWC_PWRBTNIRQ 0x4E03
  31. #define BXTWC_THRM0IRQ 0x4E04
  32. #define BXTWC_THRM1IRQ 0x4E05
  33. #define BXTWC_THRM2IRQ 0x4E06
  34. #define BXTWC_BCUIRQ 0x4E07
  35. #define BXTWC_ADCIRQ 0x4E08
  36. #define BXTWC_CHGR0IRQ 0x4E09
  37. #define BXTWC_CHGR1IRQ 0x4E0A
  38. #define BXTWC_GPIOIRQ0 0x4E0B
  39. #define BXTWC_GPIOIRQ1 0x4E0C
  40. #define BXTWC_CRITIRQ 0x4E0D
  41. /* Interrupt MASK Registers */
  42. #define BXTWC_MIRQLVL1 0x4E0E
  43. #define BXTWC_MPWRTNIRQ 0x4E0F
  44. #define BXTWC_MTHRM0IRQ 0x4E12
  45. #define BXTWC_MTHRM1IRQ 0x4E13
  46. #define BXTWC_MTHRM2IRQ 0x4E14
  47. #define BXTWC_MBCUIRQ 0x4E15
  48. #define BXTWC_MADCIRQ 0x4E16
  49. #define BXTWC_MCHGR0IRQ 0x4E17
  50. #define BXTWC_MCHGR1IRQ 0x4E18
  51. #define BXTWC_MGPIO0IRQ 0x4E19
  52. #define BXTWC_MGPIO1IRQ 0x4E1A
  53. #define BXTWC_MCRITIRQ 0x4E1B
  54. /* Whiskey Cove PMIC share same ACPI ID between different platforms */
  55. #define BROXTON_PMIC_WC_HRV 4
  56. /* Manage in two IRQ chips since mask registers are not consecutive */
  57. enum bxtwc_irqs {
  58. /* Level 1 */
  59. BXTWC_PWRBTN_LVL1_IRQ = 0,
  60. BXTWC_TMU_LVL1_IRQ,
  61. BXTWC_THRM_LVL1_IRQ,
  62. BXTWC_BCU_LVL1_IRQ,
  63. BXTWC_ADC_LVL1_IRQ,
  64. BXTWC_CHGR_LVL1_IRQ,
  65. BXTWC_GPIO_LVL1_IRQ,
  66. BXTWC_CRIT_LVL1_IRQ,
  67. /* Level 2 */
  68. BXTWC_PWRBTN_IRQ,
  69. };
  70. enum bxtwc_irqs_level2 {
  71. /* Level 2 */
  72. BXTWC_THRM0_IRQ = 0,
  73. BXTWC_THRM1_IRQ,
  74. BXTWC_THRM2_IRQ,
  75. BXTWC_BCU_IRQ,
  76. BXTWC_ADC_IRQ,
  77. BXTWC_CHGR0_IRQ,
  78. BXTWC_CHGR1_IRQ,
  79. BXTWC_GPIO0_IRQ,
  80. BXTWC_GPIO1_IRQ,
  81. BXTWC_CRIT_IRQ,
  82. };
  83. static const struct regmap_irq bxtwc_regmap_irqs[] = {
  84. REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
  85. REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
  86. REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
  87. REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
  88. REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
  89. REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
  90. REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
  91. REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
  92. REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03),
  93. };
  94. static const struct regmap_irq bxtwc_regmap_irqs_level2[] = {
  95. REGMAP_IRQ_REG(BXTWC_THRM0_IRQ, 0, 0xff),
  96. REGMAP_IRQ_REG(BXTWC_THRM1_IRQ, 1, 0xbf),
  97. REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
  98. REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
  99. REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
  100. REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
  101. REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
  102. REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
  103. REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
  104. REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
  105. };
  106. static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
  107. .name = "bxtwc_irq_chip",
  108. .status_base = BXTWC_IRQLVL1,
  109. .mask_base = BXTWC_MIRQLVL1,
  110. .irqs = bxtwc_regmap_irqs,
  111. .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
  112. .num_regs = 2,
  113. };
  114. static struct regmap_irq_chip bxtwc_regmap_irq_chip_level2 = {
  115. .name = "bxtwc_irq_chip_level2",
  116. .status_base = BXTWC_THRM0IRQ,
  117. .mask_base = BXTWC_MTHRM0IRQ,
  118. .irqs = bxtwc_regmap_irqs_level2,
  119. .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_level2),
  120. .num_regs = 10,
  121. };
  122. static struct resource gpio_resources[] = {
  123. DEFINE_RES_IRQ_NAMED(BXTWC_GPIO0_IRQ, "GPIO0"),
  124. DEFINE_RES_IRQ_NAMED(BXTWC_GPIO1_IRQ, "GPIO1"),
  125. };
  126. static struct resource adc_resources[] = {
  127. DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
  128. };
  129. static struct resource charger_resources[] = {
  130. DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
  131. DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
  132. };
  133. static struct resource thermal_resources[] = {
  134. DEFINE_RES_IRQ(BXTWC_THRM0_IRQ),
  135. DEFINE_RES_IRQ(BXTWC_THRM1_IRQ),
  136. DEFINE_RES_IRQ(BXTWC_THRM2_IRQ),
  137. };
  138. static struct resource bcu_resources[] = {
  139. DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
  140. };
  141. static struct mfd_cell bxt_wc_dev[] = {
  142. {
  143. .name = "bxt_wcove_gpadc",
  144. .num_resources = ARRAY_SIZE(adc_resources),
  145. .resources = adc_resources,
  146. },
  147. {
  148. .name = "bxt_wcove_thermal",
  149. .num_resources = ARRAY_SIZE(thermal_resources),
  150. .resources = thermal_resources,
  151. },
  152. {
  153. .name = "bxt_wcove_ext_charger",
  154. .num_resources = ARRAY_SIZE(charger_resources),
  155. .resources = charger_resources,
  156. },
  157. {
  158. .name = "bxt_wcove_bcu",
  159. .num_resources = ARRAY_SIZE(bcu_resources),
  160. .resources = bcu_resources,
  161. },
  162. {
  163. .name = "bxt_wcove_gpio",
  164. .num_resources = ARRAY_SIZE(gpio_resources),
  165. .resources = gpio_resources,
  166. },
  167. {
  168. .name = "bxt_wcove_region",
  169. },
  170. };
  171. static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
  172. unsigned int *val)
  173. {
  174. int ret;
  175. int i2c_addr;
  176. u8 ipc_in[2];
  177. u8 ipc_out[4];
  178. struct intel_soc_pmic *pmic = context;
  179. if (reg & REG_ADDR_MASK)
  180. i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
  181. else {
  182. i2c_addr = BXTWC_DEVICE1_ADDR;
  183. if (!i2c_addr) {
  184. dev_err(pmic->dev, "I2C address not set\n");
  185. return -EINVAL;
  186. }
  187. }
  188. reg &= REG_OFFSET_MASK;
  189. ipc_in[0] = reg;
  190. ipc_in[1] = i2c_addr;
  191. ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
  192. PMC_IPC_PMIC_ACCESS_READ,
  193. ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
  194. if (ret) {
  195. dev_err(pmic->dev, "Failed to read from PMIC\n");
  196. return ret;
  197. }
  198. *val = ipc_out[0];
  199. return 0;
  200. }
  201. static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
  202. unsigned int val)
  203. {
  204. int ret;
  205. int i2c_addr;
  206. u8 ipc_in[3];
  207. struct intel_soc_pmic *pmic = context;
  208. if (reg & REG_ADDR_MASK)
  209. i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
  210. else {
  211. i2c_addr = BXTWC_DEVICE1_ADDR;
  212. if (!i2c_addr) {
  213. dev_err(pmic->dev, "I2C address not set\n");
  214. return -EINVAL;
  215. }
  216. }
  217. reg &= REG_OFFSET_MASK;
  218. ipc_in[0] = reg;
  219. ipc_in[1] = i2c_addr;
  220. ipc_in[2] = val;
  221. ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
  222. PMC_IPC_PMIC_ACCESS_WRITE,
  223. ipc_in, sizeof(ipc_in), NULL, 0);
  224. if (ret) {
  225. dev_err(pmic->dev, "Failed to write to PMIC\n");
  226. return ret;
  227. }
  228. return 0;
  229. }
  230. /* sysfs interfaces to r/w PMIC registers, required by initial script */
  231. static unsigned long bxtwc_reg_addr;
  232. static ssize_t bxtwc_reg_show(struct device *dev,
  233. struct device_attribute *attr, char *buf)
  234. {
  235. return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
  236. }
  237. static ssize_t bxtwc_reg_store(struct device *dev,
  238. struct device_attribute *attr, const char *buf, size_t count)
  239. {
  240. if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
  241. dev_err(dev, "Invalid register address\n");
  242. return -EINVAL;
  243. }
  244. return (ssize_t)count;
  245. }
  246. static ssize_t bxtwc_val_show(struct device *dev,
  247. struct device_attribute *attr, char *buf)
  248. {
  249. int ret;
  250. unsigned int val;
  251. struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
  252. ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
  253. if (ret < 0) {
  254. dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
  255. return -EIO;
  256. }
  257. return sprintf(buf, "0x%02x\n", val);
  258. }
  259. static ssize_t bxtwc_val_store(struct device *dev,
  260. struct device_attribute *attr, const char *buf, size_t count)
  261. {
  262. int ret;
  263. unsigned int val;
  264. struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
  265. ret = kstrtouint(buf, 0, &val);
  266. if (ret)
  267. return ret;
  268. ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
  269. if (ret) {
  270. dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
  271. val, bxtwc_reg_addr);
  272. return -EIO;
  273. }
  274. return count;
  275. }
  276. static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store);
  277. static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store);
  278. static struct attribute *bxtwc_attrs[] = {
  279. &dev_attr_addr.attr,
  280. &dev_attr_val.attr,
  281. NULL
  282. };
  283. static const struct attribute_group bxtwc_group = {
  284. .attrs = bxtwc_attrs,
  285. };
  286. static const struct regmap_config bxtwc_regmap_config = {
  287. .reg_bits = 16,
  288. .val_bits = 8,
  289. .reg_write = regmap_ipc_byte_reg_write,
  290. .reg_read = regmap_ipc_byte_reg_read,
  291. };
  292. static int bxtwc_probe(struct platform_device *pdev)
  293. {
  294. int ret;
  295. acpi_handle handle;
  296. acpi_status status;
  297. unsigned long long hrv;
  298. struct intel_soc_pmic *pmic;
  299. handle = ACPI_HANDLE(&pdev->dev);
  300. status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
  301. if (ACPI_FAILURE(status)) {
  302. dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
  303. return -ENODEV;
  304. }
  305. if (hrv != BROXTON_PMIC_WC_HRV) {
  306. dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
  307. hrv);
  308. return -ENODEV;
  309. }
  310. pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
  311. if (!pmic)
  312. return -ENOMEM;
  313. ret = platform_get_irq(pdev, 0);
  314. if (ret < 0) {
  315. dev_err(&pdev->dev, "Invalid IRQ\n");
  316. return ret;
  317. }
  318. pmic->irq = ret;
  319. dev_set_drvdata(&pdev->dev, pmic);
  320. pmic->dev = &pdev->dev;
  321. pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
  322. &bxtwc_regmap_config);
  323. if (IS_ERR(pmic->regmap)) {
  324. ret = PTR_ERR(pmic->regmap);
  325. dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
  326. return ret;
  327. }
  328. ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
  329. IRQF_ONESHOT | IRQF_SHARED,
  330. 0, &bxtwc_regmap_irq_chip,
  331. &pmic->irq_chip_data);
  332. if (ret) {
  333. dev_err(&pdev->dev, "Failed to add IRQ chip\n");
  334. return ret;
  335. }
  336. ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
  337. IRQF_ONESHOT | IRQF_SHARED,
  338. 0, &bxtwc_regmap_irq_chip_level2,
  339. &pmic->irq_chip_data_level2);
  340. if (ret) {
  341. dev_err(&pdev->dev, "Failed to add secondary IRQ chip\n");
  342. goto err_irq_chip_level2;
  343. }
  344. ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
  345. ARRAY_SIZE(bxt_wc_dev), NULL, 0,
  346. NULL);
  347. if (ret) {
  348. dev_err(&pdev->dev, "Failed to add devices\n");
  349. goto err_mfd;
  350. }
  351. ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
  352. if (ret) {
  353. dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
  354. goto err_sysfs;
  355. }
  356. return 0;
  357. err_sysfs:
  358. mfd_remove_devices(&pdev->dev);
  359. err_mfd:
  360. regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
  361. err_irq_chip_level2:
  362. regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
  363. return ret;
  364. }
  365. static int bxtwc_remove(struct platform_device *pdev)
  366. {
  367. struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
  368. sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
  369. mfd_remove_devices(&pdev->dev);
  370. regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
  371. regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
  372. return 0;
  373. }
  374. static void bxtwc_shutdown(struct platform_device *pdev)
  375. {
  376. struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
  377. disable_irq(pmic->irq);
  378. }
  379. #ifdef CONFIG_PM_SLEEP
  380. static int bxtwc_suspend(struct device *dev)
  381. {
  382. struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
  383. disable_irq(pmic->irq);
  384. return 0;
  385. }
  386. static int bxtwc_resume(struct device *dev)
  387. {
  388. struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
  389. enable_irq(pmic->irq);
  390. return 0;
  391. }
  392. #endif
  393. static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
  394. static const struct acpi_device_id bxtwc_acpi_ids[] = {
  395. { "INT34D3", },
  396. { }
  397. };
  398. MODULE_DEVICE_TABLE(acpi, pmic_acpi_ids);
  399. static struct platform_driver bxtwc_driver = {
  400. .probe = bxtwc_probe,
  401. .remove = bxtwc_remove,
  402. .shutdown = bxtwc_shutdown,
  403. .driver = {
  404. .name = "BXTWC PMIC",
  405. .pm = &bxtwc_pm_ops,
  406. .acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
  407. },
  408. };
  409. module_platform_driver(bxtwc_driver);
  410. MODULE_LICENSE("GPL v2");
  411. MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>");