1*23684d0eSYann Gautier /* 2*23684d0eSYann Gautier * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved 3*23684d0eSYann Gautier * 4*23684d0eSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 5*23684d0eSYann Gautier */ 6*23684d0eSYann Gautier 7*23684d0eSYann Gautier #include <string.h> 8*23684d0eSYann Gautier 9*23684d0eSYann Gautier #include <common/debug.h> 10*23684d0eSYann Gautier #include <drivers/st/stpmic1.h> 11*23684d0eSYann Gautier #include <plat/common/platform.h> 12*23684d0eSYann Gautier 13*23684d0eSYann Gautier struct regul_struct { 14*23684d0eSYann Gautier const char *dt_node_name; 15*23684d0eSYann Gautier const uint16_t *voltage_table; 16*23684d0eSYann Gautier uint8_t voltage_table_size; 17*23684d0eSYann Gautier uint8_t control_reg; 18*23684d0eSYann Gautier uint8_t low_power_reg; 19*23684d0eSYann Gautier }; 20*23684d0eSYann Gautier 21*23684d0eSYann Gautier static struct i2c_handle_s *pmic_i2c_handle; 22*23684d0eSYann Gautier static uint16_t pmic_i2c_addr; 23*23684d0eSYann Gautier 24*23684d0eSYann Gautier /* Voltage tables in mV */ 25*23684d0eSYann Gautier static const uint16_t buck1_voltage_table[] = { 26*23684d0eSYann Gautier 600, 27*23684d0eSYann Gautier 625, 28*23684d0eSYann Gautier 650, 29*23684d0eSYann Gautier 675, 30*23684d0eSYann Gautier 700, 31*23684d0eSYann Gautier 725, 32*23684d0eSYann Gautier 750, 33*23684d0eSYann Gautier 775, 34*23684d0eSYann Gautier 800, 35*23684d0eSYann Gautier 825, 36*23684d0eSYann Gautier 850, 37*23684d0eSYann Gautier 875, 38*23684d0eSYann Gautier 900, 39*23684d0eSYann Gautier 925, 40*23684d0eSYann Gautier 950, 41*23684d0eSYann Gautier 975, 42*23684d0eSYann Gautier 1000, 43*23684d0eSYann Gautier 1025, 44*23684d0eSYann Gautier 1050, 45*23684d0eSYann Gautier 1075, 46*23684d0eSYann Gautier 1100, 47*23684d0eSYann Gautier 1125, 48*23684d0eSYann Gautier 1150, 49*23684d0eSYann Gautier 1175, 50*23684d0eSYann Gautier 1200, 51*23684d0eSYann Gautier 1225, 52*23684d0eSYann Gautier 1250, 53*23684d0eSYann Gautier 1275, 54*23684d0eSYann Gautier 1300, 55*23684d0eSYann Gautier 1325, 56*23684d0eSYann Gautier 1350, 57*23684d0eSYann Gautier 1350, 58*23684d0eSYann Gautier }; 59*23684d0eSYann Gautier 60*23684d0eSYann Gautier static const uint16_t buck2_voltage_table[] = { 61*23684d0eSYann Gautier 1000, 62*23684d0eSYann Gautier 1000, 63*23684d0eSYann Gautier 1000, 64*23684d0eSYann Gautier 1000, 65*23684d0eSYann Gautier 1000, 66*23684d0eSYann Gautier 1000, 67*23684d0eSYann Gautier 1000, 68*23684d0eSYann Gautier 1000, 69*23684d0eSYann Gautier 1000, 70*23684d0eSYann Gautier 1000, 71*23684d0eSYann Gautier 1000, 72*23684d0eSYann Gautier 1000, 73*23684d0eSYann Gautier 1000, 74*23684d0eSYann Gautier 1000, 75*23684d0eSYann Gautier 1000, 76*23684d0eSYann Gautier 1000, 77*23684d0eSYann Gautier 1000, 78*23684d0eSYann Gautier 1000, 79*23684d0eSYann Gautier 1050, 80*23684d0eSYann Gautier 1050, 81*23684d0eSYann Gautier 1100, 82*23684d0eSYann Gautier 1100, 83*23684d0eSYann Gautier 1150, 84*23684d0eSYann Gautier 1150, 85*23684d0eSYann Gautier 1200, 86*23684d0eSYann Gautier 1200, 87*23684d0eSYann Gautier 1250, 88*23684d0eSYann Gautier 1250, 89*23684d0eSYann Gautier 1300, 90*23684d0eSYann Gautier 1300, 91*23684d0eSYann Gautier 1350, 92*23684d0eSYann Gautier 1350, 93*23684d0eSYann Gautier 1400, 94*23684d0eSYann Gautier 1400, 95*23684d0eSYann Gautier 1450, 96*23684d0eSYann Gautier 1450, 97*23684d0eSYann Gautier 1500, 98*23684d0eSYann Gautier }; 99*23684d0eSYann Gautier 100*23684d0eSYann Gautier static const uint16_t buck3_voltage_table[] = { 101*23684d0eSYann Gautier 1000, 102*23684d0eSYann Gautier 1000, 103*23684d0eSYann Gautier 1000, 104*23684d0eSYann Gautier 1000, 105*23684d0eSYann Gautier 1000, 106*23684d0eSYann Gautier 1000, 107*23684d0eSYann Gautier 1000, 108*23684d0eSYann Gautier 1000, 109*23684d0eSYann Gautier 1000, 110*23684d0eSYann Gautier 1000, 111*23684d0eSYann Gautier 1000, 112*23684d0eSYann Gautier 1000, 113*23684d0eSYann Gautier 1000, 114*23684d0eSYann Gautier 1000, 115*23684d0eSYann Gautier 1000, 116*23684d0eSYann Gautier 1000, 117*23684d0eSYann Gautier 1000, 118*23684d0eSYann Gautier 1000, 119*23684d0eSYann Gautier 1000, 120*23684d0eSYann Gautier 1000, 121*23684d0eSYann Gautier 1100, 122*23684d0eSYann Gautier 1100, 123*23684d0eSYann Gautier 1100, 124*23684d0eSYann Gautier 1100, 125*23684d0eSYann Gautier 1200, 126*23684d0eSYann Gautier 1200, 127*23684d0eSYann Gautier 1200, 128*23684d0eSYann Gautier 1200, 129*23684d0eSYann Gautier 1300, 130*23684d0eSYann Gautier 1300, 131*23684d0eSYann Gautier 1300, 132*23684d0eSYann Gautier 1300, 133*23684d0eSYann Gautier 1400, 134*23684d0eSYann Gautier 1400, 135*23684d0eSYann Gautier 1400, 136*23684d0eSYann Gautier 1400, 137*23684d0eSYann Gautier 1500, 138*23684d0eSYann Gautier 1600, 139*23684d0eSYann Gautier 1700, 140*23684d0eSYann Gautier 1800, 141*23684d0eSYann Gautier 1900, 142*23684d0eSYann Gautier 2000, 143*23684d0eSYann Gautier 2100, 144*23684d0eSYann Gautier 2200, 145*23684d0eSYann Gautier 2300, 146*23684d0eSYann Gautier 2400, 147*23684d0eSYann Gautier 2500, 148*23684d0eSYann Gautier 2600, 149*23684d0eSYann Gautier 2700, 150*23684d0eSYann Gautier 2800, 151*23684d0eSYann Gautier 2900, 152*23684d0eSYann Gautier 3000, 153*23684d0eSYann Gautier 3100, 154*23684d0eSYann Gautier 3200, 155*23684d0eSYann Gautier 3300, 156*23684d0eSYann Gautier 3400, 157*23684d0eSYann Gautier }; 158*23684d0eSYann Gautier 159*23684d0eSYann Gautier static const uint16_t buck4_voltage_table[] = { 160*23684d0eSYann Gautier 600, 161*23684d0eSYann Gautier 625, 162*23684d0eSYann Gautier 650, 163*23684d0eSYann Gautier 675, 164*23684d0eSYann Gautier 700, 165*23684d0eSYann Gautier 725, 166*23684d0eSYann Gautier 750, 167*23684d0eSYann Gautier 775, 168*23684d0eSYann Gautier 800, 169*23684d0eSYann Gautier 825, 170*23684d0eSYann Gautier 850, 171*23684d0eSYann Gautier 875, 172*23684d0eSYann Gautier 900, 173*23684d0eSYann Gautier 925, 174*23684d0eSYann Gautier 950, 175*23684d0eSYann Gautier 975, 176*23684d0eSYann Gautier 1000, 177*23684d0eSYann Gautier 1025, 178*23684d0eSYann Gautier 1050, 179*23684d0eSYann Gautier 1075, 180*23684d0eSYann Gautier 1100, 181*23684d0eSYann Gautier 1125, 182*23684d0eSYann Gautier 1150, 183*23684d0eSYann Gautier 1175, 184*23684d0eSYann Gautier 1200, 185*23684d0eSYann Gautier 1225, 186*23684d0eSYann Gautier 1250, 187*23684d0eSYann Gautier 1275, 188*23684d0eSYann Gautier 1300, 189*23684d0eSYann Gautier 1300, 190*23684d0eSYann Gautier 1350, 191*23684d0eSYann Gautier 1350, 192*23684d0eSYann Gautier 1400, 193*23684d0eSYann Gautier 1400, 194*23684d0eSYann Gautier 1450, 195*23684d0eSYann Gautier 1450, 196*23684d0eSYann Gautier 1500, 197*23684d0eSYann Gautier 1600, 198*23684d0eSYann Gautier 1700, 199*23684d0eSYann Gautier 1800, 200*23684d0eSYann Gautier 1900, 201*23684d0eSYann Gautier 2000, 202*23684d0eSYann Gautier 2100, 203*23684d0eSYann Gautier 2200, 204*23684d0eSYann Gautier 2300, 205*23684d0eSYann Gautier 2400, 206*23684d0eSYann Gautier 2500, 207*23684d0eSYann Gautier 2600, 208*23684d0eSYann Gautier 2700, 209*23684d0eSYann Gautier 2800, 210*23684d0eSYann Gautier 2900, 211*23684d0eSYann Gautier 3000, 212*23684d0eSYann Gautier 3100, 213*23684d0eSYann Gautier 3200, 214*23684d0eSYann Gautier 3300, 215*23684d0eSYann Gautier 3400, 216*23684d0eSYann Gautier 3500, 217*23684d0eSYann Gautier 3600, 218*23684d0eSYann Gautier 3700, 219*23684d0eSYann Gautier 3800, 220*23684d0eSYann Gautier 3900, 221*23684d0eSYann Gautier }; 222*23684d0eSYann Gautier 223*23684d0eSYann Gautier static const uint16_t ldo1_voltage_table[] = { 224*23684d0eSYann Gautier 1700, 225*23684d0eSYann Gautier 1700, 226*23684d0eSYann Gautier 1700, 227*23684d0eSYann Gautier 1700, 228*23684d0eSYann Gautier 1700, 229*23684d0eSYann Gautier 1700, 230*23684d0eSYann Gautier 1700, 231*23684d0eSYann Gautier 1700, 232*23684d0eSYann Gautier 1700, 233*23684d0eSYann Gautier 1800, 234*23684d0eSYann Gautier 1900, 235*23684d0eSYann Gautier 2000, 236*23684d0eSYann Gautier 2100, 237*23684d0eSYann Gautier 2200, 238*23684d0eSYann Gautier 2300, 239*23684d0eSYann Gautier 2400, 240*23684d0eSYann Gautier 2500, 241*23684d0eSYann Gautier 2600, 242*23684d0eSYann Gautier 2700, 243*23684d0eSYann Gautier 2800, 244*23684d0eSYann Gautier 2900, 245*23684d0eSYann Gautier 3000, 246*23684d0eSYann Gautier 3100, 247*23684d0eSYann Gautier 3200, 248*23684d0eSYann Gautier 3300, 249*23684d0eSYann Gautier }; 250*23684d0eSYann Gautier 251*23684d0eSYann Gautier static const uint16_t ldo2_voltage_table[] = { 252*23684d0eSYann Gautier 1700, 253*23684d0eSYann Gautier 1700, 254*23684d0eSYann Gautier 1700, 255*23684d0eSYann Gautier 1700, 256*23684d0eSYann Gautier 1700, 257*23684d0eSYann Gautier 1700, 258*23684d0eSYann Gautier 1700, 259*23684d0eSYann Gautier 1700, 260*23684d0eSYann Gautier 1700, 261*23684d0eSYann Gautier 1800, 262*23684d0eSYann Gautier 1900, 263*23684d0eSYann Gautier 2000, 264*23684d0eSYann Gautier 2100, 265*23684d0eSYann Gautier 2200, 266*23684d0eSYann Gautier 2300, 267*23684d0eSYann Gautier 2400, 268*23684d0eSYann Gautier 2500, 269*23684d0eSYann Gautier 2600, 270*23684d0eSYann Gautier 2700, 271*23684d0eSYann Gautier 2800, 272*23684d0eSYann Gautier 2900, 273*23684d0eSYann Gautier 3000, 274*23684d0eSYann Gautier 3100, 275*23684d0eSYann Gautier 3200, 276*23684d0eSYann Gautier 3300, 277*23684d0eSYann Gautier }; 278*23684d0eSYann Gautier 279*23684d0eSYann Gautier static const uint16_t ldo3_voltage_table[] = { 280*23684d0eSYann Gautier 1700, 281*23684d0eSYann Gautier 1700, 282*23684d0eSYann Gautier 1700, 283*23684d0eSYann Gautier 1700, 284*23684d0eSYann Gautier 1700, 285*23684d0eSYann Gautier 1700, 286*23684d0eSYann Gautier 1700, 287*23684d0eSYann Gautier 1700, 288*23684d0eSYann Gautier 1700, 289*23684d0eSYann Gautier 1800, 290*23684d0eSYann Gautier 1900, 291*23684d0eSYann Gautier 2000, 292*23684d0eSYann Gautier 2100, 293*23684d0eSYann Gautier 2200, 294*23684d0eSYann Gautier 2300, 295*23684d0eSYann Gautier 2400, 296*23684d0eSYann Gautier 2500, 297*23684d0eSYann Gautier 2600, 298*23684d0eSYann Gautier 2700, 299*23684d0eSYann Gautier 2800, 300*23684d0eSYann Gautier 2900, 301*23684d0eSYann Gautier 3000, 302*23684d0eSYann Gautier 3100, 303*23684d0eSYann Gautier 3200, 304*23684d0eSYann Gautier 3300, 305*23684d0eSYann Gautier 3300, 306*23684d0eSYann Gautier 3300, 307*23684d0eSYann Gautier 3300, 308*23684d0eSYann Gautier 3300, 309*23684d0eSYann Gautier 3300, 310*23684d0eSYann Gautier 3300, 311*23684d0eSYann Gautier 0xFFFF, /* VREFDDR */ 312*23684d0eSYann Gautier }; 313*23684d0eSYann Gautier 314*23684d0eSYann Gautier static const uint16_t ldo5_voltage_table[] = { 315*23684d0eSYann Gautier 1700, 316*23684d0eSYann Gautier 1700, 317*23684d0eSYann Gautier 1700, 318*23684d0eSYann Gautier 1700, 319*23684d0eSYann Gautier 1700, 320*23684d0eSYann Gautier 1700, 321*23684d0eSYann Gautier 1700, 322*23684d0eSYann Gautier 1700, 323*23684d0eSYann Gautier 1700, 324*23684d0eSYann Gautier 1800, 325*23684d0eSYann Gautier 1900, 326*23684d0eSYann Gautier 2000, 327*23684d0eSYann Gautier 2100, 328*23684d0eSYann Gautier 2200, 329*23684d0eSYann Gautier 2300, 330*23684d0eSYann Gautier 2400, 331*23684d0eSYann Gautier 2500, 332*23684d0eSYann Gautier 2600, 333*23684d0eSYann Gautier 2700, 334*23684d0eSYann Gautier 2800, 335*23684d0eSYann Gautier 2900, 336*23684d0eSYann Gautier 3000, 337*23684d0eSYann Gautier 3100, 338*23684d0eSYann Gautier 3200, 339*23684d0eSYann Gautier 3300, 340*23684d0eSYann Gautier 3400, 341*23684d0eSYann Gautier 3500, 342*23684d0eSYann Gautier 3600, 343*23684d0eSYann Gautier 3700, 344*23684d0eSYann Gautier 3800, 345*23684d0eSYann Gautier 3900, 346*23684d0eSYann Gautier }; 347*23684d0eSYann Gautier 348*23684d0eSYann Gautier static const uint16_t ldo6_voltage_table[] = { 349*23684d0eSYann Gautier 900, 350*23684d0eSYann Gautier 1000, 351*23684d0eSYann Gautier 1100, 352*23684d0eSYann Gautier 1200, 353*23684d0eSYann Gautier 1300, 354*23684d0eSYann Gautier 1400, 355*23684d0eSYann Gautier 1500, 356*23684d0eSYann Gautier 1600, 357*23684d0eSYann Gautier 1700, 358*23684d0eSYann Gautier 1800, 359*23684d0eSYann Gautier 1900, 360*23684d0eSYann Gautier 2000, 361*23684d0eSYann Gautier 2100, 362*23684d0eSYann Gautier 2200, 363*23684d0eSYann Gautier 2300, 364*23684d0eSYann Gautier 2400, 365*23684d0eSYann Gautier 2500, 366*23684d0eSYann Gautier 2600, 367*23684d0eSYann Gautier 2700, 368*23684d0eSYann Gautier 2800, 369*23684d0eSYann Gautier 2900, 370*23684d0eSYann Gautier 3000, 371*23684d0eSYann Gautier 3100, 372*23684d0eSYann Gautier 3200, 373*23684d0eSYann Gautier 3300, 374*23684d0eSYann Gautier }; 375*23684d0eSYann Gautier 376*23684d0eSYann Gautier static const uint16_t ldo4_voltage_table[] = { 377*23684d0eSYann Gautier 3300, 378*23684d0eSYann Gautier }; 379*23684d0eSYann Gautier 380*23684d0eSYann Gautier static const uint16_t vref_ddr_voltage_table[] = { 381*23684d0eSYann Gautier 3300, 382*23684d0eSYann Gautier }; 383*23684d0eSYann Gautier 384*23684d0eSYann Gautier /* Table of Regulators in PMIC SoC */ 385*23684d0eSYann Gautier static const struct regul_struct regulators_table[] = { 386*23684d0eSYann Gautier { 387*23684d0eSYann Gautier .dt_node_name = "buck1", 388*23684d0eSYann Gautier .voltage_table = buck1_voltage_table, 389*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck1_voltage_table), 390*23684d0eSYann Gautier .control_reg = BUCK1_CONTROL_REG, 391*23684d0eSYann Gautier .low_power_reg = BUCK1_PWRCTRL_REG, 392*23684d0eSYann Gautier }, 393*23684d0eSYann Gautier { 394*23684d0eSYann Gautier .dt_node_name = "buck2", 395*23684d0eSYann Gautier .voltage_table = buck2_voltage_table, 396*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck2_voltage_table), 397*23684d0eSYann Gautier .control_reg = BUCK2_CONTROL_REG, 398*23684d0eSYann Gautier .low_power_reg = BUCK2_PWRCTRL_REG, 399*23684d0eSYann Gautier }, 400*23684d0eSYann Gautier { 401*23684d0eSYann Gautier .dt_node_name = "buck3", 402*23684d0eSYann Gautier .voltage_table = buck3_voltage_table, 403*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck3_voltage_table), 404*23684d0eSYann Gautier .control_reg = BUCK3_CONTROL_REG, 405*23684d0eSYann Gautier .low_power_reg = BUCK3_PWRCTRL_REG, 406*23684d0eSYann Gautier }, 407*23684d0eSYann Gautier { 408*23684d0eSYann Gautier .dt_node_name = "buck4", 409*23684d0eSYann Gautier .voltage_table = buck4_voltage_table, 410*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck4_voltage_table), 411*23684d0eSYann Gautier .control_reg = BUCK4_CONTROL_REG, 412*23684d0eSYann Gautier .low_power_reg = BUCK4_PWRCTRL_REG, 413*23684d0eSYann Gautier }, 414*23684d0eSYann Gautier { 415*23684d0eSYann Gautier .dt_node_name = "ldo1", 416*23684d0eSYann Gautier .voltage_table = ldo1_voltage_table, 417*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), 418*23684d0eSYann Gautier .control_reg = LDO1_CONTROL_REG, 419*23684d0eSYann Gautier .low_power_reg = LDO1_PWRCTRL_REG, 420*23684d0eSYann Gautier }, 421*23684d0eSYann Gautier { 422*23684d0eSYann Gautier .dt_node_name = "ldo2", 423*23684d0eSYann Gautier .voltage_table = ldo2_voltage_table, 424*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), 425*23684d0eSYann Gautier .control_reg = LDO2_CONTROL_REG, 426*23684d0eSYann Gautier .low_power_reg = LDO2_PWRCTRL_REG, 427*23684d0eSYann Gautier }, 428*23684d0eSYann Gautier { 429*23684d0eSYann Gautier .dt_node_name = "ldo3", 430*23684d0eSYann Gautier .voltage_table = ldo3_voltage_table, 431*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), 432*23684d0eSYann Gautier .control_reg = LDO3_CONTROL_REG, 433*23684d0eSYann Gautier .low_power_reg = LDO3_PWRCTRL_REG, 434*23684d0eSYann Gautier }, 435*23684d0eSYann Gautier { 436*23684d0eSYann Gautier .dt_node_name = "ldo4", 437*23684d0eSYann Gautier .voltage_table = ldo4_voltage_table, 438*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), 439*23684d0eSYann Gautier .control_reg = LDO4_CONTROL_REG, 440*23684d0eSYann Gautier .low_power_reg = LDO4_PWRCTRL_REG, 441*23684d0eSYann Gautier }, 442*23684d0eSYann Gautier { 443*23684d0eSYann Gautier .dt_node_name = "ldo5", 444*23684d0eSYann Gautier .voltage_table = ldo5_voltage_table, 445*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), 446*23684d0eSYann Gautier .control_reg = LDO5_CONTROL_REG, 447*23684d0eSYann Gautier .low_power_reg = LDO5_PWRCTRL_REG, 448*23684d0eSYann Gautier }, 449*23684d0eSYann Gautier { 450*23684d0eSYann Gautier .dt_node_name = "ldo6", 451*23684d0eSYann Gautier .voltage_table = ldo6_voltage_table, 452*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), 453*23684d0eSYann Gautier .control_reg = LDO6_CONTROL_REG, 454*23684d0eSYann Gautier .low_power_reg = LDO6_PWRCTRL_REG, 455*23684d0eSYann Gautier }, 456*23684d0eSYann Gautier { 457*23684d0eSYann Gautier .dt_node_name = "vref_ddr", 458*23684d0eSYann Gautier .voltage_table = vref_ddr_voltage_table, 459*23684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), 460*23684d0eSYann Gautier .control_reg = VREF_DDR_CONTROL_REG, 461*23684d0eSYann Gautier .low_power_reg = VREF_DDR_PWRCTRL_REG, 462*23684d0eSYann Gautier }, 463*23684d0eSYann Gautier }; 464*23684d0eSYann Gautier 465*23684d0eSYann Gautier #define MAX_REGUL ARRAY_SIZE(regulators_table) 466*23684d0eSYann Gautier 467*23684d0eSYann Gautier static const struct regul_struct *get_regulator_data(const char *name) 468*23684d0eSYann Gautier { 469*23684d0eSYann Gautier uint8_t i; 470*23684d0eSYann Gautier 471*23684d0eSYann Gautier for (i = 0 ; i < MAX_REGUL ; i++) { 472*23684d0eSYann Gautier if (strncmp(name, regulators_table[i].dt_node_name, 473*23684d0eSYann Gautier strlen(regulators_table[i].dt_node_name)) == 0) { 474*23684d0eSYann Gautier return ®ulators_table[i]; 475*23684d0eSYann Gautier } 476*23684d0eSYann Gautier } 477*23684d0eSYann Gautier 478*23684d0eSYann Gautier /* Regulator not found */ 479*23684d0eSYann Gautier panic(); 480*23684d0eSYann Gautier return NULL; 481*23684d0eSYann Gautier } 482*23684d0eSYann Gautier 483*23684d0eSYann Gautier static uint8_t voltage_to_index(const char *name, uint16_t millivolts) 484*23684d0eSYann Gautier { 485*23684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 486*23684d0eSYann Gautier uint8_t i; 487*23684d0eSYann Gautier 488*23684d0eSYann Gautier for (i = 0 ; i < regul->voltage_table_size ; i++) { 489*23684d0eSYann Gautier if (regul->voltage_table[i] == millivolts) { 490*23684d0eSYann Gautier return i; 491*23684d0eSYann Gautier } 492*23684d0eSYann Gautier } 493*23684d0eSYann Gautier 494*23684d0eSYann Gautier /* Voltage not found */ 495*23684d0eSYann Gautier panic(); 496*23684d0eSYann Gautier 497*23684d0eSYann Gautier return 0; 498*23684d0eSYann Gautier } 499*23684d0eSYann Gautier 500*23684d0eSYann Gautier int stpmic1_switch_off(void) 501*23684d0eSYann Gautier { 502*23684d0eSYann Gautier return stpmic1_register_update(MAIN_CONTROL_REG, 1, 503*23684d0eSYann Gautier SOFTWARE_SWITCH_OFF_ENABLED); 504*23684d0eSYann Gautier } 505*23684d0eSYann Gautier 506*23684d0eSYann Gautier int stpmic1_regulator_enable(const char *name) 507*23684d0eSYann Gautier { 508*23684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 509*23684d0eSYann Gautier 510*23684d0eSYann Gautier return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0)); 511*23684d0eSYann Gautier } 512*23684d0eSYann Gautier 513*23684d0eSYann Gautier int stpmic1_regulator_disable(const char *name) 514*23684d0eSYann Gautier { 515*23684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 516*23684d0eSYann Gautier 517*23684d0eSYann Gautier return stpmic1_register_update(regul->control_reg, 0, BIT(0)); 518*23684d0eSYann Gautier } 519*23684d0eSYann Gautier 520*23684d0eSYann Gautier uint8_t stpmic1_is_regulator_enabled(const char *name) 521*23684d0eSYann Gautier { 522*23684d0eSYann Gautier uint8_t val; 523*23684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 524*23684d0eSYann Gautier 525*23684d0eSYann Gautier if (stpmic1_register_read(regul->control_reg, &val) != 0) { 526*23684d0eSYann Gautier panic(); 527*23684d0eSYann Gautier } 528*23684d0eSYann Gautier 529*23684d0eSYann Gautier return (val & 0x1U); 530*23684d0eSYann Gautier } 531*23684d0eSYann Gautier 532*23684d0eSYann Gautier int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts) 533*23684d0eSYann Gautier { 534*23684d0eSYann Gautier uint8_t voltage_index = voltage_to_index(name, millivolts); 535*23684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name); 536*23684d0eSYann Gautier 537*23684d0eSYann Gautier return stpmic1_register_update(regul->control_reg, voltage_index << 2, 538*23684d0eSYann Gautier 0xFC); 539*23684d0eSYann Gautier } 540*23684d0eSYann Gautier 541*23684d0eSYann Gautier int stpmic1_register_read(uint8_t register_id, uint8_t *value) 542*23684d0eSYann Gautier { 543*23684d0eSYann Gautier return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr, 544*23684d0eSYann Gautier (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT, 545*23684d0eSYann Gautier value, 1, 100000); 546*23684d0eSYann Gautier } 547*23684d0eSYann Gautier 548*23684d0eSYann Gautier int stpmic1_register_write(uint8_t register_id, uint8_t value) 549*23684d0eSYann Gautier { 550*23684d0eSYann Gautier int status; 551*23684d0eSYann Gautier 552*23684d0eSYann Gautier status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr, 553*23684d0eSYann Gautier (uint16_t)register_id, 554*23684d0eSYann Gautier I2C_MEMADD_SIZE_8BIT, &value, 1, 100000); 555*23684d0eSYann Gautier 556*23684d0eSYann Gautier if (status != 0) { 557*23684d0eSYann Gautier return status; 558*23684d0eSYann Gautier } 559*23684d0eSYann Gautier 560*23684d0eSYann Gautier if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) { 561*23684d0eSYann Gautier uint8_t readval; 562*23684d0eSYann Gautier 563*23684d0eSYann Gautier status = stpmic1_register_read(register_id, &readval); 564*23684d0eSYann Gautier if (status != 0) { 565*23684d0eSYann Gautier return status; 566*23684d0eSYann Gautier } 567*23684d0eSYann Gautier 568*23684d0eSYann Gautier if (readval != value) { 569*23684d0eSYann Gautier return -1; 570*23684d0eSYann Gautier } 571*23684d0eSYann Gautier } 572*23684d0eSYann Gautier 573*23684d0eSYann Gautier return 0; 574*23684d0eSYann Gautier } 575*23684d0eSYann Gautier 576*23684d0eSYann Gautier int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) 577*23684d0eSYann Gautier { 578*23684d0eSYann Gautier int status; 579*23684d0eSYann Gautier uint8_t val; 580*23684d0eSYann Gautier 581*23684d0eSYann Gautier status = stpmic1_register_read(register_id, &val); 582*23684d0eSYann Gautier if (status != 0) { 583*23684d0eSYann Gautier return status; 584*23684d0eSYann Gautier } 585*23684d0eSYann Gautier 586*23684d0eSYann Gautier /* Clear bits to update */ 587*23684d0eSYann Gautier val &= ~mask; 588*23684d0eSYann Gautier 589*23684d0eSYann Gautier /* Update appropriate bits*/ 590*23684d0eSYann Gautier val |= (value & mask); 591*23684d0eSYann Gautier 592*23684d0eSYann Gautier /* Send new value on I2C Bus */ 593*23684d0eSYann Gautier return stpmic1_register_write(register_id, val); 594*23684d0eSYann Gautier } 595*23684d0eSYann Gautier 596*23684d0eSYann Gautier void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr) 597*23684d0eSYann Gautier { 598*23684d0eSYann Gautier pmic_i2c_handle = i2c_handle; 599*23684d0eSYann Gautier pmic_i2c_addr = i2c_addr; 600*23684d0eSYann Gautier } 601