197be8288SJisheng Zhang // SPDX-License-Identifier: GPL-2.0 297be8288SJisheng Zhang // 3751ca3aaSJisheng Zhang // MP8867/MP8869 regulator driver 497be8288SJisheng Zhang // 597be8288SJisheng Zhang // Copyright (C) 2020 Synaptics Incorporated 697be8288SJisheng Zhang // 797be8288SJisheng Zhang // Author: Jisheng Zhang <jszhang@kernel.org> 897be8288SJisheng Zhang 997be8288SJisheng Zhang #include <linux/gpio/consumer.h> 1097be8288SJisheng Zhang #include <linux/i2c.h> 1197be8288SJisheng Zhang #include <linux/module.h> 1297be8288SJisheng Zhang #include <linux/of_device.h> 1397be8288SJisheng Zhang #include <linux/regmap.h> 1497be8288SJisheng Zhang #include <linux/regulator/driver.h> 1597be8288SJisheng Zhang #include <linux/regulator/of_regulator.h> 1697be8288SJisheng Zhang 1797be8288SJisheng Zhang #define MP886X_VSEL 0x00 1897be8288SJisheng Zhang #define MP886X_V_BOOT (1 << 7) 1997be8288SJisheng Zhang #define MP886X_SYSCNTLREG1 0x01 2097be8288SJisheng Zhang #define MP886X_MODE (1 << 0) 210eddcf02SJisheng Zhang #define MP886X_SLEW_SHIFT 3 220eddcf02SJisheng Zhang #define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT) 2397be8288SJisheng Zhang #define MP886X_GO (1 << 6) 2497be8288SJisheng Zhang #define MP886X_EN (1 << 7) 25ee6ad5a2SJisheng Zhang #define MP8869_SYSCNTLREG2 0x02 2697be8288SJisheng Zhang 270eddcf02SJisheng Zhang struct mp886x_cfg_info { 280eddcf02SJisheng Zhang const struct regulator_ops *rops; 29*e1e8d55bSAxel Lin const unsigned int slew_rates[8]; 30ee6ad5a2SJisheng Zhang const int switch_freq[4]; 31ee6ad5a2SJisheng Zhang const u8 fs_reg; 32ee6ad5a2SJisheng Zhang const u8 fs_shift; 330eddcf02SJisheng Zhang }; 340eddcf02SJisheng Zhang 3597be8288SJisheng Zhang struct mp886x_device_info { 3697be8288SJisheng Zhang struct device *dev; 3797be8288SJisheng Zhang struct regulator_desc desc; 3897be8288SJisheng Zhang struct regulator_init_data *regulator; 3997be8288SJisheng Zhang struct gpio_desc *en_gpio; 400eddcf02SJisheng Zhang const struct mp886x_cfg_info *ci; 4197be8288SJisheng Zhang u32 r[2]; 4297be8288SJisheng Zhang unsigned int sel; 4397be8288SJisheng Zhang }; 4497be8288SJisheng Zhang 45ee6ad5a2SJisheng Zhang static void mp886x_set_switch_freq(struct mp886x_device_info *di, 46ee6ad5a2SJisheng Zhang struct regmap *regmap, 47ee6ad5a2SJisheng Zhang u32 freq) 48ee6ad5a2SJisheng Zhang { 49ee6ad5a2SJisheng Zhang const struct mp886x_cfg_info *ci = di->ci; 50ee6ad5a2SJisheng Zhang int i; 51ee6ad5a2SJisheng Zhang 52ee6ad5a2SJisheng Zhang for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) { 53ee6ad5a2SJisheng Zhang if (freq == ci->switch_freq[i]) { 54ee6ad5a2SJisheng Zhang regmap_update_bits(regmap, ci->fs_reg, 55ee6ad5a2SJisheng Zhang 0x3 << ci->fs_shift, i << ci->fs_shift); 56ee6ad5a2SJisheng Zhang return; 57ee6ad5a2SJisheng Zhang } 58ee6ad5a2SJisheng Zhang } 59ee6ad5a2SJisheng Zhang 60ee6ad5a2SJisheng Zhang dev_err(di->dev, "invalid frequency %d\n", freq); 61ee6ad5a2SJisheng Zhang } 62ee6ad5a2SJisheng Zhang 6397be8288SJisheng Zhang static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode) 6497be8288SJisheng Zhang { 6597be8288SJisheng Zhang switch (mode) { 6697be8288SJisheng Zhang case REGULATOR_MODE_FAST: 6797be8288SJisheng Zhang regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 6897be8288SJisheng Zhang MP886X_MODE, MP886X_MODE); 6997be8288SJisheng Zhang break; 7097be8288SJisheng Zhang case REGULATOR_MODE_NORMAL: 7197be8288SJisheng Zhang regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 7297be8288SJisheng Zhang MP886X_MODE, 0); 7397be8288SJisheng Zhang break; 7497be8288SJisheng Zhang default: 7597be8288SJisheng Zhang return -EINVAL; 7697be8288SJisheng Zhang } 7797be8288SJisheng Zhang return 0; 7897be8288SJisheng Zhang } 7997be8288SJisheng Zhang 8097be8288SJisheng Zhang static unsigned int mp886x_get_mode(struct regulator_dev *rdev) 8197be8288SJisheng Zhang { 8297be8288SJisheng Zhang u32 val; 8397be8288SJisheng Zhang int ret; 8497be8288SJisheng Zhang 8597be8288SJisheng Zhang ret = regmap_read(rdev->regmap, MP886X_SYSCNTLREG1, &val); 8697be8288SJisheng Zhang if (ret < 0) 8797be8288SJisheng Zhang return ret; 8897be8288SJisheng Zhang if (val & MP886X_MODE) 8997be8288SJisheng Zhang return REGULATOR_MODE_FAST; 9097be8288SJisheng Zhang else 9197be8288SJisheng Zhang return REGULATOR_MODE_NORMAL; 9297be8288SJisheng Zhang } 9397be8288SJisheng Zhang 9497be8288SJisheng Zhang static int mp8869_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) 9597be8288SJisheng Zhang { 9697be8288SJisheng Zhang int ret; 9797be8288SJisheng Zhang 9897be8288SJisheng Zhang ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 9997be8288SJisheng Zhang MP886X_GO, MP886X_GO); 10097be8288SJisheng Zhang if (ret < 0) 10197be8288SJisheng Zhang return ret; 10297be8288SJisheng Zhang 10397be8288SJisheng Zhang sel <<= ffs(rdev->desc->vsel_mask) - 1; 10497be8288SJisheng Zhang return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, 10597be8288SJisheng Zhang MP886X_V_BOOT | rdev->desc->vsel_mask, sel); 10697be8288SJisheng Zhang } 10797be8288SJisheng Zhang 10897be8288SJisheng Zhang static inline unsigned int mp8869_scale(unsigned int uv, u32 r1, u32 r2) 10997be8288SJisheng Zhang { 11097be8288SJisheng Zhang u32 tmp = uv * r1 / r2; 11197be8288SJisheng Zhang 11297be8288SJisheng Zhang return uv + tmp; 11397be8288SJisheng Zhang } 11497be8288SJisheng Zhang 11597be8288SJisheng Zhang static int mp8869_get_voltage_sel(struct regulator_dev *rdev) 11697be8288SJisheng Zhang { 11797be8288SJisheng Zhang struct mp886x_device_info *di = rdev_get_drvdata(rdev); 11897be8288SJisheng Zhang int ret, uv; 11997be8288SJisheng Zhang unsigned int val; 12097be8288SJisheng Zhang bool fbloop; 12197be8288SJisheng Zhang 12297be8288SJisheng Zhang ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); 12397be8288SJisheng Zhang if (ret) 12497be8288SJisheng Zhang return ret; 12597be8288SJisheng Zhang 12697be8288SJisheng Zhang fbloop = val & MP886X_V_BOOT; 12797be8288SJisheng Zhang if (fbloop) { 12897be8288SJisheng Zhang uv = rdev->desc->min_uV; 12997be8288SJisheng Zhang uv = mp8869_scale(uv, di->r[0], di->r[1]); 13097be8288SJisheng Zhang return regulator_map_voltage_linear(rdev, uv, uv); 13197be8288SJisheng Zhang } 13297be8288SJisheng Zhang 13397be8288SJisheng Zhang val &= rdev->desc->vsel_mask; 13497be8288SJisheng Zhang val >>= ffs(rdev->desc->vsel_mask) - 1; 13597be8288SJisheng Zhang 13697be8288SJisheng Zhang return val; 13797be8288SJisheng Zhang } 13897be8288SJisheng Zhang 13997be8288SJisheng Zhang static const struct regulator_ops mp8869_regulator_ops = { 14097be8288SJisheng Zhang .set_voltage_sel = mp8869_set_voltage_sel, 14197be8288SJisheng Zhang .get_voltage_sel = mp8869_get_voltage_sel, 14297be8288SJisheng Zhang .set_voltage_time_sel = regulator_set_voltage_time_sel, 14397be8288SJisheng Zhang .map_voltage = regulator_map_voltage_linear, 14497be8288SJisheng Zhang .list_voltage = regulator_list_voltage_linear, 14597be8288SJisheng Zhang .enable = regulator_enable_regmap, 14697be8288SJisheng Zhang .disable = regulator_disable_regmap, 14797be8288SJisheng Zhang .is_enabled = regulator_is_enabled_regmap, 14897be8288SJisheng Zhang .set_mode = mp886x_set_mode, 14997be8288SJisheng Zhang .get_mode = mp886x_get_mode, 150*e1e8d55bSAxel Lin .set_ramp_delay = regulator_set_ramp_delay_regmap, 1510eddcf02SJisheng Zhang }; 1520eddcf02SJisheng Zhang 1530eddcf02SJisheng Zhang static const struct mp886x_cfg_info mp8869_ci = { 1540eddcf02SJisheng Zhang .rops = &mp8869_regulator_ops, 1550eddcf02SJisheng Zhang .slew_rates = { 1560eddcf02SJisheng Zhang 40000, 1570eddcf02SJisheng Zhang 30000, 1580eddcf02SJisheng Zhang 20000, 1590eddcf02SJisheng Zhang 10000, 1600eddcf02SJisheng Zhang 5000, 1610eddcf02SJisheng Zhang 2500, 1620eddcf02SJisheng Zhang 1250, 1630eddcf02SJisheng Zhang 625, 1640eddcf02SJisheng Zhang }, 165ee6ad5a2SJisheng Zhang .switch_freq = { 166ee6ad5a2SJisheng Zhang 500000, 167ee6ad5a2SJisheng Zhang 750000, 168ee6ad5a2SJisheng Zhang 1000000, 169ee6ad5a2SJisheng Zhang 1250000, 170ee6ad5a2SJisheng Zhang }, 171ee6ad5a2SJisheng Zhang .fs_reg = MP8869_SYSCNTLREG2, 172ee6ad5a2SJisheng Zhang .fs_shift = 4, 17397be8288SJisheng Zhang }; 17497be8288SJisheng Zhang 175751ca3aaSJisheng Zhang static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) 176751ca3aaSJisheng Zhang { 177751ca3aaSJisheng Zhang struct mp886x_device_info *di = rdev_get_drvdata(rdev); 178751ca3aaSJisheng Zhang int ret, delta; 179751ca3aaSJisheng Zhang 180751ca3aaSJisheng Zhang ret = mp8869_set_voltage_sel(rdev, sel); 181751ca3aaSJisheng Zhang if (ret < 0) 182751ca3aaSJisheng Zhang return ret; 183751ca3aaSJisheng Zhang 184751ca3aaSJisheng Zhang delta = di->sel - sel; 185751ca3aaSJisheng Zhang if (abs(delta) <= 5) 186751ca3aaSJisheng Zhang ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 187751ca3aaSJisheng Zhang MP886X_GO, 0); 188751ca3aaSJisheng Zhang di->sel = sel; 189751ca3aaSJisheng Zhang 190751ca3aaSJisheng Zhang return ret; 191751ca3aaSJisheng Zhang } 192751ca3aaSJisheng Zhang 193751ca3aaSJisheng Zhang static int mp8867_get_voltage_sel(struct regulator_dev *rdev) 194751ca3aaSJisheng Zhang { 195751ca3aaSJisheng Zhang struct mp886x_device_info *di = rdev_get_drvdata(rdev); 196751ca3aaSJisheng Zhang int ret, uv; 197751ca3aaSJisheng Zhang unsigned int val; 198751ca3aaSJisheng Zhang bool fbloop; 199751ca3aaSJisheng Zhang 200751ca3aaSJisheng Zhang ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); 201751ca3aaSJisheng Zhang if (ret) 202751ca3aaSJisheng Zhang return ret; 203751ca3aaSJisheng Zhang 204751ca3aaSJisheng Zhang fbloop = val & MP886X_V_BOOT; 205751ca3aaSJisheng Zhang 206751ca3aaSJisheng Zhang val &= rdev->desc->vsel_mask; 207751ca3aaSJisheng Zhang val >>= ffs(rdev->desc->vsel_mask) - 1; 208751ca3aaSJisheng Zhang 209751ca3aaSJisheng Zhang if (fbloop) { 210751ca3aaSJisheng Zhang uv = regulator_list_voltage_linear(rdev, val); 211751ca3aaSJisheng Zhang uv = mp8869_scale(uv, di->r[0], di->r[1]); 212751ca3aaSJisheng Zhang return regulator_map_voltage_linear(rdev, uv, uv); 213751ca3aaSJisheng Zhang } 214751ca3aaSJisheng Zhang 215751ca3aaSJisheng Zhang return val; 216751ca3aaSJisheng Zhang } 217751ca3aaSJisheng Zhang 218751ca3aaSJisheng Zhang static const struct regulator_ops mp8867_regulator_ops = { 219751ca3aaSJisheng Zhang .set_voltage_sel = mp8867_set_voltage_sel, 220751ca3aaSJisheng Zhang .get_voltage_sel = mp8867_get_voltage_sel, 221751ca3aaSJisheng Zhang .set_voltage_time_sel = regulator_set_voltage_time_sel, 222751ca3aaSJisheng Zhang .map_voltage = regulator_map_voltage_linear, 223751ca3aaSJisheng Zhang .list_voltage = regulator_list_voltage_linear, 224751ca3aaSJisheng Zhang .enable = regulator_enable_regmap, 225751ca3aaSJisheng Zhang .disable = regulator_disable_regmap, 226751ca3aaSJisheng Zhang .is_enabled = regulator_is_enabled_regmap, 227751ca3aaSJisheng Zhang .set_mode = mp886x_set_mode, 228751ca3aaSJisheng Zhang .get_mode = mp886x_get_mode, 229*e1e8d55bSAxel Lin .set_ramp_delay = regulator_set_ramp_delay_regmap, 2300eddcf02SJisheng Zhang }; 2310eddcf02SJisheng Zhang 2320eddcf02SJisheng Zhang static const struct mp886x_cfg_info mp8867_ci = { 2330eddcf02SJisheng Zhang .rops = &mp8867_regulator_ops, 2340eddcf02SJisheng Zhang .slew_rates = { 2350eddcf02SJisheng Zhang 64000, 2360eddcf02SJisheng Zhang 32000, 2370eddcf02SJisheng Zhang 16000, 2380eddcf02SJisheng Zhang 8000, 2390eddcf02SJisheng Zhang 4000, 2400eddcf02SJisheng Zhang 2000, 2410eddcf02SJisheng Zhang 1000, 2420eddcf02SJisheng Zhang 500, 2430eddcf02SJisheng Zhang }, 244ee6ad5a2SJisheng Zhang .switch_freq = { 245ee6ad5a2SJisheng Zhang 500000, 246ee6ad5a2SJisheng Zhang 750000, 247ee6ad5a2SJisheng Zhang 1000000, 248ee6ad5a2SJisheng Zhang 1500000, 249ee6ad5a2SJisheng Zhang }, 250ee6ad5a2SJisheng Zhang .fs_reg = MP886X_SYSCNTLREG1, 251ee6ad5a2SJisheng Zhang .fs_shift = 1, 252751ca3aaSJisheng Zhang }; 253751ca3aaSJisheng Zhang 25497be8288SJisheng Zhang static int mp886x_regulator_register(struct mp886x_device_info *di, 25597be8288SJisheng Zhang struct regulator_config *config) 25697be8288SJisheng Zhang { 25797be8288SJisheng Zhang struct regulator_desc *rdesc = &di->desc; 25897be8288SJisheng Zhang struct regulator_dev *rdev; 25997be8288SJisheng Zhang 26097be8288SJisheng Zhang rdesc->name = "mp886x-reg"; 26197be8288SJisheng Zhang rdesc->supply_name = "vin"; 2620eddcf02SJisheng Zhang rdesc->ops = di->ci->rops; 26397be8288SJisheng Zhang rdesc->type = REGULATOR_VOLTAGE; 26497be8288SJisheng Zhang rdesc->n_voltages = 128; 26597be8288SJisheng Zhang rdesc->enable_reg = MP886X_SYSCNTLREG1; 26697be8288SJisheng Zhang rdesc->enable_mask = MP886X_EN; 26797be8288SJisheng Zhang rdesc->min_uV = 600000; 26897be8288SJisheng Zhang rdesc->uV_step = 10000; 26997be8288SJisheng Zhang rdesc->vsel_reg = MP886X_VSEL; 27097be8288SJisheng Zhang rdesc->vsel_mask = 0x3f; 271*e1e8d55bSAxel Lin rdesc->ramp_reg = MP886X_SYSCNTLREG1; 272*e1e8d55bSAxel Lin rdesc->ramp_mask = MP886X_SLEW_MASK; 273*e1e8d55bSAxel Lin rdesc->ramp_delay_table = di->ci->slew_rates; 274*e1e8d55bSAxel Lin rdesc->n_ramp_values = ARRAY_SIZE(di->ci->slew_rates); 27597be8288SJisheng Zhang rdesc->owner = THIS_MODULE; 27697be8288SJisheng Zhang 27797be8288SJisheng Zhang rdev = devm_regulator_register(di->dev, &di->desc, config); 27897be8288SJisheng Zhang if (IS_ERR(rdev)) 27997be8288SJisheng Zhang return PTR_ERR(rdev); 28097be8288SJisheng Zhang di->sel = rdesc->ops->get_voltage_sel(rdev); 28197be8288SJisheng Zhang return 0; 28297be8288SJisheng Zhang } 28397be8288SJisheng Zhang 28497be8288SJisheng Zhang static const struct regmap_config mp886x_regmap_config = { 28597be8288SJisheng Zhang .reg_bits = 8, 28697be8288SJisheng Zhang .val_bits = 8, 28797be8288SJisheng Zhang }; 28897be8288SJisheng Zhang 289e2c6678bSJisheng Zhang static int mp886x_i2c_probe(struct i2c_client *client) 29097be8288SJisheng Zhang { 29197be8288SJisheng Zhang struct device *dev = &client->dev; 29297be8288SJisheng Zhang struct device_node *np = dev->of_node; 29397be8288SJisheng Zhang struct mp886x_device_info *di; 29497be8288SJisheng Zhang struct regulator_config config = { }; 29597be8288SJisheng Zhang struct regmap *regmap; 296ee6ad5a2SJisheng Zhang u32 freq; 29797be8288SJisheng Zhang int ret; 29897be8288SJisheng Zhang 29997be8288SJisheng Zhang di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL); 30097be8288SJisheng Zhang if (!di) 30197be8288SJisheng Zhang return -ENOMEM; 30297be8288SJisheng Zhang 30397be8288SJisheng Zhang di->regulator = of_get_regulator_init_data(dev, np, &di->desc); 30497be8288SJisheng Zhang if (!di->regulator) { 30597be8288SJisheng Zhang dev_err(dev, "Platform data not found!\n"); 30697be8288SJisheng Zhang return -EINVAL; 30797be8288SJisheng Zhang } 30897be8288SJisheng Zhang 30997be8288SJisheng Zhang ret = of_property_read_u32_array(np, "mps,fb-voltage-divider", 31097be8288SJisheng Zhang di->r, 2); 31197be8288SJisheng Zhang if (ret) 31297be8288SJisheng Zhang return ret; 31397be8288SJisheng Zhang 31497be8288SJisheng Zhang di->en_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); 31597be8288SJisheng Zhang if (IS_ERR(di->en_gpio)) 31697be8288SJisheng Zhang return PTR_ERR(di->en_gpio); 31797be8288SJisheng Zhang 3180eddcf02SJisheng Zhang di->ci = of_device_get_match_data(dev); 31997be8288SJisheng Zhang di->dev = dev; 32097be8288SJisheng Zhang 32197be8288SJisheng Zhang regmap = devm_regmap_init_i2c(client, &mp886x_regmap_config); 32297be8288SJisheng Zhang if (IS_ERR(regmap)) { 32397be8288SJisheng Zhang dev_err(dev, "Failed to allocate regmap!\n"); 32497be8288SJisheng Zhang return PTR_ERR(regmap); 32597be8288SJisheng Zhang } 32697be8288SJisheng Zhang i2c_set_clientdata(client, di); 32797be8288SJisheng Zhang 32897be8288SJisheng Zhang config.dev = di->dev; 32997be8288SJisheng Zhang config.init_data = di->regulator; 33097be8288SJisheng Zhang config.regmap = regmap; 33197be8288SJisheng Zhang config.driver_data = di; 33297be8288SJisheng Zhang config.of_node = np; 33397be8288SJisheng Zhang 334a5f79495SJisheng Zhang if (!of_property_read_u32(np, "mps,switch-frequency-hz", &freq)) 335ee6ad5a2SJisheng Zhang mp886x_set_switch_freq(di, regmap, freq); 336ee6ad5a2SJisheng Zhang 33797be8288SJisheng Zhang ret = mp886x_regulator_register(di, &config); 33897be8288SJisheng Zhang if (ret < 0) 33997be8288SJisheng Zhang dev_err(dev, "Failed to register regulator!\n"); 34097be8288SJisheng Zhang return ret; 34197be8288SJisheng Zhang } 34297be8288SJisheng Zhang 34397be8288SJisheng Zhang static const struct of_device_id mp886x_dt_ids[] = { 34497be8288SJisheng Zhang { 345751ca3aaSJisheng Zhang .compatible = "mps,mp8867", 3460eddcf02SJisheng Zhang .data = &mp8867_ci 347751ca3aaSJisheng Zhang }, 348751ca3aaSJisheng Zhang { 34997be8288SJisheng Zhang .compatible = "mps,mp8869", 3500eddcf02SJisheng Zhang .data = &mp8869_ci 35197be8288SJisheng Zhang }, 35297be8288SJisheng Zhang { } 35397be8288SJisheng Zhang }; 35497be8288SJisheng Zhang MODULE_DEVICE_TABLE(of, mp886x_dt_ids); 35597be8288SJisheng Zhang 35697be8288SJisheng Zhang static const struct i2c_device_id mp886x_id[] = { 35797be8288SJisheng Zhang { "mp886x", }, 35897be8288SJisheng Zhang { }, 35997be8288SJisheng Zhang }; 36097be8288SJisheng Zhang MODULE_DEVICE_TABLE(i2c, mp886x_id); 36197be8288SJisheng Zhang 36297be8288SJisheng Zhang static struct i2c_driver mp886x_regulator_driver = { 36397be8288SJisheng Zhang .driver = { 36497be8288SJisheng Zhang .name = "mp886x-regulator", 36597be8288SJisheng Zhang .of_match_table = of_match_ptr(mp886x_dt_ids), 36697be8288SJisheng Zhang }, 367e2c6678bSJisheng Zhang .probe_new = mp886x_i2c_probe, 36897be8288SJisheng Zhang .id_table = mp886x_id, 36997be8288SJisheng Zhang }; 37097be8288SJisheng Zhang module_i2c_driver(mp886x_regulator_driver); 37197be8288SJisheng Zhang 37297be8288SJisheng Zhang MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>"); 37397be8288SJisheng Zhang MODULE_DESCRIPTION("MP886x regulator driver"); 37497be8288SJisheng Zhang MODULE_LICENSE("GPL v2"); 375