^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Device driver for regulators in Hi6421 IC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // http://www.hisilicon.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Copyright (c) <2013-2014> Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // https://www.linaro.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) // Author: Guodong Xu <guodong.xu@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/regulator/of_regulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mfd/hi6421-pmic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * @lock: mutex to serialize regulator enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct hi6421_regulator_pdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * struct hi6421_regulator_info - hi6421 regulator information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @desc: regulator description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @eco_microamp: eco mode load upper limit (in uA), valid for LDOs only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct hi6421_regulator_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct regulator_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 mode_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u32 eco_microamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* HI6421 regulators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) enum hi6421_regulator_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) HI6421_LDO0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) HI6421_LDO1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) HI6421_LDO2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) HI6421_LDO3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) HI6421_LDO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) HI6421_LDO5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) HI6421_LDO6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) HI6421_LDO7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) HI6421_LDO8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) HI6421_LDO9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) HI6421_LDO10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) HI6421_LDO11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) HI6421_LDO12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) HI6421_LDO13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) HI6421_LDO14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) HI6421_LDO15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) HI6421_LDO16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) HI6421_LDO17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) HI6421_LDO18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) HI6421_LDO19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) HI6421_LDO20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) HI6421_LDOAUDIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) HI6421_BUCK0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) HI6421_BUCK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) HI6421_BUCK2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) HI6421_BUCK3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) HI6421_BUCK4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) HI6421_BUCK5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) HI6421_NUM_REGULATORS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static const unsigned int ldo_0_voltages[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 1500000, 1800000, 2400000, 2500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 2600000, 2700000, 2850000, 3000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* LDO 8, 15 have same voltage table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static const unsigned int ldo_8_voltages[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 1500000, 1800000, 2400000, 2600000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 2700000, 2850000, 3000000, 3300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Ranges are sorted in ascending order. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static const struct linear_range ldo_audio_volt_range[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static const unsigned int buck_3_voltages[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 950000, 1050000, 1100000, 1117000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 1134000, 1150000, 1167000, 1200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const unsigned int buck_4_voltages[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 1150000, 1200000, 1250000, 1350000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 1700000, 1800000, 1900000, 2000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static const unsigned int buck_5_voltages[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 1150000, 1200000, 1250000, 1350000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 1600000, 1700000, 1800000, 1900000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static const struct regulator_ops hi6421_ldo_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static const struct regulator_ops hi6421_ldo_linear_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static const struct regulator_ops hi6421_ldo_linear_range_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static const struct regulator_ops hi6421_buck012_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static const struct regulator_ops hi6421_buck345_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define HI6421_LDO_ENABLE_TIME (350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * _id - LDO id name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * _match - of match name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * v_table - voltage table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * vreg - voltage select register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * vmask - voltage select mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * ereg - enable register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * emask - enable mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * odelay - off/on delay time in uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * ecomask - eco mode mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * ecoamp - eco mode load uppler limit in uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define HI6421_LDO(_id, _match, v_table, vreg, vmask, ereg, emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) odelay, ecomask, ecoamp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) [HI6421_##_id] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .desc = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .name = #_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .of_match = of_match_ptr(#_match), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .regulators_node = of_match_ptr("regulators"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .ops = &hi6421_ldo_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .id = HI6421_##_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .n_voltages = ARRAY_SIZE(v_table), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .volt_table = v_table, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .vsel_mask = vmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .enable_mask = emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .enable_time = HI6421_LDO_ENABLE_TIME, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .off_on_delay = odelay, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .mode_mask = ecomask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .eco_microamp = ecoamp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * _id - LDO id name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * _match - of match name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * _min_uV - minimum voltage supported in uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * n_volt - number of votages available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * vstep - voltage increase in each linear step in uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * vreg - voltage select register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * vmask - voltage select mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * ereg - enable register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * emask - enable mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * odelay - off/on delay time in uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * ecomask - eco mode mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * ecoamp - eco mode load uppler limit in uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define HI6421_LDO_LINEAR(_id, _match, _min_uV, n_volt, vstep, vreg, vmask,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ereg, emask, odelay, ecomask, ecoamp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) [HI6421_##_id] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .desc = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .name = #_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .of_match = of_match_ptr(#_match), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .regulators_node = of_match_ptr("regulators"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .ops = &hi6421_ldo_linear_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .id = HI6421_##_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .min_uV = _min_uV, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .n_voltages = n_volt, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .uV_step = vstep, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .vsel_mask = vmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .enable_mask = emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .enable_time = HI6421_LDO_ENABLE_TIME, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .off_on_delay = odelay, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .mode_mask = ecomask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .eco_microamp = ecoamp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * _id - LDO id name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * _match - of match name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * n_volt - number of votages available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * volt_ranges - array of linear_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * vstep - voltage increase in each linear step in uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * vreg - voltage select register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * vmask - voltage select mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * ereg - enable register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * emask - enable mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * odelay - off/on delay time in uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * ecomask - eco mode mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * ecoamp - eco mode load uppler limit in uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define HI6421_LDO_LINEAR_RANGE(_id, _match, n_volt, volt_ranges, vreg, vmask,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ereg, emask, odelay, ecomask, ecoamp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) [HI6421_##_id] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .desc = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .name = #_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .of_match = of_match_ptr(#_match), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .regulators_node = of_match_ptr("regulators"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .ops = &hi6421_ldo_linear_range_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .id = HI6421_##_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .n_voltages = n_volt, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .linear_ranges = volt_ranges, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .vsel_mask = vmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .enable_mask = emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .enable_time = HI6421_LDO_ENABLE_TIME, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .off_on_delay = odelay, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .mode_mask = ecomask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .eco_microamp = ecoamp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * _id - BUCK0/1/2 id name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * _match - of match name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * vreg - voltage select register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * vmask - voltage select mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * ereg - enable register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * emask - enable mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * sleepmask - mask of sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * etime - enable time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * odelay - off/on delay time in uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define HI6421_BUCK012(_id, _match, vreg, vmask, ereg, emask, sleepmask,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) etime, odelay) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) [HI6421_##_id] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .desc = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .name = #_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .of_match = of_match_ptr(#_match), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .regulators_node = of_match_ptr("regulators"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .ops = &hi6421_buck012_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .id = HI6421_##_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .min_uV = 700000, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .n_voltages = 128, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .uV_step = 7086, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .vsel_mask = vmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .enable_mask = emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .enable_time = etime, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .off_on_delay = odelay, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .mode_mask = sleepmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* HI6421 BUCK3/4/5 share similar configurations as LDOs, with exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * that it supports SLEEP mode, so has different .ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * _id - LDO id name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * _match - of match name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * v_table - voltage table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * vreg - voltage select register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * vmask - voltage select mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * ereg - enable register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * emask - enable mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * odelay - off/on delay time in uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * sleepmask - mask of sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define HI6421_BUCK345(_id, _match, v_table, vreg, vmask, ereg, emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) odelay, sleepmask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) [HI6421_##_id] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .desc = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .name = #_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .of_match = of_match_ptr(#_match), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .regulators_node = of_match_ptr("regulators"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .ops = &hi6421_buck345_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .id = HI6421_##_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .n_voltages = ARRAY_SIZE(v_table), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .volt_table = v_table, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .vsel_mask = vmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .enable_mask = emask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .enable_time = HI6421_LDO_ENABLE_TIME, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .off_on_delay = odelay, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .mode_mask = sleepmask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* HI6421 regulator information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static struct hi6421_regulator_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) hi6421_regulator_info[HI6421_NUM_REGULATORS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) HI6421_LDO(LDO0, hi6421_vout0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 10000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) HI6421_LDO_LINEAR(LDO1, hi6421_vout1, 1700000, 4, 100000, 0x21, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 0x21, 0x10, 10000, 0x20, 5000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) HI6421_LDO_LINEAR(LDO2, hi6421_vout2, 1050000, 8, 50000, 0x22, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 0x22, 0x10, 20000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) HI6421_LDO_LINEAR(LDO3, hi6421_vout3, 1050000, 8, 50000, 0x23, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 0x23, 0x10, 20000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) HI6421_LDO(LDO4, hi6421_vout4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 20000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) HI6421_LDO(LDO5, hi6421_vout5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 20000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) HI6421_LDO(LDO6, hi6421_vout6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 20000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) HI6421_LDO(LDO7, hi6421_vout7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 20000, 0x20, 5000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) HI6421_LDO(LDO8, hi6421_vout8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 20000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) HI6421_LDO(LDO9, hi6421_vout9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) HI6421_LDO(LDO10, hi6421_vout10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) HI6421_LDO(LDO11, hi6421_vout11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) HI6421_LDO(LDO12, hi6421_vout12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) HI6421_LDO(LDO13, hi6421_vout13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) HI6421_LDO(LDO14, hi6421_vout14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) HI6421_LDO(LDO15, hi6421_vout15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) HI6421_LDO(LDO16, hi6421_vout16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) HI6421_LDO(LDO17, hi6421_vout17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) HI6421_LDO(LDO18, hi6421_vout18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) HI6421_LDO(LDO19, hi6421_vout19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) HI6421_LDO(LDO20, hi6421_vout20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 40000, 0x20, 8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) HI6421_LDO_LINEAR_RANGE(LDOAUDIO, hi6421_vout_audio, 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ldo_audio_volt_range, 0x36, 0x70, 0x36, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 40000, 0x02, 5000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) HI6421_BUCK012(BUCK0, hi6421_buck0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 20000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) HI6421_BUCK012(BUCK1, hi6421_buck1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 20000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) HI6421_BUCK012(BUCK2, hi6421_buck2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) HI6421_BUCK345(BUCK3, hi6421_buck3, buck_3_voltages, 0x13, 0x07, 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 0x01, 20000, 0x10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) HI6421_BUCK345(BUCK4, hi6421_buck4, buck_4_voltages, 0x15, 0x07, 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 0x01, 20000, 0x10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) HI6421_BUCK345(BUCK5, hi6421_buck5, buck_5_voltages, 0x17, 0x07, 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 0x01, 20000, 0x10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static int hi6421_regulator_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct hi6421_regulator_pdata *pdata = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* hi6421 spec requires regulator enablement must be serialized:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * - Because when BUCK, LDO switching from off to on, it will have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * a huge instantaneous current; so you can not turn on two or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * more LDO or BUCKs simultaneously, or it may burn the chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mutex_lock(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* call regulator regmap helper */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) regulator_enable_regmap(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mutex_unlock(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct hi6421_regulator_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (reg_val & info->mode_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return REGULATOR_MODE_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct hi6421_regulator_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (reg_val & info->mode_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return REGULATOR_MODE_STANDBY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct hi6421_regulator_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned int new_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case REGULATOR_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) new_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case REGULATOR_MODE_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) new_mode = info->mode_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* set mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) info->mode_mask, new_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct hi6421_regulator_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int new_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case REGULATOR_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) new_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case REGULATOR_MODE_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) new_mode = info->mode_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* set mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) info->mode_mask, new_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int input_uV, int output_uV, int load_uA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct hi6421_regulator_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (load_uA > info->eco_microamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return REGULATOR_MODE_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static const struct regulator_ops hi6421_ldo_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .enable = hi6421_regulator_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .list_voltage = regulator_list_voltage_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .map_voltage = regulator_map_voltage_ascend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .get_mode = hi6421_regulator_ldo_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .set_mode = hi6421_regulator_ldo_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static const struct regulator_ops hi6421_ldo_linear_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .enable = hi6421_regulator_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .list_voltage = regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .map_voltage = regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .get_mode = hi6421_regulator_ldo_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .set_mode = hi6421_regulator_ldo_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static const struct regulator_ops hi6421_ldo_linear_range_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .enable = hi6421_regulator_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .list_voltage = regulator_list_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .map_voltage = regulator_map_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .get_mode = hi6421_regulator_ldo_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .set_mode = hi6421_regulator_ldo_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static const struct regulator_ops hi6421_buck012_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .enable = hi6421_regulator_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .list_voltage = regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .map_voltage = regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .get_mode = hi6421_regulator_buck_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .set_mode = hi6421_regulator_buck_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static const struct regulator_ops hi6421_buck345_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .enable = hi6421_regulator_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .list_voltage = regulator_list_voltage_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .map_voltage = regulator_map_voltage_ascend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .get_mode = hi6421_regulator_buck_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .set_mode = hi6421_regulator_buck_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int hi6421_regulator_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct hi6421_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct hi6421_regulator_pdata *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct hi6421_regulator_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) mutex_init(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* assign per-regulator data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) info = &hi6421_regulator_info[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) config.dev = pdev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) config.driver_data = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) config.regmap = pmic->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) rdev = devm_regulator_register(&pdev->dev, &info->desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dev_err(&pdev->dev, "failed to register regulator %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) info->desc.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static const struct platform_device_id hi6421_regulator_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) { .name = "hi6421-regulator" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) MODULE_DEVICE_TABLE(platform, hi6421_regulator_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static struct platform_driver hi6421_regulator_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .id_table = hi6421_regulator_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .name = "hi6421-regulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .probe = hi6421_regulator_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) module_platform_driver(hi6421_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) MODULE_DESCRIPTION("Hi6421 regulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) MODULE_LICENSE("GPL v2");