123684d0eSYann Gautier /* 2*47e62314SPatrick Delaunay * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved 323684d0eSYann Gautier * 423684d0eSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 523684d0eSYann Gautier */ 623684d0eSYann Gautier 785fb175bSYann Gautier #include <assert.h> 823684d0eSYann Gautier #include <errno.h> 923684d0eSYann Gautier 1023684d0eSYann Gautier #include <common/debug.h> 1123684d0eSYann Gautier #include <drivers/delay_timer.h> 1285fb175bSYann Gautier #include <drivers/st/regulator.h> 13d82d4ff0SYann Gautier #include <drivers/st/stm32_i2c.h> 1423684d0eSYann Gautier #include <drivers/st/stm32mp_pmic.h> 1523684d0eSYann Gautier #include <drivers/st/stpmic1.h> 1623684d0eSYann Gautier #include <lib/mmio.h> 1723684d0eSYann Gautier #include <lib/utils_def.h> 1816e56a75SNicolas Le Bayon #include <libfdt.h> 1916e56a75SNicolas Le Bayon 2016e56a75SNicolas Le Bayon #include <platform_def.h> 2123684d0eSYann Gautier 22c77c7d9eSNicolas Le Bayon #define PMIC_NODE_NOT_FOUND 1 233cebeec2SYann Gautier #define NB_REG 14U 2423684d0eSYann Gautier 2523684d0eSYann Gautier static struct i2c_handle_s i2c_handle; 2623684d0eSYann Gautier static uint32_t pmic_i2c_addr; 2723684d0eSYann Gautier 2885fb175bSYann Gautier static int register_pmic(void); 2985fb175bSYann Gautier 3023684d0eSYann Gautier static int dt_get_pmic_node(void *fdt) 3123684d0eSYann Gautier { 32c77c7d9eSNicolas Le Bayon static int node = -FDT_ERR_BADOFFSET; 33c77c7d9eSNicolas Le Bayon 34c77c7d9eSNicolas Le Bayon if (node == -FDT_ERR_BADOFFSET) { 35c77c7d9eSNicolas Le Bayon node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1"); 36c77c7d9eSNicolas Le Bayon } 37c77c7d9eSNicolas Le Bayon 38c77c7d9eSNicolas Le Bayon return node; 3923684d0eSYann Gautier } 4023684d0eSYann Gautier 41d82d4ff0SYann Gautier int dt_pmic_status(void) 4223684d0eSYann Gautier { 43c77c7d9eSNicolas Le Bayon static int status = -FDT_ERR_BADVALUE; 4423684d0eSYann Gautier int node; 4523684d0eSYann Gautier void *fdt; 4623684d0eSYann Gautier 47c77c7d9eSNicolas Le Bayon if (status != -FDT_ERR_BADVALUE) { 48c77c7d9eSNicolas Le Bayon return status; 49c77c7d9eSNicolas Le Bayon } 50c77c7d9eSNicolas Le Bayon 5123684d0eSYann Gautier if (fdt_get_address(&fdt) == 0) { 52d82d4ff0SYann Gautier return -ENOENT; 5323684d0eSYann Gautier } 5423684d0eSYann Gautier 5523684d0eSYann Gautier node = dt_get_pmic_node(fdt); 56d82d4ff0SYann Gautier if (node <= 0) { 57c77c7d9eSNicolas Le Bayon status = -FDT_ERR_NOTFOUND; 58c77c7d9eSNicolas Le Bayon 59c77c7d9eSNicolas Le Bayon return status; 6023684d0eSYann Gautier } 6123684d0eSYann Gautier 62c77c7d9eSNicolas Le Bayon status = (int)fdt_get_status(node); 63c77c7d9eSNicolas Le Bayon 64c77c7d9eSNicolas Le Bayon return status; 6523684d0eSYann Gautier } 6623684d0eSYann Gautier 67f564d439SEtienne Carriere static bool dt_pmic_is_secure(void) 68f564d439SEtienne Carriere { 69f564d439SEtienne Carriere int status = dt_pmic_status(); 70f564d439SEtienne Carriere 71f564d439SEtienne Carriere return (status >= 0) && 72f564d439SEtienne Carriere (status == DT_SECURE) && 73f564d439SEtienne Carriere (i2c_handle.dt_status == DT_SECURE); 74f564d439SEtienne Carriere } 75f564d439SEtienne Carriere 76d82d4ff0SYann Gautier /* 77d82d4ff0SYann Gautier * Get PMIC and its I2C bus configuration from the device tree. 78c77c7d9eSNicolas Le Bayon * Return 0 on success, negative on error, 1 if no PMIC node is defined. 79d82d4ff0SYann Gautier */ 80d82d4ff0SYann Gautier static int dt_pmic_i2c_config(struct dt_node_info *i2c_info, 81d82d4ff0SYann Gautier struct stm32_i2c_init_s *init) 8223684d0eSYann Gautier { 83c77c7d9eSNicolas Le Bayon static int i2c_node = -FDT_ERR_NOTFOUND; 8423684d0eSYann Gautier void *fdt; 8523684d0eSYann Gautier 8623684d0eSYann Gautier if (fdt_get_address(&fdt) == 0) { 87c77c7d9eSNicolas Le Bayon return -FDT_ERR_NOTFOUND; 8823684d0eSYann Gautier } 8923684d0eSYann Gautier 90c77c7d9eSNicolas Le Bayon if (i2c_node == -FDT_ERR_NOTFOUND) { 91c77c7d9eSNicolas Le Bayon int pmic_node; 92c77c7d9eSNicolas Le Bayon const fdt32_t *cuint; 93c77c7d9eSNicolas Le Bayon 9423684d0eSYann Gautier pmic_node = dt_get_pmic_node(fdt); 9523684d0eSYann Gautier if (pmic_node < 0) { 96c77c7d9eSNicolas Le Bayon return PMIC_NODE_NOT_FOUND; 9723684d0eSYann Gautier } 9823684d0eSYann Gautier 9923684d0eSYann Gautier cuint = fdt_getprop(fdt, pmic_node, "reg", NULL); 10023684d0eSYann Gautier if (cuint == NULL) { 10123684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 10223684d0eSYann Gautier } 10323684d0eSYann Gautier 10423684d0eSYann Gautier pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1; 10523684d0eSYann Gautier if (pmic_i2c_addr > UINT16_MAX) { 106c77c7d9eSNicolas Le Bayon return -FDT_ERR_BADVALUE; 10723684d0eSYann Gautier } 10823684d0eSYann Gautier 10923684d0eSYann Gautier i2c_node = fdt_parent_offset(fdt, pmic_node); 11023684d0eSYann Gautier if (i2c_node < 0) { 11123684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 11223684d0eSYann Gautier } 113c77c7d9eSNicolas Le Bayon } 11423684d0eSYann Gautier 11523684d0eSYann Gautier dt_fill_device_info(i2c_info, i2c_node); 11623684d0eSYann Gautier if (i2c_info->base == 0U) { 11723684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 11823684d0eSYann Gautier } 11923684d0eSYann Gautier 120d82d4ff0SYann Gautier return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init); 12123684d0eSYann Gautier } 12223684d0eSYann Gautier 123d82d4ff0SYann Gautier bool initialize_pmic_i2c(void) 12423684d0eSYann Gautier { 12523684d0eSYann Gautier int ret; 12623684d0eSYann Gautier struct dt_node_info i2c_info; 127d82d4ff0SYann Gautier struct i2c_handle_s *i2c = &i2c_handle; 128d82d4ff0SYann Gautier struct stm32_i2c_init_s i2c_init; 12923684d0eSYann Gautier 130d82d4ff0SYann Gautier ret = dt_pmic_i2c_config(&i2c_info, &i2c_init); 131d82d4ff0SYann Gautier if (ret < 0) { 132d82d4ff0SYann Gautier ERROR("I2C configuration failed %d\n", ret); 13323684d0eSYann Gautier panic(); 13423684d0eSYann Gautier } 13523684d0eSYann Gautier 136d82d4ff0SYann Gautier if (ret != 0) { 137d82d4ff0SYann Gautier return false; 13823684d0eSYann Gautier } 13923684d0eSYann Gautier 14023684d0eSYann Gautier /* Initialize PMIC I2C */ 141d82d4ff0SYann Gautier i2c->i2c_base_addr = i2c_info.base; 142d82d4ff0SYann Gautier i2c->dt_status = i2c_info.status; 143d82d4ff0SYann Gautier i2c->clock = i2c_info.clock; 14442822844SBenjamin Gaignard i2c->i2c_state = I2C_STATE_RESET; 145d82d4ff0SYann Gautier i2c_init.own_address1 = pmic_i2c_addr; 146d82d4ff0SYann Gautier i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT; 147d82d4ff0SYann Gautier i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE; 148d82d4ff0SYann Gautier i2c_init.own_address2 = 0; 149d82d4ff0SYann Gautier i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK; 150d82d4ff0SYann Gautier i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE; 151d82d4ff0SYann Gautier i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE; 152d82d4ff0SYann Gautier i2c_init.analog_filter = 1; 153d82d4ff0SYann Gautier i2c_init.digital_filter_coef = 0; 15423684d0eSYann Gautier 155d82d4ff0SYann Gautier ret = stm32_i2c_init(i2c, &i2c_init); 15623684d0eSYann Gautier if (ret != 0) { 15723684d0eSYann Gautier ERROR("Cannot initialize I2C %x (%d)\n", 158d82d4ff0SYann Gautier i2c->i2c_base_addr, ret); 15923684d0eSYann Gautier panic(); 16023684d0eSYann Gautier } 16123684d0eSYann Gautier 162d82d4ff0SYann Gautier if (!stm32_i2c_is_device_ready(i2c, pmic_i2c_addr, 1, 163d82d4ff0SYann Gautier I2C_TIMEOUT_BUSY_MS)) { 164d82d4ff0SYann Gautier ERROR("I2C device not ready\n"); 16523684d0eSYann Gautier panic(); 16623684d0eSYann Gautier } 16723684d0eSYann Gautier 168d82d4ff0SYann Gautier stpmic1_bind_i2c(i2c, (uint16_t)pmic_i2c_addr); 16923684d0eSYann Gautier 170d82d4ff0SYann Gautier return true; 17123684d0eSYann Gautier } 17223684d0eSYann Gautier 173f564d439SEtienne Carriere static void register_pmic_shared_peripherals(void) 174f564d439SEtienne Carriere { 175f564d439SEtienne Carriere uintptr_t i2c_base = i2c_handle.i2c_base_addr; 176f564d439SEtienne Carriere 177f564d439SEtienne Carriere if (dt_pmic_is_secure()) { 178f564d439SEtienne Carriere stm32mp_register_secure_periph_iomem(i2c_base); 179f564d439SEtienne Carriere } else { 180f564d439SEtienne Carriere if (i2c_base != 0U) { 181f564d439SEtienne Carriere stm32mp_register_non_secure_periph_iomem(i2c_base); 182f564d439SEtienne Carriere } 183f564d439SEtienne Carriere } 184f564d439SEtienne Carriere } 185f564d439SEtienne Carriere 18623684d0eSYann Gautier void initialize_pmic(void) 18723684d0eSYann Gautier { 188d82d4ff0SYann Gautier if (!initialize_pmic_i2c()) { 189d82d4ff0SYann Gautier VERBOSE("No PMIC\n"); 190d82d4ff0SYann Gautier return; 191d82d4ff0SYann Gautier } 19223684d0eSYann Gautier 193f564d439SEtienne Carriere register_pmic_shared_peripherals(); 194f564d439SEtienne Carriere 19585fb175bSYann Gautier if (register_pmic() < 0) { 196ae7792e0SNicolas Le Bayon panic(); 19785fb175bSYann Gautier } 19885fb175bSYann Gautier 19985fb175bSYann Gautier if (stpmic1_powerctrl_on() < 0) { 20085fb175bSYann Gautier panic(); 20185fb175bSYann Gautier } 20285fb175bSYann Gautier 203ae7792e0SNicolas Le Bayon } 204ae7792e0SNicolas Le Bayon 205ae7792e0SNicolas Le Bayon #if DEBUG 206ae7792e0SNicolas Le Bayon void print_pmic_info_and_debug(void) 207ae7792e0SNicolas Le Bayon { 208ae7792e0SNicolas Le Bayon unsigned long pmic_version; 209ae7792e0SNicolas Le Bayon 210d82d4ff0SYann Gautier if (stpmic1_get_version(&pmic_version) != 0) { 211d82d4ff0SYann Gautier ERROR("Failed to access PMIC\n"); 21223684d0eSYann Gautier panic(); 21323684d0eSYann Gautier } 21423684d0eSYann Gautier 215d82d4ff0SYann Gautier INFO("PMIC version = 0x%02lx\n", pmic_version); 21623684d0eSYann Gautier } 217ae7792e0SNicolas Le Bayon #endif 21823684d0eSYann Gautier 2195278ec3fSYann Gautier int pmic_voltages_init(void) 2205278ec3fSYann Gautier { 2215278ec3fSYann Gautier #if STM32MP13 2225278ec3fSYann Gautier struct rdev *buck1, *buck4; 2235278ec3fSYann Gautier int status; 2245278ec3fSYann Gautier 2255278ec3fSYann Gautier buck1 = regulator_get_by_name("buck1"); 2265278ec3fSYann Gautier if (buck1 == NULL) { 2275278ec3fSYann Gautier return -ENOENT; 2285278ec3fSYann Gautier } 2295278ec3fSYann Gautier 2305278ec3fSYann Gautier buck4 = regulator_get_by_name("buck4"); 2315278ec3fSYann Gautier if (buck4 == NULL) { 2325278ec3fSYann Gautier return -ENOENT; 2335278ec3fSYann Gautier } 2345278ec3fSYann Gautier 2355278ec3fSYann Gautier status = regulator_set_min_voltage(buck1); 2365278ec3fSYann Gautier if (status != 0) { 2375278ec3fSYann Gautier return status; 2385278ec3fSYann Gautier } 2395278ec3fSYann Gautier 2405278ec3fSYann Gautier status = regulator_set_min_voltage(buck4); 2415278ec3fSYann Gautier if (status != 0) { 2425278ec3fSYann Gautier return status; 2435278ec3fSYann Gautier } 2445278ec3fSYann Gautier #endif 2455278ec3fSYann Gautier 2465278ec3fSYann Gautier return 0; 2475278ec3fSYann Gautier } 2485278ec3fSYann Gautier 24985fb175bSYann Gautier enum { 25085fb175bSYann Gautier STPMIC1_BUCK1 = 0, 25185fb175bSYann Gautier STPMIC1_BUCK2, 25285fb175bSYann Gautier STPMIC1_BUCK3, 25385fb175bSYann Gautier STPMIC1_BUCK4, 25485fb175bSYann Gautier STPMIC1_LDO1, 25585fb175bSYann Gautier STPMIC1_LDO2, 25685fb175bSYann Gautier STPMIC1_LDO3, 25785fb175bSYann Gautier STPMIC1_LDO4, 25885fb175bSYann Gautier STPMIC1_LDO5, 25985fb175bSYann Gautier STPMIC1_LDO6, 26085fb175bSYann Gautier STPMIC1_VREF_DDR, 26185fb175bSYann Gautier STPMIC1_BOOST, 26285fb175bSYann Gautier STPMIC1_VBUS_OTG, 26385fb175bSYann Gautier STPMIC1_SW_OUT, 26485fb175bSYann Gautier }; 26585fb175bSYann Gautier 26685fb175bSYann Gautier static int pmic_set_state(const struct regul_description *desc, bool enable) 26785fb175bSYann Gautier { 26847065ffeSYann Gautier VERBOSE("%s: set state to %d\n", desc->node_name, enable); 26985fb175bSYann Gautier 27085fb175bSYann Gautier if (enable == STATE_ENABLE) { 27185fb175bSYann Gautier return stpmic1_regulator_enable(desc->node_name); 27285fb175bSYann Gautier } else { 27385fb175bSYann Gautier return stpmic1_regulator_disable(desc->node_name); 27485fb175bSYann Gautier } 27585fb175bSYann Gautier } 27685fb175bSYann Gautier 27785fb175bSYann Gautier static int pmic_get_state(const struct regul_description *desc) 27885fb175bSYann Gautier { 27985fb175bSYann Gautier VERBOSE("%s: get state\n", desc->node_name); 28085fb175bSYann Gautier 28185fb175bSYann Gautier return stpmic1_is_regulator_enabled(desc->node_name); 28285fb175bSYann Gautier } 28385fb175bSYann Gautier 28485fb175bSYann Gautier static int pmic_get_voltage(const struct regul_description *desc) 28585fb175bSYann Gautier { 28685fb175bSYann Gautier VERBOSE("%s: get volt\n", desc->node_name); 28785fb175bSYann Gautier 28885fb175bSYann Gautier return stpmic1_regulator_voltage_get(desc->node_name); 28985fb175bSYann Gautier } 29085fb175bSYann Gautier 29185fb175bSYann Gautier static int pmic_set_voltage(const struct regul_description *desc, uint16_t mv) 29285fb175bSYann Gautier { 29385fb175bSYann Gautier VERBOSE("%s: get volt\n", desc->node_name); 29485fb175bSYann Gautier 29585fb175bSYann Gautier return stpmic1_regulator_voltage_set(desc->node_name, mv); 29685fb175bSYann Gautier } 29785fb175bSYann Gautier 29885fb175bSYann Gautier static int pmic_list_voltages(const struct regul_description *desc, 29985fb175bSYann Gautier const uint16_t **levels, size_t *count) 30085fb175bSYann Gautier { 30185fb175bSYann Gautier VERBOSE("%s: list volt\n", desc->node_name); 30285fb175bSYann Gautier 30385fb175bSYann Gautier return stpmic1_regulator_levels_mv(desc->node_name, levels, count); 30485fb175bSYann Gautier } 30585fb175bSYann Gautier 30685fb175bSYann Gautier static int pmic_set_flag(const struct regul_description *desc, uint16_t flag) 30785fb175bSYann Gautier { 30885fb175bSYann Gautier VERBOSE("%s: set_flag 0x%x\n", desc->node_name, flag); 30985fb175bSYann Gautier 31085fb175bSYann Gautier switch (flag) { 31185fb175bSYann Gautier case REGUL_OCP: 31285fb175bSYann Gautier return stpmic1_regulator_icc_set(desc->node_name); 31385fb175bSYann Gautier 31485fb175bSYann Gautier case REGUL_ACTIVE_DISCHARGE: 31585fb175bSYann Gautier return stpmic1_active_discharge_mode_set(desc->node_name); 31685fb175bSYann Gautier 31785fb175bSYann Gautier case REGUL_PULL_DOWN: 31885fb175bSYann Gautier return stpmic1_regulator_pull_down_set(desc->node_name); 31985fb175bSYann Gautier 32085fb175bSYann Gautier case REGUL_MASK_RESET: 32185fb175bSYann Gautier return stpmic1_regulator_mask_reset_set(desc->node_name); 32285fb175bSYann Gautier 32385fb175bSYann Gautier case REGUL_SINK_SOURCE: 32485fb175bSYann Gautier return stpmic1_regulator_sink_mode_set(desc->node_name); 32585fb175bSYann Gautier 32685fb175bSYann Gautier case REGUL_ENABLE_BYPASS: 32785fb175bSYann Gautier return stpmic1_regulator_bypass_mode_set(desc->node_name); 32885fb175bSYann Gautier 32985fb175bSYann Gautier default: 33085fb175bSYann Gautier return -EINVAL; 33185fb175bSYann Gautier } 33285fb175bSYann Gautier } 33385fb175bSYann Gautier 33457e60183SYann Gautier static const struct regul_ops pmic_ops = { 33585fb175bSYann Gautier .set_state = pmic_set_state, 33685fb175bSYann Gautier .get_state = pmic_get_state, 33785fb175bSYann Gautier .set_voltage = pmic_set_voltage, 33885fb175bSYann Gautier .get_voltage = pmic_get_voltage, 33985fb175bSYann Gautier .list_voltages = pmic_list_voltages, 34085fb175bSYann Gautier .set_flag = pmic_set_flag, 34185fb175bSYann Gautier }; 34285fb175bSYann Gautier 34385fb175bSYann Gautier #define DEFINE_REGU(name) { \ 344be7195d0SYann Gautier .node_name = (name), \ 34585fb175bSYann Gautier .ops = &pmic_ops, \ 34685fb175bSYann Gautier .driver_data = NULL, \ 34785fb175bSYann Gautier .enable_ramp_delay = 1000, \ 34885fb175bSYann Gautier } 34985fb175bSYann Gautier 3503cebeec2SYann Gautier static const struct regul_description pmic_regs[NB_REG] = { 35185fb175bSYann Gautier [STPMIC1_BUCK1] = DEFINE_REGU("buck1"), 35285fb175bSYann Gautier [STPMIC1_BUCK2] = DEFINE_REGU("buck2"), 35385fb175bSYann Gautier [STPMIC1_BUCK3] = DEFINE_REGU("buck3"), 35485fb175bSYann Gautier [STPMIC1_BUCK4] = DEFINE_REGU("buck4"), 35585fb175bSYann Gautier [STPMIC1_LDO1] = DEFINE_REGU("ldo1"), 35685fb175bSYann Gautier [STPMIC1_LDO2] = DEFINE_REGU("ldo2"), 35785fb175bSYann Gautier [STPMIC1_LDO3] = DEFINE_REGU("ldo3"), 35885fb175bSYann Gautier [STPMIC1_LDO4] = DEFINE_REGU("ldo4"), 35985fb175bSYann Gautier [STPMIC1_LDO5] = DEFINE_REGU("ldo5"), 36085fb175bSYann Gautier [STPMIC1_LDO6] = DEFINE_REGU("ldo6"), 36185fb175bSYann Gautier [STPMIC1_VREF_DDR] = DEFINE_REGU("vref_ddr"), 36285fb175bSYann Gautier [STPMIC1_BOOST] = DEFINE_REGU("boost"), 36385fb175bSYann Gautier [STPMIC1_VBUS_OTG] = DEFINE_REGU("pwr_sw1"), 36485fb175bSYann Gautier [STPMIC1_SW_OUT] = DEFINE_REGU("pwr_sw2"), 36585fb175bSYann Gautier }; 36685fb175bSYann Gautier 36785fb175bSYann Gautier static int register_pmic(void) 36885fb175bSYann Gautier { 36985fb175bSYann Gautier void *fdt; 37085fb175bSYann Gautier int pmic_node, regulators_node, subnode; 37185fb175bSYann Gautier 37285fb175bSYann Gautier VERBOSE("Register pmic\n"); 37385fb175bSYann Gautier 37485fb175bSYann Gautier if (fdt_get_address(&fdt) == 0) { 37585fb175bSYann Gautier return -FDT_ERR_NOTFOUND; 37685fb175bSYann Gautier } 37785fb175bSYann Gautier 37885fb175bSYann Gautier pmic_node = dt_get_pmic_node(fdt); 37985fb175bSYann Gautier if (pmic_node < 0) { 38085fb175bSYann Gautier return pmic_node; 38185fb175bSYann Gautier } 38285fb175bSYann Gautier 38385fb175bSYann Gautier regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators"); 38485fb175bSYann Gautier if (regulators_node < 0) { 38585fb175bSYann Gautier return -ENOENT; 38685fb175bSYann Gautier } 38785fb175bSYann Gautier 38885fb175bSYann Gautier fdt_for_each_subnode(subnode, fdt, regulators_node) { 38985fb175bSYann Gautier const char *reg_name = fdt_get_name(fdt, subnode, NULL); 39085fb175bSYann Gautier const struct regul_description *desc; 39185fb175bSYann Gautier unsigned int i; 39285fb175bSYann Gautier int ret; 39385fb175bSYann Gautier 3943cebeec2SYann Gautier for (i = 0U; i < NB_REG; i++) { 39585fb175bSYann Gautier desc = &pmic_regs[i]; 39685fb175bSYann Gautier if (strcmp(desc->node_name, reg_name) == 0) { 39785fb175bSYann Gautier break; 39885fb175bSYann Gautier } 39985fb175bSYann Gautier } 40085fb175bSYann Gautier assert(i < NB_REG); 40185fb175bSYann Gautier 40285fb175bSYann Gautier ret = regulator_register(desc, subnode); 40385fb175bSYann Gautier if (ret != 0) { 40485fb175bSYann Gautier WARN("%s:%d failed to register %s\n", __func__, 40585fb175bSYann Gautier __LINE__, reg_name); 40685fb175bSYann Gautier return ret; 40785fb175bSYann Gautier } 40885fb175bSYann Gautier } 40985fb175bSYann Gautier 41085fb175bSYann Gautier return 0; 41185fb175bSYann Gautier } 412