0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/bug.h>
0010 #include <linux/err.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/regulator/driver.h>
0014 #include <linux/mfd/wm8400-private.h>
0015
0016 static const struct linear_range wm8400_ldo_ranges[] = {
0017 REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000),
0018 REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000),
0019 };
0020
0021 static const struct regulator_ops wm8400_ldo_ops = {
0022 .is_enabled = regulator_is_enabled_regmap,
0023 .enable = regulator_enable_regmap,
0024 .disable = regulator_disable_regmap,
0025 .list_voltage = regulator_list_voltage_linear_range,
0026 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0027 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0028 .map_voltage = regulator_map_voltage_linear_range,
0029 };
0030
0031 static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev)
0032 {
0033 struct regmap *rmap = rdev_get_regmap(dev);
0034 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
0035 u16 data[2];
0036 int ret;
0037
0038 ret = regmap_bulk_read(rmap, WM8400_DCDC1_CONTROL_1 + offset, data, 2);
0039 if (ret != 0)
0040 return 0;
0041
0042
0043 if (data[0] & WM8400_DC1_SLEEP)
0044 return REGULATOR_MODE_STANDBY;
0045
0046
0047 if (!(data[0] & WM8400_DC1_ACTIVE))
0048 return REGULATOR_MODE_IDLE;
0049
0050
0051 if (data[1] & WM8400_DC1_FRC_PWM)
0052 return REGULATOR_MODE_FAST;
0053 else
0054 return REGULATOR_MODE_NORMAL;
0055 }
0056
0057 static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
0058 {
0059 struct regmap *rmap = rdev_get_regmap(dev);
0060 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
0061 int ret;
0062
0063 switch (mode) {
0064 case REGULATOR_MODE_FAST:
0065
0066 ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset,
0067 WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM);
0068 if (ret != 0)
0069 return ret;
0070
0071 return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
0072 WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
0073 WM8400_DC1_ACTIVE);
0074
0075 case REGULATOR_MODE_NORMAL:
0076
0077 ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset,
0078 WM8400_DC1_FRC_PWM, 0);
0079 if (ret != 0)
0080 return ret;
0081
0082 return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
0083 WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
0084 WM8400_DC1_ACTIVE);
0085
0086 case REGULATOR_MODE_IDLE:
0087
0088 return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
0089 WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0);
0090 default:
0091 return -EINVAL;
0092 }
0093 }
0094
0095 static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev,
0096 int input_uV, int output_uV,
0097 int load_uA)
0098 {
0099 return REGULATOR_MODE_NORMAL;
0100 }
0101
0102 static const struct regulator_ops wm8400_dcdc_ops = {
0103 .is_enabled = regulator_is_enabled_regmap,
0104 .enable = regulator_enable_regmap,
0105 .disable = regulator_disable_regmap,
0106 .list_voltage = regulator_list_voltage_linear,
0107 .map_voltage = regulator_map_voltage_linear,
0108 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0109 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0110 .get_mode = wm8400_dcdc_get_mode,
0111 .set_mode = wm8400_dcdc_set_mode,
0112 .get_optimum_mode = wm8400_dcdc_get_optimum_mode,
0113 };
0114
0115 static struct regulator_desc regulators[] = {
0116 {
0117 .name = "LDO1",
0118 .id = WM8400_LDO1,
0119 .ops = &wm8400_ldo_ops,
0120 .enable_reg = WM8400_LDO1_CONTROL,
0121 .enable_mask = WM8400_LDO1_ENA,
0122 .n_voltages = WM8400_LDO1_VSEL_MASK + 1,
0123 .linear_ranges = wm8400_ldo_ranges,
0124 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
0125 .vsel_reg = WM8400_LDO1_CONTROL,
0126 .vsel_mask = WM8400_LDO1_VSEL_MASK,
0127 .type = REGULATOR_VOLTAGE,
0128 .owner = THIS_MODULE,
0129 },
0130 {
0131 .name = "LDO2",
0132 .id = WM8400_LDO2,
0133 .ops = &wm8400_ldo_ops,
0134 .enable_reg = WM8400_LDO2_CONTROL,
0135 .enable_mask = WM8400_LDO2_ENA,
0136 .n_voltages = WM8400_LDO2_VSEL_MASK + 1,
0137 .linear_ranges = wm8400_ldo_ranges,
0138 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
0139 .type = REGULATOR_VOLTAGE,
0140 .vsel_reg = WM8400_LDO2_CONTROL,
0141 .vsel_mask = WM8400_LDO2_VSEL_MASK,
0142 .owner = THIS_MODULE,
0143 },
0144 {
0145 .name = "LDO3",
0146 .id = WM8400_LDO3,
0147 .ops = &wm8400_ldo_ops,
0148 .enable_reg = WM8400_LDO3_CONTROL,
0149 .enable_mask = WM8400_LDO3_ENA,
0150 .n_voltages = WM8400_LDO3_VSEL_MASK + 1,
0151 .linear_ranges = wm8400_ldo_ranges,
0152 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
0153 .vsel_reg = WM8400_LDO3_CONTROL,
0154 .vsel_mask = WM8400_LDO3_VSEL_MASK,
0155 .type = REGULATOR_VOLTAGE,
0156 .owner = THIS_MODULE,
0157 },
0158 {
0159 .name = "LDO4",
0160 .id = WM8400_LDO4,
0161 .ops = &wm8400_ldo_ops,
0162 .enable_reg = WM8400_LDO4_CONTROL,
0163 .enable_mask = WM8400_LDO4_ENA,
0164 .n_voltages = WM8400_LDO4_VSEL_MASK + 1,
0165 .linear_ranges = wm8400_ldo_ranges,
0166 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
0167 .vsel_reg = WM8400_LDO4_CONTROL,
0168 .vsel_mask = WM8400_LDO4_VSEL_MASK,
0169 .type = REGULATOR_VOLTAGE,
0170 .owner = THIS_MODULE,
0171 },
0172 {
0173 .name = "DCDC1",
0174 .id = WM8400_DCDC1,
0175 .ops = &wm8400_dcdc_ops,
0176 .enable_reg = WM8400_DCDC1_CONTROL_1,
0177 .enable_mask = WM8400_DC1_ENA_MASK,
0178 .n_voltages = WM8400_DC1_VSEL_MASK + 1,
0179 .vsel_reg = WM8400_DCDC1_CONTROL_1,
0180 .vsel_mask = WM8400_DC1_VSEL_MASK,
0181 .min_uV = 850000,
0182 .uV_step = 25000,
0183 .type = REGULATOR_VOLTAGE,
0184 .owner = THIS_MODULE,
0185 },
0186 {
0187 .name = "DCDC2",
0188 .id = WM8400_DCDC2,
0189 .ops = &wm8400_dcdc_ops,
0190 .enable_reg = WM8400_DCDC2_CONTROL_1,
0191 .enable_mask = WM8400_DC2_ENA_MASK,
0192 .n_voltages = WM8400_DC2_VSEL_MASK + 1,
0193 .vsel_reg = WM8400_DCDC2_CONTROL_1,
0194 .vsel_mask = WM8400_DC2_VSEL_MASK,
0195 .min_uV = 850000,
0196 .uV_step = 25000,
0197 .type = REGULATOR_VOLTAGE,
0198 .owner = THIS_MODULE,
0199 },
0200 };
0201
0202 static int wm8400_regulator_probe(struct platform_device *pdev)
0203 {
0204 struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
0205 struct regulator_config config = { };
0206 struct regulator_dev *rdev;
0207
0208 config.dev = &pdev->dev;
0209 config.init_data = dev_get_platdata(&pdev->dev);
0210 config.driver_data = wm8400;
0211 config.regmap = wm8400->regmap;
0212
0213 rdev = devm_regulator_register(&pdev->dev, ®ulators[pdev->id],
0214 &config);
0215 if (IS_ERR(rdev))
0216 return PTR_ERR(rdev);
0217
0218 platform_set_drvdata(pdev, rdev);
0219
0220 return 0;
0221 }
0222
0223 static struct platform_driver wm8400_regulator_driver = {
0224 .driver = {
0225 .name = "wm8400-regulator",
0226 },
0227 .probe = wm8400_regulator_probe,
0228 };
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 int wm8400_register_regulator(struct device *dev, int reg,
0242 struct regulator_init_data *initdata)
0243 {
0244 struct wm8400 *wm8400 = dev_get_drvdata(dev);
0245
0246 if (wm8400->regulators[reg].name)
0247 return -EBUSY;
0248
0249 initdata->driver_data = wm8400;
0250
0251 wm8400->regulators[reg].name = "wm8400-regulator";
0252 wm8400->regulators[reg].id = reg;
0253 wm8400->regulators[reg].dev.parent = dev;
0254 wm8400->regulators[reg].dev.platform_data = initdata;
0255
0256 return platform_device_register(&wm8400->regulators[reg]);
0257 }
0258 EXPORT_SYMBOL_GPL(wm8400_register_regulator);
0259
0260 static int __init wm8400_regulator_init(void)
0261 {
0262 return platform_driver_register(&wm8400_regulator_driver);
0263 }
0264 subsys_initcall(wm8400_regulator_init);
0265
0266 static void __exit wm8400_regulator_exit(void)
0267 {
0268 platform_driver_unregister(&wm8400_regulator_driver);
0269 }
0270 module_exit(wm8400_regulator_exit);
0271
0272 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0273 MODULE_DESCRIPTION("WM8400 regulator driver");
0274 MODULE_LICENSE("GPL");
0275 MODULE_ALIAS("platform:wm8400-regulator");