162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci// Copyright (C) 2018 ROHM Semiconductors 362306a36Sopenharmony_ci// bd71837-regulator.c ROHM BD71837MWV/BD71847MWV regulator driver 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/delay.h> 662306a36Sopenharmony_ci#include <linux/err.h> 762306a36Sopenharmony_ci#include <linux/interrupt.h> 862306a36Sopenharmony_ci#include <linux/kernel.h> 962306a36Sopenharmony_ci#include <linux/mfd/rohm-bd718x7.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/of.h> 1262306a36Sopenharmony_ci#include <linux/platform_device.h> 1362306a36Sopenharmony_ci#include <linux/regulator/driver.h> 1462306a36Sopenharmony_ci#include <linux/regulator/machine.h> 1562306a36Sopenharmony_ci#include <linux/regulator/of_regulator.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Typical regulator startup times as per data sheet in uS */ 1962306a36Sopenharmony_ci#define BD71847_BUCK1_STARTUP_TIME 144 2062306a36Sopenharmony_ci#define BD71847_BUCK2_STARTUP_TIME 162 2162306a36Sopenharmony_ci#define BD71847_BUCK3_STARTUP_TIME 162 2262306a36Sopenharmony_ci#define BD71847_BUCK4_STARTUP_TIME 240 2362306a36Sopenharmony_ci#define BD71847_BUCK5_STARTUP_TIME 270 2462306a36Sopenharmony_ci#define BD71847_BUCK6_STARTUP_TIME 200 2562306a36Sopenharmony_ci#define BD71847_LDO1_STARTUP_TIME 440 2662306a36Sopenharmony_ci#define BD71847_LDO2_STARTUP_TIME 370 2762306a36Sopenharmony_ci#define BD71847_LDO3_STARTUP_TIME 310 2862306a36Sopenharmony_ci#define BD71847_LDO4_STARTUP_TIME 400 2962306a36Sopenharmony_ci#define BD71847_LDO5_STARTUP_TIME 530 3062306a36Sopenharmony_ci#define BD71847_LDO6_STARTUP_TIME 400 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define BD71837_BUCK1_STARTUP_TIME 160 3362306a36Sopenharmony_ci#define BD71837_BUCK2_STARTUP_TIME 180 3462306a36Sopenharmony_ci#define BD71837_BUCK3_STARTUP_TIME 180 3562306a36Sopenharmony_ci#define BD71837_BUCK4_STARTUP_TIME 180 3662306a36Sopenharmony_ci#define BD71837_BUCK5_STARTUP_TIME 160 3762306a36Sopenharmony_ci#define BD71837_BUCK6_STARTUP_TIME 240 3862306a36Sopenharmony_ci#define BD71837_BUCK7_STARTUP_TIME 220 3962306a36Sopenharmony_ci#define BD71837_BUCK8_STARTUP_TIME 200 4062306a36Sopenharmony_ci#define BD71837_LDO1_STARTUP_TIME 440 4162306a36Sopenharmony_ci#define BD71837_LDO2_STARTUP_TIME 370 4262306a36Sopenharmony_ci#define BD71837_LDO3_STARTUP_TIME 310 4362306a36Sopenharmony_ci#define BD71837_LDO4_STARTUP_TIME 400 4462306a36Sopenharmony_ci#define BD71837_LDO5_STARTUP_TIME 310 4562306a36Sopenharmony_ci#define BD71837_LDO6_STARTUP_TIME 400 4662306a36Sopenharmony_ci#define BD71837_LDO7_STARTUP_TIME 530 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* 4962306a36Sopenharmony_ci * BD718(37/47/50) have two "enable control modes". ON/OFF can either be 5062306a36Sopenharmony_ci * controlled by software - or by PMIC internal HW state machine. Whether 5162306a36Sopenharmony_ci * regulator should be under SW or HW control can be defined from device-tree. 5262306a36Sopenharmony_ci * Let's provide separate ops for regulators to use depending on the "enable 5362306a36Sopenharmony_ci * control mode". 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci#define BD718XX_HWOPNAME(swopname) swopname##_hwcontrol 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define BD718XX_OPS(name, _list_voltage, _map_voltage, _set_voltage_sel, \ 5862306a36Sopenharmony_ci _get_voltage_sel, _set_voltage_time_sel, _set_ramp_delay, \ 5962306a36Sopenharmony_ci _set_uvp, _set_ovp) \ 6062306a36Sopenharmony_cistatic const struct regulator_ops name = { \ 6162306a36Sopenharmony_ci .enable = regulator_enable_regmap, \ 6262306a36Sopenharmony_ci .disable = regulator_disable_regmap, \ 6362306a36Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, \ 6462306a36Sopenharmony_ci .list_voltage = (_list_voltage), \ 6562306a36Sopenharmony_ci .map_voltage = (_map_voltage), \ 6662306a36Sopenharmony_ci .set_voltage_sel = (_set_voltage_sel), \ 6762306a36Sopenharmony_ci .get_voltage_sel = (_get_voltage_sel), \ 6862306a36Sopenharmony_ci .set_voltage_time_sel = (_set_voltage_time_sel), \ 6962306a36Sopenharmony_ci .set_ramp_delay = (_set_ramp_delay), \ 7062306a36Sopenharmony_ci .set_under_voltage_protection = (_set_uvp), \ 7162306a36Sopenharmony_ci .set_over_voltage_protection = (_set_ovp), \ 7262306a36Sopenharmony_ci}; \ 7362306a36Sopenharmony_ci \ 7462306a36Sopenharmony_cistatic const struct regulator_ops BD718XX_HWOPNAME(name) = { \ 7562306a36Sopenharmony_ci .is_enabled = always_enabled_by_hwstate, \ 7662306a36Sopenharmony_ci .list_voltage = (_list_voltage), \ 7762306a36Sopenharmony_ci .map_voltage = (_map_voltage), \ 7862306a36Sopenharmony_ci .set_voltage_sel = (_set_voltage_sel), \ 7962306a36Sopenharmony_ci .get_voltage_sel = (_get_voltage_sel), \ 8062306a36Sopenharmony_ci .set_voltage_time_sel = (_set_voltage_time_sel), \ 8162306a36Sopenharmony_ci .set_ramp_delay = (_set_ramp_delay), \ 8262306a36Sopenharmony_ci .set_under_voltage_protection = (_set_uvp), \ 8362306a36Sopenharmony_ci .set_over_voltage_protection = (_set_ovp), \ 8462306a36Sopenharmony_ci} \ 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* 8762306a36Sopenharmony_ci * BUCK1/2/3/4 8862306a36Sopenharmony_ci * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting 8962306a36Sopenharmony_ci * 00: 10.00mV/usec 10mV 1uS 9062306a36Sopenharmony_ci * 01: 5.00mV/usec 10mV 2uS 9162306a36Sopenharmony_ci * 10: 2.50mV/usec 10mV 4uS 9262306a36Sopenharmony_ci * 11: 1.25mV/usec 10mV 8uS 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_cistatic const unsigned int bd718xx_ramp_delay[] = { 10000, 5000, 2500, 1250 }; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* These functions are used when regulators are under HW state machine control. 9762306a36Sopenharmony_ci * We assume PMIC is in RUN state because SW running and able to query the 9862306a36Sopenharmony_ci * status. Most of the regulators have fixed ON or OFF state at RUN/IDLE so for 9962306a36Sopenharmony_ci * them we just return a constant. BD71837 BUCK3 and BUCK4 are exceptions as 10062306a36Sopenharmony_ci * they support configuring the ON/OFF state for RUN. 10162306a36Sopenharmony_ci * 10262306a36Sopenharmony_ci * Note for next hacker - these PMICs have a register where the HW state can be 10362306a36Sopenharmony_ci * read. If assuming RUN appears to be false in your use-case - you can 10462306a36Sopenharmony_ci * implement state reading (although that is not going to be atomic) before 10562306a36Sopenharmony_ci * returning the enable state. 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_cistatic int always_enabled_by_hwstate(struct regulator_dev *rdev) 10862306a36Sopenharmony_ci{ 10962306a36Sopenharmony_ci return 1; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic int never_enabled_by_hwstate(struct regulator_dev *rdev) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci return 0; 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic int bd71837_get_buck34_enable_hwctrl(struct regulator_dev *rdev) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci int ret; 12062306a36Sopenharmony_ci unsigned int val; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); 12362306a36Sopenharmony_ci if (ret) 12462306a36Sopenharmony_ci return ret; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci return !!(BD718XX_BUCK_RUN_ON & val); 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic void voltage_change_done(struct regulator_dev *rdev, unsigned int sel, 13062306a36Sopenharmony_ci unsigned int *mask) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci int ret; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci if (*mask) { 13562306a36Sopenharmony_ci /* 13662306a36Sopenharmony_ci * Let's allow scheduling as we use I2C anyways. We just need to 13762306a36Sopenharmony_ci * guarantee minimum of 1ms sleep - it shouldn't matter if we 13862306a36Sopenharmony_ci * exceed it due to the scheduling. 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_ci msleep(1); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci ret = regmap_clear_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 14362306a36Sopenharmony_ci *mask); 14462306a36Sopenharmony_ci if (ret) 14562306a36Sopenharmony_ci dev_err(&rdev->dev, 14662306a36Sopenharmony_ci "Failed to re-enable voltage monitoring (%d)\n", 14762306a36Sopenharmony_ci ret); 14862306a36Sopenharmony_ci } 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel, 15262306a36Sopenharmony_ci unsigned int *mask) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci int ret; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci *mask = 0; 15762306a36Sopenharmony_ci if (rdev->desc->ops->is_enabled(rdev)) { 15862306a36Sopenharmony_ci int now, new; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci now = rdev->desc->ops->get_voltage_sel(rdev); 16162306a36Sopenharmony_ci if (now < 0) 16262306a36Sopenharmony_ci return now; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci now = rdev->desc->ops->list_voltage(rdev, now); 16562306a36Sopenharmony_ci if (now < 0) 16662306a36Sopenharmony_ci return now; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci new = rdev->desc->ops->list_voltage(rdev, sel); 16962306a36Sopenharmony_ci if (new < 0) 17062306a36Sopenharmony_ci return new; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* 17362306a36Sopenharmony_ci * If we increase LDO voltage when LDO is enabled we need to 17462306a36Sopenharmony_ci * disable the power-good detection until voltage has reached 17562306a36Sopenharmony_ci * the new level. According to HW colleagues the maximum time 17662306a36Sopenharmony_ci * it takes is 1000us. I assume that on systems with light load 17762306a36Sopenharmony_ci * this might be less - and we could probably use DT to give 17862306a36Sopenharmony_ci * system specific delay value if performance matters. 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * Well, knowing we use I2C here and can add scheduling delays 18162306a36Sopenharmony_ci * I don't think it is worth the hassle and I just add fixed 18262306a36Sopenharmony_ci * 1ms sleep here (and allow scheduling). If this turns out to 18362306a36Sopenharmony_ci * be a problem we can change it to delay and make the delay 18462306a36Sopenharmony_ci * time configurable. 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_ci if (new > now) { 18762306a36Sopenharmony_ci int tmp; 18862306a36Sopenharmony_ci int prot_bit; 18962306a36Sopenharmony_ci int ldo_offset = rdev->desc->id - BD718XX_LDO1; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci prot_bit = BD718XX_LDO1_VRMON80 << ldo_offset; 19262306a36Sopenharmony_ci ret = regmap_read(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 19362306a36Sopenharmony_ci &tmp); 19462306a36Sopenharmony_ci if (ret) { 19562306a36Sopenharmony_ci dev_err(&rdev->dev, 19662306a36Sopenharmony_ci "Failed to read voltage monitoring state\n"); 19762306a36Sopenharmony_ci return ret; 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci if (!(tmp & prot_bit)) { 20162306a36Sopenharmony_ci /* We disable protection if it was enabled... */ 20262306a36Sopenharmony_ci ret = regmap_set_bits(rdev->regmap, 20362306a36Sopenharmony_ci BD718XX_REG_MVRFLTMASK2, 20462306a36Sopenharmony_ci prot_bit); 20562306a36Sopenharmony_ci /* ...and we also want to re-enable it */ 20662306a36Sopenharmony_ci *mask = prot_bit; 20762306a36Sopenharmony_ci } 20862306a36Sopenharmony_ci if (ret) { 20962306a36Sopenharmony_ci dev_err(&rdev->dev, 21062306a36Sopenharmony_ci "Failed to stop voltage monitoring\n"); 21162306a36Sopenharmony_ci return ret; 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci } 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci return 0; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev, 22062306a36Sopenharmony_ci unsigned int sel) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci int ret; 22362306a36Sopenharmony_ci int mask; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci ret = voltage_change_prepare(rdev, sel, &mask); 22662306a36Sopenharmony_ci if (ret) 22762306a36Sopenharmony_ci return ret; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci ret = regulator_set_voltage_sel_regmap(rdev, sel); 23062306a36Sopenharmony_ci voltage_change_done(rdev, sel, &mask); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci return ret; 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic int bd718xx_set_voltage_sel_pickable_restricted( 23662306a36Sopenharmony_ci struct regulator_dev *rdev, unsigned int sel) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci int ret; 23962306a36Sopenharmony_ci int mask; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci ret = voltage_change_prepare(rdev, sel, &mask); 24262306a36Sopenharmony_ci if (ret) 24362306a36Sopenharmony_ci return ret; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel); 24662306a36Sopenharmony_ci voltage_change_done(rdev, sel, &mask); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci return ret; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic int bd71837_set_voltage_sel_pickable_restricted( 25262306a36Sopenharmony_ci struct regulator_dev *rdev, unsigned int sel) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci if (rdev->desc->ops->is_enabled(rdev)) 25562306a36Sopenharmony_ci return -EBUSY; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci return regulator_set_voltage_sel_pickable_regmap(rdev, sel); 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci/* 26162306a36Sopenharmony_ci * BD71837 BUCK1/2/3/4 26262306a36Sopenharmony_ci * BD71847 BUCK1/2 26362306a36Sopenharmony_ci * 0.70 to 1.30V (10mV step) 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_cistatic const struct linear_range bd718xx_dvs_buck_volts[] = { 26662306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000), 26762306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0), 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci/* 27162306a36Sopenharmony_ci * BD71837 BUCK5 27262306a36Sopenharmony_ci * 0.7V to 1.35V (range 0) 27362306a36Sopenharmony_ci * and 27462306a36Sopenharmony_ci * 0.675 to 1.325 (range 1) 27562306a36Sopenharmony_ci */ 27662306a36Sopenharmony_cistatic const struct linear_range bd71837_buck5_volts[] = { 27762306a36Sopenharmony_ci /* Ranges when VOLT_SEL bit is 0 */ 27862306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), 27962306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), 28062306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000), 28162306a36Sopenharmony_ci /* Ranges when VOLT_SEL bit is 1 */ 28262306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000), 28362306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000), 28462306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000), 28562306a36Sopenharmony_ci}; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci/* 28862306a36Sopenharmony_ci * Range selector for first 3 linear ranges is 0x0 28962306a36Sopenharmony_ci * and 0x1 for last 3 ranges. 29062306a36Sopenharmony_ci */ 29162306a36Sopenharmony_cistatic const unsigned int bd71837_buck5_volt_range_sel[] = { 29262306a36Sopenharmony_ci 0x0, 0x0, 0x0, 0x1, 0x1, 0x1 29362306a36Sopenharmony_ci}; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/* 29662306a36Sopenharmony_ci * BD71847 BUCK3 29762306a36Sopenharmony_ci */ 29862306a36Sopenharmony_cistatic const struct linear_range bd71847_buck3_volts[] = { 29962306a36Sopenharmony_ci /* Ranges when VOLT_SEL bits are 00 */ 30062306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), 30162306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), 30262306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000), 30362306a36Sopenharmony_ci /* Ranges when VOLT_SEL bits are 01 */ 30462306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000), 30562306a36Sopenharmony_ci /* Ranges when VOLT_SEL bits are 11 */ 30662306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000), 30762306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000), 30862306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000), 30962306a36Sopenharmony_ci}; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic const unsigned int bd71847_buck3_volt_range_sel[] = { 31262306a36Sopenharmony_ci 0x0, 0x0, 0x0, 0x1, 0x2, 0x2, 0x2 31362306a36Sopenharmony_ci}; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic const struct linear_range bd71847_buck4_volts[] = { 31662306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 31762306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000), 31862306a36Sopenharmony_ci}; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x1 }; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci/* 32362306a36Sopenharmony_ci * BUCK6 32462306a36Sopenharmony_ci * 3.0V to 3.3V (step 100mV) 32562306a36Sopenharmony_ci */ 32662306a36Sopenharmony_cistatic const struct linear_range bd71837_buck6_volts[] = { 32762306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 32862306a36Sopenharmony_ci}; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci/* 33162306a36Sopenharmony_ci * BD71837 BUCK7 33262306a36Sopenharmony_ci * BD71847 BUCK5 33362306a36Sopenharmony_ci * 000 = 1.605V 33462306a36Sopenharmony_ci * 001 = 1.695V 33562306a36Sopenharmony_ci * 010 = 1.755V 33662306a36Sopenharmony_ci * 011 = 1.8V (Initial) 33762306a36Sopenharmony_ci * 100 = 1.845V 33862306a36Sopenharmony_ci * 101 = 1.905V 33962306a36Sopenharmony_ci * 110 = 1.95V 34062306a36Sopenharmony_ci * 111 = 1.995V 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_cistatic const unsigned int bd718xx_3rd_nodvs_buck_volts[] = { 34362306a36Sopenharmony_ci 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000 34462306a36Sopenharmony_ci}; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci/* 34762306a36Sopenharmony_ci * BUCK8 34862306a36Sopenharmony_ci * 0.8V to 1.40V (step 10mV) 34962306a36Sopenharmony_ci */ 35062306a36Sopenharmony_cistatic const struct linear_range bd718xx_4th_nodvs_buck_volts[] = { 35162306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000), 35262306a36Sopenharmony_ci}; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* 35562306a36Sopenharmony_ci * LDO1 35662306a36Sopenharmony_ci * 3.0 to 3.3V (100mV step) 35762306a36Sopenharmony_ci */ 35862306a36Sopenharmony_cistatic const struct linear_range bd718xx_ldo1_volts[] = { 35962306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 36062306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000), 36162306a36Sopenharmony_ci}; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_cistatic const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x1 }; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci/* 36662306a36Sopenharmony_ci * LDO2 36762306a36Sopenharmony_ci * 0.8 or 0.9V 36862306a36Sopenharmony_ci */ 36962306a36Sopenharmony_cistatic const unsigned int ldo_2_volts[] = { 37062306a36Sopenharmony_ci 900000, 800000 37162306a36Sopenharmony_ci}; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci/* 37462306a36Sopenharmony_ci * LDO3 37562306a36Sopenharmony_ci * 1.8 to 3.3V (100mV step) 37662306a36Sopenharmony_ci */ 37762306a36Sopenharmony_cistatic const struct linear_range bd718xx_ldo3_volts[] = { 37862306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 37962306a36Sopenharmony_ci}; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci/* 38262306a36Sopenharmony_ci * LDO4 38362306a36Sopenharmony_ci * 0.9 to 1.8V (100mV step) 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_cistatic const struct linear_range bd718xx_ldo4_volts[] = { 38662306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), 38762306a36Sopenharmony_ci}; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci/* 39062306a36Sopenharmony_ci * LDO5 for BD71837 39162306a36Sopenharmony_ci * 1.8 to 3.3V (100mV step) 39262306a36Sopenharmony_ci */ 39362306a36Sopenharmony_cistatic const struct linear_range bd71837_ldo5_volts[] = { 39462306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 39562306a36Sopenharmony_ci}; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci/* 39862306a36Sopenharmony_ci * LDO5 for BD71837 39962306a36Sopenharmony_ci * 1.8 to 3.3V (100mV step) 40062306a36Sopenharmony_ci */ 40162306a36Sopenharmony_cistatic const struct linear_range bd71847_ldo5_volts[] = { 40262306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 40362306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000), 40462306a36Sopenharmony_ci}; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_cistatic const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x1 }; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci/* 40962306a36Sopenharmony_ci * LDO6 41062306a36Sopenharmony_ci * 0.9 to 1.8V (100mV step) 41162306a36Sopenharmony_ci */ 41262306a36Sopenharmony_cistatic const struct linear_range bd718xx_ldo6_volts[] = { 41362306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), 41462306a36Sopenharmony_ci}; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci/* 41762306a36Sopenharmony_ci * LDO7 41862306a36Sopenharmony_ci * 1.8 to 3.3V (100mV step) 41962306a36Sopenharmony_ci */ 42062306a36Sopenharmony_cistatic const struct linear_range bd71837_ldo7_volts[] = { 42162306a36Sopenharmony_ci REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 42262306a36Sopenharmony_ci}; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistruct reg_init { 42562306a36Sopenharmony_ci unsigned int reg; 42662306a36Sopenharmony_ci unsigned int mask; 42762306a36Sopenharmony_ci unsigned int val; 42862306a36Sopenharmony_ci}; 42962306a36Sopenharmony_cistruct bd718xx_regulator_data { 43062306a36Sopenharmony_ci struct regulator_desc desc; 43162306a36Sopenharmony_ci const struct rohm_dvs_config dvs; 43262306a36Sopenharmony_ci const struct reg_init init; 43362306a36Sopenharmony_ci const struct reg_init *additional_inits; 43462306a36Sopenharmony_ci int additional_init_amnt; 43562306a36Sopenharmony_ci}; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_cistatic int bd718x7_xvp_sanity_check(struct regulator_dev *rdev, int lim_uV, 43862306a36Sopenharmony_ci int severity) 43962306a36Sopenharmony_ci{ 44062306a36Sopenharmony_ci /* 44162306a36Sopenharmony_ci * BD71837/47/50 ... (ICs supported by this driver) do not provide 44262306a36Sopenharmony_ci * warnings, only protection 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_ci if (severity != REGULATOR_SEVERITY_PROT) { 44562306a36Sopenharmony_ci dev_err(&rdev->dev, 44662306a36Sopenharmony_ci "Unsupported Under Voltage protection level\n"); 44762306a36Sopenharmony_ci return -EINVAL; 44862306a36Sopenharmony_ci } 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci /* 45162306a36Sopenharmony_ci * And protection limit is not changeable. It can only be enabled 45262306a36Sopenharmony_ci * or disabled 45362306a36Sopenharmony_ci */ 45462306a36Sopenharmony_ci if (lim_uV) 45562306a36Sopenharmony_ci return -EINVAL; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci return 0; 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_cistatic int bd718x7_set_ldo_uvp(struct regulator_dev *rdev, int lim_uV, 46162306a36Sopenharmony_ci int severity, bool enable) 46262306a36Sopenharmony_ci{ 46362306a36Sopenharmony_ci int ldo_offset = rdev->desc->id - BD718XX_LDO1; 46462306a36Sopenharmony_ci int prot_bit, ret; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci ret = bd718x7_xvp_sanity_check(rdev, lim_uV, severity); 46762306a36Sopenharmony_ci if (ret) 46862306a36Sopenharmony_ci return ret; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci prot_bit = BD718XX_LDO1_VRMON80 << ldo_offset; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci if (enable) 47362306a36Sopenharmony_ci return regmap_clear_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 47462306a36Sopenharmony_ci prot_bit); 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci return regmap_set_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 47762306a36Sopenharmony_ci prot_bit); 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_cistatic int bd718x7_get_buck_prot_reg(int id, int *reg) 48162306a36Sopenharmony_ci{ 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci if (id > BD718XX_BUCK8) { 48462306a36Sopenharmony_ci WARN_ON(id > BD718XX_BUCK8); 48562306a36Sopenharmony_ci return -EINVAL; 48662306a36Sopenharmony_ci } 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci if (id > BD718XX_BUCK4) 48962306a36Sopenharmony_ci *reg = BD718XX_REG_MVRFLTMASK0; 49062306a36Sopenharmony_ci else 49162306a36Sopenharmony_ci *reg = BD718XX_REG_MVRFLTMASK1; 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci return 0; 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic int bd718x7_get_buck_ovp_info(int id, int *reg, int *bit) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci int ret; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci ret = bd718x7_get_buck_prot_reg(id, reg); 50162306a36Sopenharmony_ci if (ret) 50262306a36Sopenharmony_ci return ret; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci *bit = BIT((id % 4) * 2 + 1); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci return 0; 50762306a36Sopenharmony_ci} 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistatic int bd718x7_get_buck_uvp_info(int id, int *reg, int *bit) 51062306a36Sopenharmony_ci{ 51162306a36Sopenharmony_ci int ret; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci ret = bd718x7_get_buck_prot_reg(id, reg); 51462306a36Sopenharmony_ci if (ret) 51562306a36Sopenharmony_ci return ret; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci *bit = BIT((id % 4) * 2); 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci return 0; 52062306a36Sopenharmony_ci} 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_cistatic int bd718x7_set_buck_uvp(struct regulator_dev *rdev, int lim_uV, 52362306a36Sopenharmony_ci int severity, bool enable) 52462306a36Sopenharmony_ci{ 52562306a36Sopenharmony_ci int bit, reg, ret; 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci ret = bd718x7_xvp_sanity_check(rdev, lim_uV, severity); 52862306a36Sopenharmony_ci if (ret) 52962306a36Sopenharmony_ci return ret; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci ret = bd718x7_get_buck_uvp_info(rdev->desc->id, ®, &bit); 53262306a36Sopenharmony_ci if (ret) 53362306a36Sopenharmony_ci return ret; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci if (enable) 53662306a36Sopenharmony_ci return regmap_clear_bits(rdev->regmap, reg, bit); 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return regmap_set_bits(rdev->regmap, reg, bit); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci} 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_cistatic int bd718x7_set_buck_ovp(struct regulator_dev *rdev, int lim_uV, 54362306a36Sopenharmony_ci int severity, 54462306a36Sopenharmony_ci bool enable) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci int bit, reg, ret; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci ret = bd718x7_xvp_sanity_check(rdev, lim_uV, severity); 54962306a36Sopenharmony_ci if (ret) 55062306a36Sopenharmony_ci return ret; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci ret = bd718x7_get_buck_ovp_info(rdev->desc->id, ®, &bit); 55362306a36Sopenharmony_ci if (ret) 55462306a36Sopenharmony_ci return ret; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci if (enable) 55762306a36Sopenharmony_ci return regmap_clear_bits(rdev->regmap, reg, bit); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci return regmap_set_bits(rdev->regmap, reg, bit); 56062306a36Sopenharmony_ci} 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci/* 56362306a36Sopenharmony_ci * OPS common for BD71847 and BD71850 56462306a36Sopenharmony_ci */ 56562306a36Sopenharmony_ciBD718XX_OPS(bd718xx_pickable_range_ldo_ops, 56662306a36Sopenharmony_ci regulator_list_voltage_pickable_linear_range, NULL, 56762306a36Sopenharmony_ci bd718xx_set_voltage_sel_pickable_restricted, 56862306a36Sopenharmony_ci regulator_get_voltage_sel_pickable_regmap, NULL, NULL, 56962306a36Sopenharmony_ci bd718x7_set_ldo_uvp, NULL); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci/* BD71847 and BD71850 LDO 5 is by default OFF at RUN state */ 57262306a36Sopenharmony_cistatic const struct regulator_ops bd718xx_ldo5_ops_hwstate = { 57362306a36Sopenharmony_ci .is_enabled = never_enabled_by_hwstate, 57462306a36Sopenharmony_ci .list_voltage = regulator_list_voltage_pickable_linear_range, 57562306a36Sopenharmony_ci .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted, 57662306a36Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, 57762306a36Sopenharmony_ci .set_under_voltage_protection = bd718x7_set_ldo_uvp, 57862306a36Sopenharmony_ci}; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ciBD718XX_OPS(bd718xx_pickable_range_buck_ops, 58162306a36Sopenharmony_ci regulator_list_voltage_pickable_linear_range, NULL, 58262306a36Sopenharmony_ci regulator_set_voltage_sel_pickable_regmap, 58362306a36Sopenharmony_ci regulator_get_voltage_sel_pickable_regmap, 58462306a36Sopenharmony_ci regulator_set_voltage_time_sel, NULL, bd718x7_set_buck_uvp, 58562306a36Sopenharmony_ci bd718x7_set_buck_ovp); 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ciBD718XX_OPS(bd718xx_ldo_regulator_ops, regulator_list_voltage_linear_range, 58862306a36Sopenharmony_ci NULL, bd718xx_set_voltage_sel_restricted, 58962306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 59062306a36Sopenharmony_ci NULL); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ciBD718XX_OPS(bd718xx_ldo_regulator_nolinear_ops, regulator_list_voltage_table, 59362306a36Sopenharmony_ci NULL, bd718xx_set_voltage_sel_restricted, 59462306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 59562306a36Sopenharmony_ci NULL); 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ciBD718XX_OPS(bd718xx_buck_regulator_ops, regulator_list_voltage_linear_range, 59862306a36Sopenharmony_ci NULL, regulator_set_voltage_sel_regmap, 59962306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 60062306a36Sopenharmony_ci NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ciBD718XX_OPS(bd718xx_buck_regulator_nolinear_ops, regulator_list_voltage_table, 60362306a36Sopenharmony_ci regulator_map_voltage_ascend, regulator_set_voltage_sel_regmap, 60462306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 60562306a36Sopenharmony_ci NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci/* 60862306a36Sopenharmony_ci * OPS for BD71837 60962306a36Sopenharmony_ci */ 61062306a36Sopenharmony_ciBD718XX_OPS(bd71837_pickable_range_ldo_ops, 61162306a36Sopenharmony_ci regulator_list_voltage_pickable_linear_range, NULL, 61262306a36Sopenharmony_ci bd71837_set_voltage_sel_pickable_restricted, 61362306a36Sopenharmony_ci regulator_get_voltage_sel_pickable_regmap, NULL, NULL, 61462306a36Sopenharmony_ci bd718x7_set_ldo_uvp, NULL); 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ciBD718XX_OPS(bd71837_pickable_range_buck_ops, 61762306a36Sopenharmony_ci regulator_list_voltage_pickable_linear_range, NULL, 61862306a36Sopenharmony_ci bd71837_set_voltage_sel_pickable_restricted, 61962306a36Sopenharmony_ci regulator_get_voltage_sel_pickable_regmap, 62062306a36Sopenharmony_ci regulator_set_voltage_time_sel, NULL, bd718x7_set_buck_uvp, 62162306a36Sopenharmony_ci bd718x7_set_buck_ovp); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ciBD718XX_OPS(bd71837_ldo_regulator_ops, regulator_list_voltage_linear_range, 62462306a36Sopenharmony_ci NULL, rohm_regulator_set_voltage_sel_restricted, 62562306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 62662306a36Sopenharmony_ci NULL); 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ciBD718XX_OPS(bd71837_ldo_regulator_nolinear_ops, regulator_list_voltage_table, 62962306a36Sopenharmony_ci NULL, rohm_regulator_set_voltage_sel_restricted, 63062306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 63162306a36Sopenharmony_ci NULL); 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ciBD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range, 63462306a36Sopenharmony_ci NULL, rohm_regulator_set_voltage_sel_restricted, 63562306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 63662306a36Sopenharmony_ci NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ciBD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table, 63962306a36Sopenharmony_ci regulator_map_voltage_ascend, rohm_regulator_set_voltage_sel_restricted, 64062306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 64162306a36Sopenharmony_ci NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 64262306a36Sopenharmony_ci/* 64362306a36Sopenharmony_ci * BD71837 bucks 3 and 4 support defining their enable/disable state also 64462306a36Sopenharmony_ci * when buck enable state is under HW state machine control. In that case the 64562306a36Sopenharmony_ci * bit [2] in CTRL register is used to indicate if regulator should be ON. 64662306a36Sopenharmony_ci */ 64762306a36Sopenharmony_cistatic const struct regulator_ops bd71837_buck34_ops_hwctrl = { 64862306a36Sopenharmony_ci .is_enabled = bd71837_get_buck34_enable_hwctrl, 64962306a36Sopenharmony_ci .list_voltage = regulator_list_voltage_linear_range, 65062306a36Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 65162306a36Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 65262306a36Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 65362306a36Sopenharmony_ci .set_ramp_delay = regulator_set_ramp_delay_regmap, 65462306a36Sopenharmony_ci .set_under_voltage_protection = bd718x7_set_buck_uvp, 65562306a36Sopenharmony_ci .set_over_voltage_protection = bd718x7_set_buck_ovp, 65662306a36Sopenharmony_ci}; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci/* 65962306a36Sopenharmony_ci * OPS for all of the ICs - BD718(37/47/50) 66062306a36Sopenharmony_ci */ 66162306a36Sopenharmony_ciBD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range, 66262306a36Sopenharmony_ci NULL, regulator_set_voltage_sel_regmap, 66362306a36Sopenharmony_ci regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 66462306a36Sopenharmony_ci regulator_set_ramp_delay_regmap, bd718x7_set_buck_uvp, 66562306a36Sopenharmony_ci bd718x7_set_buck_ovp); 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci/* 67062306a36Sopenharmony_ci * There is a HW quirk in BD71837. The shutdown sequence timings for 67162306a36Sopenharmony_ci * bucks/LDOs which are controlled via register interface are changed. 67262306a36Sopenharmony_ci * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the 67362306a36Sopenharmony_ci * beginning of shut-down sequence. As bucks 6 and 7 are parent 67462306a36Sopenharmony_ci * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage 67562306a36Sopenharmony_ci * monitoring to errorneously detect under voltage and force PMIC to 67662306a36Sopenharmony_ci * emergency state instead of poweroff. In order to avoid this we 67762306a36Sopenharmony_ci * disable voltage monitoring for LDO5 and LDO6 67862306a36Sopenharmony_ci */ 67962306a36Sopenharmony_cistatic const struct reg_init bd71837_ldo5_inits[] = { 68062306a36Sopenharmony_ci { 68162306a36Sopenharmony_ci .reg = BD718XX_REG_MVRFLTMASK2, 68262306a36Sopenharmony_ci .mask = BD718XX_LDO5_VRMON80, 68362306a36Sopenharmony_ci .val = BD718XX_LDO5_VRMON80, 68462306a36Sopenharmony_ci }, 68562306a36Sopenharmony_ci}; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_cistatic const struct reg_init bd71837_ldo6_inits[] = { 68862306a36Sopenharmony_ci { 68962306a36Sopenharmony_ci .reg = BD718XX_REG_MVRFLTMASK2, 69062306a36Sopenharmony_ci .mask = BD718XX_LDO6_VRMON80, 69162306a36Sopenharmony_ci .val = BD718XX_LDO6_VRMON80, 69262306a36Sopenharmony_ci }, 69362306a36Sopenharmony_ci}; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_cistatic int buck_set_hw_dvs_levels(struct device_node *np, 69662306a36Sopenharmony_ci const struct regulator_desc *desc, 69762306a36Sopenharmony_ci struct regulator_config *cfg) 69862306a36Sopenharmony_ci{ 69962306a36Sopenharmony_ci struct bd718xx_regulator_data *data; 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci data = container_of(desc, struct bd718xx_regulator_data, desc); 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap); 70462306a36Sopenharmony_ci} 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_cistatic const struct regulator_ops *bd71847_swcontrol_ops[] = { 70762306a36Sopenharmony_ci &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 70862306a36Sopenharmony_ci &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops, 70962306a36Sopenharmony_ci &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops, 71062306a36Sopenharmony_ci &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_nolinear_ops, 71162306a36Sopenharmony_ci &bd718xx_ldo_regulator_ops, &bd718xx_ldo_regulator_ops, 71262306a36Sopenharmony_ci &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops, 71362306a36Sopenharmony_ci}; 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_cistatic const struct regulator_ops *bd71847_hwcontrol_ops[] = { 71662306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 71762306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 71862306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), 71962306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), 72062306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_buck_regulator_nolinear_ops), 72162306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_buck_regulator_ops), 72262306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_pickable_range_ldo_ops), 72362306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_ldo_regulator_nolinear_ops), 72462306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 72562306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 72662306a36Sopenharmony_ci &bd718xx_ldo5_ops_hwstate, 72762306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 72862306a36Sopenharmony_ci}; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_cistatic struct bd718xx_regulator_data bd71847_regulators[] = { 73162306a36Sopenharmony_ci { 73262306a36Sopenharmony_ci .desc = { 73362306a36Sopenharmony_ci .name = "buck1", 73462306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK1"), 73562306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 73662306a36Sopenharmony_ci .id = BD718XX_BUCK1, 73762306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 73862306a36Sopenharmony_ci .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 73962306a36Sopenharmony_ci .linear_ranges = bd718xx_dvs_buck_volts, 74062306a36Sopenharmony_ci .n_linear_ranges = 74162306a36Sopenharmony_ci ARRAY_SIZE(bd718xx_dvs_buck_volts), 74262306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN, 74362306a36Sopenharmony_ci .vsel_mask = DVS_BUCK_RUN_MASK, 74462306a36Sopenharmony_ci .enable_reg = BD718XX_REG_BUCK1_CTRL, 74562306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 74662306a36Sopenharmony_ci .enable_time = BD71847_BUCK1_STARTUP_TIME, 74762306a36Sopenharmony_ci .owner = THIS_MODULE, 74862306a36Sopenharmony_ci .ramp_delay_table = bd718xx_ramp_delay, 74962306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 75062306a36Sopenharmony_ci .ramp_reg = BD718XX_REG_BUCK1_CTRL, 75162306a36Sopenharmony_ci .ramp_mask = BUCK_RAMPRATE_MASK, 75262306a36Sopenharmony_ci .of_parse_cb = buck_set_hw_dvs_levels, 75362306a36Sopenharmony_ci }, 75462306a36Sopenharmony_ci .dvs = { 75562306a36Sopenharmony_ci .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 75662306a36Sopenharmony_ci ROHM_DVS_LEVEL_SUSPEND, 75762306a36Sopenharmony_ci .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 75862306a36Sopenharmony_ci .run_mask = DVS_BUCK_RUN_MASK, 75962306a36Sopenharmony_ci .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 76062306a36Sopenharmony_ci .idle_mask = DVS_BUCK_RUN_MASK, 76162306a36Sopenharmony_ci .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 76262306a36Sopenharmony_ci .suspend_mask = DVS_BUCK_RUN_MASK, 76362306a36Sopenharmony_ci }, 76462306a36Sopenharmony_ci .init = { 76562306a36Sopenharmony_ci .reg = BD718XX_REG_BUCK1_CTRL, 76662306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 76762306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 76862306a36Sopenharmony_ci }, 76962306a36Sopenharmony_ci }, 77062306a36Sopenharmony_ci { 77162306a36Sopenharmony_ci .desc = { 77262306a36Sopenharmony_ci .name = "buck2", 77362306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK2"), 77462306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 77562306a36Sopenharmony_ci .id = BD718XX_BUCK2, 77662306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 77762306a36Sopenharmony_ci .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 77862306a36Sopenharmony_ci .linear_ranges = bd718xx_dvs_buck_volts, 77962306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 78062306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN, 78162306a36Sopenharmony_ci .vsel_mask = DVS_BUCK_RUN_MASK, 78262306a36Sopenharmony_ci .enable_reg = BD718XX_REG_BUCK2_CTRL, 78362306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 78462306a36Sopenharmony_ci .enable_time = BD71847_BUCK2_STARTUP_TIME, 78562306a36Sopenharmony_ci .ramp_delay_table = bd718xx_ramp_delay, 78662306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 78762306a36Sopenharmony_ci .ramp_reg = BD718XX_REG_BUCK2_CTRL, 78862306a36Sopenharmony_ci .ramp_mask = BUCK_RAMPRATE_MASK, 78962306a36Sopenharmony_ci .owner = THIS_MODULE, 79062306a36Sopenharmony_ci .of_parse_cb = buck_set_hw_dvs_levels, 79162306a36Sopenharmony_ci }, 79262306a36Sopenharmony_ci .dvs = { 79362306a36Sopenharmony_ci .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 79462306a36Sopenharmony_ci .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 79562306a36Sopenharmony_ci .run_mask = DVS_BUCK_RUN_MASK, 79662306a36Sopenharmony_ci .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 79762306a36Sopenharmony_ci .idle_mask = DVS_BUCK_RUN_MASK, 79862306a36Sopenharmony_ci }, 79962306a36Sopenharmony_ci .init = { 80062306a36Sopenharmony_ci .reg = BD718XX_REG_BUCK2_CTRL, 80162306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 80262306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 80362306a36Sopenharmony_ci }, 80462306a36Sopenharmony_ci }, 80562306a36Sopenharmony_ci { 80662306a36Sopenharmony_ci .desc = { 80762306a36Sopenharmony_ci .name = "buck3", 80862306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK3"), 80962306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 81062306a36Sopenharmony_ci .id = BD718XX_BUCK3, 81162306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 81262306a36Sopenharmony_ci .n_voltages = BD71847_BUCK3_VOLTAGE_NUM, 81362306a36Sopenharmony_ci .linear_ranges = bd71847_buck3_volts, 81462306a36Sopenharmony_ci .n_linear_ranges = 81562306a36Sopenharmony_ci ARRAY_SIZE(bd71847_buck3_volts), 81662306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 81762306a36Sopenharmony_ci .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK, 81862306a36Sopenharmony_ci .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 81962306a36Sopenharmony_ci .vsel_range_mask = BD71847_BUCK3_RANGE_MASK, 82062306a36Sopenharmony_ci .linear_range_selectors_bitfield = bd71847_buck3_volt_range_sel, 82162306a36Sopenharmony_ci .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 82262306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 82362306a36Sopenharmony_ci .enable_time = BD71847_BUCK3_STARTUP_TIME, 82462306a36Sopenharmony_ci .owner = THIS_MODULE, 82562306a36Sopenharmony_ci }, 82662306a36Sopenharmony_ci .init = { 82762306a36Sopenharmony_ci .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 82862306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 82962306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 83062306a36Sopenharmony_ci }, 83162306a36Sopenharmony_ci }, 83262306a36Sopenharmony_ci { 83362306a36Sopenharmony_ci .desc = { 83462306a36Sopenharmony_ci .name = "buck4", 83562306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK4"), 83662306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 83762306a36Sopenharmony_ci .id = BD718XX_BUCK4, 83862306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 83962306a36Sopenharmony_ci .n_voltages = BD71847_BUCK4_VOLTAGE_NUM, 84062306a36Sopenharmony_ci .linear_ranges = bd71847_buck4_volts, 84162306a36Sopenharmony_ci .n_linear_ranges = 84262306a36Sopenharmony_ci ARRAY_SIZE(bd71847_buck4_volts), 84362306a36Sopenharmony_ci .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 84462306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 84562306a36Sopenharmony_ci .vsel_mask = BD71847_BUCK4_MASK, 84662306a36Sopenharmony_ci .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 84762306a36Sopenharmony_ci .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, 84862306a36Sopenharmony_ci .linear_range_selectors_bitfield = bd71847_buck4_volt_range_sel, 84962306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 85062306a36Sopenharmony_ci .enable_time = BD71847_BUCK4_STARTUP_TIME, 85162306a36Sopenharmony_ci .owner = THIS_MODULE, 85262306a36Sopenharmony_ci }, 85362306a36Sopenharmony_ci .init = { 85462306a36Sopenharmony_ci .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 85562306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 85662306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 85762306a36Sopenharmony_ci }, 85862306a36Sopenharmony_ci }, 85962306a36Sopenharmony_ci { 86062306a36Sopenharmony_ci .desc = { 86162306a36Sopenharmony_ci .name = "buck5", 86262306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK5"), 86362306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 86462306a36Sopenharmony_ci .id = BD718XX_BUCK5, 86562306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 86662306a36Sopenharmony_ci .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], 86762306a36Sopenharmony_ci .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), 86862306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT, 86962306a36Sopenharmony_ci .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, 87062306a36Sopenharmony_ci .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 87162306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 87262306a36Sopenharmony_ci .enable_time = BD71847_BUCK5_STARTUP_TIME, 87362306a36Sopenharmony_ci .owner = THIS_MODULE, 87462306a36Sopenharmony_ci }, 87562306a36Sopenharmony_ci .init = { 87662306a36Sopenharmony_ci .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 87762306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 87862306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 87962306a36Sopenharmony_ci }, 88062306a36Sopenharmony_ci }, 88162306a36Sopenharmony_ci { 88262306a36Sopenharmony_ci .desc = { 88362306a36Sopenharmony_ci .name = "buck6", 88462306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK6"), 88562306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 88662306a36Sopenharmony_ci .id = BD718XX_BUCK6, 88762306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 88862306a36Sopenharmony_ci .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, 88962306a36Sopenharmony_ci .linear_ranges = bd718xx_4th_nodvs_buck_volts, 89062306a36Sopenharmony_ci .n_linear_ranges = 89162306a36Sopenharmony_ci ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts), 89262306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT, 89362306a36Sopenharmony_ci .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, 89462306a36Sopenharmony_ci .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 89562306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 89662306a36Sopenharmony_ci .enable_time = BD71847_BUCK6_STARTUP_TIME, 89762306a36Sopenharmony_ci .owner = THIS_MODULE, 89862306a36Sopenharmony_ci }, 89962306a36Sopenharmony_ci .init = { 90062306a36Sopenharmony_ci .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 90162306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 90262306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 90362306a36Sopenharmony_ci }, 90462306a36Sopenharmony_ci }, 90562306a36Sopenharmony_ci { 90662306a36Sopenharmony_ci .desc = { 90762306a36Sopenharmony_ci .name = "ldo1", 90862306a36Sopenharmony_ci .of_match = of_match_ptr("LDO1"), 90962306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 91062306a36Sopenharmony_ci .id = BD718XX_LDO1, 91162306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 91262306a36Sopenharmony_ci .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, 91362306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo1_volts, 91462306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts), 91562306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO1_VOLT, 91662306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO1_MASK, 91762306a36Sopenharmony_ci .vsel_range_reg = BD718XX_REG_LDO1_VOLT, 91862306a36Sopenharmony_ci .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, 91962306a36Sopenharmony_ci .linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel, 92062306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO1_VOLT, 92162306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 92262306a36Sopenharmony_ci .enable_time = BD71847_LDO1_STARTUP_TIME, 92362306a36Sopenharmony_ci .owner = THIS_MODULE, 92462306a36Sopenharmony_ci }, 92562306a36Sopenharmony_ci .init = { 92662306a36Sopenharmony_ci .reg = BD718XX_REG_LDO1_VOLT, 92762306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 92862306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 92962306a36Sopenharmony_ci }, 93062306a36Sopenharmony_ci }, 93162306a36Sopenharmony_ci { 93262306a36Sopenharmony_ci .desc = { 93362306a36Sopenharmony_ci .name = "ldo2", 93462306a36Sopenharmony_ci .of_match = of_match_ptr("LDO2"), 93562306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 93662306a36Sopenharmony_ci .id = BD718XX_LDO2, 93762306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 93862306a36Sopenharmony_ci .volt_table = &ldo_2_volts[0], 93962306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO2_VOLT, 94062306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO2_MASK, 94162306a36Sopenharmony_ci .n_voltages = ARRAY_SIZE(ldo_2_volts), 94262306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO2_VOLT, 94362306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 94462306a36Sopenharmony_ci .enable_time = BD71847_LDO2_STARTUP_TIME, 94562306a36Sopenharmony_ci .owner = THIS_MODULE, 94662306a36Sopenharmony_ci }, 94762306a36Sopenharmony_ci .init = { 94862306a36Sopenharmony_ci .reg = BD718XX_REG_LDO2_VOLT, 94962306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 95062306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 95162306a36Sopenharmony_ci }, 95262306a36Sopenharmony_ci }, 95362306a36Sopenharmony_ci { 95462306a36Sopenharmony_ci .desc = { 95562306a36Sopenharmony_ci .name = "ldo3", 95662306a36Sopenharmony_ci .of_match = of_match_ptr("LDO3"), 95762306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 95862306a36Sopenharmony_ci .id = BD718XX_LDO3, 95962306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 96062306a36Sopenharmony_ci .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, 96162306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo3_volts, 96262306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts), 96362306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO3_VOLT, 96462306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO3_MASK, 96562306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO3_VOLT, 96662306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 96762306a36Sopenharmony_ci .enable_time = BD71847_LDO3_STARTUP_TIME, 96862306a36Sopenharmony_ci .owner = THIS_MODULE, 96962306a36Sopenharmony_ci }, 97062306a36Sopenharmony_ci .init = { 97162306a36Sopenharmony_ci .reg = BD718XX_REG_LDO3_VOLT, 97262306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 97362306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 97462306a36Sopenharmony_ci }, 97562306a36Sopenharmony_ci }, 97662306a36Sopenharmony_ci { 97762306a36Sopenharmony_ci .desc = { 97862306a36Sopenharmony_ci .name = "ldo4", 97962306a36Sopenharmony_ci .of_match = of_match_ptr("LDO4"), 98062306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 98162306a36Sopenharmony_ci .id = BD718XX_LDO4, 98262306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 98362306a36Sopenharmony_ci .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, 98462306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo4_volts, 98562306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts), 98662306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO4_VOLT, 98762306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO4_MASK, 98862306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO4_VOLT, 98962306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 99062306a36Sopenharmony_ci .enable_time = BD71847_LDO4_STARTUP_TIME, 99162306a36Sopenharmony_ci .owner = THIS_MODULE, 99262306a36Sopenharmony_ci }, 99362306a36Sopenharmony_ci .init = { 99462306a36Sopenharmony_ci .reg = BD718XX_REG_LDO4_VOLT, 99562306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 99662306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 99762306a36Sopenharmony_ci }, 99862306a36Sopenharmony_ci }, 99962306a36Sopenharmony_ci { 100062306a36Sopenharmony_ci .desc = { 100162306a36Sopenharmony_ci .name = "ldo5", 100262306a36Sopenharmony_ci .of_match = of_match_ptr("LDO5"), 100362306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 100462306a36Sopenharmony_ci .id = BD718XX_LDO5, 100562306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 100662306a36Sopenharmony_ci .n_voltages = BD71847_LDO5_VOLTAGE_NUM, 100762306a36Sopenharmony_ci .linear_ranges = bd71847_ldo5_volts, 100862306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts), 100962306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO5_VOLT, 101062306a36Sopenharmony_ci .vsel_mask = BD71847_LDO5_MASK, 101162306a36Sopenharmony_ci .vsel_range_reg = BD718XX_REG_LDO5_VOLT, 101262306a36Sopenharmony_ci .vsel_range_mask = BD71847_LDO5_RANGE_MASK, 101362306a36Sopenharmony_ci .linear_range_selectors_bitfield = bd71847_ldo5_volt_range_sel, 101462306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO5_VOLT, 101562306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 101662306a36Sopenharmony_ci .enable_time = BD71847_LDO5_STARTUP_TIME, 101762306a36Sopenharmony_ci .owner = THIS_MODULE, 101862306a36Sopenharmony_ci }, 101962306a36Sopenharmony_ci .init = { 102062306a36Sopenharmony_ci .reg = BD718XX_REG_LDO5_VOLT, 102162306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 102262306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 102362306a36Sopenharmony_ci }, 102462306a36Sopenharmony_ci }, 102562306a36Sopenharmony_ci { 102662306a36Sopenharmony_ci .desc = { 102762306a36Sopenharmony_ci .name = "ldo6", 102862306a36Sopenharmony_ci .of_match = of_match_ptr("LDO6"), 102962306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 103062306a36Sopenharmony_ci .id = BD718XX_LDO6, 103162306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 103262306a36Sopenharmony_ci .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, 103362306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo6_volts, 103462306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts), 103562306a36Sopenharmony_ci /* LDO6 is supplied by buck5 */ 103662306a36Sopenharmony_ci .supply_name = "buck5", 103762306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO6_VOLT, 103862306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO6_MASK, 103962306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO6_VOLT, 104062306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 104162306a36Sopenharmony_ci .enable_time = BD71847_LDO6_STARTUP_TIME, 104262306a36Sopenharmony_ci .owner = THIS_MODULE, 104362306a36Sopenharmony_ci }, 104462306a36Sopenharmony_ci .init = { 104562306a36Sopenharmony_ci .reg = BD718XX_REG_LDO6_VOLT, 104662306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 104762306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 104862306a36Sopenharmony_ci }, 104962306a36Sopenharmony_ci }, 105062306a36Sopenharmony_ci}; 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_cistatic const struct regulator_ops *bd71837_swcontrol_ops[] = { 105362306a36Sopenharmony_ci &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 105462306a36Sopenharmony_ci &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 105562306a36Sopenharmony_ci &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops, 105662306a36Sopenharmony_ci &bd71837_buck_regulator_nolinear_ops, &bd71837_buck_regulator_ops, 105762306a36Sopenharmony_ci &bd71837_pickable_range_ldo_ops, &bd71837_ldo_regulator_nolinear_ops, 105862306a36Sopenharmony_ci &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, 105962306a36Sopenharmony_ci &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, 106062306a36Sopenharmony_ci &bd71837_ldo_regulator_ops, 106162306a36Sopenharmony_ci}; 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_cistatic const struct regulator_ops *bd71837_hwcontrol_ops[] = { 106462306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 106562306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 106662306a36Sopenharmony_ci &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl, 106762306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_pickable_range_buck_ops), 106862306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), 106962306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_buck_regulator_nolinear_ops), 107062306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), 107162306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_pickable_range_ldo_ops), 107262306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_ldo_regulator_nolinear_ops), 107362306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 107462306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 107562306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 107662306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 107762306a36Sopenharmony_ci &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 107862306a36Sopenharmony_ci}; 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_cistatic struct bd718xx_regulator_data bd71837_regulators[] = { 108162306a36Sopenharmony_ci { 108262306a36Sopenharmony_ci .desc = { 108362306a36Sopenharmony_ci .name = "buck1", 108462306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK1"), 108562306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 108662306a36Sopenharmony_ci .id = BD718XX_BUCK1, 108762306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 108862306a36Sopenharmony_ci .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 108962306a36Sopenharmony_ci .linear_ranges = bd718xx_dvs_buck_volts, 109062306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 109162306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN, 109262306a36Sopenharmony_ci .vsel_mask = DVS_BUCK_RUN_MASK, 109362306a36Sopenharmony_ci .enable_reg = BD718XX_REG_BUCK1_CTRL, 109462306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 109562306a36Sopenharmony_ci .enable_time = BD71837_BUCK1_STARTUP_TIME, 109662306a36Sopenharmony_ci .ramp_delay_table = bd718xx_ramp_delay, 109762306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 109862306a36Sopenharmony_ci .ramp_reg = BD718XX_REG_BUCK1_CTRL, 109962306a36Sopenharmony_ci .ramp_mask = BUCK_RAMPRATE_MASK, 110062306a36Sopenharmony_ci .owner = THIS_MODULE, 110162306a36Sopenharmony_ci .of_parse_cb = buck_set_hw_dvs_levels, 110262306a36Sopenharmony_ci }, 110362306a36Sopenharmony_ci .dvs = { 110462306a36Sopenharmony_ci .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 110562306a36Sopenharmony_ci ROHM_DVS_LEVEL_SUSPEND, 110662306a36Sopenharmony_ci .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 110762306a36Sopenharmony_ci .run_mask = DVS_BUCK_RUN_MASK, 110862306a36Sopenharmony_ci .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 110962306a36Sopenharmony_ci .idle_mask = DVS_BUCK_RUN_MASK, 111062306a36Sopenharmony_ci .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 111162306a36Sopenharmony_ci .suspend_mask = DVS_BUCK_RUN_MASK, 111262306a36Sopenharmony_ci }, 111362306a36Sopenharmony_ci .init = { 111462306a36Sopenharmony_ci .reg = BD718XX_REG_BUCK1_CTRL, 111562306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 111662306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 111762306a36Sopenharmony_ci }, 111862306a36Sopenharmony_ci }, 111962306a36Sopenharmony_ci { 112062306a36Sopenharmony_ci .desc = { 112162306a36Sopenharmony_ci .name = "buck2", 112262306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK2"), 112362306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 112462306a36Sopenharmony_ci .id = BD718XX_BUCK2, 112562306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 112662306a36Sopenharmony_ci .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 112762306a36Sopenharmony_ci .linear_ranges = bd718xx_dvs_buck_volts, 112862306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 112962306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN, 113062306a36Sopenharmony_ci .vsel_mask = DVS_BUCK_RUN_MASK, 113162306a36Sopenharmony_ci .enable_reg = BD718XX_REG_BUCK2_CTRL, 113262306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 113362306a36Sopenharmony_ci .enable_time = BD71837_BUCK2_STARTUP_TIME, 113462306a36Sopenharmony_ci .ramp_delay_table = bd718xx_ramp_delay, 113562306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 113662306a36Sopenharmony_ci .ramp_reg = BD718XX_REG_BUCK2_CTRL, 113762306a36Sopenharmony_ci .ramp_mask = BUCK_RAMPRATE_MASK, 113862306a36Sopenharmony_ci .owner = THIS_MODULE, 113962306a36Sopenharmony_ci .of_parse_cb = buck_set_hw_dvs_levels, 114062306a36Sopenharmony_ci }, 114162306a36Sopenharmony_ci .dvs = { 114262306a36Sopenharmony_ci .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 114362306a36Sopenharmony_ci .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 114462306a36Sopenharmony_ci .run_mask = DVS_BUCK_RUN_MASK, 114562306a36Sopenharmony_ci .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 114662306a36Sopenharmony_ci .idle_mask = DVS_BUCK_RUN_MASK, 114762306a36Sopenharmony_ci }, 114862306a36Sopenharmony_ci .init = { 114962306a36Sopenharmony_ci .reg = BD718XX_REG_BUCK2_CTRL, 115062306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 115162306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 115262306a36Sopenharmony_ci }, 115362306a36Sopenharmony_ci }, 115462306a36Sopenharmony_ci { 115562306a36Sopenharmony_ci .desc = { 115662306a36Sopenharmony_ci .name = "buck3", 115762306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK3"), 115862306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 115962306a36Sopenharmony_ci .id = BD718XX_BUCK3, 116062306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 116162306a36Sopenharmony_ci .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 116262306a36Sopenharmony_ci .linear_ranges = bd718xx_dvs_buck_volts, 116362306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 116462306a36Sopenharmony_ci .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN, 116562306a36Sopenharmony_ci .vsel_mask = DVS_BUCK_RUN_MASK, 116662306a36Sopenharmony_ci .enable_reg = BD71837_REG_BUCK3_CTRL, 116762306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 116862306a36Sopenharmony_ci .enable_time = BD71837_BUCK3_STARTUP_TIME, 116962306a36Sopenharmony_ci .ramp_delay_table = bd718xx_ramp_delay, 117062306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 117162306a36Sopenharmony_ci .ramp_reg = BD71837_REG_BUCK3_CTRL, 117262306a36Sopenharmony_ci .ramp_mask = BUCK_RAMPRATE_MASK, 117362306a36Sopenharmony_ci .owner = THIS_MODULE, 117462306a36Sopenharmony_ci .of_parse_cb = buck_set_hw_dvs_levels, 117562306a36Sopenharmony_ci }, 117662306a36Sopenharmony_ci .dvs = { 117762306a36Sopenharmony_ci .level_map = ROHM_DVS_LEVEL_RUN, 117862306a36Sopenharmony_ci .run_reg = BD71837_REG_BUCK3_VOLT_RUN, 117962306a36Sopenharmony_ci .run_mask = DVS_BUCK_RUN_MASK, 118062306a36Sopenharmony_ci }, 118162306a36Sopenharmony_ci .init = { 118262306a36Sopenharmony_ci .reg = BD71837_REG_BUCK3_CTRL, 118362306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 118462306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 118562306a36Sopenharmony_ci }, 118662306a36Sopenharmony_ci }, 118762306a36Sopenharmony_ci { 118862306a36Sopenharmony_ci .desc = { 118962306a36Sopenharmony_ci .name = "buck4", 119062306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK4"), 119162306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 119262306a36Sopenharmony_ci .id = BD718XX_BUCK4, 119362306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 119462306a36Sopenharmony_ci .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 119562306a36Sopenharmony_ci .linear_ranges = bd718xx_dvs_buck_volts, 119662306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 119762306a36Sopenharmony_ci .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN, 119862306a36Sopenharmony_ci .vsel_mask = DVS_BUCK_RUN_MASK, 119962306a36Sopenharmony_ci .enable_reg = BD71837_REG_BUCK4_CTRL, 120062306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 120162306a36Sopenharmony_ci .enable_time = BD71837_BUCK4_STARTUP_TIME, 120262306a36Sopenharmony_ci .ramp_delay_table = bd718xx_ramp_delay, 120362306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 120462306a36Sopenharmony_ci .ramp_reg = BD71837_REG_BUCK4_CTRL, 120562306a36Sopenharmony_ci .ramp_mask = BUCK_RAMPRATE_MASK, 120662306a36Sopenharmony_ci .owner = THIS_MODULE, 120762306a36Sopenharmony_ci .of_parse_cb = buck_set_hw_dvs_levels, 120862306a36Sopenharmony_ci }, 120962306a36Sopenharmony_ci .dvs = { 121062306a36Sopenharmony_ci .level_map = ROHM_DVS_LEVEL_RUN, 121162306a36Sopenharmony_ci .run_reg = BD71837_REG_BUCK4_VOLT_RUN, 121262306a36Sopenharmony_ci .run_mask = DVS_BUCK_RUN_MASK, 121362306a36Sopenharmony_ci }, 121462306a36Sopenharmony_ci .init = { 121562306a36Sopenharmony_ci .reg = BD71837_REG_BUCK4_CTRL, 121662306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 121762306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 121862306a36Sopenharmony_ci }, 121962306a36Sopenharmony_ci }, 122062306a36Sopenharmony_ci { 122162306a36Sopenharmony_ci .desc = { 122262306a36Sopenharmony_ci .name = "buck5", 122362306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK5"), 122462306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 122562306a36Sopenharmony_ci .id = BD718XX_BUCK5, 122662306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 122762306a36Sopenharmony_ci .n_voltages = BD71837_BUCK5_VOLTAGE_NUM, 122862306a36Sopenharmony_ci .linear_ranges = bd71837_buck5_volts, 122962306a36Sopenharmony_ci .n_linear_ranges = 123062306a36Sopenharmony_ci ARRAY_SIZE(bd71837_buck5_volts), 123162306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 123262306a36Sopenharmony_ci .vsel_mask = BD71837_BUCK5_MASK, 123362306a36Sopenharmony_ci .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 123462306a36Sopenharmony_ci .vsel_range_mask = BD71837_BUCK5_RANGE_MASK, 123562306a36Sopenharmony_ci .linear_range_selectors_bitfield = bd71837_buck5_volt_range_sel, 123662306a36Sopenharmony_ci .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 123762306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 123862306a36Sopenharmony_ci .enable_time = BD71837_BUCK5_STARTUP_TIME, 123962306a36Sopenharmony_ci .owner = THIS_MODULE, 124062306a36Sopenharmony_ci }, 124162306a36Sopenharmony_ci .init = { 124262306a36Sopenharmony_ci .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 124362306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 124462306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 124562306a36Sopenharmony_ci }, 124662306a36Sopenharmony_ci }, 124762306a36Sopenharmony_ci { 124862306a36Sopenharmony_ci .desc = { 124962306a36Sopenharmony_ci .name = "buck6", 125062306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK6"), 125162306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 125262306a36Sopenharmony_ci .id = BD718XX_BUCK6, 125362306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 125462306a36Sopenharmony_ci .n_voltages = BD71837_BUCK6_VOLTAGE_NUM, 125562306a36Sopenharmony_ci .linear_ranges = bd71837_buck6_volts, 125662306a36Sopenharmony_ci .n_linear_ranges = 125762306a36Sopenharmony_ci ARRAY_SIZE(bd71837_buck6_volts), 125862306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 125962306a36Sopenharmony_ci .vsel_mask = BD71837_BUCK6_MASK, 126062306a36Sopenharmony_ci .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 126162306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 126262306a36Sopenharmony_ci .enable_time = BD71837_BUCK6_STARTUP_TIME, 126362306a36Sopenharmony_ci .owner = THIS_MODULE, 126462306a36Sopenharmony_ci }, 126562306a36Sopenharmony_ci .init = { 126662306a36Sopenharmony_ci .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 126762306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 126862306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 126962306a36Sopenharmony_ci }, 127062306a36Sopenharmony_ci }, 127162306a36Sopenharmony_ci { 127262306a36Sopenharmony_ci .desc = { 127362306a36Sopenharmony_ci .name = "buck7", 127462306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK7"), 127562306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 127662306a36Sopenharmony_ci .id = BD718XX_BUCK7, 127762306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 127862306a36Sopenharmony_ci .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], 127962306a36Sopenharmony_ci .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), 128062306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT, 128162306a36Sopenharmony_ci .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, 128262306a36Sopenharmony_ci .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 128362306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 128462306a36Sopenharmony_ci .enable_time = BD71837_BUCK7_STARTUP_TIME, 128562306a36Sopenharmony_ci .owner = THIS_MODULE, 128662306a36Sopenharmony_ci }, 128762306a36Sopenharmony_ci .init = { 128862306a36Sopenharmony_ci .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 128962306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 129062306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 129162306a36Sopenharmony_ci }, 129262306a36Sopenharmony_ci }, 129362306a36Sopenharmony_ci { 129462306a36Sopenharmony_ci .desc = { 129562306a36Sopenharmony_ci .name = "buck8", 129662306a36Sopenharmony_ci .of_match = of_match_ptr("BUCK8"), 129762306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 129862306a36Sopenharmony_ci .id = BD718XX_BUCK8, 129962306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 130062306a36Sopenharmony_ci .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, 130162306a36Sopenharmony_ci .linear_ranges = bd718xx_4th_nodvs_buck_volts, 130262306a36Sopenharmony_ci .n_linear_ranges = 130362306a36Sopenharmony_ci ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts), 130462306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT, 130562306a36Sopenharmony_ci .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, 130662306a36Sopenharmony_ci .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 130762306a36Sopenharmony_ci .enable_mask = BD718XX_BUCK_EN, 130862306a36Sopenharmony_ci .enable_time = BD71837_BUCK8_STARTUP_TIME, 130962306a36Sopenharmony_ci .owner = THIS_MODULE, 131062306a36Sopenharmony_ci }, 131162306a36Sopenharmony_ci .init = { 131262306a36Sopenharmony_ci .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 131362306a36Sopenharmony_ci .mask = BD718XX_BUCK_SEL, 131462306a36Sopenharmony_ci .val = BD718XX_BUCK_SEL, 131562306a36Sopenharmony_ci }, 131662306a36Sopenharmony_ci }, 131762306a36Sopenharmony_ci { 131862306a36Sopenharmony_ci .desc = { 131962306a36Sopenharmony_ci .name = "ldo1", 132062306a36Sopenharmony_ci .of_match = of_match_ptr("LDO1"), 132162306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 132262306a36Sopenharmony_ci .id = BD718XX_LDO1, 132362306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 132462306a36Sopenharmony_ci .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, 132562306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo1_volts, 132662306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts), 132762306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO1_VOLT, 132862306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO1_MASK, 132962306a36Sopenharmony_ci .vsel_range_reg = BD718XX_REG_LDO1_VOLT, 133062306a36Sopenharmony_ci .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, 133162306a36Sopenharmony_ci .linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel, 133262306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO1_VOLT, 133362306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 133462306a36Sopenharmony_ci .enable_time = BD71837_LDO1_STARTUP_TIME, 133562306a36Sopenharmony_ci .owner = THIS_MODULE, 133662306a36Sopenharmony_ci }, 133762306a36Sopenharmony_ci .init = { 133862306a36Sopenharmony_ci .reg = BD718XX_REG_LDO1_VOLT, 133962306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 134062306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 134162306a36Sopenharmony_ci }, 134262306a36Sopenharmony_ci }, 134362306a36Sopenharmony_ci { 134462306a36Sopenharmony_ci .desc = { 134562306a36Sopenharmony_ci .name = "ldo2", 134662306a36Sopenharmony_ci .of_match = of_match_ptr("LDO2"), 134762306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 134862306a36Sopenharmony_ci .id = BD718XX_LDO2, 134962306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 135062306a36Sopenharmony_ci .volt_table = &ldo_2_volts[0], 135162306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO2_VOLT, 135262306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO2_MASK, 135362306a36Sopenharmony_ci .n_voltages = ARRAY_SIZE(ldo_2_volts), 135462306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO2_VOLT, 135562306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 135662306a36Sopenharmony_ci .enable_time = BD71837_LDO2_STARTUP_TIME, 135762306a36Sopenharmony_ci .owner = THIS_MODULE, 135862306a36Sopenharmony_ci }, 135962306a36Sopenharmony_ci .init = { 136062306a36Sopenharmony_ci .reg = BD718XX_REG_LDO2_VOLT, 136162306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 136262306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 136362306a36Sopenharmony_ci }, 136462306a36Sopenharmony_ci }, 136562306a36Sopenharmony_ci { 136662306a36Sopenharmony_ci .desc = { 136762306a36Sopenharmony_ci .name = "ldo3", 136862306a36Sopenharmony_ci .of_match = of_match_ptr("LDO3"), 136962306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 137062306a36Sopenharmony_ci .id = BD718XX_LDO3, 137162306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 137262306a36Sopenharmony_ci .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, 137362306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo3_volts, 137462306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts), 137562306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO3_VOLT, 137662306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO3_MASK, 137762306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO3_VOLT, 137862306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 137962306a36Sopenharmony_ci .enable_time = BD71837_LDO3_STARTUP_TIME, 138062306a36Sopenharmony_ci .owner = THIS_MODULE, 138162306a36Sopenharmony_ci }, 138262306a36Sopenharmony_ci .init = { 138362306a36Sopenharmony_ci .reg = BD718XX_REG_LDO3_VOLT, 138462306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 138562306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 138662306a36Sopenharmony_ci }, 138762306a36Sopenharmony_ci }, 138862306a36Sopenharmony_ci { 138962306a36Sopenharmony_ci .desc = { 139062306a36Sopenharmony_ci .name = "ldo4", 139162306a36Sopenharmony_ci .of_match = of_match_ptr("LDO4"), 139262306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 139362306a36Sopenharmony_ci .id = BD718XX_LDO4, 139462306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 139562306a36Sopenharmony_ci .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, 139662306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo4_volts, 139762306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts), 139862306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO4_VOLT, 139962306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO4_MASK, 140062306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO4_VOLT, 140162306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 140262306a36Sopenharmony_ci .enable_time = BD71837_LDO4_STARTUP_TIME, 140362306a36Sopenharmony_ci .owner = THIS_MODULE, 140462306a36Sopenharmony_ci }, 140562306a36Sopenharmony_ci .init = { 140662306a36Sopenharmony_ci .reg = BD718XX_REG_LDO4_VOLT, 140762306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 140862306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 140962306a36Sopenharmony_ci }, 141062306a36Sopenharmony_ci }, 141162306a36Sopenharmony_ci { 141262306a36Sopenharmony_ci .desc = { 141362306a36Sopenharmony_ci .name = "ldo5", 141462306a36Sopenharmony_ci .of_match = of_match_ptr("LDO5"), 141562306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 141662306a36Sopenharmony_ci .id = BD718XX_LDO5, 141762306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 141862306a36Sopenharmony_ci .n_voltages = BD71837_LDO5_VOLTAGE_NUM, 141962306a36Sopenharmony_ci .linear_ranges = bd71837_ldo5_volts, 142062306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts), 142162306a36Sopenharmony_ci /* LDO5 is supplied by buck6 */ 142262306a36Sopenharmony_ci .supply_name = "buck6", 142362306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO5_VOLT, 142462306a36Sopenharmony_ci .vsel_mask = BD71837_LDO5_MASK, 142562306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO5_VOLT, 142662306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 142762306a36Sopenharmony_ci .enable_time = BD71837_LDO5_STARTUP_TIME, 142862306a36Sopenharmony_ci .owner = THIS_MODULE, 142962306a36Sopenharmony_ci }, 143062306a36Sopenharmony_ci .init = { 143162306a36Sopenharmony_ci .reg = BD718XX_REG_LDO5_VOLT, 143262306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 143362306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 143462306a36Sopenharmony_ci }, 143562306a36Sopenharmony_ci .additional_inits = bd71837_ldo5_inits, 143662306a36Sopenharmony_ci .additional_init_amnt = ARRAY_SIZE(bd71837_ldo5_inits), 143762306a36Sopenharmony_ci }, 143862306a36Sopenharmony_ci { 143962306a36Sopenharmony_ci .desc = { 144062306a36Sopenharmony_ci .name = "ldo6", 144162306a36Sopenharmony_ci .of_match = of_match_ptr("LDO6"), 144262306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 144362306a36Sopenharmony_ci .id = BD718XX_LDO6, 144462306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 144562306a36Sopenharmony_ci .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, 144662306a36Sopenharmony_ci .linear_ranges = bd718xx_ldo6_volts, 144762306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts), 144862306a36Sopenharmony_ci /* LDO6 is supplied by buck7 */ 144962306a36Sopenharmony_ci .supply_name = "buck7", 145062306a36Sopenharmony_ci .vsel_reg = BD718XX_REG_LDO6_VOLT, 145162306a36Sopenharmony_ci .vsel_mask = BD718XX_LDO6_MASK, 145262306a36Sopenharmony_ci .enable_reg = BD718XX_REG_LDO6_VOLT, 145362306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 145462306a36Sopenharmony_ci .enable_time = BD71837_LDO6_STARTUP_TIME, 145562306a36Sopenharmony_ci .owner = THIS_MODULE, 145662306a36Sopenharmony_ci }, 145762306a36Sopenharmony_ci .init = { 145862306a36Sopenharmony_ci .reg = BD718XX_REG_LDO6_VOLT, 145962306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 146062306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 146162306a36Sopenharmony_ci }, 146262306a36Sopenharmony_ci .additional_inits = bd71837_ldo6_inits, 146362306a36Sopenharmony_ci .additional_init_amnt = ARRAY_SIZE(bd71837_ldo6_inits), 146462306a36Sopenharmony_ci }, 146562306a36Sopenharmony_ci { 146662306a36Sopenharmony_ci .desc = { 146762306a36Sopenharmony_ci .name = "ldo7", 146862306a36Sopenharmony_ci .of_match = of_match_ptr("LDO7"), 146962306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 147062306a36Sopenharmony_ci .id = BD718XX_LDO7, 147162306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 147262306a36Sopenharmony_ci .n_voltages = BD71837_LDO7_VOLTAGE_NUM, 147362306a36Sopenharmony_ci .linear_ranges = bd71837_ldo7_volts, 147462306a36Sopenharmony_ci .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts), 147562306a36Sopenharmony_ci .vsel_reg = BD71837_REG_LDO7_VOLT, 147662306a36Sopenharmony_ci .vsel_mask = BD71837_LDO7_MASK, 147762306a36Sopenharmony_ci .enable_reg = BD71837_REG_LDO7_VOLT, 147862306a36Sopenharmony_ci .enable_mask = BD718XX_LDO_EN, 147962306a36Sopenharmony_ci .enable_time = BD71837_LDO7_STARTUP_TIME, 148062306a36Sopenharmony_ci .owner = THIS_MODULE, 148162306a36Sopenharmony_ci }, 148262306a36Sopenharmony_ci .init = { 148362306a36Sopenharmony_ci .reg = BD71837_REG_LDO7_VOLT, 148462306a36Sopenharmony_ci .mask = BD718XX_LDO_SEL, 148562306a36Sopenharmony_ci .val = BD718XX_LDO_SEL, 148662306a36Sopenharmony_ci }, 148762306a36Sopenharmony_ci }, 148862306a36Sopenharmony_ci}; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_cistatic void mark_hw_controlled(struct device *dev, struct device_node *np, 149162306a36Sopenharmony_ci struct bd718xx_regulator_data *reg_data, 149262306a36Sopenharmony_ci unsigned int num_reg_data, int *info) 149362306a36Sopenharmony_ci{ 149462306a36Sopenharmony_ci int i; 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci for (i = 1; i <= num_reg_data; i++) { 149762306a36Sopenharmony_ci if (!of_node_name_eq(np, reg_data[i-1].desc.of_match)) 149862306a36Sopenharmony_ci continue; 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci *info |= 1 << (i - 1); 150162306a36Sopenharmony_ci dev_dbg(dev, "regulator %d runlevel controlled\n", i); 150262306a36Sopenharmony_ci return; 150362306a36Sopenharmony_ci } 150462306a36Sopenharmony_ci dev_warn(dev, "Bad regulator node\n"); 150562306a36Sopenharmony_ci} 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci/* 150862306a36Sopenharmony_ci * Setups where regulator (especially the buck8) output voltage is scaled 150962306a36Sopenharmony_ci * by adding external connection where some other regulator output is connected 151062306a36Sopenharmony_ci * to feedback-pin (over suitable resistors) is getting popular amongst users 151162306a36Sopenharmony_ci * of BD71837. (This allows for example scaling down the buck8 voltages to suit 151262306a36Sopenharmony_ci * lover GPU voltages for projects where buck8 is (ab)used to supply power 151362306a36Sopenharmony_ci * for GPU. Additionally some setups do allow DVS for buck8 but as this do 151462306a36Sopenharmony_ci * produce voltage spikes the HW must be evaluated to be able to survive this 151562306a36Sopenharmony_ci * - hence I keep the DVS disabled for non DVS bucks by default. I don't want 151662306a36Sopenharmony_ci * to help you burn your proto board) 151762306a36Sopenharmony_ci * 151862306a36Sopenharmony_ci * So we allow describing this external connection from DT and scale the 151962306a36Sopenharmony_ci * voltages accordingly. This is what the connection should look like: 152062306a36Sopenharmony_ci * 152162306a36Sopenharmony_ci * |------------| 152262306a36Sopenharmony_ci * | buck 8 |-------+----->Vout 152362306a36Sopenharmony_ci * | | | 152462306a36Sopenharmony_ci * |------------| | 152562306a36Sopenharmony_ci * | FB pin | 152662306a36Sopenharmony_ci * | | 152762306a36Sopenharmony_ci * +-------+--R2---+ 152862306a36Sopenharmony_ci * | 152962306a36Sopenharmony_ci * R1 153062306a36Sopenharmony_ci * | 153162306a36Sopenharmony_ci * V FB-pull-up 153262306a36Sopenharmony_ci * 153362306a36Sopenharmony_ci * Here the buck output is sifted according to formula: 153462306a36Sopenharmony_ci * 153562306a36Sopenharmony_ci * Vout_o = Vo - (Vpu - Vo)*R2/R1 153662306a36Sopenharmony_ci * Linear_step = step_orig*(R1+R2)/R1 153762306a36Sopenharmony_ci * 153862306a36Sopenharmony_ci * where: 153962306a36Sopenharmony_ci * Vout_o is adjusted voltage output at vsel reg value 0 154062306a36Sopenharmony_ci * Vo is original voltage output at vsel reg value 0 154162306a36Sopenharmony_ci * Vpu is the pull-up voltage V FB-pull-up in the picture 154262306a36Sopenharmony_ci * R1 and R2 are resistor values. 154362306a36Sopenharmony_ci * 154462306a36Sopenharmony_ci * As a real world example for buck8 and a specific GPU: 154562306a36Sopenharmony_ci * VLDO = 1.6V (used as FB-pull-up) 154662306a36Sopenharmony_ci * R1 = 1000ohms 154762306a36Sopenharmony_ci * R2 = 150ohms 154862306a36Sopenharmony_ci * VSEL 0x0 => 0.8V – (VLDO – 0.8) * R2 / R1 = 0.68V 154962306a36Sopenharmony_ci * Linear Step = 10mV * (R1 + R2) / R1 = 11.5mV 155062306a36Sopenharmony_ci */ 155162306a36Sopenharmony_cistatic int setup_feedback_loop(struct device *dev, struct device_node *np, 155262306a36Sopenharmony_ci struct bd718xx_regulator_data *reg_data, 155362306a36Sopenharmony_ci unsigned int num_reg_data, int fb_uv) 155462306a36Sopenharmony_ci{ 155562306a36Sopenharmony_ci int i, r1, r2, ret; 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci /* 155862306a36Sopenharmony_ci * We do adjust the values in the global desc based on DT settings. 155962306a36Sopenharmony_ci * This may not be best approach as it can cause problems if more than 156062306a36Sopenharmony_ci * one PMIC is controlled from same processor. I don't see such use-case 156162306a36Sopenharmony_ci * for BD718x7 now - so we spare some bits. 156262306a36Sopenharmony_ci * 156362306a36Sopenharmony_ci * If this will point out to be a problem - then we can allocate new 156462306a36Sopenharmony_ci * bd718xx_regulator_data array at probe and just use the global 156562306a36Sopenharmony_ci * array as a template where we copy initial values. Then we can 156662306a36Sopenharmony_ci * use allocated descs for regultor registration and do IC specific 156762306a36Sopenharmony_ci * modifications to this copy while leaving other PMICs untouched. But 156862306a36Sopenharmony_ci * that means allocating new array for each PMIC - and currently I see 156962306a36Sopenharmony_ci * no need for that. 157062306a36Sopenharmony_ci */ 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_ci for (i = 0; i < num_reg_data; i++) { 157362306a36Sopenharmony_ci struct regulator_desc *desc = ®_data[i].desc; 157462306a36Sopenharmony_ci int j; 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci if (!of_node_name_eq(np, desc->of_match)) 157762306a36Sopenharmony_ci continue; 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci /* The feedback loop connection does not make sense for LDOs */ 158062306a36Sopenharmony_ci if (desc->id >= BD718XX_LDO1) 158162306a36Sopenharmony_ci return -EINVAL; 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci ret = of_property_read_u32(np, "rohm,feedback-pull-up-r1-ohms", 158462306a36Sopenharmony_ci &r1); 158562306a36Sopenharmony_ci if (ret) 158662306a36Sopenharmony_ci return ret; 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_ci if (!r1) 158962306a36Sopenharmony_ci return -EINVAL; 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci ret = of_property_read_u32(np, "rohm,feedback-pull-up-r2-ohms", 159262306a36Sopenharmony_ci &r2); 159362306a36Sopenharmony_ci if (ret) 159462306a36Sopenharmony_ci return ret; 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_ci if (desc->n_linear_ranges && desc->linear_ranges) { 159762306a36Sopenharmony_ci struct linear_range *new; 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_ci new = devm_kzalloc(dev, desc->n_linear_ranges * 160062306a36Sopenharmony_ci sizeof(struct linear_range), 160162306a36Sopenharmony_ci GFP_KERNEL); 160262306a36Sopenharmony_ci if (!new) 160362306a36Sopenharmony_ci return -ENOMEM; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci for (j = 0; j < desc->n_linear_ranges; j++) { 160662306a36Sopenharmony_ci int min = desc->linear_ranges[j].min; 160762306a36Sopenharmony_ci int step = desc->linear_ranges[j].step; 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci min -= (fb_uv - min)*r2/r1; 161062306a36Sopenharmony_ci step = step * (r1 + r2); 161162306a36Sopenharmony_ci step /= r1; 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci new[j].min = min; 161462306a36Sopenharmony_ci new[j].step = step; 161562306a36Sopenharmony_ci 161662306a36Sopenharmony_ci dev_dbg(dev, "%s: old range min %d, step %d\n", 161762306a36Sopenharmony_ci desc->name, desc->linear_ranges[j].min, 161862306a36Sopenharmony_ci desc->linear_ranges[j].step); 161962306a36Sopenharmony_ci dev_dbg(dev, "new range min %d, step %d\n", min, 162062306a36Sopenharmony_ci step); 162162306a36Sopenharmony_ci } 162262306a36Sopenharmony_ci desc->linear_ranges = new; 162362306a36Sopenharmony_ci } 162462306a36Sopenharmony_ci dev_dbg(dev, "regulator '%s' has FB pull-up configured\n", 162562306a36Sopenharmony_ci desc->name); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci return 0; 162862306a36Sopenharmony_ci } 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci return -ENODEV; 163162306a36Sopenharmony_ci} 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_cistatic int get_special_regulators(struct device *dev, 163462306a36Sopenharmony_ci struct bd718xx_regulator_data *reg_data, 163562306a36Sopenharmony_ci unsigned int num_reg_data, int *info) 163662306a36Sopenharmony_ci{ 163762306a36Sopenharmony_ci int ret; 163862306a36Sopenharmony_ci struct device_node *np; 163962306a36Sopenharmony_ci struct device_node *nproot = dev->of_node; 164062306a36Sopenharmony_ci int uv; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci *info = 0; 164362306a36Sopenharmony_ci 164462306a36Sopenharmony_ci nproot = of_get_child_by_name(nproot, "regulators"); 164562306a36Sopenharmony_ci if (!nproot) { 164662306a36Sopenharmony_ci dev_err(dev, "failed to find regulators node\n"); 164762306a36Sopenharmony_ci return -ENODEV; 164862306a36Sopenharmony_ci } 164962306a36Sopenharmony_ci for_each_child_of_node(nproot, np) { 165062306a36Sopenharmony_ci if (of_property_read_bool(np, "rohm,no-regulator-enable-control")) 165162306a36Sopenharmony_ci mark_hw_controlled(dev, np, reg_data, num_reg_data, 165262306a36Sopenharmony_ci info); 165362306a36Sopenharmony_ci ret = of_property_read_u32(np, "rohm,fb-pull-up-microvolt", 165462306a36Sopenharmony_ci &uv); 165562306a36Sopenharmony_ci if (ret) { 165662306a36Sopenharmony_ci if (ret == -EINVAL) 165762306a36Sopenharmony_ci continue; 165862306a36Sopenharmony_ci else 165962306a36Sopenharmony_ci goto err_out; 166062306a36Sopenharmony_ci } 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci ret = setup_feedback_loop(dev, np, reg_data, num_reg_data, uv); 166362306a36Sopenharmony_ci if (ret) 166462306a36Sopenharmony_ci goto err_out; 166562306a36Sopenharmony_ci } 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci of_node_put(nproot); 166862306a36Sopenharmony_ci return 0; 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_cierr_out: 167162306a36Sopenharmony_ci of_node_put(np); 167262306a36Sopenharmony_ci of_node_put(nproot); 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_ci return ret; 167562306a36Sopenharmony_ci} 167662306a36Sopenharmony_ci 167762306a36Sopenharmony_cistatic int bd718xx_probe(struct platform_device *pdev) 167862306a36Sopenharmony_ci{ 167962306a36Sopenharmony_ci struct regmap *regmap; 168062306a36Sopenharmony_ci struct regulator_config config = { 0 }; 168162306a36Sopenharmony_ci int i, j, err, omit_enable; 168262306a36Sopenharmony_ci bool use_snvs; 168362306a36Sopenharmony_ci struct bd718xx_regulator_data *reg_data; 168462306a36Sopenharmony_ci unsigned int num_reg_data; 168562306a36Sopenharmony_ci enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 168662306a36Sopenharmony_ci const struct regulator_ops **swops, **hwops; 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci regmap = dev_get_regmap(pdev->dev.parent, NULL); 168962306a36Sopenharmony_ci if (!regmap) { 169062306a36Sopenharmony_ci dev_err(&pdev->dev, "No MFD driver data\n"); 169162306a36Sopenharmony_ci return -EINVAL; 169262306a36Sopenharmony_ci } 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci switch (chip) { 169562306a36Sopenharmony_ci case ROHM_CHIP_TYPE_BD71837: 169662306a36Sopenharmony_ci reg_data = bd71837_regulators; 169762306a36Sopenharmony_ci num_reg_data = ARRAY_SIZE(bd71837_regulators); 169862306a36Sopenharmony_ci swops = &bd71837_swcontrol_ops[0]; 169962306a36Sopenharmony_ci hwops = &bd71837_hwcontrol_ops[0]; 170062306a36Sopenharmony_ci break; 170162306a36Sopenharmony_ci case ROHM_CHIP_TYPE_BD71847: 170262306a36Sopenharmony_ci reg_data = bd71847_regulators; 170362306a36Sopenharmony_ci num_reg_data = ARRAY_SIZE(bd71847_regulators); 170462306a36Sopenharmony_ci swops = &bd71847_swcontrol_ops[0]; 170562306a36Sopenharmony_ci hwops = &bd71847_hwcontrol_ops[0]; 170662306a36Sopenharmony_ci break; 170762306a36Sopenharmony_ci default: 170862306a36Sopenharmony_ci dev_err(&pdev->dev, "Unsupported chip type\n"); 170962306a36Sopenharmony_ci return -EINVAL; 171062306a36Sopenharmony_ci } 171162306a36Sopenharmony_ci 171262306a36Sopenharmony_ci /* Register LOCK release */ 171362306a36Sopenharmony_ci err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK, 171462306a36Sopenharmony_ci (REGLOCK_PWRSEQ | REGLOCK_VREG), 0); 171562306a36Sopenharmony_ci if (err) 171662306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, err, "Failed to unlock PMIC\n"); 171762306a36Sopenharmony_ci 171862306a36Sopenharmony_ci dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n", 171962306a36Sopenharmony_ci BD718XX_REG_REGLOCK); 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ci use_snvs = of_property_read_bool(pdev->dev.parent->of_node, 172262306a36Sopenharmony_ci "rohm,reset-snvs-powered"); 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci /* 172562306a36Sopenharmony_ci * Change the next stage from poweroff to be READY instead of SNVS 172662306a36Sopenharmony_ci * for all reset types because OTP loading at READY will clear SEL 172762306a36Sopenharmony_ci * bit allowing HW defaults for power rails to be used 172862306a36Sopenharmony_ci */ 172962306a36Sopenharmony_ci if (!use_snvs) { 173062306a36Sopenharmony_ci err = regmap_update_bits(regmap, BD718XX_REG_TRANS_COND1, 173162306a36Sopenharmony_ci BD718XX_ON_REQ_POWEROFF_MASK | 173262306a36Sopenharmony_ci BD718XX_SWRESET_POWEROFF_MASK | 173362306a36Sopenharmony_ci BD718XX_WDOG_POWEROFF_MASK | 173462306a36Sopenharmony_ci BD718XX_KEY_L_POWEROFF_MASK, 173562306a36Sopenharmony_ci BD718XX_POWOFF_TO_RDY); 173662306a36Sopenharmony_ci if (err) 173762306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, err, 173862306a36Sopenharmony_ci "Failed to change reset target\n"); 173962306a36Sopenharmony_ci 174062306a36Sopenharmony_ci dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n"); 174162306a36Sopenharmony_ci } 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_ci config.dev = pdev->dev.parent; 174462306a36Sopenharmony_ci config.regmap = regmap; 174562306a36Sopenharmony_ci /* 174662306a36Sopenharmony_ci * There are cases when we want to leave the enable-control for 174762306a36Sopenharmony_ci * the HW state machine and use this driver only for voltage control. 174862306a36Sopenharmony_ci * One special case is when we use PMIC_STBY_REQ line from SoC to PMIC 174962306a36Sopenharmony_ci * in order to set the system to SUSPEND state. 175062306a36Sopenharmony_ci * 175162306a36Sopenharmony_ci * If regulator is taken under SW control the regulator state will not 175262306a36Sopenharmony_ci * be affected by PMIC state machine - Eg. regulator is likely to stay 175362306a36Sopenharmony_ci * on even in SUSPEND 175462306a36Sopenharmony_ci */ 175562306a36Sopenharmony_ci err = get_special_regulators(pdev->dev.parent, reg_data, num_reg_data, 175662306a36Sopenharmony_ci &omit_enable); 175762306a36Sopenharmony_ci if (err) 175862306a36Sopenharmony_ci return err; 175962306a36Sopenharmony_ci 176062306a36Sopenharmony_ci for (i = 0; i < num_reg_data; i++) { 176162306a36Sopenharmony_ci 176262306a36Sopenharmony_ci struct regulator_desc *desc; 176362306a36Sopenharmony_ci struct regulator_dev *rdev; 176462306a36Sopenharmony_ci struct bd718xx_regulator_data *r; 176562306a36Sopenharmony_ci int no_enable_control = omit_enable & (1 << i); 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci r = ®_data[i]; 176862306a36Sopenharmony_ci desc = &r->desc; 176962306a36Sopenharmony_ci 177062306a36Sopenharmony_ci if (no_enable_control) 177162306a36Sopenharmony_ci desc->ops = hwops[i]; 177262306a36Sopenharmony_ci else 177362306a36Sopenharmony_ci desc->ops = swops[i]; 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci rdev = devm_regulator_register(&pdev->dev, desc, &config); 177662306a36Sopenharmony_ci if (IS_ERR(rdev)) 177762306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, PTR_ERR(rdev), 177862306a36Sopenharmony_ci "failed to register %s regulator\n", 177962306a36Sopenharmony_ci desc->name); 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci /* 178262306a36Sopenharmony_ci * Regulator register gets the regulator constraints and 178362306a36Sopenharmony_ci * applies them (set_machine_constraints). This should have 178462306a36Sopenharmony_ci * turned the control register(s) to correct values and we 178562306a36Sopenharmony_ci * can now switch the control from PMIC state machine to the 178662306a36Sopenharmony_ci * register interface 178762306a36Sopenharmony_ci * 178862306a36Sopenharmony_ci * At poweroff transition PMIC HW disables EN bit for 178962306a36Sopenharmony_ci * regulators but leaves SEL bit untouched. So if state 179062306a36Sopenharmony_ci * transition from POWEROFF is done to SNVS - then all power 179162306a36Sopenharmony_ci * rails controlled by SW (having SEL bit set) stay disabled 179262306a36Sopenharmony_ci * as EN is cleared. This will result boot failure if any 179362306a36Sopenharmony_ci * crucial systems are powered by these rails. We don't 179462306a36Sopenharmony_ci * enable SW control for crucial regulators if snvs state is 179562306a36Sopenharmony_ci * used 179662306a36Sopenharmony_ci */ 179762306a36Sopenharmony_ci if (!no_enable_control && (!use_snvs || 179862306a36Sopenharmony_ci !rdev->constraints->always_on || 179962306a36Sopenharmony_ci !rdev->constraints->boot_on)) { 180062306a36Sopenharmony_ci err = regmap_update_bits(regmap, r->init.reg, 180162306a36Sopenharmony_ci r->init.mask, r->init.val); 180262306a36Sopenharmony_ci if (err) 180362306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, err, 180462306a36Sopenharmony_ci "Failed to take control for (%s)\n", 180562306a36Sopenharmony_ci desc->name); 180662306a36Sopenharmony_ci } 180762306a36Sopenharmony_ci for (j = 0; j < r->additional_init_amnt; j++) { 180862306a36Sopenharmony_ci err = regmap_update_bits(regmap, 180962306a36Sopenharmony_ci r->additional_inits[j].reg, 181062306a36Sopenharmony_ci r->additional_inits[j].mask, 181162306a36Sopenharmony_ci r->additional_inits[j].val); 181262306a36Sopenharmony_ci if (err) 181362306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, err, 181462306a36Sopenharmony_ci "Buck (%s) initialization failed\n", 181562306a36Sopenharmony_ci desc->name); 181662306a36Sopenharmony_ci } 181762306a36Sopenharmony_ci } 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci return err; 182062306a36Sopenharmony_ci} 182162306a36Sopenharmony_ci 182262306a36Sopenharmony_cistatic const struct platform_device_id bd718x7_pmic_id[] = { 182362306a36Sopenharmony_ci { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 }, 182462306a36Sopenharmony_ci { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 }, 182562306a36Sopenharmony_ci { }, 182662306a36Sopenharmony_ci}; 182762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(platform, bd718x7_pmic_id); 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_cistatic struct platform_driver bd718xx_regulator = { 183062306a36Sopenharmony_ci .driver = { 183162306a36Sopenharmony_ci .name = "bd718xx-pmic", 183262306a36Sopenharmony_ci .probe_type = PROBE_PREFER_ASYNCHRONOUS, 183362306a36Sopenharmony_ci }, 183462306a36Sopenharmony_ci .probe = bd718xx_probe, 183562306a36Sopenharmony_ci .id_table = bd718x7_pmic_id, 183662306a36Sopenharmony_ci}; 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_cimodule_platform_driver(bd718xx_regulator); 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ciMODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 184162306a36Sopenharmony_ciMODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver"); 184262306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 184362306a36Sopenharmony_ciMODULE_ALIAS("platform:bd718xx-pmic"); 1844