stpmic2.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /*
  2. * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include <common/debug.h>
  10. #include <drivers/st/stpmic2.h>
  11. #define RET_SUCCESS 0
  12. #define RET_ERROR_NOT_SUPPORTED -1
  13. #define RET_ERROR_GENERIC -2
  14. #define RET_ERROR_BAD_PARAMETERS -3
  15. #define I2C_TIMEOUT_MS 25
  16. #define VOLTAGE_INDEX_INVALID ((size_t)~0U)
  17. struct regul_struct {
  18. const char *name;
  19. const uint16_t *volt_table;
  20. uint8_t volt_table_size;
  21. uint8_t volt_cr;
  22. uint8_t volt_shift;
  23. uint8_t en_cr;
  24. uint8_t alt_en_cr;
  25. uint8_t msrt_reg;
  26. uint8_t msrt_mask;
  27. uint8_t pd_reg;
  28. uint8_t pd_val;
  29. uint8_t ocp_reg;
  30. uint8_t ocp_mask;
  31. };
  32. /* Voltage tables in mV */
  33. static const uint16_t buck1236_volt_table[] = {
  34. 500U, 510U, 520U, 530U, 540U, 550U, 560U, 570U, 580U, 590U,
  35. 600U, 610U, 620U, 630U, 640U, 650U, 660U, 670U, 680U, 690U,
  36. 700U, 710U, 720U, 730U, 740U, 750U, 760U, 770U, 780U, 790U,
  37. 800U, 810U, 820U, 830U, 840U, 850U, 860U, 870U, 880U, 890U,
  38. 900U, 910U, 920U, 930U, 940U, 950U, 960U, 970U, 980U, 990U,
  39. 1000U, 1010U, 1020U, 1030U, 1040U, 1050U, 1060U, 1070U, 1080U, 1090U,
  40. 1100U, 1110U, 1120U, 1130U, 1140U, 1150U, 1160U, 1170U, 1180U, 1190U,
  41. 1200U, 1210U, 1220U, 1230U, 1240U, 1250U, 1260U, 1270U, 1280U, 1290U,
  42. 1300U, 1310U, 1320U, 1330U, 1340U, 1350U, 1360U, 1370U, 1380U, 1390U,
  43. 1400U, 1410U, 1420U, 1430U, 1440U, 1450U, 1460U, 1470U, 1480U, 1490U,
  44. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  45. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  46. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U
  47. };
  48. static const uint16_t buck457_volt_table[] = {
  49. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  50. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  51. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  52. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  53. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  54. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  55. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  56. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  57. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  58. 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
  59. 1500U, 1600U, 1700U, 1800U, 1900U, 2000U, 2100U, 2200U, 2300U, 2400U,
  60. 2500U, 2600U, 2700U, 2800U, 2900U, 3000U, 3100U, 3200U, 3300U, 3400U,
  61. 3500U, 3600U, 3700U, 3800U, 3900U, 4000U, 4100U, 4200U
  62. };
  63. static const uint16_t ldo235678_volt_table[] = {
  64. 900U, 1000U, 1100U, 1200U, 1300U, 1400U, 1500U, 1600U, 1700U, 1800U,
  65. 1900U, 2000U, 2100U, 2200U, 2300U, 2400U, 2500U, 2600U, 2700U, 2800U,
  66. 2900U, 3000U, 3100U, 3200U, 3300U, 3400U, 3500U, 3600U, 3700U, 3800U,
  67. 3900U, 4000U
  68. };
  69. static const uint16_t ldo1_volt_table[] = {
  70. 1800U,
  71. };
  72. static const uint16_t ldo4_volt_table[] = {
  73. 3300U,
  74. };
  75. static const uint16_t refddr_volt_table[] = {
  76. 0,
  77. };
  78. #define DEFINE_BUCK(regu_name, ID, pd, table) { \
  79. .name = regu_name, \
  80. .volt_table = table, \
  81. .volt_table_size = ARRAY_SIZE(table), \
  82. .en_cr = ID ## _MAIN_CR2, \
  83. .volt_cr = ID ## _MAIN_CR1, \
  84. .alt_en_cr = ID ## _ALT_CR2, \
  85. .msrt_reg = BUCKS_MRST_CR, \
  86. .msrt_mask = ID ## _MRST, \
  87. .pd_reg = pd, \
  88. .pd_val = ID ## _PD_FAST, \
  89. .ocp_reg = FS_OCP_CR1, \
  90. .ocp_mask = FS_OCP_ ## ID, \
  91. }
  92. #define DEFINE_LDOx(regu_name, ID, table) { \
  93. .name = regu_name, \
  94. .volt_table = table, \
  95. .volt_table_size = ARRAY_SIZE(table), \
  96. .volt_shift = LDO_VOLT_SHIFT, \
  97. .en_cr = ID ## _MAIN_CR, \
  98. .volt_cr = ID ## _MAIN_CR, \
  99. .alt_en_cr = ID ## _ALT_CR, \
  100. .msrt_reg = LDOS_MRST_CR, \
  101. .msrt_mask = ID ## _MRST, \
  102. .pd_reg = LDOS_PD_CR1, \
  103. .pd_val = ID ## _PD, \
  104. .ocp_reg = FS_OCP_CR2, \
  105. .ocp_mask = FS_OCP_ ## ID, \
  106. }
  107. #define DEFINE_REFDDR(regu_name, ID, table) { \
  108. .name = regu_name, \
  109. .volt_table = table, \
  110. .volt_table_size = ARRAY_SIZE(table), \
  111. .en_cr = ID ## _MAIN_CR, \
  112. .volt_cr = ID ## _MAIN_CR, \
  113. .alt_en_cr = ID ## _ALT_CR, \
  114. .msrt_reg = BUCKS_MRST_CR, \
  115. .msrt_mask = ID ## _MRST, \
  116. .pd_reg = LDOS_PD_CR2, \
  117. .pd_val = ID ## _PD, \
  118. .ocp_reg = FS_OCP_CR1, \
  119. .ocp_mask = FS_OCP_ ## ID, \
  120. }
  121. /* Table of Regulators in PMIC SoC */
  122. static const struct regul_struct regul_table[STPMIC2_NB_REG] = {
  123. [STPMIC2_BUCK1] = DEFINE_BUCK("buck1", BUCK1, BUCKS_PD_CR1,
  124. buck1236_volt_table),
  125. [STPMIC2_BUCK2] = DEFINE_BUCK("buck2", BUCK2, BUCKS_PD_CR1,
  126. buck1236_volt_table),
  127. [STPMIC2_BUCK3] = DEFINE_BUCK("buck3", BUCK3, BUCKS_PD_CR1,
  128. buck1236_volt_table),
  129. [STPMIC2_BUCK4] = DEFINE_BUCK("buck4", BUCK4, BUCKS_PD_CR1,
  130. buck457_volt_table),
  131. [STPMIC2_BUCK5] = DEFINE_BUCK("buck5", BUCK5, BUCKS_PD_CR2,
  132. buck457_volt_table),
  133. [STPMIC2_BUCK6] = DEFINE_BUCK("buck6", BUCK6, BUCKS_PD_CR2,
  134. buck1236_volt_table),
  135. [STPMIC2_BUCK7] = DEFINE_BUCK("buck7", BUCK7, BUCKS_PD_CR2,
  136. buck457_volt_table),
  137. [STPMIC2_REFDDR] = DEFINE_REFDDR("refddr", REFDDR, refddr_volt_table),
  138. [STPMIC2_LDO1] = DEFINE_LDOx("ldo1", LDO1, ldo1_volt_table),
  139. [STPMIC2_LDO2] = DEFINE_LDOx("ldo2", LDO2, ldo235678_volt_table),
  140. [STPMIC2_LDO3] = DEFINE_LDOx("ldo3", LDO3, ldo235678_volt_table),
  141. [STPMIC2_LDO4] = DEFINE_LDOx("ldo4", LDO4, ldo4_volt_table),
  142. [STPMIC2_LDO5] = DEFINE_LDOx("ldo5", LDO5, ldo235678_volt_table),
  143. [STPMIC2_LDO6] = DEFINE_LDOx("ldo6", LDO6, ldo235678_volt_table),
  144. [STPMIC2_LDO7] = DEFINE_LDOx("ldo7", LDO7, ldo235678_volt_table),
  145. [STPMIC2_LDO8] = DEFINE_LDOx("ldo8", LDO8, ldo235678_volt_table),
  146. };
  147. int stpmic2_register_read(struct pmic_handle_s *pmic,
  148. uint8_t register_id, uint8_t *value)
  149. {
  150. int ret = stm32_i2c_mem_read(pmic->i2c_handle,
  151. pmic->i2c_addr,
  152. (uint16_t)register_id,
  153. I2C_MEMADD_SIZE_8BIT, value,
  154. 1, I2C_TIMEOUT_MS);
  155. if (ret != 0) {
  156. ERROR("Failed to read reg:0x%x\n", register_id);
  157. }
  158. return ret;
  159. }
  160. int stpmic2_register_write(struct pmic_handle_s *pmic,
  161. uint8_t register_id, uint8_t value)
  162. {
  163. uint8_t val = value;
  164. int ret = stm32_i2c_mem_write(pmic->i2c_handle,
  165. pmic->i2c_addr,
  166. (uint16_t)register_id,
  167. I2C_MEMADD_SIZE_8BIT, &val,
  168. 1, I2C_TIMEOUT_MS);
  169. if (ret != 0) {
  170. ERROR("Failed to write reg:0x%x\n", register_id);
  171. }
  172. return ret;
  173. }
  174. int stpmic2_register_update(struct pmic_handle_s *pmic,
  175. uint8_t register_id, uint8_t value, uint8_t mask)
  176. {
  177. int status;
  178. uint8_t val = 0U;
  179. status = stpmic2_register_read(pmic, register_id, &val);
  180. if (status != 0) {
  181. return status;
  182. }
  183. val = (val & ((uint8_t)~mask)) | (value & mask);
  184. VERBOSE("REG:0x%x v=0x%x mask=0x%x -> 0x%x\n",
  185. register_id, value, mask, val);
  186. return stpmic2_register_write(pmic, register_id, val);
  187. }
  188. int stpmic2_regulator_set_state(struct pmic_handle_s *pmic,
  189. uint8_t id, bool enable)
  190. {
  191. const struct regul_struct *regul = &regul_table[id];
  192. if (enable) {
  193. return stpmic2_register_update(pmic, regul->en_cr, 1U, 1U);
  194. } else {
  195. return stpmic2_register_update(pmic, regul->en_cr, 0, 1U);
  196. }
  197. }
  198. int stpmic2_regulator_get_state(struct pmic_handle_s *pmic,
  199. uint8_t id, bool *enabled)
  200. {
  201. const struct regul_struct *regul = &regul_table[id];
  202. uint8_t val;
  203. if (stpmic2_register_read(pmic, regul->en_cr, &val) != 0) {
  204. return RET_ERROR_GENERIC;
  205. }
  206. *enabled = (val & 1U) == 1U;
  207. return RET_SUCCESS;
  208. }
  209. int stpmic2_regulator_levels_mv(struct pmic_handle_s *pmic,
  210. uint8_t id, const uint16_t **levels,
  211. size_t *levels_count)
  212. {
  213. const struct regul_struct *regul = &regul_table[id];
  214. if (regul == NULL) {
  215. return RET_ERROR_BAD_PARAMETERS;
  216. }
  217. if (levels_count != NULL) {
  218. *levels_count = regul->volt_table_size;
  219. }
  220. if (levels != NULL) {
  221. *levels = regul->volt_table;
  222. }
  223. return RET_SUCCESS;
  224. }
  225. int stpmic2_regulator_get_voltage(struct pmic_handle_s *pmic,
  226. uint8_t id, uint16_t *val)
  227. {
  228. const struct regul_struct *regul = &regul_table[id];
  229. uint8_t value = 0U;
  230. uint8_t mask;
  231. if (regul->volt_table_size == 0U) {
  232. return RET_ERROR_GENERIC;
  233. }
  234. mask = regul->volt_table_size - 1U;
  235. if (mask != 0U) {
  236. if (stpmic2_register_read(pmic, regul->volt_cr, &value) != 0) {
  237. return RET_ERROR_GENERIC;
  238. }
  239. value = (value >> regul->volt_shift) & mask;
  240. }
  241. if (value > regul->volt_table_size) {
  242. return RET_ERROR_GENERIC;
  243. }
  244. *val = regul->volt_table[value];
  245. return RET_SUCCESS;
  246. }
  247. static size_t voltage_to_index(const struct regul_struct *regul,
  248. uint16_t millivolts)
  249. {
  250. unsigned int i;
  251. assert(regul->volt_table);
  252. for (i = 0U; i < regul->volt_table_size; i++) {
  253. if (regul->volt_table[i] == millivolts) {
  254. return i;
  255. }
  256. }
  257. return VOLTAGE_INDEX_INVALID;
  258. }
  259. int stpmic2_regulator_set_voltage(struct pmic_handle_s *pmic,
  260. uint8_t id, uint16_t millivolts)
  261. {
  262. const struct regul_struct *regul = &regul_table[id];
  263. size_t index;
  264. uint8_t mask;
  265. if (!regul->volt_table_size) {
  266. return RET_SUCCESS;
  267. }
  268. mask = regul->volt_table_size - 1U;
  269. index = voltage_to_index(regul, millivolts);
  270. if (index == VOLTAGE_INDEX_INVALID) {
  271. return RET_ERROR_GENERIC;
  272. }
  273. return stpmic2_register_update(pmic, regul->volt_cr,
  274. index << regul->volt_shift,
  275. mask << regul->volt_shift);
  276. }
  277. /* update both normal and alternate register */
  278. static int stpmic2_update_en_crs(struct pmic_handle_s *pmic, uint8_t id,
  279. uint8_t value, uint8_t mask)
  280. {
  281. const struct regul_struct *regul = &regul_table[id];
  282. if (stpmic2_register_update(pmic, regul->en_cr, value, mask) != 0) {
  283. return RET_ERROR_GENERIC;
  284. }
  285. if (stpmic2_register_update(pmic, regul->alt_en_cr, value, mask) != 0) {
  286. return RET_ERROR_GENERIC;
  287. }
  288. return RET_SUCCESS;
  289. }
  290. int stpmic2_regulator_get_prop(struct pmic_handle_s *pmic, uint8_t id,
  291. enum stpmic2_prop_id prop)
  292. {
  293. const struct regul_struct *regul = &regul_table[id];
  294. uint8_t val;
  295. VERBOSE("%s: get prop 0x%x\n", regul->name, prop);
  296. switch (prop) {
  297. case STPMIC2_BYPASS:
  298. if ((id <= STPMIC2_BUCK7) || (id == STPMIC2_LDO1) ||
  299. (id == STPMIC2_LDO4) || (id == STPMIC2_REFDDR)) {
  300. return 0;
  301. }
  302. if (stpmic2_register_read(pmic, regul->en_cr, &val) != 0) {
  303. return -EIO;
  304. }
  305. if ((val & LDO_BYPASS) != 0) {
  306. return 1;
  307. }
  308. break;
  309. default:
  310. ERROR("Invalid prop %u\n", prop);
  311. panic();
  312. }
  313. return 0;
  314. }
  315. int stpmic2_regulator_set_prop(struct pmic_handle_s *pmic, uint8_t id,
  316. enum stpmic2_prop_id prop, uint32_t arg)
  317. {
  318. const struct regul_struct *regul = &regul_table[id];
  319. VERBOSE("%s: set prop 0x%x arg=%u\n", regul->name, prop, arg);
  320. switch (prop) {
  321. case STPMIC2_PULL_DOWN:
  322. return stpmic2_register_update(pmic, regul->pd_reg,
  323. regul->pd_val,
  324. regul->pd_val);
  325. case STPMIC2_MASK_RESET:
  326. if (!regul->msrt_mask) {
  327. return RET_ERROR_NOT_SUPPORTED;
  328. }
  329. /* enable mask reset */
  330. return stpmic2_register_update(pmic, regul->msrt_reg,
  331. regul->msrt_mask,
  332. regul->msrt_mask);
  333. case STPMIC2_BYPASS:
  334. if ((id <= STPMIC2_BUCK7) || (id == STPMIC2_LDO1) ||
  335. (id == STPMIC2_LDO4) || (id == STPMIC2_REFDDR)) {
  336. return RET_ERROR_NOT_SUPPORTED;
  337. }
  338. /* clear sink source mode */
  339. if ((id == STPMIC2_LDO3) && (arg != 0U)) {
  340. if (stpmic2_update_en_crs(pmic, id, 0, LDO3_SNK_SRC) != 0) {
  341. return RET_ERROR_GENERIC;
  342. }
  343. }
  344. /* enable bypass mode */
  345. return stpmic2_update_en_crs(pmic, id,
  346. (arg != 0U) ? LDO_BYPASS : 0,
  347. LDO_BYPASS);
  348. case STPMIC2_SINK_SOURCE:
  349. if (id != STPMIC2_LDO3) {
  350. return RET_ERROR_NOT_SUPPORTED;
  351. }
  352. /* clear bypass mode */
  353. if (stpmic2_update_en_crs(pmic, id, 0, LDO_BYPASS) != 0) {
  354. return RET_ERROR_GENERIC;
  355. }
  356. return stpmic2_update_en_crs(pmic, id, LDO3_SNK_SRC,
  357. LDO3_SNK_SRC);
  358. case STPMIC2_OCP:
  359. return stpmic2_register_update(pmic, regul->ocp_reg,
  360. regul->ocp_mask,
  361. regul->ocp_mask);
  362. default:
  363. ERROR("Invalid prop %u\n", prop);
  364. panic();
  365. }
  366. return -EPERM;
  367. }
  368. #if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
  369. void stpmic2_dump_regulators(struct pmic_handle_s *pmic)
  370. {
  371. size_t i;
  372. char const *name;
  373. for (i = 0U; i < ARRAY_SIZE(regul_table); i++) {
  374. uint16_t val;
  375. bool state;
  376. if (!regul_table[i].volt_cr) {
  377. continue;
  378. }
  379. stpmic2_regulator_get_voltage(pmic, i, &val);
  380. stpmic2_regulator_get_state(pmic, i, &state);
  381. name = regul_table[i].name;
  382. VERBOSE("PMIC regul %s: %s, %dmV\n",
  383. name, state ? "EN" : "DIS", val);
  384. }
  385. }
  386. #endif
  387. int stpmic2_get_version(struct pmic_handle_s *pmic, uint8_t *val)
  388. {
  389. return stpmic2_register_read(pmic, VERSION_SR, val);
  390. }
  391. int stpmic2_get_product_id(struct pmic_handle_s *pmic, uint8_t *val)
  392. {
  393. return stpmic2_register_read(pmic, PRODUCT_ID, val);
  394. }