Commit 914df8fa authored by Joseph Chen's avatar Joseph Chen Committed by Mark Brown

regulator: fan53555: Add TCS4525 DCDC support

TCS4525 main features:

- 2.7V to 5.5V Input Voltage Range;
- 3MHz Constant Switching Frequency;
- 5A Available Load Current;
- Programmable Output Voltage: 0.6V to 1.4V in 6.25mV Steps;
- PFM/PWM Operation for Optimum Increased Efficiency;
Signed-off-by: default avatarJoseph Chen <chenjh@rock-chips.com>
[Ezequiel: Forward port]
Signed-off-by: default avatarEzequiel Garcia <ezequiel@collabora.com>
Link: https://lore.kernel.org/r/20210421210338.43819-3-ezequiel@collabora.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 3007accc
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
/* Voltage setting */ /* Voltage setting */
#define FAN53555_VSEL0 0x00 #define FAN53555_VSEL0 0x00
#define FAN53555_VSEL1 0x01 #define FAN53555_VSEL1 0x01
#define TCS4525_VSEL0 0x11
#define TCS4525_VSEL1 0x10
#define TCS4525_TIME 0x13
#define TCS4525_COMMAND 0x14
/* Control register */ /* Control register */
#define FAN53555_CONTROL 0x02 #define FAN53555_CONTROL 0x02
/* IC Type */ /* IC Type */
...@@ -49,11 +55,20 @@ ...@@ -49,11 +55,20 @@
#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */ #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
#define FAN53526_NVOLTAGES 128 #define FAN53526_NVOLTAGES 128
#define TCS4525_NVOLTAGES 127 /* Numbers of voltages */
#define TCS_VSEL_NSEL_MASK 0x7f
#define TCS_VSEL0_MODE (1 << 7)
#define TCS_VSEL1_MODE (1 << 6)
#define TCS_SLEW_SHIFT 3
#define TCS_SLEW_MASK (0x3 < 3)
enum fan53555_vendor { enum fan53555_vendor {
FAN53526_VENDOR_FAIRCHILD = 0, FAN53526_VENDOR_FAIRCHILD = 0,
FAN53555_VENDOR_FAIRCHILD, FAN53555_VENDOR_FAIRCHILD,
FAN53555_VENDOR_SILERGY, FAN53555_VENDOR_SILERGY,
FAN53555_VENDOR_TCS,
}; };
enum { enum {
...@@ -106,6 +121,11 @@ struct fan53555_device_info { ...@@ -106,6 +121,11 @@ struct fan53555_device_info {
unsigned int mode_mask; unsigned int mode_mask;
/* Sleep voltage cache */ /* Sleep voltage cache */
unsigned int sleep_vol_cache; unsigned int sleep_vol_cache;
/* Slew rate */
unsigned int slew_reg;
unsigned int slew_mask;
unsigned int slew_shift;
unsigned int slew_rate;
}; };
static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
...@@ -189,13 +209,37 @@ static const int slew_rates[] = { ...@@ -189,13 +209,37 @@ static const int slew_rates[] = {
500, 500,
}; };
static const int tcs_slew_rates[] = {
18700,
9300,
4600,
2300,
};
static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
{ {
struct fan53555_device_info *di = rdev_get_drvdata(rdev); struct fan53555_device_info *di = rdev_get_drvdata(rdev);
int regval = -1, i; int regval = -1, i;
const int *slew_rate_t;
int slew_rate_n;
for (i = 0; i < ARRAY_SIZE(slew_rates); i++) { switch (di->vendor) {
if (ramp <= slew_rates[i]) case FAN53526_VENDOR_FAIRCHILD:
case FAN53555_VENDOR_FAIRCHILD:
case FAN53555_VENDOR_SILERGY:
slew_rate_t = slew_rates;
slew_rate_n = ARRAY_SIZE(slew_rates);
break;
case FAN53555_VENDOR_TCS:
slew_rate_t = tcs_slew_rates;
slew_rate_n = ARRAY_SIZE(tcs_slew_rates);
break;
default:
return -EINVAL;
}
for (i = 0; i < slew_rate_n; i++) {
if (ramp <= slew_rate_t[i])
regval = i; regval = i;
else else
break; break;
...@@ -206,8 +250,8 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) ...@@ -206,8 +250,8 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
return -EINVAL; return -EINVAL;
} }
return regmap_update_bits(rdev->regmap, FAN53555_CONTROL, return regmap_update_bits(rdev->regmap, di->slew_reg,
CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT); di->slew_mask, regval << di->slew_shift);
} }
static const struct regulator_ops fan53555_regulator_ops = { static const struct regulator_ops fan53555_regulator_ops = {
...@@ -292,7 +336,9 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) ...@@ -292,7 +336,9 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
"Chip ID %d not supported!\n", di->chip_id); "Chip ID %d not supported!\n", di->chip_id);
return -EINVAL; return -EINVAL;
} }
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->slew_shift = CTL_SLEW_SHIFT;
di->vsel_count = FAN53555_NVOLTAGES; di->vsel_count = FAN53555_NVOLTAGES;
return 0; return 0;
...@@ -312,12 +358,29 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) ...@@ -312,12 +358,29 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
"Chip ID %d not supported!\n", di->chip_id); "Chip ID %d not supported!\n", di->chip_id);
return -EINVAL; return -EINVAL;
} }
di->slew_reg = FAN53555_CONTROL;
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->slew_shift = CTL_SLEW_SHIFT;
di->vsel_count = FAN53555_NVOLTAGES; di->vsel_count = FAN53555_NVOLTAGES;
return 0; return 0;
} }
static int fan53555_voltages_setup_tcs(struct fan53555_device_info *di)
{
di->slew_reg = TCS4525_TIME;
di->slew_mask = TCS_SLEW_MASK;
di->slew_shift = TCS_SLEW_MASK;
/* Init voltage range and step */
di->vsel_min = 600000;
di->vsel_step = 6250;
di->vsel_count = TCS4525_NVOLTAGES;
return 0;
}
/* For 00,01,03,05 options: /* For 00,01,03,05 options:
* VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V. * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
* For 04 option: * For 04 option:
...@@ -329,17 +392,41 @@ static int fan53555_device_setup(struct fan53555_device_info *di, ...@@ -329,17 +392,41 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
int ret = 0; int ret = 0;
/* Setup voltage control register */ /* Setup voltage control register */
switch (pdata->sleep_vsel_id) { switch (di->vendor) {
case FAN53555_VSEL_ID_0: case FAN53526_VENDOR_FAIRCHILD:
di->sleep_reg = FAN53555_VSEL0; case FAN53555_VENDOR_FAIRCHILD:
di->vol_reg = FAN53555_VSEL1; case FAN53555_VENDOR_SILERGY:
switch (pdata->sleep_vsel_id) {
case FAN53555_VSEL_ID_0:
di->sleep_reg = FAN53555_VSEL0;
di->vol_reg = FAN53555_VSEL1;
break;
case FAN53555_VSEL_ID_1:
di->sleep_reg = FAN53555_VSEL1;
di->vol_reg = FAN53555_VSEL0;
break;
default:
dev_err(di->dev, "Invalid VSEL ID!\n");
return -EINVAL;
}
break; break;
case FAN53555_VSEL_ID_1: case FAN53555_VENDOR_TCS:
di->sleep_reg = FAN53555_VSEL1; switch (pdata->sleep_vsel_id) {
di->vol_reg = FAN53555_VSEL0; case FAN53555_VSEL_ID_0:
di->sleep_reg = TCS4525_VSEL0;
di->vol_reg = TCS4525_VSEL1;
break;
case FAN53555_VSEL_ID_1:
di->sleep_reg = TCS4525_VSEL1;
di->vol_reg = TCS4525_VSEL0;
break;
default:
dev_err(di->dev, "Invalid VSEL ID!\n");
return -EINVAL;
}
break; break;
default: default:
dev_err(di->dev, "Invalid VSEL ID!\n"); dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
return -EINVAL; return -EINVAL;
} }
...@@ -362,6 +449,18 @@ static int fan53555_device_setup(struct fan53555_device_info *di, ...@@ -362,6 +449,18 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
di->mode_reg = di->vol_reg; di->mode_reg = di->vol_reg;
di->mode_mask = VSEL_MODE; di->mode_mask = VSEL_MODE;
break; break;
case FAN53555_VENDOR_TCS:
di->mode_reg = TCS4525_COMMAND;
switch (pdata->sleep_vsel_id) {
case FAN53555_VSEL_ID_0:
di->mode_mask = TCS_VSEL1_MODE;
break;
case FAN53555_VSEL_ID_1:
di->mode_mask = TCS_VSEL0_MODE;
break;
}
break;
default: default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor); dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
return -EINVAL; return -EINVAL;
...@@ -378,6 +477,9 @@ static int fan53555_device_setup(struct fan53555_device_info *di, ...@@ -378,6 +477,9 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
case FAN53555_VENDOR_SILERGY: case FAN53555_VENDOR_SILERGY:
ret = fan53555_voltages_setup_silergy(di); ret = fan53555_voltages_setup_silergy(di);
break; break;
case FAN53555_VENDOR_TCS:
ret = fan53555_voltages_setup_tcs(di);
break;
default: default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor); dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
return -EINVAL; return -EINVAL;
...@@ -449,6 +551,9 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = { ...@@ -449,6 +551,9 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
}, { }, {
.compatible = "silergy,syr828", .compatible = "silergy,syr828",
.data = (void *)FAN53555_VENDOR_SILERGY, .data = (void *)FAN53555_VENDOR_SILERGY,
}, {
.compatible = "tcs,tcs4525",
.data = (void *)FAN53555_VENDOR_TCS
}, },
{ } { }
}; };
...@@ -554,6 +659,9 @@ static const struct i2c_device_id fan53555_id[] = { ...@@ -554,6 +659,9 @@ static const struct i2c_device_id fan53555_id[] = {
}, { }, {
.name = "syr828", .name = "syr828",
.driver_data = FAN53555_VENDOR_SILERGY .driver_data = FAN53555_VENDOR_SILERGY
}, {
.name = "tcs4525",
.driver_data = FAN53555_VENDOR_TCS
}, },
{ }, { },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment