1*817f42f0SPascal Paillet /* 2*817f42f0SPascal Paillet * Copyright (C) 2024, STMicroelectronics - All Rights Reserved 3*817f42f0SPascal Paillet * 4*817f42f0SPascal Paillet * SPDX-License-Identifier: BSD-3-Clause 5*817f42f0SPascal Paillet */ 6*817f42f0SPascal Paillet 7*817f42f0SPascal Paillet #include <assert.h> 8*817f42f0SPascal Paillet #include <errno.h> 9*817f42f0SPascal Paillet 10*817f42f0SPascal Paillet #include <common/debug.h> 11*817f42f0SPascal Paillet #include <drivers/delay_timer.h> 12*817f42f0SPascal Paillet #include <drivers/st/regulator.h> 13*817f42f0SPascal Paillet #include <drivers/st/stm32_i2c.h> 14*817f42f0SPascal Paillet #include <drivers/st/stm32mp_pmic2.h> 15*817f42f0SPascal Paillet #include <drivers/st/stpmic2.h> 16*817f42f0SPascal Paillet #include <lib/mmio.h> 17*817f42f0SPascal Paillet #include <lib/spinlock.h> 18*817f42f0SPascal Paillet #include <lib/utils_def.h> 19*817f42f0SPascal Paillet #include <libfdt.h> 20*817f42f0SPascal Paillet 21*817f42f0SPascal Paillet #include <platform_def.h> 22*817f42f0SPascal Paillet 23*817f42f0SPascal Paillet #define PMIC_NODE_NOT_FOUND 1 24*817f42f0SPascal Paillet 25*817f42f0SPascal Paillet struct regul_handle_s { 26*817f42f0SPascal Paillet const uint32_t id; 27*817f42f0SPascal Paillet uint16_t bypass_mv; 28*817f42f0SPascal Paillet }; 29*817f42f0SPascal Paillet 30*817f42f0SPascal Paillet static struct pmic_handle_s pmic2_handle; 31*817f42f0SPascal Paillet static struct i2c_handle_s i2c_handle; 32*817f42f0SPascal Paillet 33*817f42f0SPascal Paillet /* This driver is monoinstance */ 34*817f42f0SPascal Paillet static struct pmic_handle_s *pmic2; 35*817f42f0SPascal Paillet 36*817f42f0SPascal Paillet static int dt_get_pmic_node(void *fdt) 37*817f42f0SPascal Paillet { 38*817f42f0SPascal Paillet static int node = -FDT_ERR_BADOFFSET; 39*817f42f0SPascal Paillet 40*817f42f0SPascal Paillet if (node == -FDT_ERR_BADOFFSET) { 41*817f42f0SPascal Paillet node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic2"); 42*817f42f0SPascal Paillet } 43*817f42f0SPascal Paillet 44*817f42f0SPascal Paillet return node; 45*817f42f0SPascal Paillet } 46*817f42f0SPascal Paillet 47*817f42f0SPascal Paillet int dt_pmic_status(void) 48*817f42f0SPascal Paillet { 49*817f42f0SPascal Paillet static int status = -FDT_ERR_BADVALUE; 50*817f42f0SPascal Paillet int node; 51*817f42f0SPascal Paillet void *fdt; 52*817f42f0SPascal Paillet 53*817f42f0SPascal Paillet if (status != -FDT_ERR_BADVALUE) { 54*817f42f0SPascal Paillet return status; 55*817f42f0SPascal Paillet } 56*817f42f0SPascal Paillet 57*817f42f0SPascal Paillet if (fdt_get_address(&fdt) == 0) { 58*817f42f0SPascal Paillet return -ENOENT; 59*817f42f0SPascal Paillet } 60*817f42f0SPascal Paillet 61*817f42f0SPascal Paillet node = dt_get_pmic_node(fdt); 62*817f42f0SPascal Paillet if (node <= 0) { 63*817f42f0SPascal Paillet status = -FDT_ERR_NOTFOUND; 64*817f42f0SPascal Paillet 65*817f42f0SPascal Paillet return status; 66*817f42f0SPascal Paillet } 67*817f42f0SPascal Paillet 68*817f42f0SPascal Paillet status = DT_SECURE; 69*817f42f0SPascal Paillet 70*817f42f0SPascal Paillet return status; 71*817f42f0SPascal Paillet } 72*817f42f0SPascal Paillet 73*817f42f0SPascal Paillet /* 74*817f42f0SPascal Paillet * Get PMIC and its I2C bus configuration from the device tree. 75*817f42f0SPascal Paillet * Return 0 on success, negative on error, 1 if no PMIC node is defined. 76*817f42f0SPascal Paillet */ 77*817f42f0SPascal Paillet static int dt_pmic2_i2c_config(struct dt_node_info *i2c_info, 78*817f42f0SPascal Paillet struct stm32_i2c_init_s *init, 79*817f42f0SPascal Paillet uint32_t *i2c_addr) 80*817f42f0SPascal Paillet { 81*817f42f0SPascal Paillet static int i2c_node = -FDT_ERR_NOTFOUND; 82*817f42f0SPascal Paillet void *fdt; 83*817f42f0SPascal Paillet 84*817f42f0SPascal Paillet if (fdt_get_address(&fdt) == 0) { 85*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND; 86*817f42f0SPascal Paillet } 87*817f42f0SPascal Paillet 88*817f42f0SPascal Paillet if (i2c_node == -FDT_ERR_NOTFOUND) { 89*817f42f0SPascal Paillet int pmic_node; 90*817f42f0SPascal Paillet const fdt32_t *cuint; 91*817f42f0SPascal Paillet 92*817f42f0SPascal Paillet pmic_node = dt_get_pmic_node(fdt); 93*817f42f0SPascal Paillet if (pmic_node < 0) { 94*817f42f0SPascal Paillet return PMIC_NODE_NOT_FOUND; 95*817f42f0SPascal Paillet } 96*817f42f0SPascal Paillet 97*817f42f0SPascal Paillet cuint = fdt_getprop(fdt, pmic_node, "reg", NULL); 98*817f42f0SPascal Paillet if (cuint == NULL) { 99*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND; 100*817f42f0SPascal Paillet } 101*817f42f0SPascal Paillet 102*817f42f0SPascal Paillet *i2c_addr = fdt32_to_cpu(*cuint) << 1; 103*817f42f0SPascal Paillet if (*i2c_addr > UINT16_MAX) { 104*817f42f0SPascal Paillet return -FDT_ERR_BADVALUE; 105*817f42f0SPascal Paillet } 106*817f42f0SPascal Paillet 107*817f42f0SPascal Paillet i2c_node = fdt_parent_offset(fdt, pmic_node); 108*817f42f0SPascal Paillet if (i2c_node < 0) { 109*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND; 110*817f42f0SPascal Paillet } 111*817f42f0SPascal Paillet } 112*817f42f0SPascal Paillet 113*817f42f0SPascal Paillet dt_fill_device_info(i2c_info, i2c_node); 114*817f42f0SPascal Paillet if (i2c_info->base == 0U) { 115*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND; 116*817f42f0SPascal Paillet } 117*817f42f0SPascal Paillet 118*817f42f0SPascal Paillet i2c_info->status = DT_SECURE; 119*817f42f0SPascal Paillet 120*817f42f0SPascal Paillet return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init); 121*817f42f0SPascal Paillet } 122*817f42f0SPascal Paillet 123*817f42f0SPascal Paillet bool initialize_pmic_i2c(void) 124*817f42f0SPascal Paillet { 125*817f42f0SPascal Paillet int ret; 126*817f42f0SPascal Paillet struct dt_node_info i2c_info; 127*817f42f0SPascal Paillet struct i2c_handle_s *i2c = &i2c_handle; 128*817f42f0SPascal Paillet uint32_t i2c_addr = 0U; 129*817f42f0SPascal Paillet struct stm32_i2c_init_s i2c_init; 130*817f42f0SPascal Paillet 131*817f42f0SPascal Paillet ret = dt_pmic2_i2c_config(&i2c_info, &i2c_init, &i2c_addr); 132*817f42f0SPascal Paillet if (ret < 0) { 133*817f42f0SPascal Paillet ERROR("I2C configuration failed %d\n", ret); 134*817f42f0SPascal Paillet panic(); 135*817f42f0SPascal Paillet } 136*817f42f0SPascal Paillet 137*817f42f0SPascal Paillet if (ret != 0) { 138*817f42f0SPascal Paillet return false; 139*817f42f0SPascal Paillet } 140*817f42f0SPascal Paillet 141*817f42f0SPascal Paillet /* Initialize PMIC I2C */ 142*817f42f0SPascal Paillet i2c->i2c_base_addr = i2c_info.base; 143*817f42f0SPascal Paillet i2c->dt_status = i2c_info.status; 144*817f42f0SPascal Paillet i2c->clock = i2c_info.clock; 145*817f42f0SPascal Paillet i2c->i2c_state = I2C_STATE_RESET; 146*817f42f0SPascal Paillet i2c_init.own_address1 = i2c_addr; 147*817f42f0SPascal Paillet i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT; 148*817f42f0SPascal Paillet i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE; 149*817f42f0SPascal Paillet i2c_init.own_address2 = 0; 150*817f42f0SPascal Paillet i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK; 151*817f42f0SPascal Paillet i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE; 152*817f42f0SPascal Paillet i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE; 153*817f42f0SPascal Paillet i2c_init.analog_filter = 1; 154*817f42f0SPascal Paillet i2c_init.digital_filter_coef = 0; 155*817f42f0SPascal Paillet 156*817f42f0SPascal Paillet ret = stm32_i2c_init(i2c, &i2c_init); 157*817f42f0SPascal Paillet if (ret != 0) { 158*817f42f0SPascal Paillet ERROR("Cannot initialize I2C %x (%d)\n", 159*817f42f0SPascal Paillet i2c->i2c_base_addr, ret); 160*817f42f0SPascal Paillet panic(); 161*817f42f0SPascal Paillet } 162*817f42f0SPascal Paillet 163*817f42f0SPascal Paillet if (!stm32_i2c_is_device_ready(i2c, i2c_addr, 1, 164*817f42f0SPascal Paillet I2C_TIMEOUT_BUSY_MS)) { 165*817f42f0SPascal Paillet ERROR("I2C device not ready\n"); 166*817f42f0SPascal Paillet panic(); 167*817f42f0SPascal Paillet } 168*817f42f0SPascal Paillet 169*817f42f0SPascal Paillet pmic2 = &pmic2_handle; 170*817f42f0SPascal Paillet pmic2->i2c_handle = &i2c_handle; 171*817f42f0SPascal Paillet pmic2->i2c_addr = i2c_addr; 172*817f42f0SPascal Paillet 173*817f42f0SPascal Paillet return true; 174*817f42f0SPascal Paillet } 175*817f42f0SPascal Paillet 176*817f42f0SPascal Paillet static int pmic2_set_state(const struct regul_description *desc, bool enable) 177*817f42f0SPascal Paillet { 178*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 179*817f42f0SPascal Paillet 180*817f42f0SPascal Paillet VERBOSE("%s: set state to %d\n", desc->node_name, enable); 181*817f42f0SPascal Paillet 182*817f42f0SPascal Paillet return stpmic2_regulator_set_state(pmic2, regul->id, enable); 183*817f42f0SPascal Paillet } 184*817f42f0SPascal Paillet 185*817f42f0SPascal Paillet static int pmic2_get_state(const struct regul_description *desc) 186*817f42f0SPascal Paillet { 187*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 188*817f42f0SPascal Paillet bool enabled; 189*817f42f0SPascal Paillet 190*817f42f0SPascal Paillet VERBOSE("%s: get state\n", desc->node_name); 191*817f42f0SPascal Paillet 192*817f42f0SPascal Paillet if (stpmic2_regulator_get_state(pmic2, regul->id, &enabled) < 0) { 193*817f42f0SPascal Paillet panic(); 194*817f42f0SPascal Paillet } 195*817f42f0SPascal Paillet 196*817f42f0SPascal Paillet return enabled; 197*817f42f0SPascal Paillet } 198*817f42f0SPascal Paillet 199*817f42f0SPascal Paillet static int pmic2_get_voltage(const struct regul_description *desc) 200*817f42f0SPascal Paillet { 201*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 202*817f42f0SPascal Paillet uint16_t mv; 203*817f42f0SPascal Paillet 204*817f42f0SPascal Paillet VERBOSE("%s: get volt\n", desc->node_name); 205*817f42f0SPascal Paillet 206*817f42f0SPascal Paillet if (regul->bypass_mv != 0U) { 207*817f42f0SPascal Paillet int ret; 208*817f42f0SPascal Paillet 209*817f42f0SPascal Paillet /* If the regul is in bypass mode, return bypass value */ 210*817f42f0SPascal Paillet ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS); 211*817f42f0SPascal Paillet if (ret < 0) { 212*817f42f0SPascal Paillet return ret; 213*817f42f0SPascal Paillet } 214*817f42f0SPascal Paillet 215*817f42f0SPascal Paillet if (ret == 1) { 216*817f42f0SPascal Paillet return regul->bypass_mv; 217*817f42f0SPascal Paillet } 218*817f42f0SPascal Paillet }; 219*817f42f0SPascal Paillet 220*817f42f0SPascal Paillet if (stpmic2_regulator_get_voltage(pmic2, regul->id, &mv) < 0) { 221*817f42f0SPascal Paillet panic(); 222*817f42f0SPascal Paillet } 223*817f42f0SPascal Paillet 224*817f42f0SPascal Paillet return mv; 225*817f42f0SPascal Paillet } 226*817f42f0SPascal Paillet 227*817f42f0SPascal Paillet static int pmic2_set_voltage(const struct regul_description *desc, uint16_t mv) 228*817f42f0SPascal Paillet { 229*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 230*817f42f0SPascal Paillet 231*817f42f0SPascal Paillet VERBOSE("%s: set volt\n", desc->node_name); 232*817f42f0SPascal Paillet 233*817f42f0SPascal Paillet if (regul->bypass_mv != 0U) { 234*817f42f0SPascal Paillet int ret; 235*817f42f0SPascal Paillet 236*817f42f0SPascal Paillet /* If the regul is in bypass mode, authorize bypass mV */ 237*817f42f0SPascal Paillet ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS); 238*817f42f0SPascal Paillet if (ret < 0) { 239*817f42f0SPascal Paillet return ret; 240*817f42f0SPascal Paillet } 241*817f42f0SPascal Paillet 242*817f42f0SPascal Paillet if ((ret == 1) && (mv != regul->bypass_mv)) { 243*817f42f0SPascal Paillet return -EPERM; 244*817f42f0SPascal Paillet } 245*817f42f0SPascal Paillet }; 246*817f42f0SPascal Paillet 247*817f42f0SPascal Paillet return stpmic2_regulator_set_voltage(pmic2, regul->id, mv); 248*817f42f0SPascal Paillet } 249*817f42f0SPascal Paillet 250*817f42f0SPascal Paillet static int pmic2_list_voltages(const struct regul_description *desc, 251*817f42f0SPascal Paillet const uint16_t **levels, size_t *count) 252*817f42f0SPascal Paillet { 253*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 254*817f42f0SPascal Paillet 255*817f42f0SPascal Paillet VERBOSE("%s: list volt\n", desc->node_name); 256*817f42f0SPascal Paillet 257*817f42f0SPascal Paillet if (regul->bypass_mv != 0U) { 258*817f42f0SPascal Paillet int ret; 259*817f42f0SPascal Paillet 260*817f42f0SPascal Paillet ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS); 261*817f42f0SPascal Paillet if (ret < 0) { 262*817f42f0SPascal Paillet return ret; 263*817f42f0SPascal Paillet } 264*817f42f0SPascal Paillet 265*817f42f0SPascal Paillet /* bypass is enabled, return a list with only bypass mV */ 266*817f42f0SPascal Paillet if (ret == 1) { 267*817f42f0SPascal Paillet if (count != NULL) { 268*817f42f0SPascal Paillet *count = 1U; 269*817f42f0SPascal Paillet } 270*817f42f0SPascal Paillet if (levels != NULL) { 271*817f42f0SPascal Paillet *levels = ®ul->bypass_mv; 272*817f42f0SPascal Paillet } 273*817f42f0SPascal Paillet return 0; 274*817f42f0SPascal Paillet } 275*817f42f0SPascal Paillet }; 276*817f42f0SPascal Paillet 277*817f42f0SPascal Paillet return stpmic2_regulator_levels_mv(pmic2, regul->id, levels, count); 278*817f42f0SPascal Paillet } 279*817f42f0SPascal Paillet 280*817f42f0SPascal Paillet static int pmic2_set_flag(const struct regul_description *desc, uint16_t flag) 281*817f42f0SPascal Paillet { 282*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 283*817f42f0SPascal Paillet uint32_t id = regul->id; 284*817f42f0SPascal Paillet int ret = -EPERM; 285*817f42f0SPascal Paillet 286*817f42f0SPascal Paillet VERBOSE("%s: set_flag 0x%x\n", desc->node_name, flag); 287*817f42f0SPascal Paillet 288*817f42f0SPascal Paillet switch (flag) { 289*817f42f0SPascal Paillet case REGUL_PULL_DOWN: 290*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_PULL_DOWN, 1U); 291*817f42f0SPascal Paillet break; 292*817f42f0SPascal Paillet case REGUL_OCP: 293*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_OCP, 1U); 294*817f42f0SPascal Paillet break; 295*817f42f0SPascal Paillet case REGUL_SINK_SOURCE: 296*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_SINK_SOURCE, 1U); 297*817f42f0SPascal Paillet break; 298*817f42f0SPascal Paillet case REGUL_ENABLE_BYPASS: 299*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_BYPASS, 1U); 300*817f42f0SPascal Paillet break; 301*817f42f0SPascal Paillet case REGUL_MASK_RESET: 302*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_MASK_RESET, 1U); 303*817f42f0SPascal Paillet break; 304*817f42f0SPascal Paillet default: 305*817f42f0SPascal Paillet ERROR("Invalid flag %u", flag); 306*817f42f0SPascal Paillet panic(); 307*817f42f0SPascal Paillet } 308*817f42f0SPascal Paillet 309*817f42f0SPascal Paillet if (ret != 0) { 310*817f42f0SPascal Paillet return -EPERM; 311*817f42f0SPascal Paillet } 312*817f42f0SPascal Paillet 313*817f42f0SPascal Paillet return 0; 314*817f42f0SPascal Paillet } 315*817f42f0SPascal Paillet 316*817f42f0SPascal Paillet int stpmic2_set_prop(const struct regul_description *desc, uint16_t prop, uint32_t value) 317*817f42f0SPascal Paillet { 318*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 319*817f42f0SPascal Paillet int ret; 320*817f42f0SPascal Paillet 321*817f42f0SPascal Paillet VERBOSE("%s: set_prop 0x%x val=%u\n", desc->node_name, prop, value); 322*817f42f0SPascal Paillet 323*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, regul->id, prop, value); 324*817f42f0SPascal Paillet if (ret != 0) 325*817f42f0SPascal Paillet return -EPERM; 326*817f42f0SPascal Paillet 327*817f42f0SPascal Paillet return 0; 328*817f42f0SPascal Paillet } 329*817f42f0SPascal Paillet 330*817f42f0SPascal Paillet static struct regul_ops pmic2_ops = { 331*817f42f0SPascal Paillet .set_state = pmic2_set_state, 332*817f42f0SPascal Paillet .get_state = pmic2_get_state, 333*817f42f0SPascal Paillet .set_voltage = pmic2_set_voltage, 334*817f42f0SPascal Paillet .get_voltage = pmic2_get_voltage, 335*817f42f0SPascal Paillet .list_voltages = pmic2_list_voltages, 336*817f42f0SPascal Paillet .set_flag = pmic2_set_flag, 337*817f42f0SPascal Paillet }; 338*817f42f0SPascal Paillet 339*817f42f0SPascal Paillet #define DEFINE_PMIC_REGUL_HANDLE(rid) \ 340*817f42f0SPascal Paillet [(rid)] = { \ 341*817f42f0SPascal Paillet .id = (rid), \ 342*817f42f0SPascal Paillet } 343*817f42f0SPascal Paillet 344*817f42f0SPascal Paillet static struct regul_handle_s pmic2_regul_handles[STPMIC2_NB_REG] = { 345*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK1), 346*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK2), 347*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK3), 348*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK4), 349*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK5), 350*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK6), 351*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK7), 352*817f42f0SPascal Paillet 353*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO1), 354*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO2), 355*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO3), 356*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO4), 357*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO5), 358*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO6), 359*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO7), 360*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO8), 361*817f42f0SPascal Paillet 362*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_REFDDR), 363*817f42f0SPascal Paillet }; 364*817f42f0SPascal Paillet 365*817f42f0SPascal Paillet #define DEFINE_REGUL(rid, name) \ 366*817f42f0SPascal Paillet [rid] = { \ 367*817f42f0SPascal Paillet .node_name = name, \ 368*817f42f0SPascal Paillet .ops = &pmic2_ops, \ 369*817f42f0SPascal Paillet .driver_data = &pmic2_regul_handles[rid], \ 370*817f42f0SPascal Paillet } 371*817f42f0SPascal Paillet 372*817f42f0SPascal Paillet static const struct regul_description pmic2_descs[STPMIC2_NB_REG] = { 373*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK1, "buck1"), 374*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK2, "buck2"), 375*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK3, "buck3"), 376*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK4, "buck4"), 377*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK5, "buck5"), 378*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK6, "buck6"), 379*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK7, "buck7"), 380*817f42f0SPascal Paillet 381*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO1, "ldo1"), 382*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO2, "ldo2"), 383*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO3, "ldo3"), 384*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO4, "ldo4"), 385*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO5, "ldo5"), 386*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO6, "ldo6"), 387*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO7, "ldo7"), 388*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO8, "ldo8"), 389*817f42f0SPascal Paillet 390*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_REFDDR, "refddr"), 391*817f42f0SPascal Paillet }; 392*817f42f0SPascal Paillet 393*817f42f0SPascal Paillet static int register_pmic2(void) 394*817f42f0SPascal Paillet { 395*817f42f0SPascal Paillet void *fdt; 396*817f42f0SPascal Paillet int pmic_node, regulators_node, subnode; 397*817f42f0SPascal Paillet 398*817f42f0SPascal Paillet VERBOSE("Register pmic2\n"); 399*817f42f0SPascal Paillet 400*817f42f0SPascal Paillet if (fdt_get_address(&fdt) == 0) { 401*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND; 402*817f42f0SPascal Paillet } 403*817f42f0SPascal Paillet 404*817f42f0SPascal Paillet pmic_node = dt_get_pmic_node(fdt); 405*817f42f0SPascal Paillet if (pmic_node < 0) { 406*817f42f0SPascal Paillet return pmic_node; 407*817f42f0SPascal Paillet } 408*817f42f0SPascal Paillet 409*817f42f0SPascal Paillet regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators"); 410*817f42f0SPascal Paillet if (regulators_node < 0) { 411*817f42f0SPascal Paillet return -ENOENT; 412*817f42f0SPascal Paillet } 413*817f42f0SPascal Paillet 414*817f42f0SPascal Paillet fdt_for_each_subnode(subnode, fdt, regulators_node) { 415*817f42f0SPascal Paillet const char *reg_name = fdt_get_name(fdt, subnode, NULL); 416*817f42f0SPascal Paillet const struct regul_description *desc; 417*817f42f0SPascal Paillet unsigned int i; 418*817f42f0SPascal Paillet int ret; 419*817f42f0SPascal Paillet const fdt32_t *cuint; 420*817f42f0SPascal Paillet 421*817f42f0SPascal Paillet for (i = 0; i < STPMIC2_NB_REG; i++) { 422*817f42f0SPascal Paillet desc = &pmic2_descs[i]; 423*817f42f0SPascal Paillet if (strcmp(desc->node_name, reg_name) == 0) { 424*817f42f0SPascal Paillet break; 425*817f42f0SPascal Paillet } 426*817f42f0SPascal Paillet } 427*817f42f0SPascal Paillet assert(i < STPMIC2_NB_REG); 428*817f42f0SPascal Paillet 429*817f42f0SPascal Paillet ret = regulator_register(desc, subnode); 430*817f42f0SPascal Paillet if (ret != 0) { 431*817f42f0SPascal Paillet WARN("%s:%d failed to register %s\n", __func__, 432*817f42f0SPascal Paillet __LINE__, reg_name); 433*817f42f0SPascal Paillet return ret; 434*817f42f0SPascal Paillet } 435*817f42f0SPascal Paillet 436*817f42f0SPascal Paillet cuint = fdt_getprop(fdt, subnode, "st,regulator-bypass-microvolt", NULL); 437*817f42f0SPascal Paillet if (cuint != NULL) { 438*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data; 439*817f42f0SPascal Paillet 440*817f42f0SPascal Paillet regul->bypass_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U); 441*817f42f0SPascal Paillet VERBOSE("%s: bypass voltage=%umV\n", desc->node_name, 442*817f42f0SPascal Paillet regul->bypass_mv); 443*817f42f0SPascal Paillet } 444*817f42f0SPascal Paillet 445*817f42f0SPascal Paillet if (fdt_getprop(fdt, subnode, "st,mask-reset", NULL) != NULL) { 446*817f42f0SPascal Paillet VERBOSE("%s: set mask-reset\n", desc->node_name); 447*817f42f0SPascal Paillet ret = pmic2_set_flag(desc, REGUL_MASK_RESET); 448*817f42f0SPascal Paillet if (ret != 0) { 449*817f42f0SPascal Paillet ERROR("set mask-reset failed\n"); 450*817f42f0SPascal Paillet return ret; 451*817f42f0SPascal Paillet } 452*817f42f0SPascal Paillet } 453*817f42f0SPascal Paillet 454*817f42f0SPascal Paillet if (fdt_getprop(fdt, subnode, "st,regulator-sink-source", NULL) != NULL) { 455*817f42f0SPascal Paillet VERBOSE("%s: set regulator-sink-source\n", desc->node_name); 456*817f42f0SPascal Paillet ret = pmic2_set_flag(desc, REGUL_SINK_SOURCE); 457*817f42f0SPascal Paillet if (ret != 0) { 458*817f42f0SPascal Paillet ERROR("set regulator-sink-source failed\n"); 459*817f42f0SPascal Paillet return ret; 460*817f42f0SPascal Paillet } 461*817f42f0SPascal Paillet } 462*817f42f0SPascal Paillet } 463*817f42f0SPascal Paillet 464*817f42f0SPascal Paillet return 0; 465*817f42f0SPascal Paillet } 466*817f42f0SPascal Paillet 467*817f42f0SPascal Paillet void initialize_pmic(void) 468*817f42f0SPascal Paillet { 469*817f42f0SPascal Paillet int ret; 470*817f42f0SPascal Paillet uint8_t val; 471*817f42f0SPascal Paillet 472*817f42f0SPascal Paillet ret = initialize_pmic_i2c(); 473*817f42f0SPascal Paillet if (!ret) { 474*817f42f0SPascal Paillet VERBOSE("No PMIC2\n"); 475*817f42f0SPascal Paillet return; 476*817f42f0SPascal Paillet } 477*817f42f0SPascal Paillet 478*817f42f0SPascal Paillet if (stpmic2_get_version(pmic2, &val) != 0) { 479*817f42f0SPascal Paillet ERROR("Failed to access PMIC\n"); 480*817f42f0SPascal Paillet panic(); 481*817f42f0SPascal Paillet } 482*817f42f0SPascal Paillet INFO("PMIC2 version = 0x%02x\n", val); 483*817f42f0SPascal Paillet 484*817f42f0SPascal Paillet if (stpmic2_get_product_id(pmic2, &val) != 0) { 485*817f42f0SPascal Paillet ERROR("Failed to access PMIC\n"); 486*817f42f0SPascal Paillet panic(); 487*817f42f0SPascal Paillet } 488*817f42f0SPascal Paillet INFO("PMIC2 product ID = 0x%02x\n", val); 489*817f42f0SPascal Paillet 490*817f42f0SPascal Paillet ret = register_pmic2(); 491*817f42f0SPascal Paillet if (ret < 0) { 492*817f42f0SPascal Paillet ERROR("Register pmic2 failed\n"); 493*817f42f0SPascal Paillet panic(); 494*817f42f0SPascal Paillet } 495*817f42f0SPascal Paillet 496*817f42f0SPascal Paillet #if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE 497*817f42f0SPascal Paillet stpmic2_dump_regulators(pmic2); 498*817f42f0SPascal Paillet #endif 499*817f42f0SPascal Paillet } 500