intel_soc_pmic_mrfld.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Device access for Basin Cove PMIC
  4. *
  5. * Copyright (c) 2019, Intel Corporation.
  6. * Author: Andy Shevchenko <[email protected]>
  7. */
  8. #include <linux/acpi.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/mfd/core.h>
  11. #include <linux/mfd/intel_soc_pmic.h>
  12. #include <linux/mfd/intel_soc_pmic_mrfld.h>
  13. #include <linux/module.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/regmap.h>
  16. #include <asm/intel_scu_ipc.h>
  17. /*
  18. * Level 2 IRQs
  19. *
  20. * Firmware on the systems with Basin Cove PMIC services Level 1 IRQs
  21. * without an assistance. Thus, each of the Level 1 IRQ is represented
  22. * as a separate RTE in IOAPIC.
  23. */
  24. static struct resource irq_level2_resources[] = {
  25. DEFINE_RES_IRQ(0), /* power button */
  26. DEFINE_RES_IRQ(0), /* TMU */
  27. DEFINE_RES_IRQ(0), /* thermal */
  28. DEFINE_RES_IRQ(0), /* BCU */
  29. DEFINE_RES_IRQ(0), /* ADC */
  30. DEFINE_RES_IRQ(0), /* charger */
  31. DEFINE_RES_IRQ(0), /* GPIO */
  32. };
  33. static const struct mfd_cell bcove_dev[] = {
  34. {
  35. .name = "mrfld_bcove_pwrbtn",
  36. .num_resources = 1,
  37. .resources = &irq_level2_resources[0],
  38. }, {
  39. .name = "mrfld_bcove_tmu",
  40. .num_resources = 1,
  41. .resources = &irq_level2_resources[1],
  42. }, {
  43. .name = "mrfld_bcove_thermal",
  44. .num_resources = 1,
  45. .resources = &irq_level2_resources[2],
  46. }, {
  47. .name = "mrfld_bcove_bcu",
  48. .num_resources = 1,
  49. .resources = &irq_level2_resources[3],
  50. }, {
  51. .name = "mrfld_bcove_adc",
  52. .num_resources = 1,
  53. .resources = &irq_level2_resources[4],
  54. }, {
  55. .name = "mrfld_bcove_charger",
  56. .num_resources = 1,
  57. .resources = &irq_level2_resources[5],
  58. }, {
  59. .name = "mrfld_bcove_pwrsrc",
  60. .num_resources = 1,
  61. .resources = &irq_level2_resources[5],
  62. }, {
  63. .name = "mrfld_bcove_gpio",
  64. .num_resources = 1,
  65. .resources = &irq_level2_resources[6],
  66. },
  67. { .name = "mrfld_bcove_region", },
  68. };
  69. static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
  70. unsigned int *val)
  71. {
  72. struct intel_soc_pmic *pmic = context;
  73. u8 ipc_out;
  74. int ret;
  75. ret = intel_scu_ipc_dev_ioread8(pmic->scu, reg, &ipc_out);
  76. if (ret)
  77. return ret;
  78. *val = ipc_out;
  79. return 0;
  80. }
  81. static int bcove_ipc_byte_reg_write(void *context, unsigned int reg,
  82. unsigned int val)
  83. {
  84. struct intel_soc_pmic *pmic = context;
  85. u8 ipc_in = val;
  86. return intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in);
  87. }
  88. static const struct regmap_config bcove_regmap_config = {
  89. .reg_bits = 16,
  90. .val_bits = 8,
  91. .max_register = 0xff,
  92. .reg_write = bcove_ipc_byte_reg_write,
  93. .reg_read = bcove_ipc_byte_reg_read,
  94. };
  95. static int bcove_probe(struct platform_device *pdev)
  96. {
  97. struct device *dev = &pdev->dev;
  98. struct intel_soc_pmic *pmic;
  99. unsigned int i;
  100. int ret;
  101. pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
  102. if (!pmic)
  103. return -ENOMEM;
  104. pmic->scu = devm_intel_scu_ipc_dev_get(dev);
  105. if (!pmic->scu)
  106. return -ENOMEM;
  107. platform_set_drvdata(pdev, pmic);
  108. pmic->dev = &pdev->dev;
  109. pmic->regmap = devm_regmap_init(dev, NULL, pmic, &bcove_regmap_config);
  110. if (IS_ERR(pmic->regmap))
  111. return PTR_ERR(pmic->regmap);
  112. for (i = 0; i < ARRAY_SIZE(irq_level2_resources); i++) {
  113. ret = platform_get_irq(pdev, i);
  114. if (ret < 0)
  115. return ret;
  116. irq_level2_resources[i].start = ret;
  117. irq_level2_resources[i].end = ret;
  118. }
  119. return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
  120. bcove_dev, ARRAY_SIZE(bcove_dev),
  121. NULL, 0, NULL);
  122. }
  123. static const struct acpi_device_id bcove_acpi_ids[] = {
  124. { "INTC100E" },
  125. {}
  126. };
  127. MODULE_DEVICE_TABLE(acpi, bcove_acpi_ids);
  128. static struct platform_driver bcove_driver = {
  129. .driver = {
  130. .name = "intel_soc_pmic_mrfld",
  131. .acpi_match_table = bcove_acpi_ids,
  132. },
  133. .probe = bcove_probe,
  134. };
  135. module_platform_driver(bcove_driver);
  136. MODULE_DESCRIPTION("IPC driver for Intel SoC Basin Cove PMIC");
  137. MODULE_LICENSE("GPL v2");