rohm-bd9576.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2021 ROHM Semiconductors
  4. *
  5. * ROHM BD9576MUF and BD9573MUF PMIC driver
  6. */
  7. #include <linux/i2c.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/ioport.h>
  10. #include <linux/irq.h>
  11. #include <linux/mfd/core.h>
  12. #include <linux/mfd/rohm-bd957x.h>
  13. #include <linux/mfd/rohm-generic.h>
  14. #include <linux/module.h>
  15. #include <linux/of_device.h>
  16. #include <linux/regmap.h>
  17. #include <linux/types.h>
  18. enum {
  19. BD957X_REGULATOR_CELL,
  20. BD957X_WDT_CELL,
  21. };
  22. /*
  23. * Due to the BD9576MUF nasty IRQ behaviour we don't always populate IRQs.
  24. * These will be added to regulator resources only if IRQ information for the
  25. * PMIC is populated in device-tree.
  26. */
  27. static const struct resource bd9576_regulator_irqs[] = {
  28. DEFINE_RES_IRQ_NAMED(BD9576_INT_THERM, "bd9576-temp"),
  29. DEFINE_RES_IRQ_NAMED(BD9576_INT_OVD, "bd9576-ovd"),
  30. DEFINE_RES_IRQ_NAMED(BD9576_INT_UVD, "bd9576-uvd"),
  31. };
  32. static struct mfd_cell bd9573_mfd_cells[] = {
  33. [BD957X_REGULATOR_CELL] = { .name = "bd9573-regulator", },
  34. [BD957X_WDT_CELL] = { .name = "bd9576-wdt", },
  35. };
  36. static struct mfd_cell bd9576_mfd_cells[] = {
  37. [BD957X_REGULATOR_CELL] = { .name = "bd9576-regulator", },
  38. [BD957X_WDT_CELL] = { .name = "bd9576-wdt", },
  39. };
  40. static const struct regmap_range volatile_ranges[] = {
  41. regmap_reg_range(BD957X_REG_SMRB_ASSERT, BD957X_REG_SMRB_ASSERT),
  42. regmap_reg_range(BD957X_REG_PMIC_INTERNAL_STAT,
  43. BD957X_REG_PMIC_INTERNAL_STAT),
  44. regmap_reg_range(BD957X_REG_INT_THERM_STAT, BD957X_REG_INT_THERM_STAT),
  45. regmap_reg_range(BD957X_REG_INT_OVP_STAT, BD957X_REG_INT_SYS_STAT),
  46. regmap_reg_range(BD957X_REG_INT_MAIN_STAT, BD957X_REG_INT_MAIN_STAT),
  47. };
  48. static const struct regmap_access_table volatile_regs = {
  49. .yes_ranges = &volatile_ranges[0],
  50. .n_yes_ranges = ARRAY_SIZE(volatile_ranges),
  51. };
  52. static struct regmap_config bd957x_regmap = {
  53. .reg_bits = 8,
  54. .val_bits = 8,
  55. .volatile_table = &volatile_regs,
  56. .max_register = BD957X_MAX_REGISTER,
  57. .cache_type = REGCACHE_RBTREE,
  58. };
  59. static struct regmap_irq bd9576_irqs[] = {
  60. REGMAP_IRQ_REG(BD9576_INT_THERM, 0, BD957X_MASK_INT_MAIN_THERM),
  61. REGMAP_IRQ_REG(BD9576_INT_OVP, 0, BD957X_MASK_INT_MAIN_OVP),
  62. REGMAP_IRQ_REG(BD9576_INT_SCP, 0, BD957X_MASK_INT_MAIN_SCP),
  63. REGMAP_IRQ_REG(BD9576_INT_OCP, 0, BD957X_MASK_INT_MAIN_OCP),
  64. REGMAP_IRQ_REG(BD9576_INT_OVD, 0, BD957X_MASK_INT_MAIN_OVD),
  65. REGMAP_IRQ_REG(BD9576_INT_UVD, 0, BD957X_MASK_INT_MAIN_UVD),
  66. REGMAP_IRQ_REG(BD9576_INT_UVP, 0, BD957X_MASK_INT_MAIN_UVP),
  67. REGMAP_IRQ_REG(BD9576_INT_SYS, 0, BD957X_MASK_INT_MAIN_SYS),
  68. };
  69. static struct regmap_irq_chip bd9576_irq_chip = {
  70. .name = "bd9576_irq",
  71. .irqs = &bd9576_irqs[0],
  72. .num_irqs = ARRAY_SIZE(bd9576_irqs),
  73. .status_base = BD957X_REG_INT_MAIN_STAT,
  74. .mask_base = BD957X_REG_INT_MAIN_MASK,
  75. .ack_base = BD957X_REG_INT_MAIN_STAT,
  76. .init_ack_masked = true,
  77. .num_regs = 1,
  78. .irq_reg_stride = 1,
  79. };
  80. static int bd957x_i2c_probe(struct i2c_client *i2c,
  81. const struct i2c_device_id *id)
  82. {
  83. int ret;
  84. struct regmap *regmap;
  85. struct mfd_cell *cells;
  86. int num_cells;
  87. unsigned long chip_type;
  88. struct irq_domain *domain;
  89. bool usable_irqs;
  90. chip_type = (unsigned long)of_device_get_match_data(&i2c->dev);
  91. switch (chip_type) {
  92. case ROHM_CHIP_TYPE_BD9576:
  93. cells = bd9576_mfd_cells;
  94. num_cells = ARRAY_SIZE(bd9576_mfd_cells);
  95. usable_irqs = !!i2c->irq;
  96. break;
  97. case ROHM_CHIP_TYPE_BD9573:
  98. cells = bd9573_mfd_cells;
  99. num_cells = ARRAY_SIZE(bd9573_mfd_cells);
  100. /*
  101. * BD9573 only supports fatal IRQs which we can not handle
  102. * because SoC is going to lose the power.
  103. */
  104. usable_irqs = false;
  105. break;
  106. default:
  107. dev_err(&i2c->dev, "Unknown device type");
  108. return -EINVAL;
  109. }
  110. regmap = devm_regmap_init_i2c(i2c, &bd957x_regmap);
  111. if (IS_ERR(regmap)) {
  112. dev_err(&i2c->dev, "Failed to initialize Regmap\n");
  113. return PTR_ERR(regmap);
  114. }
  115. /*
  116. * BD9576 behaves badly. It kepts IRQ line asserted for the whole
  117. * duration of detected HW condition (like over temperature). So we
  118. * don't require IRQ to be populated.
  119. * If IRQ information is not given, then we mask all IRQs and do not
  120. * provide IRQ resources to regulator driver - which then just omits
  121. * the notifiers.
  122. */
  123. if (usable_irqs) {
  124. struct regmap_irq_chip_data *irq_data;
  125. struct mfd_cell *regulators;
  126. regulators = &bd9576_mfd_cells[BD957X_REGULATOR_CELL];
  127. regulators->resources = bd9576_regulator_irqs;
  128. regulators->num_resources = ARRAY_SIZE(bd9576_regulator_irqs);
  129. ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq,
  130. IRQF_ONESHOT, 0,
  131. &bd9576_irq_chip, &irq_data);
  132. if (ret) {
  133. dev_err(&i2c->dev, "Failed to add IRQ chip\n");
  134. return ret;
  135. }
  136. domain = regmap_irq_get_domain(irq_data);
  137. } else {
  138. ret = regmap_update_bits(regmap, BD957X_REG_INT_MAIN_MASK,
  139. BD957X_MASK_INT_ALL,
  140. BD957X_MASK_INT_ALL);
  141. if (ret)
  142. return ret;
  143. domain = NULL;
  144. }
  145. ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, cells,
  146. num_cells, NULL, 0, domain);
  147. if (ret)
  148. dev_err(&i2c->dev, "Failed to create subdevices\n");
  149. return ret;
  150. }
  151. static const struct of_device_id bd957x_of_match[] = {
  152. { .compatible = "rohm,bd9576", .data = (void *)ROHM_CHIP_TYPE_BD9576, },
  153. { .compatible = "rohm,bd9573", .data = (void *)ROHM_CHIP_TYPE_BD9573, },
  154. { },
  155. };
  156. MODULE_DEVICE_TABLE(of, bd957x_of_match);
  157. static struct i2c_driver bd957x_drv = {
  158. .driver = {
  159. .name = "rohm-bd957x",
  160. .of_match_table = bd957x_of_match,
  161. },
  162. .probe = &bd957x_i2c_probe,
  163. };
  164. module_i2c_driver(bd957x_drv);
  165. MODULE_AUTHOR("Matti Vaittinen <[email protected]>");
  166. MODULE_DESCRIPTION("ROHM BD9576MUF and BD9573MUF Power Management IC driver");
  167. MODULE_LICENSE("GPL");