1c7cf2933SEtienne Carriere // SPDX-License-Identifier: BSD-3-Clause 2c7cf2933SEtienne Carriere /* 368cfb83dSEtienne Carriere * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved 4c7cf2933SEtienne Carriere */ 5c7cf2933SEtienne Carriere 6c7cf2933SEtienne Carriere #include <assert.h> 7c7cf2933SEtienne Carriere #include <drivers/stpmic1.h> 8c7cf2933SEtienne Carriere #include <kernel/panic.h> 9c7cf2933SEtienne Carriere #include <platform_config.h> 10c7cf2933SEtienne Carriere #include <stdint.h> 11c7cf2933SEtienne Carriere #include <string.h> 12c7cf2933SEtienne Carriere #include <trace.h> 1342032ea0SEtienne Carriere #include <util.h> 14c7cf2933SEtienne Carriere 15*6a63363bSEtienne Carriere #define VOLTAGE_INDEX_INVALID ((unsigned int)~0) 16*6a63363bSEtienne Carriere 17c7cf2933SEtienne Carriere struct regul_struct { 18c7cf2933SEtienne Carriere const char *dt_node_name; 19c7cf2933SEtienne Carriere const uint16_t *voltage_table; 20c7cf2933SEtienne Carriere uint8_t voltage_table_size; 21c7cf2933SEtienne Carriere uint8_t control_reg; 22c7cf2933SEtienne Carriere uint8_t low_power_reg; 2368cfb83dSEtienne Carriere uint8_t enable_pos; 24c7cf2933SEtienne Carriere uint8_t pull_down_reg; 25c7cf2933SEtienne Carriere uint8_t pull_down_pos; 26c7cf2933SEtienne Carriere uint8_t mask_reset_reg; 27c7cf2933SEtienne Carriere uint8_t mask_reset_pos; 28c7cf2933SEtienne Carriere }; 29c7cf2933SEtienne Carriere 30c7cf2933SEtienne Carriere static struct i2c_handle_s *pmic_i2c_handle; 31c7cf2933SEtienne Carriere static uint16_t pmic_i2c_addr; 32c7cf2933SEtienne Carriere 33c7cf2933SEtienne Carriere /* Voltage tables in mV */ 34c7cf2933SEtienne Carriere static const uint16_t buck1_voltage_table[] = { 35c7cf2933SEtienne Carriere 725, 36c7cf2933SEtienne Carriere 725, 37c7cf2933SEtienne Carriere 725, 38c7cf2933SEtienne Carriere 725, 39c7cf2933SEtienne Carriere 725, 40c7cf2933SEtienne Carriere 725, 41c7cf2933SEtienne Carriere 750, 42c7cf2933SEtienne Carriere 775, 43c7cf2933SEtienne Carriere 800, 44c7cf2933SEtienne Carriere 825, 45c7cf2933SEtienne Carriere 850, 46c7cf2933SEtienne Carriere 875, 47c7cf2933SEtienne Carriere 900, 48c7cf2933SEtienne Carriere 925, 49c7cf2933SEtienne Carriere 950, 50c7cf2933SEtienne Carriere 975, 51c7cf2933SEtienne Carriere 1000, 52c7cf2933SEtienne Carriere 1025, 53c7cf2933SEtienne Carriere 1050, 54c7cf2933SEtienne Carriere 1075, 55c7cf2933SEtienne Carriere 1100, 56c7cf2933SEtienne Carriere 1125, 57c7cf2933SEtienne Carriere 1150, 58c7cf2933SEtienne Carriere 1175, 59c7cf2933SEtienne Carriere 1200, 60c7cf2933SEtienne Carriere 1225, 61c7cf2933SEtienne Carriere 1250, 62c7cf2933SEtienne Carriere 1275, 63c7cf2933SEtienne Carriere 1300, 64c7cf2933SEtienne Carriere 1325, 65c7cf2933SEtienne Carriere 1350, 66c7cf2933SEtienne Carriere 1375, 67c7cf2933SEtienne Carriere 1400, 68c7cf2933SEtienne Carriere 1425, 69c7cf2933SEtienne Carriere 1450, 70c7cf2933SEtienne Carriere 1475, 71c7cf2933SEtienne Carriere 1500, 72c7cf2933SEtienne Carriere 1500, 73c7cf2933SEtienne Carriere 1500, 74c7cf2933SEtienne Carriere 1500, 75c7cf2933SEtienne Carriere 1500, 76c7cf2933SEtienne Carriere 1500, 77c7cf2933SEtienne Carriere 1500, 78c7cf2933SEtienne Carriere 1500, 79c7cf2933SEtienne Carriere 1500, 80c7cf2933SEtienne Carriere 1500, 81c7cf2933SEtienne Carriere 1500, 82c7cf2933SEtienne Carriere 1500, 83c7cf2933SEtienne Carriere 1500, 84c7cf2933SEtienne Carriere 1500, 85c7cf2933SEtienne Carriere 1500, 86c7cf2933SEtienne Carriere 1500, 87c7cf2933SEtienne Carriere 1500, 88c7cf2933SEtienne Carriere 1500, 89c7cf2933SEtienne Carriere 1500, 90c7cf2933SEtienne Carriere 1500, 91c7cf2933SEtienne Carriere 1500, 92c7cf2933SEtienne Carriere 1500, 93c7cf2933SEtienne Carriere 1500, 94c7cf2933SEtienne Carriere 1500, 95c7cf2933SEtienne Carriere 1500, 96c7cf2933SEtienne Carriere 1500, 97c7cf2933SEtienne Carriere 1500, 98c7cf2933SEtienne Carriere 1500, 99c7cf2933SEtienne Carriere }; 100c7cf2933SEtienne Carriere 101c7cf2933SEtienne Carriere static const uint16_t buck2_voltage_table[] = { 102c7cf2933SEtienne Carriere 1000, 103c7cf2933SEtienne Carriere 1000, 104c7cf2933SEtienne Carriere 1000, 105c7cf2933SEtienne Carriere 1000, 106c7cf2933SEtienne Carriere 1000, 107c7cf2933SEtienne Carriere 1000, 108c7cf2933SEtienne Carriere 1000, 109c7cf2933SEtienne Carriere 1000, 110c7cf2933SEtienne Carriere 1000, 111c7cf2933SEtienne Carriere 1000, 112c7cf2933SEtienne Carriere 1000, 113c7cf2933SEtienne Carriere 1000, 114c7cf2933SEtienne Carriere 1000, 115c7cf2933SEtienne Carriere 1000, 116c7cf2933SEtienne Carriere 1000, 117c7cf2933SEtienne Carriere 1000, 118c7cf2933SEtienne Carriere 1000, 119c7cf2933SEtienne Carriere 1000, 120c7cf2933SEtienne Carriere 1050, 121c7cf2933SEtienne Carriere 1050, 122c7cf2933SEtienne Carriere 1100, 123c7cf2933SEtienne Carriere 1100, 124c7cf2933SEtienne Carriere 1150, 125c7cf2933SEtienne Carriere 1150, 126c7cf2933SEtienne Carriere 1200, 127c7cf2933SEtienne Carriere 1200, 128c7cf2933SEtienne Carriere 1250, 129c7cf2933SEtienne Carriere 1250, 130c7cf2933SEtienne Carriere 1300, 131c7cf2933SEtienne Carriere 1300, 132c7cf2933SEtienne Carriere 1350, 133c7cf2933SEtienne Carriere 1350, 134c7cf2933SEtienne Carriere 1400, 135c7cf2933SEtienne Carriere 1400, 136c7cf2933SEtienne Carriere 1450, 137c7cf2933SEtienne Carriere 1450, 138c7cf2933SEtienne Carriere 1500, 139c7cf2933SEtienne Carriere }; 140c7cf2933SEtienne Carriere 141c7cf2933SEtienne Carriere static const uint16_t buck3_voltage_table[] = { 142c7cf2933SEtienne Carriere 1000, 143c7cf2933SEtienne Carriere 1000, 144c7cf2933SEtienne Carriere 1000, 145c7cf2933SEtienne Carriere 1000, 146c7cf2933SEtienne Carriere 1000, 147c7cf2933SEtienne Carriere 1000, 148c7cf2933SEtienne Carriere 1000, 149c7cf2933SEtienne Carriere 1000, 150c7cf2933SEtienne Carriere 1000, 151c7cf2933SEtienne Carriere 1000, 152c7cf2933SEtienne Carriere 1000, 153c7cf2933SEtienne Carriere 1000, 154c7cf2933SEtienne Carriere 1000, 155c7cf2933SEtienne Carriere 1000, 156c7cf2933SEtienne Carriere 1000, 157c7cf2933SEtienne Carriere 1000, 158c7cf2933SEtienne Carriere 1000, 159c7cf2933SEtienne Carriere 1000, 160c7cf2933SEtienne Carriere 1000, 161c7cf2933SEtienne Carriere 1000, 162c7cf2933SEtienne Carriere 1100, 163c7cf2933SEtienne Carriere 1100, 164c7cf2933SEtienne Carriere 1100, 165c7cf2933SEtienne Carriere 1100, 166c7cf2933SEtienne Carriere 1200, 167c7cf2933SEtienne Carriere 1200, 168c7cf2933SEtienne Carriere 1200, 169c7cf2933SEtienne Carriere 1200, 170c7cf2933SEtienne Carriere 1300, 171c7cf2933SEtienne Carriere 1300, 172c7cf2933SEtienne Carriere 1300, 173c7cf2933SEtienne Carriere 1300, 174c7cf2933SEtienne Carriere 1400, 175c7cf2933SEtienne Carriere 1400, 176c7cf2933SEtienne Carriere 1400, 177c7cf2933SEtienne Carriere 1400, 178c7cf2933SEtienne Carriere 1500, 179c7cf2933SEtienne Carriere 1600, 180c7cf2933SEtienne Carriere 1700, 181c7cf2933SEtienne Carriere 1800, 182c7cf2933SEtienne Carriere 1900, 183c7cf2933SEtienne Carriere 2000, 184c7cf2933SEtienne Carriere 2100, 185c7cf2933SEtienne Carriere 2200, 186c7cf2933SEtienne Carriere 2300, 187c7cf2933SEtienne Carriere 2400, 188c7cf2933SEtienne Carriere 2500, 189c7cf2933SEtienne Carriere 2600, 190c7cf2933SEtienne Carriere 2700, 191c7cf2933SEtienne Carriere 2800, 192c7cf2933SEtienne Carriere 2900, 193c7cf2933SEtienne Carriere 3000, 194c7cf2933SEtienne Carriere 3100, 195c7cf2933SEtienne Carriere 3200, 196c7cf2933SEtienne Carriere 3300, 197c7cf2933SEtienne Carriere 3400, 198c7cf2933SEtienne Carriere }; 199c7cf2933SEtienne Carriere 200c7cf2933SEtienne Carriere static const uint16_t buck4_voltage_table[] = { 201c7cf2933SEtienne Carriere 600, 202c7cf2933SEtienne Carriere 625, 203c7cf2933SEtienne Carriere 650, 204c7cf2933SEtienne Carriere 675, 205c7cf2933SEtienne Carriere 700, 206c7cf2933SEtienne Carriere 725, 207c7cf2933SEtienne Carriere 750, 208c7cf2933SEtienne Carriere 775, 209c7cf2933SEtienne Carriere 800, 210c7cf2933SEtienne Carriere 825, 211c7cf2933SEtienne Carriere 850, 212c7cf2933SEtienne Carriere 875, 213c7cf2933SEtienne Carriere 900, 214c7cf2933SEtienne Carriere 925, 215c7cf2933SEtienne Carriere 950, 216c7cf2933SEtienne Carriere 975, 217c7cf2933SEtienne Carriere 1000, 218c7cf2933SEtienne Carriere 1025, 219c7cf2933SEtienne Carriere 1050, 220c7cf2933SEtienne Carriere 1075, 221c7cf2933SEtienne Carriere 1100, 222c7cf2933SEtienne Carriere 1125, 223c7cf2933SEtienne Carriere 1150, 224c7cf2933SEtienne Carriere 1175, 225c7cf2933SEtienne Carriere 1200, 226c7cf2933SEtienne Carriere 1225, 227c7cf2933SEtienne Carriere 1250, 228c7cf2933SEtienne Carriere 1275, 229c7cf2933SEtienne Carriere 1300, 230c7cf2933SEtienne Carriere 1300, 231c7cf2933SEtienne Carriere 1350, 232c7cf2933SEtienne Carriere 1350, 233c7cf2933SEtienne Carriere 1400, 234c7cf2933SEtienne Carriere 1400, 235c7cf2933SEtienne Carriere 1450, 236c7cf2933SEtienne Carriere 1450, 237c7cf2933SEtienne Carriere 1500, 238c7cf2933SEtienne Carriere 1600, 239c7cf2933SEtienne Carriere 1700, 240c7cf2933SEtienne Carriere 1800, 241c7cf2933SEtienne Carriere 1900, 242c7cf2933SEtienne Carriere 2000, 243c7cf2933SEtienne Carriere 2100, 244c7cf2933SEtienne Carriere 2200, 245c7cf2933SEtienne Carriere 2300, 246c7cf2933SEtienne Carriere 2400, 247c7cf2933SEtienne Carriere 2500, 248c7cf2933SEtienne Carriere 2600, 249c7cf2933SEtienne Carriere 2700, 250c7cf2933SEtienne Carriere 2800, 251c7cf2933SEtienne Carriere 2900, 252c7cf2933SEtienne Carriere 3000, 253c7cf2933SEtienne Carriere 3100, 254c7cf2933SEtienne Carriere 3200, 255c7cf2933SEtienne Carriere 3300, 256c7cf2933SEtienne Carriere 3400, 257c7cf2933SEtienne Carriere 3500, 258c7cf2933SEtienne Carriere 3600, 259c7cf2933SEtienne Carriere 3700, 260c7cf2933SEtienne Carriere 3800, 261c7cf2933SEtienne Carriere 3900, 262c7cf2933SEtienne Carriere }; 263c7cf2933SEtienne Carriere 264c7cf2933SEtienne Carriere static const uint16_t ldo1_voltage_table[] = { 265c7cf2933SEtienne Carriere 1700, 266c7cf2933SEtienne Carriere 1700, 267c7cf2933SEtienne Carriere 1700, 268c7cf2933SEtienne Carriere 1700, 269c7cf2933SEtienne Carriere 1700, 270c7cf2933SEtienne Carriere 1700, 271c7cf2933SEtienne Carriere 1700, 272c7cf2933SEtienne Carriere 1700, 273c7cf2933SEtienne Carriere 1700, 274c7cf2933SEtienne Carriere 1800, 275c7cf2933SEtienne Carriere 1900, 276c7cf2933SEtienne Carriere 2000, 277c7cf2933SEtienne Carriere 2100, 278c7cf2933SEtienne Carriere 2200, 279c7cf2933SEtienne Carriere 2300, 280c7cf2933SEtienne Carriere 2400, 281c7cf2933SEtienne Carriere 2500, 282c7cf2933SEtienne Carriere 2600, 283c7cf2933SEtienne Carriere 2700, 284c7cf2933SEtienne Carriere 2800, 285c7cf2933SEtienne Carriere 2900, 286c7cf2933SEtienne Carriere 3000, 287c7cf2933SEtienne Carriere 3100, 288c7cf2933SEtienne Carriere 3200, 289c7cf2933SEtienne Carriere 3300, 290c7cf2933SEtienne Carriere }; 291c7cf2933SEtienne Carriere 292c7cf2933SEtienne Carriere static const uint16_t ldo2_voltage_table[] = { 293c7cf2933SEtienne Carriere 1700, 294c7cf2933SEtienne Carriere 1700, 295c7cf2933SEtienne Carriere 1700, 296c7cf2933SEtienne Carriere 1700, 297c7cf2933SEtienne Carriere 1700, 298c7cf2933SEtienne Carriere 1700, 299c7cf2933SEtienne Carriere 1700, 300c7cf2933SEtienne Carriere 1700, 301c7cf2933SEtienne Carriere 1700, 302c7cf2933SEtienne Carriere 1800, 303c7cf2933SEtienne Carriere 1900, 304c7cf2933SEtienne Carriere 2000, 305c7cf2933SEtienne Carriere 2100, 306c7cf2933SEtienne Carriere 2200, 307c7cf2933SEtienne Carriere 2300, 308c7cf2933SEtienne Carriere 2400, 309c7cf2933SEtienne Carriere 2500, 310c7cf2933SEtienne Carriere 2600, 311c7cf2933SEtienne Carriere 2700, 312c7cf2933SEtienne Carriere 2800, 313c7cf2933SEtienne Carriere 2900, 314c7cf2933SEtienne Carriere 3000, 315c7cf2933SEtienne Carriere 3100, 316c7cf2933SEtienne Carriere 3200, 317c7cf2933SEtienne Carriere 3300, 318c7cf2933SEtienne Carriere }; 319c7cf2933SEtienne Carriere 320c7cf2933SEtienne Carriere static const uint16_t ldo3_voltage_table[] = { 321c7cf2933SEtienne Carriere 1700, 322c7cf2933SEtienne Carriere 1700, 323c7cf2933SEtienne Carriere 1700, 324c7cf2933SEtienne Carriere 1700, 325c7cf2933SEtienne Carriere 1700, 326c7cf2933SEtienne Carriere 1700, 327c7cf2933SEtienne Carriere 1700, 328c7cf2933SEtienne Carriere 1700, 329c7cf2933SEtienne Carriere 1700, 330c7cf2933SEtienne Carriere 1800, 331c7cf2933SEtienne Carriere 1900, 332c7cf2933SEtienne Carriere 2000, 333c7cf2933SEtienne Carriere 2100, 334c7cf2933SEtienne Carriere 2200, 335c7cf2933SEtienne Carriere 2300, 336c7cf2933SEtienne Carriere 2400, 337c7cf2933SEtienne Carriere 2500, 338c7cf2933SEtienne Carriere 2600, 339c7cf2933SEtienne Carriere 2700, 340c7cf2933SEtienne Carriere 2800, 341c7cf2933SEtienne Carriere 2900, 342c7cf2933SEtienne Carriere 3000, 343c7cf2933SEtienne Carriere 3100, 344c7cf2933SEtienne Carriere 3200, 345c7cf2933SEtienne Carriere 3300, 346c7cf2933SEtienne Carriere 3300, 347c7cf2933SEtienne Carriere 3300, 348c7cf2933SEtienne Carriere 3300, 349c7cf2933SEtienne Carriere 3300, 350c7cf2933SEtienne Carriere 3300, 351c7cf2933SEtienne Carriere 3300, 352f7e28951SEtienne Carriere 500, /* VOUT2/2 (Sink/source mode) */ 353c7cf2933SEtienne Carriere 0xFFFF, /* VREFDDR */ 354c7cf2933SEtienne Carriere }; 355c7cf2933SEtienne Carriere 356c7cf2933SEtienne Carriere static const uint16_t ldo5_voltage_table[] = { 357c7cf2933SEtienne Carriere 1700, 358c7cf2933SEtienne Carriere 1700, 359c7cf2933SEtienne Carriere 1700, 360c7cf2933SEtienne Carriere 1700, 361c7cf2933SEtienne Carriere 1700, 362c7cf2933SEtienne Carriere 1700, 363c7cf2933SEtienne Carriere 1700, 364c7cf2933SEtienne Carriere 1700, 365c7cf2933SEtienne Carriere 1700, 366c7cf2933SEtienne Carriere 1800, 367c7cf2933SEtienne Carriere 1900, 368c7cf2933SEtienne Carriere 2000, 369c7cf2933SEtienne Carriere 2100, 370c7cf2933SEtienne Carriere 2200, 371c7cf2933SEtienne Carriere 2300, 372c7cf2933SEtienne Carriere 2400, 373c7cf2933SEtienne Carriere 2500, 374c7cf2933SEtienne Carriere 2600, 375c7cf2933SEtienne Carriere 2700, 376c7cf2933SEtienne Carriere 2800, 377c7cf2933SEtienne Carriere 2900, 378c7cf2933SEtienne Carriere 3000, 379c7cf2933SEtienne Carriere 3100, 380c7cf2933SEtienne Carriere 3200, 381c7cf2933SEtienne Carriere 3300, 382c7cf2933SEtienne Carriere 3400, 383c7cf2933SEtienne Carriere 3500, 384c7cf2933SEtienne Carriere 3600, 385c7cf2933SEtienne Carriere 3700, 386c7cf2933SEtienne Carriere 3800, 387c7cf2933SEtienne Carriere 3900, 388c7cf2933SEtienne Carriere }; 389c7cf2933SEtienne Carriere 390c7cf2933SEtienne Carriere static const uint16_t ldo6_voltage_table[] = { 391c7cf2933SEtienne Carriere 900, 392c7cf2933SEtienne Carriere 1000, 393c7cf2933SEtienne Carriere 1100, 394c7cf2933SEtienne Carriere 1200, 395c7cf2933SEtienne Carriere 1300, 396c7cf2933SEtienne Carriere 1400, 397c7cf2933SEtienne Carriere 1500, 398c7cf2933SEtienne Carriere 1600, 399c7cf2933SEtienne Carriere 1700, 400c7cf2933SEtienne Carriere 1800, 401c7cf2933SEtienne Carriere 1900, 402c7cf2933SEtienne Carriere 2000, 403c7cf2933SEtienne Carriere 2100, 404c7cf2933SEtienne Carriere 2200, 405c7cf2933SEtienne Carriere 2300, 406c7cf2933SEtienne Carriere 2400, 407c7cf2933SEtienne Carriere 2500, 408c7cf2933SEtienne Carriere 2600, 409c7cf2933SEtienne Carriere 2700, 410c7cf2933SEtienne Carriere 2800, 411c7cf2933SEtienne Carriere 2900, 412c7cf2933SEtienne Carriere 3000, 413c7cf2933SEtienne Carriere 3100, 414c7cf2933SEtienne Carriere 3200, 415c7cf2933SEtienne Carriere 3300, 416c7cf2933SEtienne Carriere }; 417c7cf2933SEtienne Carriere 418c7cf2933SEtienne Carriere static const uint16_t ldo4_voltage_table[] = { 419c7cf2933SEtienne Carriere 3300, 420c7cf2933SEtienne Carriere }; 421c7cf2933SEtienne Carriere 422c7cf2933SEtienne Carriere static const uint16_t vref_ddr_voltage_table[] = { 423c7cf2933SEtienne Carriere 3300, 424c7cf2933SEtienne Carriere }; 425c7cf2933SEtienne Carriere 4263f692bdfSEtienne Carriere static const uint16_t fixed_5v_voltage_table[] = { 4273f692bdfSEtienne Carriere 5000, 4283f692bdfSEtienne Carriere }; 4293f692bdfSEtienne Carriere 430c7cf2933SEtienne Carriere /* Table of Regulators in PMIC SoC */ 431c7cf2933SEtienne Carriere static const struct regul_struct regulators_table[] = { 432c7cf2933SEtienne Carriere { 433c7cf2933SEtienne Carriere .dt_node_name = "buck1", 434c7cf2933SEtienne Carriere .voltage_table = buck1_voltage_table, 435c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(buck1_voltage_table), 436c7cf2933SEtienne Carriere .control_reg = BUCK1_CONTROL_REG, 437c7cf2933SEtienne Carriere .low_power_reg = BUCK1_PWRCTRL_REG, 43868cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 439c7cf2933SEtienne Carriere .pull_down_reg = BUCK_PULL_DOWN_REG, 440c7cf2933SEtienne Carriere .pull_down_pos = BUCK1_PULL_DOWN_SHIFT, 441c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_BUCK_REG, 442c7cf2933SEtienne Carriere .mask_reset_pos = BUCK1_MASK_RESET_SHIFT, 443c7cf2933SEtienne Carriere }, 444c7cf2933SEtienne Carriere { 445c7cf2933SEtienne Carriere .dt_node_name = "buck2", 446c7cf2933SEtienne Carriere .voltage_table = buck2_voltage_table, 447c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(buck2_voltage_table), 448c7cf2933SEtienne Carriere .control_reg = BUCK2_CONTROL_REG, 449c7cf2933SEtienne Carriere .low_power_reg = BUCK2_PWRCTRL_REG, 45068cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 451c7cf2933SEtienne Carriere .pull_down_reg = BUCK_PULL_DOWN_REG, 452c7cf2933SEtienne Carriere .pull_down_pos = BUCK2_PULL_DOWN_SHIFT, 453c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_BUCK_REG, 454c7cf2933SEtienne Carriere .mask_reset_pos = BUCK2_MASK_RESET_SHIFT, 455c7cf2933SEtienne Carriere }, 456c7cf2933SEtienne Carriere { 457c7cf2933SEtienne Carriere .dt_node_name = "buck3", 458c7cf2933SEtienne Carriere .voltage_table = buck3_voltage_table, 459c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(buck3_voltage_table), 460c7cf2933SEtienne Carriere .control_reg = BUCK3_CONTROL_REG, 461c7cf2933SEtienne Carriere .low_power_reg = BUCK3_PWRCTRL_REG, 46268cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 463c7cf2933SEtienne Carriere .pull_down_reg = BUCK_PULL_DOWN_REG, 464c7cf2933SEtienne Carriere .pull_down_pos = BUCK3_PULL_DOWN_SHIFT, 465c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_BUCK_REG, 466c7cf2933SEtienne Carriere .mask_reset_pos = BUCK3_MASK_RESET_SHIFT, 467c7cf2933SEtienne Carriere }, 468c7cf2933SEtienne Carriere { 469c7cf2933SEtienne Carriere .dt_node_name = "buck4", 470c7cf2933SEtienne Carriere .voltage_table = buck4_voltage_table, 471c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(buck4_voltage_table), 472c7cf2933SEtienne Carriere .control_reg = BUCK4_CONTROL_REG, 473c7cf2933SEtienne Carriere .low_power_reg = BUCK4_PWRCTRL_REG, 47468cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 475c7cf2933SEtienne Carriere .pull_down_reg = BUCK_PULL_DOWN_REG, 476c7cf2933SEtienne Carriere .pull_down_pos = BUCK4_PULL_DOWN_SHIFT, 477c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_BUCK_REG, 478c7cf2933SEtienne Carriere .mask_reset_pos = BUCK4_MASK_RESET_SHIFT, 479c7cf2933SEtienne Carriere }, 480c7cf2933SEtienne Carriere { 481c7cf2933SEtienne Carriere .dt_node_name = "ldo1", 482c7cf2933SEtienne Carriere .voltage_table = ldo1_voltage_table, 483c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), 484c7cf2933SEtienne Carriere .control_reg = LDO1_CONTROL_REG, 485c7cf2933SEtienne Carriere .low_power_reg = LDO1_PWRCTRL_REG, 48668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 487c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 488c7cf2933SEtienne Carriere .mask_reset_pos = LDO1_MASK_RESET_SHIFT, 489c7cf2933SEtienne Carriere }, 490c7cf2933SEtienne Carriere { 491c7cf2933SEtienne Carriere .dt_node_name = "ldo2", 492c7cf2933SEtienne Carriere .voltage_table = ldo2_voltage_table, 493c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), 494c7cf2933SEtienne Carriere .control_reg = LDO2_CONTROL_REG, 495c7cf2933SEtienne Carriere .low_power_reg = LDO2_PWRCTRL_REG, 49668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 497c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 498c7cf2933SEtienne Carriere .mask_reset_pos = LDO2_MASK_RESET_SHIFT, 499c7cf2933SEtienne Carriere }, 500c7cf2933SEtienne Carriere { 501c7cf2933SEtienne Carriere .dt_node_name = "ldo3", 502c7cf2933SEtienne Carriere .voltage_table = ldo3_voltage_table, 503c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), 504c7cf2933SEtienne Carriere .control_reg = LDO3_CONTROL_REG, 505c7cf2933SEtienne Carriere .low_power_reg = LDO3_PWRCTRL_REG, 50668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 507c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 508c7cf2933SEtienne Carriere .mask_reset_pos = LDO3_MASK_RESET_SHIFT, 509c7cf2933SEtienne Carriere }, 510c7cf2933SEtienne Carriere { 511c7cf2933SEtienne Carriere .dt_node_name = "ldo4", 512c7cf2933SEtienne Carriere .voltage_table = ldo4_voltage_table, 513c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), 514c7cf2933SEtienne Carriere .control_reg = LDO4_CONTROL_REG, 515c7cf2933SEtienne Carriere .low_power_reg = LDO4_PWRCTRL_REG, 51668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 517c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 518c7cf2933SEtienne Carriere .mask_reset_pos = LDO4_MASK_RESET_SHIFT, 519c7cf2933SEtienne Carriere }, 520c7cf2933SEtienne Carriere { 521c7cf2933SEtienne Carriere .dt_node_name = "ldo5", 522c7cf2933SEtienne Carriere .voltage_table = ldo5_voltage_table, 523c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), 524c7cf2933SEtienne Carriere .control_reg = LDO5_CONTROL_REG, 525c7cf2933SEtienne Carriere .low_power_reg = LDO5_PWRCTRL_REG, 52668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 527c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 528c7cf2933SEtienne Carriere .mask_reset_pos = LDO5_MASK_RESET_SHIFT, 529c7cf2933SEtienne Carriere }, 530c7cf2933SEtienne Carriere { 531c7cf2933SEtienne Carriere .dt_node_name = "ldo6", 532c7cf2933SEtienne Carriere .voltage_table = ldo6_voltage_table, 533c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), 534c7cf2933SEtienne Carriere .control_reg = LDO6_CONTROL_REG, 535c7cf2933SEtienne Carriere .low_power_reg = LDO6_PWRCTRL_REG, 53668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 537c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 538c7cf2933SEtienne Carriere .mask_reset_pos = LDO6_MASK_RESET_SHIFT, 539c7cf2933SEtienne Carriere }, 540c7cf2933SEtienne Carriere { 541c7cf2933SEtienne Carriere .dt_node_name = "vref_ddr", 542c7cf2933SEtienne Carriere .voltage_table = vref_ddr_voltage_table, 543c7cf2933SEtienne Carriere .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), 544c7cf2933SEtienne Carriere .control_reg = VREF_DDR_CONTROL_REG, 545c7cf2933SEtienne Carriere .low_power_reg = VREF_DDR_PWRCTRL_REG, 54668cfb83dSEtienne Carriere .enable_pos = LDO_BUCK_ENABLE_POS, 547c7cf2933SEtienne Carriere .mask_reset_reg = MASK_RESET_LDO_REG, 548c7cf2933SEtienne Carriere .mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT, 549c7cf2933SEtienne Carriere }, 550c7cf2933SEtienne Carriere { 551c7cf2933SEtienne Carriere .dt_node_name = "boost", 5523f692bdfSEtienne Carriere .voltage_table = fixed_5v_voltage_table, 5533f692bdfSEtienne Carriere .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table), 5543f692bdfSEtienne Carriere .control_reg = USB_CONTROL_REG, 5553f692bdfSEtienne Carriere .enable_pos = BOOST_ENABLED_POS, 556c7cf2933SEtienne Carriere }, 557c7cf2933SEtienne Carriere { 558c7cf2933SEtienne Carriere .dt_node_name = "pwr_sw1", 5593f692bdfSEtienne Carriere .voltage_table = fixed_5v_voltage_table, 5603f692bdfSEtienne Carriere .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table), 5613f692bdfSEtienne Carriere .control_reg = USB_CONTROL_REG, 5623f692bdfSEtienne Carriere .enable_pos = USBSW_OTG_SWITCH_ENABLED_POS, 563c7cf2933SEtienne Carriere }, 564c7cf2933SEtienne Carriere { 565c7cf2933SEtienne Carriere .dt_node_name = "pwr_sw2", 5663f692bdfSEtienne Carriere .voltage_table = fixed_5v_voltage_table, 5673f692bdfSEtienne Carriere .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table), 5683f692bdfSEtienne Carriere .control_reg = USB_CONTROL_REG, 5693f692bdfSEtienne Carriere .enable_pos = SWIN_SWOUT_ENABLED_POS, 570c7cf2933SEtienne Carriere }, 571c7cf2933SEtienne Carriere }; 572c7cf2933SEtienne Carriere 573c7cf2933SEtienne Carriere static const struct regul_struct *get_regulator_data(const char *name) 574c7cf2933SEtienne Carriere { 575c7cf2933SEtienne Carriere unsigned int i = 0; 576c7cf2933SEtienne Carriere 577c7cf2933SEtienne Carriere for (i = 0; i < ARRAY_SIZE(regulators_table); i++) 578c7cf2933SEtienne Carriere if (strcmp(name, regulators_table[i].dt_node_name) == 0) 579c7cf2933SEtienne Carriere return ®ulators_table[i]; 580c7cf2933SEtienne Carriere 581*6a63363bSEtienne Carriere DMSG("Regulator %s not found", name); 582*6a63363bSEtienne Carriere return NULL; 583c7cf2933SEtienne Carriere } 584c7cf2933SEtienne Carriere 585*6a63363bSEtienne Carriere static size_t voltage_to_index(const char *name, uint16_t millivolts) 586c7cf2933SEtienne Carriere { 587c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 588c7cf2933SEtienne Carriere unsigned int i = 0; 589c7cf2933SEtienne Carriere 590c7cf2933SEtienne Carriere assert(regul->voltage_table); 591c7cf2933SEtienne Carriere for (i = 0; i < regul->voltage_table_size; i++) 592c7cf2933SEtienne Carriere if (regul->voltage_table[i] == millivolts) 593c7cf2933SEtienne Carriere return i; 594c7cf2933SEtienne Carriere 595*6a63363bSEtienne Carriere return VOLTAGE_INDEX_INVALID; 596c7cf2933SEtienne Carriere } 597c7cf2933SEtienne Carriere 598c7cf2933SEtienne Carriere int stpmic1_powerctrl_on(void) 599c7cf2933SEtienne Carriere { 600c7cf2933SEtienne Carriere return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID, 601c7cf2933SEtienne Carriere PWRCTRL_PIN_VALID); 602c7cf2933SEtienne Carriere } 603c7cf2933SEtienne Carriere 604c7cf2933SEtienne Carriere int stpmic1_switch_off(void) 605c7cf2933SEtienne Carriere { 606c7cf2933SEtienne Carriere return stpmic1_register_update(MAIN_CONTROL_REG, 1, 607c7cf2933SEtienne Carriere SOFTWARE_SWITCH_OFF_ENABLED); 608c7cf2933SEtienne Carriere } 609c7cf2933SEtienne Carriere 610c7cf2933SEtienne Carriere int stpmic1_regulator_enable(const char *name) 611c7cf2933SEtienne Carriere { 612c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 613c7cf2933SEtienne Carriere 61468cfb83dSEtienne Carriere return stpmic1_register_update(regul->control_reg, 61568cfb83dSEtienne Carriere BIT(regul->enable_pos), 61668cfb83dSEtienne Carriere BIT(regul->enable_pos)); 617c7cf2933SEtienne Carriere } 618c7cf2933SEtienne Carriere 619c7cf2933SEtienne Carriere int stpmic1_regulator_disable(const char *name) 620c7cf2933SEtienne Carriere { 621c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 622c7cf2933SEtienne Carriere 62368cfb83dSEtienne Carriere return stpmic1_register_update(regul->control_reg, 0, 62468cfb83dSEtienne Carriere BIT(regul->enable_pos)); 625c7cf2933SEtienne Carriere } 626c7cf2933SEtienne Carriere 6272619b28cSEtienne Carriere bool stpmic1_is_regulator_enabled(const char *name) 628c7cf2933SEtienne Carriere { 629c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 630c7cf2933SEtienne Carriere uint8_t val = 0; 631c7cf2933SEtienne Carriere 632c7cf2933SEtienne Carriere if (stpmic1_register_read(regul->control_reg, &val)) 633c7cf2933SEtienne Carriere panic(); 634c7cf2933SEtienne Carriere 63568cfb83dSEtienne Carriere return val & BIT(regul->enable_pos); 636c7cf2933SEtienne Carriere } 637c7cf2933SEtienne Carriere 6381764a894SEtienne Carriere /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */ 6391764a894SEtienne Carriere static uint8_t find_plat_mask(const char *name) 6401764a894SEtienne Carriere { 6411764a894SEtienne Carriere if (!strncmp(name, "buck", 4)) 6421764a894SEtienne Carriere return BUCK_VOLTAGE_MASK; 6431764a894SEtienne Carriere 6441764a894SEtienne Carriere if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4")) 6451764a894SEtienne Carriere return LDO_VOLTAGE_MASK; 6461764a894SEtienne Carriere 6471764a894SEtienne Carriere return 0; 6481764a894SEtienne Carriere } 6491764a894SEtienne Carriere 650c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts) 651c7cf2933SEtienne Carriere { 652*6a63363bSEtienne Carriere size_t voltage_index = voltage_to_index(name, millivolts); 653c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 654c7cf2933SEtienne Carriere uint8_t mask = 0; 655c7cf2933SEtienne Carriere 656*6a63363bSEtienne Carriere if (voltage_index == VOLTAGE_INDEX_INVALID) 657*6a63363bSEtienne Carriere return -1; 658*6a63363bSEtienne Carriere 6591764a894SEtienne Carriere mask = find_plat_mask(name); 6601764a894SEtienne Carriere if (!mask) 661c7cf2933SEtienne Carriere return 0; 662c7cf2933SEtienne Carriere 663c7cf2933SEtienne Carriere return stpmic1_register_update(regul->control_reg, 664c7cf2933SEtienne Carriere voltage_index << LDO_BUCK_VOLTAGE_SHIFT, 665c7cf2933SEtienne Carriere mask); 666c7cf2933SEtienne Carriere } 667c7cf2933SEtienne Carriere 668c7cf2933SEtienne Carriere int stpmic1_regulator_mask_reset_set(const char *name) 669c7cf2933SEtienne Carriere { 670c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 671c7cf2933SEtienne Carriere 6723f692bdfSEtienne Carriere if (regul->control_reg == USB_CONTROL_REG) { 6733f692bdfSEtienne Carriere DMSG("No reset for USB control"); 6743f692bdfSEtienne Carriere return -1; 6753f692bdfSEtienne Carriere } 6763f692bdfSEtienne Carriere 677c7cf2933SEtienne Carriere return stpmic1_register_update(regul->mask_reset_reg, 678c7cf2933SEtienne Carriere BIT(regul->mask_reset_pos), 679c7cf2933SEtienne Carriere LDO_BUCK_RESET_MASK << 680c7cf2933SEtienne Carriere regul->mask_reset_pos); 681c7cf2933SEtienne Carriere } 682c7cf2933SEtienne Carriere 6836149e2d8SEtienne Carriere int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg) 6846149e2d8SEtienne Carriere { 6856149e2d8SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 6866149e2d8SEtienne Carriere 6876149e2d8SEtienne Carriere cfg->ctrl_reg = regul->control_reg; 6886149e2d8SEtienne Carriere cfg->enable_pos = regul->enable_pos; 6896149e2d8SEtienne Carriere 6906149e2d8SEtienne Carriere return 0; 6916149e2d8SEtienne Carriere } 6926149e2d8SEtienne Carriere 693eb5d5313SEtienne Carriere int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg) 694eb5d5313SEtienne Carriere { 69568cfb83dSEtienne Carriere return stpmic1_register_update(cfg->ctrl_reg, 69668cfb83dSEtienne Carriere BIT(cfg->enable_pos), 69768cfb83dSEtienne Carriere BIT(cfg->enable_pos)); 698eb5d5313SEtienne Carriere } 699eb5d5313SEtienne Carriere 700eb5d5313SEtienne Carriere /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */ 70144219e70SEtienne Carriere int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt, 702eb5d5313SEtienne Carriere struct stpmic1_bo_cfg *cfg) 703eb5d5313SEtienne Carriere { 704*6a63363bSEtienne Carriere size_t min_index = voltage_to_index(name, min_millivolt); 705eb5d5313SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 706eb5d5313SEtienne Carriere uint8_t mask = 0; 707eb5d5313SEtienne Carriere 708*6a63363bSEtienne Carriere if (min_index == VOLTAGE_INDEX_INVALID) 709*6a63363bSEtienne Carriere panic(); 710*6a63363bSEtienne Carriere 7111764a894SEtienne Carriere mask = find_plat_mask(name); 7121764a894SEtienne Carriere if (!mask) 713eb5d5313SEtienne Carriere return 1; 714eb5d5313SEtienne Carriere 715eb5d5313SEtienne Carriere cfg->ctrl_reg = regul->control_reg; 71644219e70SEtienne Carriere cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT; 717eb5d5313SEtienne Carriere cfg->mask = mask; 718eb5d5313SEtienne Carriere 719eb5d5313SEtienne Carriere return 0; 720eb5d5313SEtienne Carriere } 721eb5d5313SEtienne Carriere 722eb5d5313SEtienne Carriere int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg) 723eb5d5313SEtienne Carriere { 72444219e70SEtienne Carriere uint8_t value = 0; 72544219e70SEtienne Carriere 72644219e70SEtienne Carriere assert(cfg->ctrl_reg); 72744219e70SEtienne Carriere 72844219e70SEtienne Carriere if (stpmic1_register_read(cfg->ctrl_reg, &value)) 72944219e70SEtienne Carriere return -1; 73044219e70SEtienne Carriere 731187ba5c2SEtienne Carriere if ((value & cfg->mask) >= cfg->min_value) 73244219e70SEtienne Carriere return 0; 73344219e70SEtienne Carriere 73444219e70SEtienne Carriere return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value, 73544219e70SEtienne Carriere cfg->mask); 736eb5d5313SEtienne Carriere } 737eb5d5313SEtienne Carriere 738eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg) 739eb5d5313SEtienne Carriere { 740eb5d5313SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 741eb5d5313SEtienne Carriere 742ef18a901SEtienne Carriere if (!regul->pull_down_reg) { 743ef18a901SEtienne Carriere DMSG("No pull down for regu %s", name); 744ef18a901SEtienne Carriere panic(); 745ef18a901SEtienne Carriere } 746ef18a901SEtienne Carriere 747eb5d5313SEtienne Carriere cfg->pd_reg = regul->pull_down_reg; 748eb5d5313SEtienne Carriere cfg->pd_value = BIT(regul->pull_down_pos); 749eb5d5313SEtienne Carriere cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos; 750eb5d5313SEtienne Carriere 751eb5d5313SEtienne Carriere return 0; 752eb5d5313SEtienne Carriere } 753eb5d5313SEtienne Carriere 754eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg) 755eb5d5313SEtienne Carriere { 756ef18a901SEtienne Carriere assert(cfg->pd_reg); 757ef18a901SEtienne Carriere 758eb5d5313SEtienne Carriere return stpmic1_register_update(cfg->pd_reg, cfg->pd_value, 759eb5d5313SEtienne Carriere cfg->pd_mask); 760eb5d5313SEtienne Carriere } 761eb5d5313SEtienne Carriere 762eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg) 763eb5d5313SEtienne Carriere { 764eb5d5313SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 765eb5d5313SEtienne Carriere 766ef18a901SEtienne Carriere if (!regul->mask_reset_reg) { 767ef18a901SEtienne Carriere DMSG("No reset mask for regu %s", name); 768ef18a901SEtienne Carriere panic(); 769ef18a901SEtienne Carriere } 770ef18a901SEtienne Carriere 771eb5d5313SEtienne Carriere cfg->mrst_reg = regul->mask_reset_reg; 772eb5d5313SEtienne Carriere cfg->mrst_value = BIT(regul->mask_reset_pos); 773eb5d5313SEtienne Carriere cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos; 774eb5d5313SEtienne Carriere 775eb5d5313SEtienne Carriere return 0; 776eb5d5313SEtienne Carriere } 777eb5d5313SEtienne Carriere 778eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg) 779eb5d5313SEtienne Carriere { 780ef18a901SEtienne Carriere assert(cfg->mrst_reg); 781ef18a901SEtienne Carriere 782eb5d5313SEtienne Carriere return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value, 783eb5d5313SEtienne Carriere cfg->mrst_mask); 784eb5d5313SEtienne Carriere } 785eb5d5313SEtienne Carriere 786c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_get(const char *name) 787c7cf2933SEtienne Carriere { 788c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 789c7cf2933SEtienne Carriere uint8_t value = 0; 790c7cf2933SEtienne Carriere uint8_t mask = 0; 791c7cf2933SEtienne Carriere 7921764a894SEtienne Carriere mask = find_plat_mask(name); 7931764a894SEtienne Carriere if (!mask) 794c7cf2933SEtienne Carriere return 0; 795c7cf2933SEtienne Carriere 796c7cf2933SEtienne Carriere if (stpmic1_register_read(regul->control_reg, &value)) 797c7cf2933SEtienne Carriere return -1; 798c7cf2933SEtienne Carriere 799c7cf2933SEtienne Carriere value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT; 800c7cf2933SEtienne Carriere 801c7cf2933SEtienne Carriere if (value > regul->voltage_table_size) 802c7cf2933SEtienne Carriere return -1; 803c7cf2933SEtienne Carriere 804c7cf2933SEtienne Carriere return regul->voltage_table[value]; 805c7cf2933SEtienne Carriere } 806c7cf2933SEtienne Carriere 807c7cf2933SEtienne Carriere int stpmic1_lp_copy_reg(const char *name) 808c7cf2933SEtienne Carriere { 809c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 810c7cf2933SEtienne Carriere uint8_t val = 0; 811c7cf2933SEtienne Carriere int status = 0; 812c7cf2933SEtienne Carriere 813972b3d9aSEtienne Carriere if (!regul->low_power_reg) 814972b3d9aSEtienne Carriere return -1; 815972b3d9aSEtienne Carriere 816c7cf2933SEtienne Carriere status = stpmic1_register_read(regul->control_reg, &val); 817c7cf2933SEtienne Carriere if (status) 818c7cf2933SEtienne Carriere return status; 819c7cf2933SEtienne Carriere 820c7cf2933SEtienne Carriere return stpmic1_register_write(regul->low_power_reg, val); 821c7cf2933SEtienne Carriere } 822c7cf2933SEtienne Carriere 823972b3d9aSEtienne Carriere bool stpmic1_regu_has_lp_cfg(const char *name) 824972b3d9aSEtienne Carriere { 825972b3d9aSEtienne Carriere return get_regulator_data(name)->low_power_reg; 826972b3d9aSEtienne Carriere } 827972b3d9aSEtienne Carriere 828eb5d5313SEtienne Carriere int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg) 829eb5d5313SEtienne Carriere { 830eb5d5313SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 831eb5d5313SEtienne Carriere 832972b3d9aSEtienne Carriere if (!regul->low_power_reg) 833972b3d9aSEtienne Carriere return -1; 834972b3d9aSEtienne Carriere 835eb5d5313SEtienne Carriere cfg->ctrl_reg = regul->control_reg; 836eb5d5313SEtienne Carriere cfg->lp_reg = regul->low_power_reg; 837eb5d5313SEtienne Carriere 838eb5d5313SEtienne Carriere return 0; 839eb5d5313SEtienne Carriere } 840eb5d5313SEtienne Carriere 841eb5d5313SEtienne Carriere int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg) 842eb5d5313SEtienne Carriere { 843eb5d5313SEtienne Carriere uint8_t val = 0; 844eb5d5313SEtienne Carriere int status = 0; 845eb5d5313SEtienne Carriere 846ef18a901SEtienne Carriere assert(cfg->lp_reg); 847ef18a901SEtienne Carriere 848eb5d5313SEtienne Carriere status = stpmic1_register_read(cfg->ctrl_reg, &val); 849eb5d5313SEtienne Carriere if (!status) 850eb5d5313SEtienne Carriere status = stpmic1_register_write(cfg->lp_reg, val); 851eb5d5313SEtienne Carriere 852eb5d5313SEtienne Carriere return status; 853eb5d5313SEtienne Carriere } 854eb5d5313SEtienne Carriere 855c7cf2933SEtienne Carriere int stpmic1_lp_reg_on_off(const char *name, uint8_t enable) 856c7cf2933SEtienne Carriere { 857c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 858c7cf2933SEtienne Carriere 859972b3d9aSEtienne Carriere if (!regul->low_power_reg) 860972b3d9aSEtienne Carriere return -1; 861972b3d9aSEtienne Carriere 862c7cf2933SEtienne Carriere return stpmic1_register_update(regul->low_power_reg, enable, 863c7cf2933SEtienne Carriere LDO_BUCK_ENABLE_MASK); 864c7cf2933SEtienne Carriere } 865c7cf2933SEtienne Carriere 866eb5d5313SEtienne Carriere int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable) 867eb5d5313SEtienne Carriere { 868ef18a901SEtienne Carriere assert(cfg->lp_reg && (enable == 0 || enable == 1)); 869ef18a901SEtienne Carriere 870eb5d5313SEtienne Carriere return stpmic1_register_update(cfg->lp_reg, enable, 871eb5d5313SEtienne Carriere LDO_BUCK_ENABLE_MASK); 872eb5d5313SEtienne Carriere } 873eb5d5313SEtienne Carriere 874c7cf2933SEtienne Carriere int stpmic1_lp_set_mode(const char *name, uint8_t hplp) 875c7cf2933SEtienne Carriere { 876c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 877c7cf2933SEtienne Carriere 878ef18a901SEtienne Carriere assert(regul->low_power_reg && (hplp == 0 || hplp == 1)); 879ef18a901SEtienne Carriere 880c7cf2933SEtienne Carriere return stpmic1_register_update(regul->low_power_reg, 88142032ea0SEtienne Carriere hplp << LDO_BUCK_HPLP_POS, 88242032ea0SEtienne Carriere BIT(LDO_BUCK_HPLP_POS)); 883c7cf2933SEtienne Carriere } 884c7cf2933SEtienne Carriere 885eb5d5313SEtienne Carriere int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode) 886eb5d5313SEtienne Carriere { 887ef18a901SEtienne Carriere assert(cfg->lp_reg && (mode == 0 || mode == 1)); 888eb5d5313SEtienne Carriere return stpmic1_register_update(cfg->lp_reg, 88942032ea0SEtienne Carriere mode << LDO_BUCK_HPLP_POS, 89042032ea0SEtienne Carriere BIT(LDO_BUCK_HPLP_POS)); 891eb5d5313SEtienne Carriere } 892eb5d5313SEtienne Carriere 893c7cf2933SEtienne Carriere int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts) 894c7cf2933SEtienne Carriere { 895*6a63363bSEtienne Carriere size_t voltage_index = voltage_to_index(name, millivolts); 896c7cf2933SEtienne Carriere const struct regul_struct *regul = get_regulator_data(name); 897c7cf2933SEtienne Carriere uint8_t mask = 0; 898c7cf2933SEtienne Carriere 899*6a63363bSEtienne Carriere assert(voltage_index != VOLTAGE_INDEX_INVALID); 900*6a63363bSEtienne Carriere 9011764a894SEtienne Carriere mask = find_plat_mask(name); 9021764a894SEtienne Carriere if (!mask) 903c7cf2933SEtienne Carriere return 0; 904c7cf2933SEtienne Carriere 905c7cf2933SEtienne Carriere return stpmic1_register_update(regul->low_power_reg, voltage_index << 2, 906c7cf2933SEtienne Carriere mask); 907c7cf2933SEtienne Carriere } 908c7cf2933SEtienne Carriere 909eb5d5313SEtienne Carriere /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */ 910eb5d5313SEtienne Carriere int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts, 911eb5d5313SEtienne Carriere struct stpmic1_lp_cfg *cfg) 912eb5d5313SEtienne Carriere 913eb5d5313SEtienne Carriere { 914*6a63363bSEtienne Carriere size_t voltage_index = voltage_to_index(name, millivolts); 915eb5d5313SEtienne Carriere uint8_t mask = 0; 916eb5d5313SEtienne Carriere 9171764a894SEtienne Carriere mask = find_plat_mask(name); 9181764a894SEtienne Carriere if (!mask) 919eb5d5313SEtienne Carriere return 1; 920eb5d5313SEtienne Carriere 921*6a63363bSEtienne Carriere assert(voltage_index != VOLTAGE_INDEX_INVALID && 922*6a63363bSEtienne Carriere cfg->lp_reg == get_regulator_data(name)->low_power_reg); 923*6a63363bSEtienne Carriere 924eb5d5313SEtienne Carriere cfg->value = voltage_index << 2; 925eb5d5313SEtienne Carriere cfg->mask = mask; 926eb5d5313SEtienne Carriere 927eb5d5313SEtienne Carriere return 0; 928eb5d5313SEtienne Carriere } 929eb5d5313SEtienne Carriere 930eb5d5313SEtienne Carriere int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg) 931eb5d5313SEtienne Carriere { 932ef18a901SEtienne Carriere assert(cfg->lp_reg); 933ef18a901SEtienne Carriere 934eb5d5313SEtienne Carriere return stpmic1_register_update(cfg->lp_reg, cfg->value, cfg->mask); 935eb5d5313SEtienne Carriere } 936eb5d5313SEtienne Carriere 937c7cf2933SEtienne Carriere int stpmic1_register_read(uint8_t register_id, uint8_t *value) 938c7cf2933SEtienne Carriere { 939c7cf2933SEtienne Carriere struct i2c_handle_s *i2c = pmic_i2c_handle; 940c7cf2933SEtienne Carriere 941eb5d5313SEtienne Carriere return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr, 942eb5d5313SEtienne Carriere register_id, value, 943eb5d5313SEtienne Carriere false /* !write */); 944c7cf2933SEtienne Carriere } 945c7cf2933SEtienne Carriere 946c7cf2933SEtienne Carriere int stpmic1_register_write(uint8_t register_id, uint8_t value) 947c7cf2933SEtienne Carriere { 948c7cf2933SEtienne Carriere struct i2c_handle_s *i2c = pmic_i2c_handle; 949c7cf2933SEtienne Carriere uint8_t val = value; 950c7cf2933SEtienne Carriere 951eb5d5313SEtienne Carriere return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr, 952eb5d5313SEtienne Carriere register_id, &val, 953eb5d5313SEtienne Carriere true /* write */); 954c7cf2933SEtienne Carriere } 955c7cf2933SEtienne Carriere 956c7cf2933SEtienne Carriere int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) 957c7cf2933SEtienne Carriere { 958c7cf2933SEtienne Carriere int status = 0; 959c7cf2933SEtienne Carriere uint8_t val = 0; 960c7cf2933SEtienne Carriere 961c7cf2933SEtienne Carriere status = stpmic1_register_read(register_id, &val); 962c7cf2933SEtienne Carriere if (status) 963c7cf2933SEtienne Carriere return status; 964c7cf2933SEtienne Carriere 965c7cf2933SEtienne Carriere val = (val & ~mask) | (value & mask); 966c7cf2933SEtienne Carriere 967c7cf2933SEtienne Carriere return stpmic1_register_write(register_id, val); 968c7cf2933SEtienne Carriere } 969c7cf2933SEtienne Carriere 970c7cf2933SEtienne Carriere void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr) 971c7cf2933SEtienne Carriere { 972c7cf2933SEtienne Carriere pmic_i2c_handle = i2c_handle; 973c7cf2933SEtienne Carriere pmic_i2c_addr = i2c_addr; 974c7cf2933SEtienne Carriere } 975c7cf2933SEtienne Carriere 976c7cf2933SEtienne Carriere void stpmic1_dump_regulators(void) 977c7cf2933SEtienne Carriere { 978c7cf2933SEtienne Carriere size_t i = 0; 979c7cf2933SEtienne Carriere char __maybe_unused const *name = NULL; 980c7cf2933SEtienne Carriere 981c7cf2933SEtienne Carriere for (i = 0; i < ARRAY_SIZE(regulators_table); i++) { 982c7cf2933SEtienne Carriere if (!regulators_table[i].control_reg) 983c7cf2933SEtienne Carriere continue; 984c7cf2933SEtienne Carriere 985c7cf2933SEtienne Carriere name = regulators_table[i].dt_node_name; 986c7cf2933SEtienne Carriere DMSG("PMIC regul %s: %sable, %dmV", 987c7cf2933SEtienne Carriere name, stpmic1_is_regulator_enabled(name) ? "en" : "dis", 988c7cf2933SEtienne Carriere stpmic1_regulator_voltage_get(name)); 989c7cf2933SEtienne Carriere } 990c7cf2933SEtienne Carriere } 991c7cf2933SEtienne Carriere 992c7cf2933SEtienne Carriere int stpmic1_get_version(unsigned long *version) 993c7cf2933SEtienne Carriere { 994c7cf2933SEtienne Carriere uint8_t read_val = 0; 995c7cf2933SEtienne Carriere 996c7cf2933SEtienne Carriere if (stpmic1_register_read(VERSION_STATUS_REG, &read_val)) 997c7cf2933SEtienne Carriere return -1; 998c7cf2933SEtienne Carriere 999c7cf2933SEtienne Carriere *version = read_val; 1000c7cf2933SEtienne Carriere return 0; 1001c7cf2933SEtienne Carriere } 1002