1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // MP8867/MP8869 regulator driver 4 // 5 // Copyright (C) 2020 Synaptics Incorporated 6 // 7 // Author: Jisheng Zhang <jszhang@kernel.org> 8 9 #include <linux/gpio/consumer.h> 10 #include <linux/i2c.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <linux/regmap.h> 14 #include <linux/regulator/driver.h> 15 #include <linux/regulator/of_regulator.h> 16 17 #define MP886X_VSEL 0x00 18 #define MP886X_V_BOOT (1 << 7) 19 #define MP886X_SYSCNTLREG1 0x01 20 #define MP886X_MODE (1 << 0) 21 #define MP886X_SLEW_SHIFT 3 22 #define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT) 23 #define MP886X_GO (1 << 6) 24 #define MP886X_EN (1 << 7) 25 #define MP8869_SYSCNTLREG2 0x02 26 27 struct mp886x_cfg_info { 28 const struct regulator_ops *rops; 29 const int slew_rates[8]; 30 const int switch_freq[4]; 31 const u8 fs_reg; 32 const u8 fs_shift; 33 }; 34 35 struct mp886x_device_info { 36 struct device *dev; 37 struct regulator_desc desc; 38 struct regulator_init_data *regulator; 39 struct gpio_desc *en_gpio; 40 const struct mp886x_cfg_info *ci; 41 u32 r[2]; 42 unsigned int sel; 43 }; 44 45 static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp) 46 { 47 struct mp886x_device_info *di = rdev_get_drvdata(rdev); 48 const struct mp886x_cfg_info *ci = di->ci; 49 int reg = -1, i; 50 51 for (i = 0; i < ARRAY_SIZE(ci->slew_rates); i++) { 52 if (ramp <= ci->slew_rates[i]) 53 reg = i; 54 else 55 break; 56 } 57 58 if (reg < 0) { 59 dev_err(di->dev, "unsupported ramp value %d\n", ramp); 60 return -EINVAL; 61 } 62 63 return regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 64 MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT); 65 } 66 67 static void mp886x_set_switch_freq(struct mp886x_device_info *di, 68 struct regmap *regmap, 69 u32 freq) 70 { 71 const struct mp886x_cfg_info *ci = di->ci; 72 int i; 73 74 for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) { 75 if (freq == ci->switch_freq[i]) { 76 regmap_update_bits(regmap, ci->fs_reg, 77 0x3 << ci->fs_shift, i << ci->fs_shift); 78 return; 79 } 80 } 81 82 dev_err(di->dev, "invalid frequency %d\n", freq); 83 } 84 85 static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode) 86 { 87 switch (mode) { 88 case REGULATOR_MODE_FAST: 89 regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 90 MP886X_MODE, MP886X_MODE); 91 break; 92 case REGULATOR_MODE_NORMAL: 93 regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 94 MP886X_MODE, 0); 95 break; 96 default: 97 return -EINVAL; 98 } 99 return 0; 100 } 101 102 static unsigned int mp886x_get_mode(struct regulator_dev *rdev) 103 { 104 u32 val; 105 int ret; 106 107 ret = regmap_read(rdev->regmap, MP886X_SYSCNTLREG1, &val); 108 if (ret < 0) 109 return ret; 110 if (val & MP886X_MODE) 111 return REGULATOR_MODE_FAST; 112 else 113 return REGULATOR_MODE_NORMAL; 114 } 115 116 static int mp8869_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) 117 { 118 int ret; 119 120 ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 121 MP886X_GO, MP886X_GO); 122 if (ret < 0) 123 return ret; 124 125 sel <<= ffs(rdev->desc->vsel_mask) - 1; 126 return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, 127 MP886X_V_BOOT | rdev->desc->vsel_mask, sel); 128 } 129 130 static inline unsigned int mp8869_scale(unsigned int uv, u32 r1, u32 r2) 131 { 132 u32 tmp = uv * r1 / r2; 133 134 return uv + tmp; 135 } 136 137 static int mp8869_get_voltage_sel(struct regulator_dev *rdev) 138 { 139 struct mp886x_device_info *di = rdev_get_drvdata(rdev); 140 int ret, uv; 141 unsigned int val; 142 bool fbloop; 143 144 ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); 145 if (ret) 146 return ret; 147 148 fbloop = val & MP886X_V_BOOT; 149 if (fbloop) { 150 uv = rdev->desc->min_uV; 151 uv = mp8869_scale(uv, di->r[0], di->r[1]); 152 return regulator_map_voltage_linear(rdev, uv, uv); 153 } 154 155 val &= rdev->desc->vsel_mask; 156 val >>= ffs(rdev->desc->vsel_mask) - 1; 157 158 return val; 159 } 160 161 static const struct regulator_ops mp8869_regulator_ops = { 162 .set_voltage_sel = mp8869_set_voltage_sel, 163 .get_voltage_sel = mp8869_get_voltage_sel, 164 .set_voltage_time_sel = regulator_set_voltage_time_sel, 165 .map_voltage = regulator_map_voltage_linear, 166 .list_voltage = regulator_list_voltage_linear, 167 .enable = regulator_enable_regmap, 168 .disable = regulator_disable_regmap, 169 .is_enabled = regulator_is_enabled_regmap, 170 .set_mode = mp886x_set_mode, 171 .get_mode = mp886x_get_mode, 172 .set_ramp_delay = mp886x_set_ramp, 173 }; 174 175 static const struct mp886x_cfg_info mp8869_ci = { 176 .rops = &mp8869_regulator_ops, 177 .slew_rates = { 178 40000, 179 30000, 180 20000, 181 10000, 182 5000, 183 2500, 184 1250, 185 625, 186 }, 187 .switch_freq = { 188 500000, 189 750000, 190 1000000, 191 1250000, 192 }, 193 .fs_reg = MP8869_SYSCNTLREG2, 194 .fs_shift = 4, 195 }; 196 197 static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) 198 { 199 struct mp886x_device_info *di = rdev_get_drvdata(rdev); 200 int ret, delta; 201 202 ret = mp8869_set_voltage_sel(rdev, sel); 203 if (ret < 0) 204 return ret; 205 206 delta = di->sel - sel; 207 if (abs(delta) <= 5) 208 ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, 209 MP886X_GO, 0); 210 di->sel = sel; 211 212 return ret; 213 } 214 215 static int mp8867_get_voltage_sel(struct regulator_dev *rdev) 216 { 217 struct mp886x_device_info *di = rdev_get_drvdata(rdev); 218 int ret, uv; 219 unsigned int val; 220 bool fbloop; 221 222 ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); 223 if (ret) 224 return ret; 225 226 fbloop = val & MP886X_V_BOOT; 227 228 val &= rdev->desc->vsel_mask; 229 val >>= ffs(rdev->desc->vsel_mask) - 1; 230 231 if (fbloop) { 232 uv = regulator_list_voltage_linear(rdev, val); 233 uv = mp8869_scale(uv, di->r[0], di->r[1]); 234 return regulator_map_voltage_linear(rdev, uv, uv); 235 } 236 237 return val; 238 } 239 240 static const struct regulator_ops mp8867_regulator_ops = { 241 .set_voltage_sel = mp8867_set_voltage_sel, 242 .get_voltage_sel = mp8867_get_voltage_sel, 243 .set_voltage_time_sel = regulator_set_voltage_time_sel, 244 .map_voltage = regulator_map_voltage_linear, 245 .list_voltage = regulator_list_voltage_linear, 246 .enable = regulator_enable_regmap, 247 .disable = regulator_disable_regmap, 248 .is_enabled = regulator_is_enabled_regmap, 249 .set_mode = mp886x_set_mode, 250 .get_mode = mp886x_get_mode, 251 .set_ramp_delay = mp886x_set_ramp, 252 }; 253 254 static const struct mp886x_cfg_info mp8867_ci = { 255 .rops = &mp8867_regulator_ops, 256 .slew_rates = { 257 64000, 258 32000, 259 16000, 260 8000, 261 4000, 262 2000, 263 1000, 264 500, 265 }, 266 .switch_freq = { 267 500000, 268 750000, 269 1000000, 270 1500000, 271 }, 272 .fs_reg = MP886X_SYSCNTLREG1, 273 .fs_shift = 1, 274 }; 275 276 static int mp886x_regulator_register(struct mp886x_device_info *di, 277 struct regulator_config *config) 278 { 279 struct regulator_desc *rdesc = &di->desc; 280 struct regulator_dev *rdev; 281 282 rdesc->name = "mp886x-reg"; 283 rdesc->supply_name = "vin"; 284 rdesc->ops = di->ci->rops; 285 rdesc->type = REGULATOR_VOLTAGE; 286 rdesc->n_voltages = 128; 287 rdesc->enable_reg = MP886X_SYSCNTLREG1; 288 rdesc->enable_mask = MP886X_EN; 289 rdesc->min_uV = 600000; 290 rdesc->uV_step = 10000; 291 rdesc->vsel_reg = MP886X_VSEL; 292 rdesc->vsel_mask = 0x3f; 293 rdesc->owner = THIS_MODULE; 294 295 rdev = devm_regulator_register(di->dev, &di->desc, config); 296 if (IS_ERR(rdev)) 297 return PTR_ERR(rdev); 298 di->sel = rdesc->ops->get_voltage_sel(rdev); 299 return 0; 300 } 301 302 static const struct regmap_config mp886x_regmap_config = { 303 .reg_bits = 8, 304 .val_bits = 8, 305 }; 306 307 static int mp886x_i2c_probe(struct i2c_client *client) 308 { 309 struct device *dev = &client->dev; 310 struct device_node *np = dev->of_node; 311 struct mp886x_device_info *di; 312 struct regulator_config config = { }; 313 struct regmap *regmap; 314 u32 freq; 315 int ret; 316 317 di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL); 318 if (!di) 319 return -ENOMEM; 320 321 di->regulator = of_get_regulator_init_data(dev, np, &di->desc); 322 if (!di->regulator) { 323 dev_err(dev, "Platform data not found!\n"); 324 return -EINVAL; 325 } 326 327 ret = of_property_read_u32_array(np, "mps,fb-voltage-divider", 328 di->r, 2); 329 if (ret) 330 return ret; 331 332 di->en_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); 333 if (IS_ERR(di->en_gpio)) 334 return PTR_ERR(di->en_gpio); 335 336 di->ci = of_device_get_match_data(dev); 337 di->dev = dev; 338 339 regmap = devm_regmap_init_i2c(client, &mp886x_regmap_config); 340 if (IS_ERR(regmap)) { 341 dev_err(dev, "Failed to allocate regmap!\n"); 342 return PTR_ERR(regmap); 343 } 344 i2c_set_clientdata(client, di); 345 346 config.dev = di->dev; 347 config.init_data = di->regulator; 348 config.regmap = regmap; 349 config.driver_data = di; 350 config.of_node = np; 351 352 if (!of_property_read_u32(np, "mps,switch-frequency-hz", &freq)) 353 mp886x_set_switch_freq(di, regmap, freq); 354 355 ret = mp886x_regulator_register(di, &config); 356 if (ret < 0) 357 dev_err(dev, "Failed to register regulator!\n"); 358 return ret; 359 } 360 361 static const struct of_device_id mp886x_dt_ids[] = { 362 { 363 .compatible = "mps,mp8867", 364 .data = &mp8867_ci 365 }, 366 { 367 .compatible = "mps,mp8869", 368 .data = &mp8869_ci 369 }, 370 { } 371 }; 372 MODULE_DEVICE_TABLE(of, mp886x_dt_ids); 373 374 static const struct i2c_device_id mp886x_id[] = { 375 { "mp886x", }, 376 { }, 377 }; 378 MODULE_DEVICE_TABLE(i2c, mp886x_id); 379 380 static struct i2c_driver mp886x_regulator_driver = { 381 .driver = { 382 .name = "mp886x-regulator", 383 .of_match_table = of_match_ptr(mp886x_dt_ids), 384 }, 385 .probe_new = mp886x_i2c_probe, 386 .id_table = mp886x_id, 387 }; 388 module_i2c_driver(mp886x_regulator_driver); 389 390 MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>"); 391 MODULE_DESCRIPTION("MP886x regulator driver"); 392 MODULE_LICENSE("GPL v2"); 393