#include <linux/mfd/arizona/pdata.h>
#include <linux/mfd/arizona/registers.h>
------ -#define ARIZONA_MICSUPP_MAX_SELECTOR 0x1f
------ -
struct arizona_micsupp {
struct regulator_dev *regulator;
struct arizona *arizona;
struct work_struct check_cp_work;
};
------ -static int arizona_micsupp_list_voltage(struct regulator_dev *rdev,
------ - unsigned int selector)
------ -{
------ - if (selector > ARIZONA_MICSUPP_MAX_SELECTOR)
------ - return -EINVAL;
------ -
------ - if (selector == ARIZONA_MICSUPP_MAX_SELECTOR)
------ - return 3300000;
------ - else
------ - return (selector * 50000) + 1700000;
------ -}
------ -
------ -static int arizona_micsupp_map_voltage(struct regulator_dev *rdev,
------ - int min_uV, int max_uV)
------ -{
------ - unsigned int voltage;
------ - int selector;
------ -
------ - if (min_uV < 1700000)
------ - min_uV = 1700000;
------ -
------ - if (min_uV > 3200000)
------ - selector = ARIZONA_MICSUPP_MAX_SELECTOR;
------ - else
------ - selector = DIV_ROUND_UP(min_uV - 1700000, 50000);
------ -
------ - if (selector < 0)
------ - return -EINVAL;
------ -
------ - voltage = arizona_micsupp_list_voltage(rdev, selector);
------ - if (voltage < min_uV || voltage > max_uV)
------ - return -EINVAL;
------ -
------ - return selector;
------ -}
------ -
static void arizona_micsupp_check_cp(struct work_struct *work)
{
struct arizona_micsupp *micsupp =
.disable = arizona_micsupp_disable,
.is_enabled = regulator_is_enabled_regmap,
------ - .list_voltage = arizona_micsupp_list_voltage,
------ - .map_voltage = arizona_micsupp_map_voltage,
++++++ + .list_voltage = regulator_list_voltage_linear_range,
++++++ + .map_voltage = regulator_map_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_bypass = arizona_micsupp_set_bypass,
};
++++++ +static const struct regulator_linear_range arizona_micsupp_ranges[] = {
++++++ + REGULATOR_LINEAR_RANGE(1700000, 0, 0x1e, 50000),
++++++ + REGULATOR_LINEAR_RANGE(3300000, 0x1f, 0x1f, 0),
++++++ +};
++++++ +
static const struct regulator_desc arizona_micsupp = {
.name = "MICVDD",
.supply_name = "CPVDD",
.type = REGULATOR_VOLTAGE,
------ - .n_voltages = ARIZONA_MICSUPP_MAX_SELECTOR + 1,
++++++ + .n_voltages = 32,
++++ + .ops = &arizona_micsupp_ops,
++++ +
++++ + .vsel_reg = ARIZONA_LDO2_CONTROL_1,
++++ + .vsel_mask = ARIZONA_LDO2_VSEL_MASK,
++++ + .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
++++ + .enable_mask = ARIZONA_CPMIC_ENA,
++++ + .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
++++ + .bypass_mask = ARIZONA_CPMIC_BYPASS,
++++ +
++++++ + .linear_ranges = arizona_micsupp_ranges,
++++++ + .n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ranges),
++++++ +
++++ + .enable_time = 3000,
++++ +
++++ + .owner = THIS_MODULE,
++++ +};
++++ +
++++++static const struct regulator_linear_range arizona_micsupp_ext_ranges[] = {
++++++ REGULATOR_LINEAR_RANGE(900000, 0, 0x14, 25000),
++++++ REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000),
++++++};
++++++
++++++static const struct regulator_desc arizona_micsupp_ext = {
++++++ .name = "MICVDD",
++++++ .supply_name = "CPVDD",
++++++ .type = REGULATOR_VOLTAGE,
++++++ .n_voltages = 40,
+ .ops = &arizona_micsupp_ops,
+
+ .vsel_reg = ARIZONA_LDO2_CONTROL_1,
+ .vsel_mask = ARIZONA_LDO2_VSEL_MASK,
+ .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+ .enable_mask = ARIZONA_CPMIC_ENA,
+ .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+ .bypass_mask = ARIZONA_CPMIC_BYPASS,
+
++++++ .linear_ranges = arizona_micsupp_ext_ranges,
++++++ .n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
++++++
+ .enable_time = 3000,
+
+ .owner = THIS_MODULE,
+ };
+
static const struct regulator_init_data arizona_micsupp_default = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS |
.num_consumer_supplies = 1,
};
++++++static const struct regulator_init_data arizona_micsupp_ext_default = {
++++++ .constraints = {
++++++ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
++++++ REGULATOR_CHANGE_VOLTAGE |
++++++ REGULATOR_CHANGE_BYPASS,
++++++ .min_uV = 900000,
++++++ .max_uV = 3300000,
++++++ },
++++++
++++++ .num_consumer_supplies = 1,
++++++};
++++++
static int arizona_micsupp_probe(struct platform_device *pdev)
{
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
++++++ const struct regulator_desc *desc;
struct regulator_config config = { };
struct arizona_micsupp *micsupp;
int ret;
* default init_data for it. This will be overridden with
* platform data if provided.
*/
------ micsupp->init_data = arizona_micsupp_default;
++++++ switch (arizona->type) {
++++++ case WM5110:
++++++ desc = &arizona_micsupp_ext;
++++++ micsupp->init_data = arizona_micsupp_ext_default;
++++++ break;
++++++ default:
++++++ desc = &arizona_micsupp;
++++++ micsupp->init_data = arizona_micsupp_default;
++++++ break;
++++++ }
++++++
micsupp->init_data.consumer_supplies = &micsupp->supply;
micsupp->supply.supply = "MICVDD";
micsupp->supply.dev_name = dev_name(arizona->dev);
ARIZONA_CPMIC_BYPASS, 0);
micsupp->regulator = devm_regulator_register(&pdev->dev,
------ &arizona_micsupp,
++++++ desc,
&config);
if (IS_ERR(micsupp->regulator)) {
ret = PTR_ERR(micsupp->regulator);
.sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK,
.control_reg = AS3722_SD0_CONTROL_REG,
.mode_mask = AS3722_SD0_MODE_FAST,
------- .n_voltages = AS3722_SD0_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD1,
.sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK,
.control_reg = AS3722_SD1_CONTROL_REG,
.mode_mask = AS3722_SD1_MODE_FAST,
------- .n_voltages = AS3722_SD0_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD2,
.sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK,
.control_reg = AS3722_SD6_CONTROL_REG,
.mode_mask = AS3722_SD6_MODE_FAST,
------- .n_voltages = AS3722_SD0_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO0,
default:
return -EINVAL;
}
++++++ ret <<= ffs(mask) - 1;
val = ret & mask;
------ val <<= ffs(mask) - 1;
return as3722_update_bits(as3722, reg, mask, val);
}
+++++++ static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
+++++++ {
+++++++ int err;
+++++++ unsigned val;
+++++++
+++++++ err = as3722_read(as3722_regs->as3722, AS3722_FUSE7_REG, &val);
+++++++ if (err < 0) {
+++++++ dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
+++++++ AS3722_FUSE7_REG, err);
+++++++ return false;
+++++++ }
+++++++ if (val & AS3722_FUSE7_SD0_LOW_VOLTAGE)
+++++++ return true;
+++++++ return false;
+++++++ }
+++++++
static const struct regulator_linear_range as3722_sd2345_ranges[] = {
REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
ops = &as3722_sd016_extcntrl_ops;
else
ops = &as3722_sd016_ops;
------- as3722_regs->desc[id].min_uV = 610000;
+++++++ if (id == AS3722_REGULATOR_ID_SD0 &&
+++++++ as3722_sd0_is_low_voltage(as3722_regs)) {
+++++++ as3722_regs->desc[id].n_voltages =
+++++++ AS3722_SD0_VSEL_LOW_VOL_MAX + 1;
+++++++ as3722_regs->desc[id].min_uV = 410000;
+++++++ } else {
+++++++ as3722_regs->desc[id].n_voltages =
+++++++ AS3722_SD0_VSEL_MAX + 1,
+++++++ as3722_regs->desc[id].min_uV = 610000;
+++++++ }
as3722_regs->desc[id].uV_step = 10000;
as3722_regs->desc[id].linear_min_sel = 1;
+++++++ as3722_regs->desc[id].enable_time = 600;
break;
case AS3722_REGULATOR_ID_SD2:
case AS3722_REGULATOR_ID_SD3:
ops = &as3722_ldo_extcntrl_ops;
else
ops = &as3722_ldo_ops;
------- as3722_regs->desc[id].min_uV = 825000;
------- as3722_regs->desc[id].uV_step = 25000;
------- as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500;
as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
as3722_regs->desc[id].n_linear_ranges =