stpmic1.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /*
  2. * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <errno.h>
  7. #include <string.h>
  8. #include <common/debug.h>
  9. #include <drivers/st/stpmic1.h>
  10. #define I2C_TIMEOUT_MS 25
  11. struct regul_struct {
  12. const char *dt_node_name;
  13. const uint16_t *voltage_table;
  14. uint8_t voltage_table_size;
  15. uint8_t control_reg;
  16. uint8_t enable_mask;
  17. uint8_t low_power_reg;
  18. uint8_t pull_down_reg;
  19. uint8_t pull_down;
  20. uint8_t mask_reset_reg;
  21. uint8_t mask_reset;
  22. uint8_t icc_reg;
  23. uint8_t icc_mask;
  24. };
  25. static struct i2c_handle_s *pmic_i2c_handle;
  26. static uint16_t pmic_i2c_addr;
  27. /*
  28. * Special mode corresponds to LDO3 in sink source mode or in bypass mode.
  29. * LDO3 doesn't switch back from special to normal mode.
  30. */
  31. static bool ldo3_special_mode;
  32. /* Voltage tables in mV */
  33. static const uint16_t buck1_voltage_table[] = {
  34. 725,
  35. 725,
  36. 725,
  37. 725,
  38. 725,
  39. 725,
  40. 750,
  41. 775,
  42. 800,
  43. 825,
  44. 850,
  45. 875,
  46. 900,
  47. 925,
  48. 950,
  49. 975,
  50. 1000,
  51. 1025,
  52. 1050,
  53. 1075,
  54. 1100,
  55. 1125,
  56. 1150,
  57. 1175,
  58. 1200,
  59. 1225,
  60. 1250,
  61. 1275,
  62. 1300,
  63. 1325,
  64. 1350,
  65. 1375,
  66. 1400,
  67. 1425,
  68. 1450,
  69. 1475,
  70. 1500,
  71. 1500,
  72. 1500,
  73. 1500,
  74. 1500,
  75. 1500,
  76. 1500,
  77. 1500,
  78. 1500,
  79. 1500,
  80. 1500,
  81. 1500,
  82. 1500,
  83. 1500,
  84. 1500,
  85. 1500,
  86. 1500,
  87. 1500,
  88. 1500,
  89. 1500,
  90. 1500,
  91. 1500,
  92. 1500,
  93. 1500,
  94. 1500,
  95. 1500,
  96. 1500,
  97. 1500,
  98. };
  99. static const uint16_t buck2_voltage_table[] = {
  100. 1000,
  101. 1000,
  102. 1000,
  103. 1000,
  104. 1000,
  105. 1000,
  106. 1000,
  107. 1000,
  108. 1000,
  109. 1000,
  110. 1000,
  111. 1000,
  112. 1000,
  113. 1000,
  114. 1000,
  115. 1000,
  116. 1000,
  117. 1000,
  118. 1050,
  119. 1050,
  120. 1100,
  121. 1100,
  122. 1150,
  123. 1150,
  124. 1200,
  125. 1200,
  126. 1250,
  127. 1250,
  128. 1300,
  129. 1300,
  130. 1350,
  131. 1350,
  132. 1400,
  133. 1400,
  134. 1450,
  135. 1450,
  136. 1500,
  137. };
  138. static const uint16_t buck3_voltage_table[] = {
  139. 1000,
  140. 1000,
  141. 1000,
  142. 1000,
  143. 1000,
  144. 1000,
  145. 1000,
  146. 1000,
  147. 1000,
  148. 1000,
  149. 1000,
  150. 1000,
  151. 1000,
  152. 1000,
  153. 1000,
  154. 1000,
  155. 1000,
  156. 1000,
  157. 1000,
  158. 1000,
  159. 1100,
  160. 1100,
  161. 1100,
  162. 1100,
  163. 1200,
  164. 1200,
  165. 1200,
  166. 1200,
  167. 1300,
  168. 1300,
  169. 1300,
  170. 1300,
  171. 1400,
  172. 1400,
  173. 1400,
  174. 1400,
  175. 1500,
  176. 1600,
  177. 1700,
  178. 1800,
  179. 1900,
  180. 2000,
  181. 2100,
  182. 2200,
  183. 2300,
  184. 2400,
  185. 2500,
  186. 2600,
  187. 2700,
  188. 2800,
  189. 2900,
  190. 3000,
  191. 3100,
  192. 3200,
  193. 3300,
  194. 3400,
  195. };
  196. static const uint16_t buck4_voltage_table[] = {
  197. 600,
  198. 625,
  199. 650,
  200. 675,
  201. 700,
  202. 725,
  203. 750,
  204. 775,
  205. 800,
  206. 825,
  207. 850,
  208. 875,
  209. 900,
  210. 925,
  211. 950,
  212. 975,
  213. 1000,
  214. 1025,
  215. 1050,
  216. 1075,
  217. 1100,
  218. 1125,
  219. 1150,
  220. 1175,
  221. 1200,
  222. 1225,
  223. 1250,
  224. 1275,
  225. 1300,
  226. 1300,
  227. 1350,
  228. 1350,
  229. 1400,
  230. 1400,
  231. 1450,
  232. 1450,
  233. 1500,
  234. 1600,
  235. 1700,
  236. 1800,
  237. 1900,
  238. 2000,
  239. 2100,
  240. 2200,
  241. 2300,
  242. 2400,
  243. 2500,
  244. 2600,
  245. 2700,
  246. 2800,
  247. 2900,
  248. 3000,
  249. 3100,
  250. 3200,
  251. 3300,
  252. 3400,
  253. 3500,
  254. 3600,
  255. 3700,
  256. 3800,
  257. 3900,
  258. };
  259. static const uint16_t ldo1_voltage_table[] = {
  260. 1700,
  261. 1700,
  262. 1700,
  263. 1700,
  264. 1700,
  265. 1700,
  266. 1700,
  267. 1700,
  268. 1700,
  269. 1800,
  270. 1900,
  271. 2000,
  272. 2100,
  273. 2200,
  274. 2300,
  275. 2400,
  276. 2500,
  277. 2600,
  278. 2700,
  279. 2800,
  280. 2900,
  281. 3000,
  282. 3100,
  283. 3200,
  284. 3300,
  285. };
  286. static const uint16_t ldo2_voltage_table[] = {
  287. 1700,
  288. 1700,
  289. 1700,
  290. 1700,
  291. 1700,
  292. 1700,
  293. 1700,
  294. 1700,
  295. 1700,
  296. 1800,
  297. 1900,
  298. 2000,
  299. 2100,
  300. 2200,
  301. 2300,
  302. 2400,
  303. 2500,
  304. 2600,
  305. 2700,
  306. 2800,
  307. 2900,
  308. 3000,
  309. 3100,
  310. 3200,
  311. 3300,
  312. };
  313. static const uint16_t ldo3_voltage_table[] = {
  314. 1700,
  315. 1700,
  316. 1700,
  317. 1700,
  318. 1700,
  319. 1700,
  320. 1700,
  321. 1700,
  322. 1700,
  323. 1800,
  324. 1900,
  325. 2000,
  326. 2100,
  327. 2200,
  328. 2300,
  329. 2400,
  330. 2500,
  331. 2600,
  332. 2700,
  333. 2800,
  334. 2900,
  335. 3000,
  336. 3100,
  337. 3200,
  338. 3300,
  339. 3300,
  340. 3300,
  341. 3300,
  342. 3300,
  343. 3300,
  344. 3300,
  345. };
  346. /* Special mode table is used for sink source OR bypass mode */
  347. static const uint16_t ldo3_special_mode_table[] = {
  348. 0,
  349. };
  350. static const uint16_t ldo5_voltage_table[] = {
  351. 1700,
  352. 1700,
  353. 1700,
  354. 1700,
  355. 1700,
  356. 1700,
  357. 1700,
  358. 1700,
  359. 1700,
  360. 1800,
  361. 1900,
  362. 2000,
  363. 2100,
  364. 2200,
  365. 2300,
  366. 2400,
  367. 2500,
  368. 2600,
  369. 2700,
  370. 2800,
  371. 2900,
  372. 3000,
  373. 3100,
  374. 3200,
  375. 3300,
  376. 3400,
  377. 3500,
  378. 3600,
  379. 3700,
  380. 3800,
  381. 3900,
  382. };
  383. static const uint16_t ldo6_voltage_table[] = {
  384. 900,
  385. 1000,
  386. 1100,
  387. 1200,
  388. 1300,
  389. 1400,
  390. 1500,
  391. 1600,
  392. 1700,
  393. 1800,
  394. 1900,
  395. 2000,
  396. 2100,
  397. 2200,
  398. 2300,
  399. 2400,
  400. 2500,
  401. 2600,
  402. 2700,
  403. 2800,
  404. 2900,
  405. 3000,
  406. 3100,
  407. 3200,
  408. 3300,
  409. };
  410. static const uint16_t ldo4_voltage_table[] = {
  411. 3300,
  412. };
  413. static const uint16_t vref_ddr_voltage_table[] = {
  414. 3300,
  415. };
  416. static const uint16_t fixed_5v_voltage_table[] = {
  417. 5000,
  418. };
  419. /* Table of Regulators in PMIC SoC */
  420. static const struct regul_struct regulators_table[] = {
  421. {
  422. .dt_node_name = "buck1",
  423. .voltage_table = buck1_voltage_table,
  424. .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
  425. .control_reg = BUCK1_CONTROL_REG,
  426. .enable_mask = LDO_BUCK_ENABLE_MASK,
  427. .low_power_reg = BUCK1_PWRCTRL_REG,
  428. .pull_down_reg = BUCK_PULL_DOWN_REG,
  429. .pull_down = BUCK1_PULL_DOWN_SHIFT,
  430. .mask_reset_reg = MASK_RESET_BUCK_REG,
  431. .mask_reset = BUCK1_MASK_RESET,
  432. .icc_reg = BUCK_ICC_TURNOFF_REG,
  433. .icc_mask = BUCK1_ICC_SHIFT,
  434. },
  435. {
  436. .dt_node_name = "buck2",
  437. .voltage_table = buck2_voltage_table,
  438. .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
  439. .control_reg = BUCK2_CONTROL_REG,
  440. .enable_mask = LDO_BUCK_ENABLE_MASK,
  441. .low_power_reg = BUCK2_PWRCTRL_REG,
  442. .pull_down_reg = BUCK_PULL_DOWN_REG,
  443. .pull_down = BUCK2_PULL_DOWN_SHIFT,
  444. .mask_reset_reg = MASK_RESET_BUCK_REG,
  445. .mask_reset = BUCK2_MASK_RESET,
  446. .icc_reg = BUCK_ICC_TURNOFF_REG,
  447. .icc_mask = BUCK2_ICC_SHIFT,
  448. },
  449. {
  450. .dt_node_name = "buck3",
  451. .voltage_table = buck3_voltage_table,
  452. .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
  453. .control_reg = BUCK3_CONTROL_REG,
  454. .enable_mask = LDO_BUCK_ENABLE_MASK,
  455. .low_power_reg = BUCK3_PWRCTRL_REG,
  456. .pull_down_reg = BUCK_PULL_DOWN_REG,
  457. .pull_down = BUCK3_PULL_DOWN_SHIFT,
  458. .mask_reset_reg = MASK_RESET_BUCK_REG,
  459. .mask_reset = BUCK3_MASK_RESET,
  460. .icc_reg = BUCK_ICC_TURNOFF_REG,
  461. .icc_mask = BUCK3_ICC_SHIFT,
  462. },
  463. {
  464. .dt_node_name = "buck4",
  465. .voltage_table = buck4_voltage_table,
  466. .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
  467. .control_reg = BUCK4_CONTROL_REG,
  468. .enable_mask = LDO_BUCK_ENABLE_MASK,
  469. .low_power_reg = BUCK4_PWRCTRL_REG,
  470. .pull_down_reg = BUCK_PULL_DOWN_REG,
  471. .pull_down = BUCK4_PULL_DOWN_SHIFT,
  472. .mask_reset_reg = MASK_RESET_BUCK_REG,
  473. .mask_reset = BUCK4_MASK_RESET,
  474. .icc_reg = BUCK_ICC_TURNOFF_REG,
  475. .icc_mask = BUCK4_ICC_SHIFT,
  476. },
  477. {
  478. .dt_node_name = "ldo1",
  479. .voltage_table = ldo1_voltage_table,
  480. .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
  481. .control_reg = LDO1_CONTROL_REG,
  482. .enable_mask = LDO_BUCK_ENABLE_MASK,
  483. .low_power_reg = LDO1_PWRCTRL_REG,
  484. .mask_reset_reg = MASK_RESET_LDO_REG,
  485. .mask_reset = LDO1_MASK_RESET,
  486. .icc_reg = LDO_ICC_TURNOFF_REG,
  487. .icc_mask = LDO1_ICC_SHIFT,
  488. },
  489. {
  490. .dt_node_name = "ldo2",
  491. .voltage_table = ldo2_voltage_table,
  492. .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
  493. .control_reg = LDO2_CONTROL_REG,
  494. .enable_mask = LDO_BUCK_ENABLE_MASK,
  495. .low_power_reg = LDO2_PWRCTRL_REG,
  496. .mask_reset_reg = MASK_RESET_LDO_REG,
  497. .mask_reset = LDO2_MASK_RESET,
  498. .icc_reg = LDO_ICC_TURNOFF_REG,
  499. .icc_mask = LDO2_ICC_SHIFT,
  500. },
  501. {
  502. .dt_node_name = "ldo3",
  503. .voltage_table = ldo3_voltage_table,
  504. .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
  505. .control_reg = LDO3_CONTROL_REG,
  506. .enable_mask = LDO_BUCK_ENABLE_MASK,
  507. .low_power_reg = LDO3_PWRCTRL_REG,
  508. .mask_reset_reg = MASK_RESET_LDO_REG,
  509. .mask_reset = LDO3_MASK_RESET,
  510. .icc_reg = LDO_ICC_TURNOFF_REG,
  511. .icc_mask = LDO3_ICC_SHIFT,
  512. },
  513. {
  514. .dt_node_name = "ldo4",
  515. .voltage_table = ldo4_voltage_table,
  516. .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
  517. .control_reg = LDO4_CONTROL_REG,
  518. .enable_mask = LDO_BUCK_ENABLE_MASK,
  519. .low_power_reg = LDO4_PWRCTRL_REG,
  520. .mask_reset_reg = MASK_RESET_LDO_REG,
  521. .mask_reset = LDO4_MASK_RESET,
  522. .icc_reg = LDO_ICC_TURNOFF_REG,
  523. .icc_mask = LDO4_ICC_SHIFT,
  524. },
  525. {
  526. .dt_node_name = "ldo5",
  527. .voltage_table = ldo5_voltage_table,
  528. .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
  529. .control_reg = LDO5_CONTROL_REG,
  530. .enable_mask = LDO_BUCK_ENABLE_MASK,
  531. .low_power_reg = LDO5_PWRCTRL_REG,
  532. .mask_reset_reg = MASK_RESET_LDO_REG,
  533. .mask_reset = LDO5_MASK_RESET,
  534. .icc_reg = LDO_ICC_TURNOFF_REG,
  535. .icc_mask = LDO5_ICC_SHIFT,
  536. },
  537. {
  538. .dt_node_name = "ldo6",
  539. .voltage_table = ldo6_voltage_table,
  540. .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
  541. .control_reg = LDO6_CONTROL_REG,
  542. .enable_mask = LDO_BUCK_ENABLE_MASK,
  543. .low_power_reg = LDO6_PWRCTRL_REG,
  544. .mask_reset_reg = MASK_RESET_LDO_REG,
  545. .mask_reset = LDO6_MASK_RESET,
  546. .icc_reg = LDO_ICC_TURNOFF_REG,
  547. .icc_mask = LDO6_ICC_SHIFT,
  548. },
  549. {
  550. .dt_node_name = "vref_ddr",
  551. .voltage_table = vref_ddr_voltage_table,
  552. .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
  553. .control_reg = VREF_DDR_CONTROL_REG,
  554. .enable_mask = LDO_BUCK_ENABLE_MASK,
  555. .low_power_reg = VREF_DDR_PWRCTRL_REG,
  556. .mask_reset_reg = MASK_RESET_LDO_REG,
  557. .mask_reset = VREF_DDR_MASK_RESET,
  558. },
  559. {
  560. .dt_node_name = "boost",
  561. .voltage_table = fixed_5v_voltage_table,
  562. .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
  563. .control_reg = USB_CONTROL_REG,
  564. .enable_mask = BOOST_ENABLED,
  565. .icc_reg = BUCK_ICC_TURNOFF_REG,
  566. .icc_mask = BOOST_ICC_SHIFT,
  567. },
  568. {
  569. .dt_node_name = "pwr_sw1",
  570. .voltage_table = fixed_5v_voltage_table,
  571. .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
  572. .control_reg = USB_CONTROL_REG,
  573. .enable_mask = USBSW_OTG_SWITCH_ENABLED,
  574. .icc_reg = BUCK_ICC_TURNOFF_REG,
  575. .icc_mask = PWR_SW1_ICC_SHIFT,
  576. },
  577. {
  578. .dt_node_name = "pwr_sw2",
  579. .voltage_table = fixed_5v_voltage_table,
  580. .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
  581. .control_reg = USB_CONTROL_REG,
  582. .enable_mask = SWIN_SWOUT_ENABLED,
  583. .icc_reg = BUCK_ICC_TURNOFF_REG,
  584. .icc_mask = PWR_SW2_ICC_SHIFT,
  585. },
  586. };
  587. #define MAX_REGUL ARRAY_SIZE(regulators_table)
  588. static const struct regul_struct *get_regulator_data(const char *name)
  589. {
  590. uint8_t i;
  591. for (i = 0 ; i < MAX_REGUL ; i++) {
  592. if (strncmp(name, regulators_table[i].dt_node_name,
  593. strlen(regulators_table[i].dt_node_name)) == 0) {
  594. return &regulators_table[i];
  595. }
  596. }
  597. /* Regulator not found */
  598. panic();
  599. return NULL;
  600. }
  601. static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
  602. {
  603. const struct regul_struct *regul = get_regulator_data(name);
  604. uint8_t i;
  605. for (i = 0 ; i < regul->voltage_table_size ; i++) {
  606. if (regul->voltage_table[i] == millivolts) {
  607. return i;
  608. }
  609. }
  610. /* Voltage not found */
  611. panic();
  612. return 0;
  613. }
  614. int stpmic1_powerctrl_on(void)
  615. {
  616. return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
  617. PWRCTRL_PIN_VALID);
  618. }
  619. int stpmic1_switch_off(void)
  620. {
  621. return stpmic1_register_update(MAIN_CONTROL_REG, 1,
  622. SOFTWARE_SWITCH_OFF_ENABLED);
  623. }
  624. int stpmic1_regulator_enable(const char *name)
  625. {
  626. const struct regul_struct *regul = get_regulator_data(name);
  627. return stpmic1_register_update(regul->control_reg, regul->enable_mask,
  628. regul->enable_mask);
  629. }
  630. int stpmic1_regulator_disable(const char *name)
  631. {
  632. const struct regul_struct *regul = get_regulator_data(name);
  633. return stpmic1_register_update(regul->control_reg, 0,
  634. regul->enable_mask);
  635. }
  636. bool stpmic1_is_regulator_enabled(const char *name)
  637. {
  638. uint8_t val;
  639. const struct regul_struct *regul = get_regulator_data(name);
  640. if (stpmic1_register_read(regul->control_reg, &val) != 0) {
  641. panic();
  642. }
  643. return (val & regul->enable_mask) == regul->enable_mask;
  644. }
  645. int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
  646. {
  647. uint8_t voltage_index = voltage_to_index(name, millivolts);
  648. const struct regul_struct *regul = get_regulator_data(name);
  649. uint8_t mask;
  650. if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
  651. /*
  652. * when the LDO3 is in special mode, we do not change voltage,
  653. * because by setting voltage, the LDO would leaves sink-source
  654. * mode. There is obviously no reason to leave sink-source mode
  655. * at runtime.
  656. */
  657. return 0;
  658. }
  659. /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
  660. if (strncmp(name, "buck", 4) == 0) {
  661. mask = BUCK_VOLTAGE_MASK;
  662. } else if ((strncmp(name, "ldo", 3) == 0) &&
  663. (strncmp(name, "ldo4", 5) != 0)) {
  664. mask = LDO_VOLTAGE_MASK;
  665. } else {
  666. return 0;
  667. }
  668. return stpmic1_register_update(regul->control_reg,
  669. voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
  670. mask);
  671. }
  672. int stpmic1_regulator_pull_down_set(const char *name)
  673. {
  674. const struct regul_struct *regul = get_regulator_data(name);
  675. if (regul->pull_down_reg != 0) {
  676. return stpmic1_register_update(regul->pull_down_reg,
  677. BIT(regul->pull_down),
  678. LDO_BUCK_PULL_DOWN_MASK <<
  679. regul->pull_down);
  680. }
  681. return 0;
  682. }
  683. int stpmic1_regulator_mask_reset_set(const char *name)
  684. {
  685. const struct regul_struct *regul = get_regulator_data(name);
  686. if (regul->mask_reset_reg == 0U) {
  687. return -EPERM;
  688. }
  689. return stpmic1_register_update(regul->mask_reset_reg,
  690. BIT(regul->mask_reset),
  691. LDO_BUCK_RESET_MASK <<
  692. regul->mask_reset);
  693. }
  694. int stpmic1_regulator_icc_set(const char *name)
  695. {
  696. const struct regul_struct *regul = get_regulator_data(name);
  697. if (regul->mask_reset_reg == 0U) {
  698. return -EPERM;
  699. }
  700. return stpmic1_register_update(regul->icc_reg,
  701. BIT(regul->icc_mask),
  702. BIT(regul->icc_mask));
  703. }
  704. int stpmic1_regulator_sink_mode_set(const char *name)
  705. {
  706. if (strncmp(name, "ldo3", 5) != 0) {
  707. return -EPERM;
  708. }
  709. ldo3_special_mode = true;
  710. /* disable bypass mode, enable sink mode */
  711. return stpmic1_register_update(LDO3_CONTROL_REG,
  712. LDO3_DDR_SEL << LDO_BUCK_VOLTAGE_SHIFT,
  713. LDO3_BYPASS | LDO_VOLTAGE_MASK);
  714. }
  715. int stpmic1_regulator_bypass_mode_set(const char *name)
  716. {
  717. if (strncmp(name, "ldo3", 5) != 0) {
  718. return -EPERM;
  719. }
  720. ldo3_special_mode = true;
  721. /* enable bypass mode, disable sink mode */
  722. return stpmic1_register_update(LDO3_CONTROL_REG,
  723. LDO3_BYPASS,
  724. LDO3_BYPASS | LDO_VOLTAGE_MASK);
  725. }
  726. int stpmic1_active_discharge_mode_set(const char *name)
  727. {
  728. if (strncmp(name, "pwr_sw1", 8) == 0) {
  729. return stpmic1_register_update(USB_CONTROL_REG,
  730. VBUS_OTG_DISCHARGE,
  731. VBUS_OTG_DISCHARGE);
  732. }
  733. if (strncmp(name, "pwr_sw2", 8) == 0) {
  734. return stpmic1_register_update(USB_CONTROL_REG,
  735. SW_OUT_DISCHARGE,
  736. SW_OUT_DISCHARGE);
  737. }
  738. return -EPERM;
  739. }
  740. int stpmic1_regulator_levels_mv(const char *name, const uint16_t **levels,
  741. size_t *levels_count)
  742. {
  743. const struct regul_struct *regul = get_regulator_data(name);
  744. if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
  745. *levels_count = ARRAY_SIZE(ldo3_special_mode_table);
  746. *levels = ldo3_special_mode_table;
  747. } else {
  748. *levels_count = regul->voltage_table_size;
  749. *levels = regul->voltage_table;
  750. }
  751. return 0;
  752. }
  753. int stpmic1_regulator_voltage_get(const char *name)
  754. {
  755. const struct regul_struct *regul = get_regulator_data(name);
  756. uint8_t value;
  757. uint8_t mask;
  758. int status;
  759. if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
  760. return 0;
  761. }
  762. /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
  763. if (strncmp(name, "buck", 4) == 0) {
  764. mask = BUCK_VOLTAGE_MASK;
  765. } else if ((strncmp(name, "ldo", 3) == 0) &&
  766. (strncmp(name, "ldo4", 5) != 0)) {
  767. mask = LDO_VOLTAGE_MASK;
  768. } else {
  769. return 0;
  770. }
  771. status = stpmic1_register_read(regul->control_reg, &value);
  772. if (status < 0) {
  773. return status;
  774. }
  775. value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
  776. if (value > regul->voltage_table_size) {
  777. return -ERANGE;
  778. }
  779. return (int)regul->voltage_table[value];
  780. }
  781. int stpmic1_register_read(uint8_t register_id, uint8_t *value)
  782. {
  783. return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
  784. (uint16_t)register_id,
  785. I2C_MEMADD_SIZE_8BIT, value,
  786. 1, I2C_TIMEOUT_MS);
  787. }
  788. int stpmic1_register_write(uint8_t register_id, uint8_t value)
  789. {
  790. int status;
  791. status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
  792. (uint16_t)register_id,
  793. I2C_MEMADD_SIZE_8BIT, &value,
  794. 1, I2C_TIMEOUT_MS);
  795. #if ENABLE_ASSERTIONS
  796. if (status != 0) {
  797. return status;
  798. }
  799. if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
  800. uint8_t readval;
  801. status = stpmic1_register_read(register_id, &readval);
  802. if (status != 0) {
  803. return status;
  804. }
  805. if (readval != value) {
  806. return -EIO;
  807. }
  808. }
  809. #endif
  810. return status;
  811. }
  812. int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
  813. {
  814. int status;
  815. uint8_t val;
  816. status = stpmic1_register_read(register_id, &val);
  817. if (status != 0) {
  818. return status;
  819. }
  820. val = (val & ~mask) | (value & mask);
  821. return stpmic1_register_write(register_id, val);
  822. }
  823. void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
  824. {
  825. pmic_i2c_handle = i2c_handle;
  826. pmic_i2c_addr = i2c_addr;
  827. }
  828. void stpmic1_dump_regulators(void)
  829. {
  830. uint32_t i;
  831. for (i = 0U; i < MAX_REGUL; i++) {
  832. const char *name __unused = regulators_table[i].dt_node_name;
  833. VERBOSE("PMIC regul %s: %sable, %dmV",
  834. name,
  835. stpmic1_is_regulator_enabled(name) ? "en" : "dis",
  836. stpmic1_regulator_voltage_get(name));
  837. }
  838. }
  839. int stpmic1_get_version(unsigned long *version)
  840. {
  841. uint8_t read_val;
  842. int status;
  843. status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
  844. if (status < 0) {
  845. return status;
  846. }
  847. *version = (unsigned long)read_val;
  848. return 0;
  849. }