fan53555.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) 2018 Theobroma Systems Design und Consulting GmbH
  4. */
  5. #include <common.h>
  6. #include <bitfield.h>
  7. #include <errno.h>
  8. #include <dm.h>
  9. #include <fdtdec.h>
  10. #include <i2c.h>
  11. #include <log.h>
  12. #include <asm/gpio.h>
  13. #include <linux/bitops.h>
  14. #include <power/fan53555.h>
  15. #include <power/pmic.h>
  16. #include <power/regulator.h>
  17. /**
  18. * struct ic_types - definition of fan53555-family devices
  19. *
  20. * @die_id: Identifies the DIE_ID (lower nibble of the ID1 register)
  21. * @die_rev: Identifies the DIE_REV (lower nibble of the ID2 register)
  22. * @vsel_min: starting voltage (step 0) in uV
  23. * @vsel_step: increment of the voltage in uV
  24. *
  25. * The voltage ramp (i.e. minimum voltage and step) is selected from the
  26. * combination of 2 nibbles: DIE_ID and DIE_REV.
  27. *
  28. * See http://www.onsemi.com/pub/Collateral/FAN53555-D.pdf for details.
  29. */
  30. static const struct {
  31. unsigned int vendor;
  32. u8 die_id;
  33. u8 die_rev;
  34. bool check_rev;
  35. u32 vsel_min;
  36. u32 vsel_step;
  37. } ic_types[] = {
  38. /* Option 00 */
  39. { FAN53555_VENDOR_FAIRCHILD, 0x0, 0x3, true, 600000, 10000 },
  40. /* Option 13 */
  41. { FAN53555_VENDOR_FAIRCHILD, 0x0, 0xf, true, 800000, 10000 },
  42. /* Option 23 */
  43. { FAN53555_VENDOR_FAIRCHILD, 0x0, 0xc, true, 600000, 12500 },
  44. /* Option 01 */
  45. { FAN53555_VENDOR_FAIRCHILD, 0x1, 0x3, true, 600000, 10000 },
  46. /* Option 03 */
  47. { FAN53555_VENDOR_FAIRCHILD, 0x3, 0x3, true, 600000, 10000 },
  48. /* Option 04 */
  49. { FAN53555_VENDOR_FAIRCHILD, 0x4, 0xf, true, 603000, 12826 },
  50. /* Option 05 */
  51. { FAN53555_VENDOR_FAIRCHILD, 0x5, 0x3, true, 600000, 10000 },
  52. /* Option 08 */
  53. { FAN53555_VENDOR_FAIRCHILD, 0x8, 0x1, true, 600000, 10000 },
  54. /* Option 08 */
  55. { FAN53555_VENDOR_FAIRCHILD, 0x8, 0xf, true, 600000, 10000 },
  56. /* Option 09 */
  57. { FAN53555_VENDOR_FAIRCHILD, 0xc, 0xf, true, 603000, 12826 },
  58. /* SYL82X */
  59. { FAN53555_VENDOR_SILERGY, 0x8, 0x0, false, 712500, 12500 },
  60. /* SYL83X */
  61. { FAN53555_VENDOR_SILERGY, 0x9, 0x0, false, 712500, 12500 },
  62. };
  63. /* I2C-accessible byte-sized registers */
  64. enum {
  65. /* Voltage setting */
  66. FAN53555_VSEL0 = 0x00,
  67. FAN53555_VSEL1,
  68. /* Control register */
  69. FAN53555_CONTROL,
  70. /* IC Type */
  71. FAN53555_ID1,
  72. /* IC mask version */
  73. FAN53555_ID2,
  74. /* Monitor register */
  75. FAN53555_MONITOR,
  76. };
  77. struct fan53555_plat {
  78. /* Voltage setting register */
  79. unsigned int vol_reg;
  80. unsigned int sleep_reg;
  81. };
  82. struct fan53555_priv {
  83. /* IC Vendor */
  84. unsigned int vendor;
  85. /* IC Type and Rev */
  86. unsigned int die_id;
  87. unsigned int die_rev;
  88. /* Voltage range and step(linear) */
  89. unsigned int vsel_min;
  90. unsigned int vsel_step;
  91. /* Voltage slew rate limiting */
  92. unsigned int slew_rate;
  93. /* Sleep voltage cache */
  94. unsigned int sleep_vol_cache;
  95. };
  96. static int fan53555_regulator_of_to_plat(struct udevice *dev)
  97. {
  98. struct fan53555_plat *dev_pdata = dev_get_plat(dev);
  99. struct dm_regulator_uclass_plat *uc_pdata =
  100. dev_get_uclass_plat(dev);
  101. u32 sleep_vsel;
  102. /* This is a buck regulator */
  103. uc_pdata->type = REGULATOR_TYPE_BUCK;
  104. sleep_vsel = dev_read_u32_default(dev, "fcs,suspend-voltage-selector",
  105. FAN53555_VSEL1);
  106. /*
  107. * Depending on the device-tree settings, the 'normal mode'
  108. * voltage is either controlled by VSEL0 or VSEL1.
  109. */
  110. switch (sleep_vsel) {
  111. case FAN53555_VSEL0:
  112. dev_pdata->sleep_reg = FAN53555_VSEL0;
  113. dev_pdata->vol_reg = FAN53555_VSEL1;
  114. break;
  115. case FAN53555_VSEL1:
  116. dev_pdata->sleep_reg = FAN53555_VSEL1;
  117. dev_pdata->vol_reg = FAN53555_VSEL0;
  118. break;
  119. default:
  120. pr_err("%s: invalid vsel id %d\n", dev->name, sleep_vsel);
  121. return -EINVAL;
  122. }
  123. return 0;
  124. }
  125. static int fan53555_regulator_get_value(struct udevice *dev)
  126. {
  127. struct fan53555_plat *pdata = dev_get_plat(dev);
  128. struct fan53555_priv *priv = dev_get_priv(dev);
  129. int reg;
  130. int voltage;
  131. /* We only support a single voltage selector (i.e. 'normal' mode). */
  132. reg = pmic_reg_read(dev->parent, pdata->vol_reg);
  133. if (reg < 0)
  134. return reg;
  135. voltage = priv->vsel_min + (reg & 0x3f) * priv->vsel_step;
  136. debug("%s: %d uV\n", __func__, voltage);
  137. return voltage;
  138. }
  139. static int fan53555_regulator_set_value(struct udevice *dev, int uV)
  140. {
  141. struct fan53555_plat *pdata = dev_get_plat(dev);
  142. struct fan53555_priv *priv = dev_get_priv(dev);
  143. u8 vol;
  144. vol = (uV - priv->vsel_min) / priv->vsel_step;
  145. debug("%s: uV=%d; writing volume %d: %02x\n",
  146. __func__, uV, pdata->vol_reg, vol);
  147. return pmic_clrsetbits(dev->parent, pdata->vol_reg, GENMASK(6, 0), vol);
  148. }
  149. static int fan53555_voltages_setup(struct udevice *dev)
  150. {
  151. struct fan53555_priv *priv = dev_get_priv(dev);
  152. int i;
  153. /* Init voltage range and step */
  154. for (i = 0; i < ARRAY_SIZE(ic_types); ++i) {
  155. if (ic_types[i].vendor != priv->vendor)
  156. continue;
  157. if (ic_types[i].die_id != priv->die_id)
  158. continue;
  159. if (ic_types[i].check_rev &&
  160. ic_types[i].die_rev != priv->die_rev)
  161. continue;
  162. priv->vsel_min = ic_types[i].vsel_min;
  163. priv->vsel_step = ic_types[i].vsel_step;
  164. return 0;
  165. }
  166. pr_err("%s: %s: die id %d rev %d not supported!\n",
  167. dev->name, __func__, priv->die_id, priv->die_rev);
  168. return -EINVAL;
  169. }
  170. enum {
  171. DIE_ID_SHIFT = 0,
  172. DIE_ID_WIDTH = 4,
  173. DIE_REV_SHIFT = 0,
  174. DIE_REV_WIDTH = 4,
  175. };
  176. static int fan53555_probe(struct udevice *dev)
  177. {
  178. struct fan53555_priv *priv = dev_get_priv(dev);
  179. int ID1, ID2;
  180. debug("%s\n", __func__);
  181. /* read chip ID1 and ID2 (two registers, starting at ID1) */
  182. ID1 = pmic_reg_read(dev->parent, FAN53555_ID1);
  183. if (ID1 < 0)
  184. return ID1;
  185. ID2 = pmic_reg_read(dev->parent, FAN53555_ID2);
  186. if (ID2 < 0)
  187. return ID2;
  188. /* extract vendor, die_id and die_rev */
  189. priv->vendor = dev->driver_data;
  190. priv->die_id = ID1 & GENMASK(3, 0);
  191. priv->die_rev = ID2 & GENMASK(3, 0);
  192. if (fan53555_voltages_setup(dev) < 0)
  193. return -ENODATA;
  194. debug("%s: FAN53555 option %d rev %d detected\n",
  195. __func__, priv->die_id, priv->die_rev);
  196. return 0;
  197. }
  198. static const struct dm_regulator_ops fan53555_regulator_ops = {
  199. .get_value = fan53555_regulator_get_value,
  200. .set_value = fan53555_regulator_set_value,
  201. };
  202. U_BOOT_DRIVER(fan53555_regulator) = {
  203. .name = "fan53555_regulator",
  204. .id = UCLASS_REGULATOR,
  205. .ops = &fan53555_regulator_ops,
  206. .of_to_plat = fan53555_regulator_of_to_plat,
  207. .plat_auto = sizeof(struct fan53555_plat),
  208. .priv_auto = sizeof(struct fan53555_priv),
  209. .probe = fan53555_probe,
  210. };