123684d0eSYann Gautier /* 2*ed6a8523SYann Gautier * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved 323684d0eSYann Gautier * 423684d0eSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 523684d0eSYann Gautier */ 623684d0eSYann Gautier 7*ed6a8523SYann Gautier #include <errno.h> 823684d0eSYann Gautier #include <string.h> 923684d0eSYann Gautier 1023684d0eSYann Gautier #include <common/debug.h> 1123684d0eSYann Gautier #include <drivers/st/stpmic1.h> 12d82d4ff0SYann Gautier 13d82d4ff0SYann Gautier #define I2C_TIMEOUT_MS 25 1423684d0eSYann Gautier 1523684d0eSYann Gautier struct regul_struct { 1623684d0eSYann Gautier const char *dt_node_name; 1723684d0eSYann Gautier const uint16_t *voltage_table; 1823684d0eSYann Gautier uint8_t voltage_table_size; 1923684d0eSYann Gautier uint8_t control_reg; 2023684d0eSYann Gautier uint8_t low_power_reg; 21077f6828SYann Gautier uint8_t pull_down_reg; 22077f6828SYann Gautier uint8_t pull_down; 23077f6828SYann Gautier uint8_t mask_reset_reg; 24077f6828SYann Gautier uint8_t mask_reset; 2523684d0eSYann Gautier }; 2623684d0eSYann Gautier 2723684d0eSYann Gautier static struct i2c_handle_s *pmic_i2c_handle; 2823684d0eSYann Gautier static uint16_t pmic_i2c_addr; 2923684d0eSYann Gautier 3023684d0eSYann Gautier /* Voltage tables in mV */ 3123684d0eSYann Gautier static const uint16_t buck1_voltage_table[] = { 32077f6828SYann Gautier 725, 33077f6828SYann Gautier 725, 34077f6828SYann Gautier 725, 35077f6828SYann Gautier 725, 36077f6828SYann Gautier 725, 3723684d0eSYann Gautier 725, 3823684d0eSYann Gautier 750, 3923684d0eSYann Gautier 775, 4023684d0eSYann Gautier 800, 4123684d0eSYann Gautier 825, 4223684d0eSYann Gautier 850, 4323684d0eSYann Gautier 875, 4423684d0eSYann Gautier 900, 4523684d0eSYann Gautier 925, 4623684d0eSYann Gautier 950, 4723684d0eSYann Gautier 975, 4823684d0eSYann Gautier 1000, 4923684d0eSYann Gautier 1025, 5023684d0eSYann Gautier 1050, 5123684d0eSYann Gautier 1075, 5223684d0eSYann Gautier 1100, 5323684d0eSYann Gautier 1125, 5423684d0eSYann Gautier 1150, 5523684d0eSYann Gautier 1175, 5623684d0eSYann Gautier 1200, 5723684d0eSYann Gautier 1225, 5823684d0eSYann Gautier 1250, 5923684d0eSYann Gautier 1275, 6023684d0eSYann Gautier 1300, 6123684d0eSYann Gautier 1325, 6223684d0eSYann Gautier 1350, 63077f6828SYann Gautier 1375, 64077f6828SYann Gautier 1400, 65077f6828SYann Gautier 1425, 66077f6828SYann Gautier 1450, 67077f6828SYann Gautier 1475, 68077f6828SYann Gautier 1500, 69077f6828SYann Gautier 1500, 70077f6828SYann Gautier 1500, 71077f6828SYann Gautier 1500, 72077f6828SYann Gautier 1500, 73077f6828SYann Gautier 1500, 74077f6828SYann Gautier 1500, 75077f6828SYann Gautier 1500, 76077f6828SYann Gautier 1500, 77077f6828SYann Gautier 1500, 78077f6828SYann Gautier 1500, 79077f6828SYann Gautier 1500, 80077f6828SYann Gautier 1500, 81077f6828SYann Gautier 1500, 82077f6828SYann Gautier 1500, 83077f6828SYann Gautier 1500, 84077f6828SYann Gautier 1500, 85077f6828SYann Gautier 1500, 86077f6828SYann Gautier 1500, 87077f6828SYann Gautier 1500, 88077f6828SYann Gautier 1500, 89077f6828SYann Gautier 1500, 90077f6828SYann Gautier 1500, 91077f6828SYann Gautier 1500, 92077f6828SYann Gautier 1500, 93077f6828SYann Gautier 1500, 94077f6828SYann Gautier 1500, 95077f6828SYann Gautier 1500, 9623684d0eSYann Gautier }; 9723684d0eSYann Gautier 9823684d0eSYann Gautier static const uint16_t buck2_voltage_table[] = { 9923684d0eSYann Gautier 1000, 10023684d0eSYann Gautier 1000, 10123684d0eSYann Gautier 1000, 10223684d0eSYann Gautier 1000, 10323684d0eSYann Gautier 1000, 10423684d0eSYann Gautier 1000, 10523684d0eSYann Gautier 1000, 10623684d0eSYann Gautier 1000, 10723684d0eSYann Gautier 1000, 10823684d0eSYann Gautier 1000, 10923684d0eSYann Gautier 1000, 11023684d0eSYann Gautier 1000, 11123684d0eSYann Gautier 1000, 11223684d0eSYann Gautier 1000, 11323684d0eSYann Gautier 1000, 11423684d0eSYann Gautier 1000, 11523684d0eSYann Gautier 1000, 11623684d0eSYann Gautier 1000, 11723684d0eSYann Gautier 1050, 11823684d0eSYann Gautier 1050, 11923684d0eSYann Gautier 1100, 12023684d0eSYann Gautier 1100, 12123684d0eSYann Gautier 1150, 12223684d0eSYann Gautier 1150, 12323684d0eSYann Gautier 1200, 12423684d0eSYann Gautier 1200, 12523684d0eSYann Gautier 1250, 12623684d0eSYann Gautier 1250, 12723684d0eSYann Gautier 1300, 12823684d0eSYann Gautier 1300, 12923684d0eSYann Gautier 1350, 13023684d0eSYann Gautier 1350, 13123684d0eSYann Gautier 1400, 13223684d0eSYann Gautier 1400, 13323684d0eSYann Gautier 1450, 13423684d0eSYann Gautier 1450, 13523684d0eSYann Gautier 1500, 13623684d0eSYann Gautier }; 13723684d0eSYann Gautier 13823684d0eSYann Gautier static const uint16_t buck3_voltage_table[] = { 13923684d0eSYann Gautier 1000, 14023684d0eSYann Gautier 1000, 14123684d0eSYann Gautier 1000, 14223684d0eSYann Gautier 1000, 14323684d0eSYann Gautier 1000, 14423684d0eSYann Gautier 1000, 14523684d0eSYann Gautier 1000, 14623684d0eSYann Gautier 1000, 14723684d0eSYann Gautier 1000, 14823684d0eSYann Gautier 1000, 14923684d0eSYann Gautier 1000, 15023684d0eSYann Gautier 1000, 15123684d0eSYann Gautier 1000, 15223684d0eSYann Gautier 1000, 15323684d0eSYann Gautier 1000, 15423684d0eSYann Gautier 1000, 15523684d0eSYann Gautier 1000, 15623684d0eSYann Gautier 1000, 15723684d0eSYann Gautier 1000, 15823684d0eSYann Gautier 1000, 15923684d0eSYann Gautier 1100, 16023684d0eSYann Gautier 1100, 16123684d0eSYann Gautier 1100, 16223684d0eSYann Gautier 1100, 16323684d0eSYann Gautier 1200, 16423684d0eSYann Gautier 1200, 16523684d0eSYann Gautier 1200, 16623684d0eSYann Gautier 1200, 16723684d0eSYann Gautier 1300, 16823684d0eSYann Gautier 1300, 16923684d0eSYann Gautier 1300, 17023684d0eSYann Gautier 1300, 17123684d0eSYann Gautier 1400, 17223684d0eSYann Gautier 1400, 17323684d0eSYann Gautier 1400, 17423684d0eSYann Gautier 1400, 17523684d0eSYann Gautier 1500, 17623684d0eSYann Gautier 1600, 17723684d0eSYann Gautier 1700, 17823684d0eSYann Gautier 1800, 17923684d0eSYann Gautier 1900, 18023684d0eSYann Gautier 2000, 18123684d0eSYann Gautier 2100, 18223684d0eSYann Gautier 2200, 18323684d0eSYann Gautier 2300, 18423684d0eSYann Gautier 2400, 18523684d0eSYann Gautier 2500, 18623684d0eSYann Gautier 2600, 18723684d0eSYann Gautier 2700, 18823684d0eSYann Gautier 2800, 18923684d0eSYann Gautier 2900, 19023684d0eSYann Gautier 3000, 19123684d0eSYann Gautier 3100, 19223684d0eSYann Gautier 3200, 19323684d0eSYann Gautier 3300, 19423684d0eSYann Gautier 3400, 19523684d0eSYann Gautier }; 19623684d0eSYann Gautier 19723684d0eSYann Gautier static const uint16_t buck4_voltage_table[] = { 19823684d0eSYann Gautier 600, 19923684d0eSYann Gautier 625, 20023684d0eSYann Gautier 650, 20123684d0eSYann Gautier 675, 20223684d0eSYann Gautier 700, 20323684d0eSYann Gautier 725, 20423684d0eSYann Gautier 750, 20523684d0eSYann Gautier 775, 20623684d0eSYann Gautier 800, 20723684d0eSYann Gautier 825, 20823684d0eSYann Gautier 850, 20923684d0eSYann Gautier 875, 21023684d0eSYann Gautier 900, 21123684d0eSYann Gautier 925, 21223684d0eSYann Gautier 950, 21323684d0eSYann Gautier 975, 21423684d0eSYann Gautier 1000, 21523684d0eSYann Gautier 1025, 21623684d0eSYann Gautier 1050, 21723684d0eSYann Gautier 1075, 21823684d0eSYann Gautier 1100, 21923684d0eSYann Gautier 1125, 22023684d0eSYann Gautier 1150, 22123684d0eSYann Gautier 1175, 22223684d0eSYann Gautier 1200, 22323684d0eSYann Gautier 1225, 22423684d0eSYann Gautier 1250, 22523684d0eSYann Gautier 1275, 22623684d0eSYann Gautier 1300, 22723684d0eSYann Gautier 1300, 22823684d0eSYann Gautier 1350, 22923684d0eSYann Gautier 1350, 23023684d0eSYann Gautier 1400, 23123684d0eSYann Gautier 1400, 23223684d0eSYann Gautier 1450, 23323684d0eSYann Gautier 1450, 23423684d0eSYann Gautier 1500, 23523684d0eSYann Gautier 1600, 23623684d0eSYann Gautier 1700, 23723684d0eSYann Gautier 1800, 23823684d0eSYann Gautier 1900, 23923684d0eSYann Gautier 2000, 24023684d0eSYann Gautier 2100, 24123684d0eSYann Gautier 2200, 24223684d0eSYann Gautier 2300, 24323684d0eSYann Gautier 2400, 24423684d0eSYann Gautier 2500, 24523684d0eSYann Gautier 2600, 24623684d0eSYann Gautier 2700, 24723684d0eSYann Gautier 2800, 24823684d0eSYann Gautier 2900, 24923684d0eSYann Gautier 3000, 25023684d0eSYann Gautier 3100, 25123684d0eSYann Gautier 3200, 25223684d0eSYann Gautier 3300, 25323684d0eSYann Gautier 3400, 25423684d0eSYann Gautier 3500, 25523684d0eSYann Gautier 3600, 25623684d0eSYann Gautier 3700, 25723684d0eSYann Gautier 3800, 25823684d0eSYann Gautier 3900, 25923684d0eSYann Gautier }; 26023684d0eSYann Gautier 26123684d0eSYann Gautier static const uint16_t ldo1_voltage_table[] = { 26223684d0eSYann Gautier 1700, 26323684d0eSYann Gautier 1700, 26423684d0eSYann Gautier 1700, 26523684d0eSYann Gautier 1700, 26623684d0eSYann Gautier 1700, 26723684d0eSYann Gautier 1700, 26823684d0eSYann Gautier 1700, 26923684d0eSYann Gautier 1700, 27023684d0eSYann Gautier 1700, 27123684d0eSYann Gautier 1800, 27223684d0eSYann Gautier 1900, 27323684d0eSYann Gautier 2000, 27423684d0eSYann Gautier 2100, 27523684d0eSYann Gautier 2200, 27623684d0eSYann Gautier 2300, 27723684d0eSYann Gautier 2400, 27823684d0eSYann Gautier 2500, 27923684d0eSYann Gautier 2600, 28023684d0eSYann Gautier 2700, 28123684d0eSYann Gautier 2800, 28223684d0eSYann Gautier 2900, 28323684d0eSYann Gautier 3000, 28423684d0eSYann Gautier 3100, 28523684d0eSYann Gautier 3200, 28623684d0eSYann Gautier 3300, 28723684d0eSYann Gautier }; 28823684d0eSYann Gautier 28923684d0eSYann Gautier static const uint16_t ldo2_voltage_table[] = { 29023684d0eSYann Gautier 1700, 29123684d0eSYann Gautier 1700, 29223684d0eSYann Gautier 1700, 29323684d0eSYann Gautier 1700, 29423684d0eSYann Gautier 1700, 29523684d0eSYann Gautier 1700, 29623684d0eSYann Gautier 1700, 29723684d0eSYann Gautier 1700, 29823684d0eSYann Gautier 1700, 29923684d0eSYann Gautier 1800, 30023684d0eSYann Gautier 1900, 30123684d0eSYann Gautier 2000, 30223684d0eSYann Gautier 2100, 30323684d0eSYann Gautier 2200, 30423684d0eSYann Gautier 2300, 30523684d0eSYann Gautier 2400, 30623684d0eSYann Gautier 2500, 30723684d0eSYann Gautier 2600, 30823684d0eSYann Gautier 2700, 30923684d0eSYann Gautier 2800, 31023684d0eSYann Gautier 2900, 31123684d0eSYann Gautier 3000, 31223684d0eSYann Gautier 3100, 31323684d0eSYann Gautier 3200, 31423684d0eSYann Gautier 3300, 31523684d0eSYann Gautier }; 31623684d0eSYann Gautier 31723684d0eSYann Gautier static const uint16_t ldo3_voltage_table[] = { 31823684d0eSYann Gautier 1700, 31923684d0eSYann Gautier 1700, 32023684d0eSYann Gautier 1700, 32123684d0eSYann Gautier 1700, 32223684d0eSYann Gautier 1700, 32323684d0eSYann Gautier 1700, 32423684d0eSYann Gautier 1700, 32523684d0eSYann Gautier 1700, 32623684d0eSYann Gautier 1700, 32723684d0eSYann Gautier 1800, 32823684d0eSYann Gautier 1900, 32923684d0eSYann Gautier 2000, 33023684d0eSYann Gautier 2100, 33123684d0eSYann Gautier 2200, 33223684d0eSYann Gautier 2300, 33323684d0eSYann Gautier 2400, 33423684d0eSYann Gautier 2500, 33523684d0eSYann Gautier 2600, 33623684d0eSYann Gautier 2700, 33723684d0eSYann Gautier 2800, 33823684d0eSYann Gautier 2900, 33923684d0eSYann Gautier 3000, 34023684d0eSYann Gautier 3100, 34123684d0eSYann Gautier 3200, 34223684d0eSYann Gautier 3300, 34323684d0eSYann Gautier 3300, 34423684d0eSYann Gautier 3300, 34523684d0eSYann Gautier 3300, 34623684d0eSYann Gautier 3300, 34723684d0eSYann Gautier 3300, 34823684d0eSYann Gautier 3300, 349077f6828SYann Gautier 500, 35023684d0eSYann Gautier 0xFFFF, /* VREFDDR */ 35123684d0eSYann Gautier }; 35223684d0eSYann Gautier 35323684d0eSYann Gautier static const uint16_t ldo5_voltage_table[] = { 35423684d0eSYann Gautier 1700, 35523684d0eSYann Gautier 1700, 35623684d0eSYann Gautier 1700, 35723684d0eSYann Gautier 1700, 35823684d0eSYann Gautier 1700, 35923684d0eSYann Gautier 1700, 36023684d0eSYann Gautier 1700, 36123684d0eSYann Gautier 1700, 36223684d0eSYann Gautier 1700, 36323684d0eSYann Gautier 1800, 36423684d0eSYann Gautier 1900, 36523684d0eSYann Gautier 2000, 36623684d0eSYann Gautier 2100, 36723684d0eSYann Gautier 2200, 36823684d0eSYann Gautier 2300, 36923684d0eSYann Gautier 2400, 37023684d0eSYann Gautier 2500, 37123684d0eSYann Gautier 2600, 37223684d0eSYann Gautier 2700, 37323684d0eSYann Gautier 2800, 37423684d0eSYann Gautier 2900, 37523684d0eSYann Gautier 3000, 37623684d0eSYann Gautier 3100, 37723684d0eSYann Gautier 3200, 37823684d0eSYann Gautier 3300, 37923684d0eSYann Gautier 3400, 38023684d0eSYann Gautier 3500, 38123684d0eSYann Gautier 3600, 38223684d0eSYann Gautier 3700, 38323684d0eSYann Gautier 3800, 38423684d0eSYann Gautier 3900, 38523684d0eSYann Gautier }; 38623684d0eSYann Gautier 38723684d0eSYann Gautier static const uint16_t ldo6_voltage_table[] = { 38823684d0eSYann Gautier 900, 38923684d0eSYann Gautier 1000, 39023684d0eSYann Gautier 1100, 39123684d0eSYann Gautier 1200, 39223684d0eSYann Gautier 1300, 39323684d0eSYann Gautier 1400, 39423684d0eSYann Gautier 1500, 39523684d0eSYann Gautier 1600, 39623684d0eSYann Gautier 1700, 39723684d0eSYann Gautier 1800, 39823684d0eSYann Gautier 1900, 39923684d0eSYann Gautier 2000, 40023684d0eSYann Gautier 2100, 40123684d0eSYann Gautier 2200, 40223684d0eSYann Gautier 2300, 40323684d0eSYann Gautier 2400, 40423684d0eSYann Gautier 2500, 40523684d0eSYann Gautier 2600, 40623684d0eSYann Gautier 2700, 40723684d0eSYann Gautier 2800, 40823684d0eSYann Gautier 2900, 40923684d0eSYann Gautier 3000, 41023684d0eSYann Gautier 3100, 41123684d0eSYann Gautier 3200, 41223684d0eSYann Gautier 3300, 41323684d0eSYann Gautier }; 41423684d0eSYann Gautier 41523684d0eSYann Gautier static const uint16_t ldo4_voltage_table[] = { 41623684d0eSYann Gautier 3300, 41723684d0eSYann Gautier }; 41823684d0eSYann Gautier 41923684d0eSYann Gautier static const uint16_t vref_ddr_voltage_table[] = { 42023684d0eSYann Gautier 3300, 42123684d0eSYann Gautier }; 42223684d0eSYann Gautier 42323684d0eSYann Gautier /* Table of Regulators in PMIC SoC */ 42423684d0eSYann Gautier static const struct regul_struct regulators_table[] = { 42523684d0eSYann Gautier { 42623684d0eSYann Gautier .dt_node_name = "buck1", 42723684d0eSYann Gautier .voltage_table = buck1_voltage_table, 42823684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck1_voltage_table), 42923684d0eSYann Gautier .control_reg = BUCK1_CONTROL_REG, 43023684d0eSYann Gautier .low_power_reg = BUCK1_PWRCTRL_REG, 431077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG, 432077f6828SYann Gautier .pull_down = BUCK1_PULL_DOWN_SHIFT, 433077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG, 434077f6828SYann Gautier .mask_reset = BUCK1_MASK_RESET, 43523684d0eSYann Gautier }, 43623684d0eSYann Gautier { 43723684d0eSYann Gautier .dt_node_name = "buck2", 43823684d0eSYann Gautier .voltage_table = buck2_voltage_table, 43923684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck2_voltage_table), 44023684d0eSYann Gautier .control_reg = BUCK2_CONTROL_REG, 44123684d0eSYann Gautier .low_power_reg = BUCK2_PWRCTRL_REG, 442077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG, 443077f6828SYann Gautier .pull_down = BUCK2_PULL_DOWN_SHIFT, 444077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG, 445077f6828SYann Gautier .mask_reset = BUCK2_MASK_RESET, 44623684d0eSYann Gautier }, 44723684d0eSYann Gautier { 44823684d0eSYann Gautier .dt_node_name = "buck3", 44923684d0eSYann Gautier .voltage_table = buck3_voltage_table, 45023684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck3_voltage_table), 45123684d0eSYann Gautier .control_reg = BUCK3_CONTROL_REG, 45223684d0eSYann Gautier .low_power_reg = BUCK3_PWRCTRL_REG, 453077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG, 454077f6828SYann Gautier .pull_down = BUCK3_PULL_DOWN_SHIFT, 455077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG, 456077f6828SYann Gautier .mask_reset = BUCK3_MASK_RESET, 45723684d0eSYann Gautier }, 45823684d0eSYann Gautier { 45923684d0eSYann Gautier .dt_node_name = "buck4", 46023684d0eSYann Gautier .voltage_table = buck4_voltage_table, 46123684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck4_voltage_table), 46223684d0eSYann Gautier .control_reg = BUCK4_CONTROL_REG, 46323684d0eSYann Gautier .low_power_reg = BUCK4_PWRCTRL_REG, 464077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG, 465077f6828SYann Gautier .pull_down = BUCK4_PULL_DOWN_SHIFT, 466077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG, 467077f6828SYann Gautier .mask_reset = BUCK4_MASK_RESET, 46823684d0eSYann Gautier }, 46923684d0eSYann Gautier { 47023684d0eSYann Gautier .dt_node_name = "ldo1", 47123684d0eSYann Gautier .voltage_table = ldo1_voltage_table, 47223684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), 47323684d0eSYann Gautier .control_reg = LDO1_CONTROL_REG, 47423684d0eSYann Gautier .low_power_reg = LDO1_PWRCTRL_REG, 475077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 476077f6828SYann Gautier .mask_reset = LDO1_MASK_RESET, 47723684d0eSYann Gautier }, 47823684d0eSYann Gautier { 47923684d0eSYann Gautier .dt_node_name = "ldo2", 48023684d0eSYann Gautier .voltage_table = ldo2_voltage_table, 48123684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), 48223684d0eSYann Gautier .control_reg = LDO2_CONTROL_REG, 48323684d0eSYann Gautier .low_power_reg = LDO2_PWRCTRL_REG, 484077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 485077f6828SYann Gautier .mask_reset = LDO2_MASK_RESET, 48623684d0eSYann Gautier }, 48723684d0eSYann Gautier { 48823684d0eSYann Gautier .dt_node_name = "ldo3", 48923684d0eSYann Gautier .voltage_table = ldo3_voltage_table, 49023684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), 49123684d0eSYann Gautier .control_reg = LDO3_CONTROL_REG, 49223684d0eSYann Gautier .low_power_reg = LDO3_PWRCTRL_REG, 493077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 494077f6828SYann Gautier .mask_reset = LDO3_MASK_RESET, 49523684d0eSYann Gautier }, 49623684d0eSYann Gautier { 49723684d0eSYann Gautier .dt_node_name = "ldo4", 49823684d0eSYann Gautier .voltage_table = ldo4_voltage_table, 49923684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), 50023684d0eSYann Gautier .control_reg = LDO4_CONTROL_REG, 50123684d0eSYann Gautier .low_power_reg = LDO4_PWRCTRL_REG, 502077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 503077f6828SYann Gautier .mask_reset = LDO4_MASK_RESET, 50423684d0eSYann Gautier }, 50523684d0eSYann Gautier { 50623684d0eSYann Gautier .dt_node_name = "ldo5", 50723684d0eSYann Gautier .voltage_table = ldo5_voltage_table, 50823684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), 50923684d0eSYann Gautier .control_reg = LDO5_CONTROL_REG, 51023684d0eSYann Gautier .low_power_reg = LDO5_PWRCTRL_REG, 511077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 512077f6828SYann Gautier .mask_reset = LDO5_MASK_RESET, 51323684d0eSYann Gautier }, 51423684d0eSYann Gautier { 51523684d0eSYann Gautier .dt_node_name = "ldo6", 51623684d0eSYann Gautier .voltage_table = ldo6_voltage_table, 51723684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), 51823684d0eSYann Gautier .control_reg = LDO6_CONTROL_REG, 51923684d0eSYann Gautier .low_power_reg = LDO6_PWRCTRL_REG, 520077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 521077f6828SYann Gautier .mask_reset = LDO6_MASK_RESET, 52223684d0eSYann Gautier }, 52323684d0eSYann Gautier { 52423684d0eSYann Gautier .dt_node_name = "vref_ddr", 52523684d0eSYann Gautier .voltage_table = vref_ddr_voltage_table, 52623684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), 52723684d0eSYann Gautier .control_reg = VREF_DDR_CONTROL_REG, 52823684d0eSYann Gautier .low_power_reg = VREF_DDR_PWRCTRL_REG, 529077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG, 530077f6828SYann Gautier .mask_reset = VREF_DDR_MASK_RESET, 53123684d0eSYann Gautier }, 53223684d0eSYann Gautier }; 53323684d0eSYann Gautier 53423684d0eSYann Gautier #define MAX_REGUL ARRAY_SIZE(regulators_table) 53523684d0eSYann Gautier 53623684d0eSYann Gautier static const struct regul_struct *get_regulator_data(const char *name) 53723684d0eSYann Gautier { 53823684d0eSYann Gautier uint8_t i; 53923684d0eSYann Gautier 54023684d0eSYann Gautier for (i = 0 ; i < MAX_REGUL ; i++) { 54123684d0eSYann Gautier if (strncmp(name, regulators_table[i].dt_node_name, 54223684d0eSYann Gautier strlen(regulators_table[i].dt_node_name)) == 0) { 54323684d0eSYann Gautier return ®ulators_table[i]; 54423684d0eSYann Gautier } 54523684d0eSYann Gautier } 54623684d0eSYann Gautier 54723684d0eSYann Gautier /* Regulator not found */ 54823684d0eSYann Gautier panic(); 54923684d0eSYann Gautier return NULL; 55023684d0eSYann Gautier } 55123684d0eSYann Gautier 55223684d0eSYann Gautier static uint8_t voltage_to_index(const char *name, uint16_t millivolts) 55323684d0eSYann Gautier { 55423684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 55523684d0eSYann Gautier uint8_t i; 55623684d0eSYann Gautier 55723684d0eSYann Gautier for (i = 0 ; i < regul->voltage_table_size ; i++) { 55823684d0eSYann Gautier if (regul->voltage_table[i] == millivolts) { 55923684d0eSYann Gautier return i; 56023684d0eSYann Gautier } 56123684d0eSYann Gautier } 56223684d0eSYann Gautier 56323684d0eSYann Gautier /* Voltage not found */ 56423684d0eSYann Gautier panic(); 56523684d0eSYann Gautier 56623684d0eSYann Gautier return 0; 56723684d0eSYann Gautier } 56823684d0eSYann Gautier 569077f6828SYann Gautier int stpmic1_powerctrl_on(void) 570077f6828SYann Gautier { 571077f6828SYann Gautier return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID, 572077f6828SYann Gautier PWRCTRL_PIN_VALID); 573077f6828SYann Gautier } 574077f6828SYann Gautier 57523684d0eSYann Gautier int stpmic1_switch_off(void) 57623684d0eSYann Gautier { 57723684d0eSYann Gautier return stpmic1_register_update(MAIN_CONTROL_REG, 1, 57823684d0eSYann Gautier SOFTWARE_SWITCH_OFF_ENABLED); 57923684d0eSYann Gautier } 58023684d0eSYann Gautier 58123684d0eSYann Gautier int stpmic1_regulator_enable(const char *name) 58223684d0eSYann Gautier { 58323684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 58423684d0eSYann Gautier 58523684d0eSYann Gautier return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0)); 58623684d0eSYann Gautier } 58723684d0eSYann Gautier 58823684d0eSYann Gautier int stpmic1_regulator_disable(const char *name) 58923684d0eSYann Gautier { 59023684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 59123684d0eSYann Gautier 59223684d0eSYann Gautier return stpmic1_register_update(regul->control_reg, 0, BIT(0)); 59323684d0eSYann Gautier } 59423684d0eSYann Gautier 59523684d0eSYann Gautier uint8_t stpmic1_is_regulator_enabled(const char *name) 59623684d0eSYann Gautier { 59723684d0eSYann Gautier uint8_t val; 59823684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 59923684d0eSYann Gautier 60023684d0eSYann Gautier if (stpmic1_register_read(regul->control_reg, &val) != 0) { 60123684d0eSYann Gautier panic(); 60223684d0eSYann Gautier } 60323684d0eSYann Gautier 60423684d0eSYann Gautier return (val & 0x1U); 60523684d0eSYann Gautier } 60623684d0eSYann Gautier 60723684d0eSYann Gautier int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts) 60823684d0eSYann Gautier { 60923684d0eSYann Gautier uint8_t voltage_index = voltage_to_index(name, millivolts); 61023684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 611077f6828SYann Gautier uint8_t mask; 61223684d0eSYann Gautier 613077f6828SYann Gautier /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */ 614077f6828SYann Gautier if (strncmp(name, "buck", 4) == 0) { 615077f6828SYann Gautier mask = BUCK_VOLTAGE_MASK; 616077f6828SYann Gautier } else if ((strncmp(name, "ldo", 3) == 0) && 617077f6828SYann Gautier (strncmp(name, "ldo4", 4) != 0)) { 618077f6828SYann Gautier mask = LDO_VOLTAGE_MASK; 619077f6828SYann Gautier } else { 620077f6828SYann Gautier return 0; 621077f6828SYann Gautier } 622077f6828SYann Gautier 623077f6828SYann Gautier return stpmic1_register_update(regul->control_reg, 624077f6828SYann Gautier voltage_index << LDO_BUCK_VOLTAGE_SHIFT, 625077f6828SYann Gautier mask); 626077f6828SYann Gautier } 627077f6828SYann Gautier 628077f6828SYann Gautier int stpmic1_regulator_pull_down_set(const char *name) 629077f6828SYann Gautier { 630077f6828SYann Gautier const struct regul_struct *regul = get_regulator_data(name); 631077f6828SYann Gautier 632077f6828SYann Gautier if (regul->pull_down_reg != 0) { 633077f6828SYann Gautier return stpmic1_register_update(regul->pull_down_reg, 634077f6828SYann Gautier BIT(regul->pull_down), 635077f6828SYann Gautier LDO_BUCK_PULL_DOWN_MASK << 636077f6828SYann Gautier regul->pull_down); 637077f6828SYann Gautier } 638077f6828SYann Gautier 639077f6828SYann Gautier return 0; 640077f6828SYann Gautier } 641077f6828SYann Gautier 642077f6828SYann Gautier int stpmic1_regulator_mask_reset_set(const char *name) 643077f6828SYann Gautier { 644077f6828SYann Gautier const struct regul_struct *regul = get_regulator_data(name); 645077f6828SYann Gautier 646077f6828SYann Gautier return stpmic1_register_update(regul->mask_reset_reg, 647077f6828SYann Gautier BIT(regul->mask_reset), 648077f6828SYann Gautier LDO_BUCK_RESET_MASK << 649077f6828SYann Gautier regul->mask_reset); 650077f6828SYann Gautier } 651077f6828SYann Gautier 652077f6828SYann Gautier int stpmic1_regulator_voltage_get(const char *name) 653077f6828SYann Gautier { 654077f6828SYann Gautier const struct regul_struct *regul = get_regulator_data(name); 655077f6828SYann Gautier uint8_t value; 656077f6828SYann Gautier uint8_t mask; 657*ed6a8523SYann Gautier int status; 658077f6828SYann Gautier 659077f6828SYann Gautier /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */ 660077f6828SYann Gautier if (strncmp(name, "buck", 4) == 0) { 661077f6828SYann Gautier mask = BUCK_VOLTAGE_MASK; 662077f6828SYann Gautier } else if ((strncmp(name, "ldo", 3) == 0) && 663077f6828SYann Gautier (strncmp(name, "ldo4", 4) != 0)) { 664077f6828SYann Gautier mask = LDO_VOLTAGE_MASK; 665077f6828SYann Gautier } else { 666077f6828SYann Gautier return 0; 667077f6828SYann Gautier } 668077f6828SYann Gautier 669*ed6a8523SYann Gautier status = stpmic1_register_read(regul->control_reg, &value); 670*ed6a8523SYann Gautier if (status < 0) { 671*ed6a8523SYann Gautier return status; 672*ed6a8523SYann Gautier } 673077f6828SYann Gautier 674077f6828SYann Gautier value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT; 675077f6828SYann Gautier 676*ed6a8523SYann Gautier if (value > regul->voltage_table_size) { 677*ed6a8523SYann Gautier return -ERANGE; 678*ed6a8523SYann Gautier } 679077f6828SYann Gautier 680077f6828SYann Gautier return (int)regul->voltage_table[value]; 68123684d0eSYann Gautier } 68223684d0eSYann Gautier 68323684d0eSYann Gautier int stpmic1_register_read(uint8_t register_id, uint8_t *value) 68423684d0eSYann Gautier { 68523684d0eSYann Gautier return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr, 686d82d4ff0SYann Gautier (uint16_t)register_id, 687d82d4ff0SYann Gautier I2C_MEMADD_SIZE_8BIT, value, 688d82d4ff0SYann Gautier 1, I2C_TIMEOUT_MS); 68923684d0eSYann Gautier } 69023684d0eSYann Gautier 69123684d0eSYann Gautier int stpmic1_register_write(uint8_t register_id, uint8_t value) 69223684d0eSYann Gautier { 69323684d0eSYann Gautier int status; 69423684d0eSYann Gautier 69523684d0eSYann Gautier status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr, 69623684d0eSYann Gautier (uint16_t)register_id, 697d82d4ff0SYann Gautier I2C_MEMADD_SIZE_8BIT, &value, 698d82d4ff0SYann Gautier 1, I2C_TIMEOUT_MS); 69923684d0eSYann Gautier 700077f6828SYann Gautier #if ENABLE_ASSERTIONS 70123684d0eSYann Gautier if (status != 0) { 70223684d0eSYann Gautier return status; 70323684d0eSYann Gautier } 70423684d0eSYann Gautier 70523684d0eSYann Gautier if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) { 70623684d0eSYann Gautier uint8_t readval; 70723684d0eSYann Gautier 70823684d0eSYann Gautier status = stpmic1_register_read(register_id, &readval); 70923684d0eSYann Gautier if (status != 0) { 71023684d0eSYann Gautier return status; 71123684d0eSYann Gautier } 71223684d0eSYann Gautier 71323684d0eSYann Gautier if (readval != value) { 714*ed6a8523SYann Gautier return -EIO; 71523684d0eSYann Gautier } 71623684d0eSYann Gautier } 717077f6828SYann Gautier #endif 71823684d0eSYann Gautier 719077f6828SYann Gautier return status; 72023684d0eSYann Gautier } 72123684d0eSYann Gautier 72223684d0eSYann Gautier int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) 72323684d0eSYann Gautier { 72423684d0eSYann Gautier int status; 72523684d0eSYann Gautier uint8_t val; 72623684d0eSYann Gautier 72723684d0eSYann Gautier status = stpmic1_register_read(register_id, &val); 72823684d0eSYann Gautier if (status != 0) { 72923684d0eSYann Gautier return status; 73023684d0eSYann Gautier } 73123684d0eSYann Gautier 732077f6828SYann Gautier val = (val & ~mask) | (value & mask); 73323684d0eSYann Gautier 73423684d0eSYann Gautier return stpmic1_register_write(register_id, val); 73523684d0eSYann Gautier } 73623684d0eSYann Gautier 73723684d0eSYann Gautier void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr) 73823684d0eSYann Gautier { 73923684d0eSYann Gautier pmic_i2c_handle = i2c_handle; 74023684d0eSYann Gautier pmic_i2c_addr = i2c_addr; 74123684d0eSYann Gautier } 742077f6828SYann Gautier 743077f6828SYann Gautier void stpmic1_dump_regulators(void) 744077f6828SYann Gautier { 745077f6828SYann Gautier uint32_t i; 746077f6828SYann Gautier 747077f6828SYann Gautier for (i = 0U; i < MAX_REGUL; i++) { 748077f6828SYann Gautier const char *name __unused = regulators_table[i].dt_node_name; 749077f6828SYann Gautier 750077f6828SYann Gautier VERBOSE("PMIC regul %s: %sable, %dmV", 751077f6828SYann Gautier name, 752077f6828SYann Gautier stpmic1_is_regulator_enabled(name) ? "en" : "dis", 753077f6828SYann Gautier stpmic1_regulator_voltage_get(name)); 754077f6828SYann Gautier } 755077f6828SYann Gautier } 756077f6828SYann Gautier 757077f6828SYann Gautier int stpmic1_get_version(unsigned long *version) 758077f6828SYann Gautier { 759077f6828SYann Gautier uint8_t read_val; 760*ed6a8523SYann Gautier int status; 761077f6828SYann Gautier 762*ed6a8523SYann Gautier status = stpmic1_register_read(VERSION_STATUS_REG, &read_val); 763*ed6a8523SYann Gautier if (status < 0) { 764*ed6a8523SYann Gautier return status; 765077f6828SYann Gautier } 766077f6828SYann Gautier 767077f6828SYann Gautier *version = (unsigned long)read_val; 768077f6828SYann Gautier 769077f6828SYann Gautier return 0; 770077f6828SYann Gautier } 771