1 /* 2 * Regulator support for WM8400 3 * 4 * Copyright 2008 Wolfson Microelectronics PLC. 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of the 11 * License, or (at your option) any later version. 12 * 13 */ 14 15 #include <linux/bug.h> 16 #include <linux/err.h> 17 #include <linux/kernel.h> 18 #include <linux/regulator/driver.h> 19 #include <linux/mfd/wm8400-private.h> 20 21 static int wm8400_ldo_is_enabled(struct regulator_dev *dev) 22 { 23 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 24 u16 val; 25 26 val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); 27 return (val & WM8400_LDO1_ENA) != 0; 28 } 29 30 static int wm8400_ldo_enable(struct regulator_dev *dev) 31 { 32 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 33 34 return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), 35 WM8400_LDO1_ENA, WM8400_LDO1_ENA); 36 } 37 38 static int wm8400_ldo_disable(struct regulator_dev *dev) 39 { 40 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 41 42 return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), 43 WM8400_LDO1_ENA, 0); 44 } 45 46 static int wm8400_ldo_list_voltage(struct regulator_dev *dev, 47 unsigned selector) 48 { 49 if (selector > WM8400_LDO1_VSEL_MASK) 50 return -EINVAL; 51 52 if (selector < 15) 53 return 900000 + (selector * 50000); 54 else 55 return 1600000 + ((selector - 14) * 100000); 56 } 57 58 static int wm8400_ldo_get_voltage_sel(struct regulator_dev *dev) 59 { 60 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 61 u16 val; 62 63 val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); 64 val &= WM8400_LDO1_VSEL_MASK; 65 66 return val; 67 } 68 69 static int wm8400_ldo_set_voltage(struct regulator_dev *dev, 70 int min_uV, int max_uV, unsigned *selector) 71 { 72 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 73 u16 val; 74 75 if (min_uV < 900000 || min_uV > 3300000) 76 return -EINVAL; 77 78 if (min_uV < 1700000) { 79 /* Steps of 50mV from 900mV; */ 80 val = (min_uV - 850001) / 50000; 81 82 if ((val * 50000) + 900000 > max_uV) 83 return -EINVAL; 84 BUG_ON((val * 50000) + 900000 < min_uV); 85 } else { 86 /* Steps of 100mV from 1700mV */ 87 val = ((min_uV - 1600001) / 100000); 88 89 if ((val * 100000) + 1700000 > max_uV) 90 return -EINVAL; 91 BUG_ON((val * 100000) + 1700000 < min_uV); 92 93 val += 0xf; 94 } 95 96 *selector = val; 97 98 return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), 99 WM8400_LDO1_VSEL_MASK, val); 100 } 101 102 static struct regulator_ops wm8400_ldo_ops = { 103 .is_enabled = wm8400_ldo_is_enabled, 104 .enable = wm8400_ldo_enable, 105 .disable = wm8400_ldo_disable, 106 .list_voltage = wm8400_ldo_list_voltage, 107 .get_voltage_sel = wm8400_ldo_get_voltage_sel, 108 .set_voltage = wm8400_ldo_set_voltage, 109 }; 110 111 static int wm8400_dcdc_is_enabled(struct regulator_dev *dev) 112 { 113 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 114 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 115 u16 val; 116 117 val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); 118 return (val & WM8400_DC1_ENA) != 0; 119 } 120 121 static int wm8400_dcdc_enable(struct regulator_dev *dev) 122 { 123 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 124 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 125 126 return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 127 WM8400_DC1_ENA, WM8400_DC1_ENA); 128 } 129 130 static int wm8400_dcdc_disable(struct regulator_dev *dev) 131 { 132 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 133 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 134 135 return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 136 WM8400_DC1_ENA, 0); 137 } 138 139 static int wm8400_dcdc_list_voltage(struct regulator_dev *dev, 140 unsigned selector) 141 { 142 if (selector > WM8400_DC1_VSEL_MASK) 143 return -EINVAL; 144 145 return 850000 + (selector * 25000); 146 } 147 148 static int wm8400_dcdc_get_voltage_sel(struct regulator_dev *dev) 149 { 150 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 151 u16 val; 152 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 153 154 val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); 155 val &= WM8400_DC1_VSEL_MASK; 156 157 return val; 158 } 159 160 static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, 161 int min_uV, int max_uV, unsigned *selector) 162 { 163 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 164 u16 val; 165 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 166 167 if (min_uV < 850000) 168 return -EINVAL; 169 170 val = (min_uV - 825001) / 25000; 171 172 if (850000 + (25000 * val) > max_uV) 173 return -EINVAL; 174 BUG_ON(850000 + (25000 * val) < min_uV); 175 176 *selector = val; 177 178 return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 179 WM8400_DC1_VSEL_MASK, val); 180 } 181 182 static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) 183 { 184 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 185 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 186 u16 data[2]; 187 int ret; 188 189 ret = wm8400_block_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 2, 190 data); 191 if (ret != 0) 192 return 0; 193 194 /* Datasheet: hibernate */ 195 if (data[0] & WM8400_DC1_SLEEP) 196 return REGULATOR_MODE_STANDBY; 197 198 /* Datasheet: standby */ 199 if (!(data[0] & WM8400_DC1_ACTIVE)) 200 return REGULATOR_MODE_IDLE; 201 202 /* Datasheet: active with or without force PWM */ 203 if (data[1] & WM8400_DC1_FRC_PWM) 204 return REGULATOR_MODE_FAST; 205 else 206 return REGULATOR_MODE_NORMAL; 207 } 208 209 static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode) 210 { 211 struct wm8400 *wm8400 = rdev_get_drvdata(dev); 212 int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; 213 int ret; 214 215 switch (mode) { 216 case REGULATOR_MODE_FAST: 217 /* Datasheet: active with force PWM */ 218 ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, 219 WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM); 220 if (ret != 0) 221 return ret; 222 223 return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 224 WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 225 WM8400_DC1_ACTIVE); 226 227 case REGULATOR_MODE_NORMAL: 228 /* Datasheet: active */ 229 ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, 230 WM8400_DC1_FRC_PWM, 0); 231 if (ret != 0) 232 return ret; 233 234 return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 235 WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 236 WM8400_DC1_ACTIVE); 237 238 case REGULATOR_MODE_IDLE: 239 /* Datasheet: standby */ 240 ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 241 WM8400_DC1_ACTIVE, 0); 242 if (ret != 0) 243 return ret; 244 return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 245 WM8400_DC1_SLEEP, 0); 246 247 default: 248 return -EINVAL; 249 } 250 } 251 252 static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev, 253 int input_uV, int output_uV, 254 int load_uA) 255 { 256 return REGULATOR_MODE_NORMAL; 257 } 258 259 static struct regulator_ops wm8400_dcdc_ops = { 260 .is_enabled = wm8400_dcdc_is_enabled, 261 .enable = wm8400_dcdc_enable, 262 .disable = wm8400_dcdc_disable, 263 .list_voltage = wm8400_dcdc_list_voltage, 264 .get_voltage_sel = wm8400_dcdc_get_voltage_sel, 265 .set_voltage = wm8400_dcdc_set_voltage, 266 .get_mode = wm8400_dcdc_get_mode, 267 .set_mode = wm8400_dcdc_set_mode, 268 .get_optimum_mode = wm8400_dcdc_get_optimum_mode, 269 }; 270 271 static struct regulator_desc regulators[] = { 272 { 273 .name = "LDO1", 274 .id = WM8400_LDO1, 275 .ops = &wm8400_ldo_ops, 276 .n_voltages = WM8400_LDO1_VSEL_MASK + 1, 277 .type = REGULATOR_VOLTAGE, 278 .owner = THIS_MODULE, 279 }, 280 { 281 .name = "LDO2", 282 .id = WM8400_LDO2, 283 .ops = &wm8400_ldo_ops, 284 .n_voltages = WM8400_LDO2_VSEL_MASK + 1, 285 .type = REGULATOR_VOLTAGE, 286 .owner = THIS_MODULE, 287 }, 288 { 289 .name = "LDO3", 290 .id = WM8400_LDO3, 291 .ops = &wm8400_ldo_ops, 292 .n_voltages = WM8400_LDO3_VSEL_MASK + 1, 293 .type = REGULATOR_VOLTAGE, 294 .owner = THIS_MODULE, 295 }, 296 { 297 .name = "LDO4", 298 .id = WM8400_LDO4, 299 .ops = &wm8400_ldo_ops, 300 .n_voltages = WM8400_LDO4_VSEL_MASK + 1, 301 .type = REGULATOR_VOLTAGE, 302 .owner = THIS_MODULE, 303 }, 304 { 305 .name = "DCDC1", 306 .id = WM8400_DCDC1, 307 .ops = &wm8400_dcdc_ops, 308 .n_voltages = WM8400_DC1_VSEL_MASK + 1, 309 .type = REGULATOR_VOLTAGE, 310 .owner = THIS_MODULE, 311 }, 312 { 313 .name = "DCDC2", 314 .id = WM8400_DCDC2, 315 .ops = &wm8400_dcdc_ops, 316 .n_voltages = WM8400_DC2_VSEL_MASK + 1, 317 .type = REGULATOR_VOLTAGE, 318 .owner = THIS_MODULE, 319 }, 320 }; 321 322 static int __devinit wm8400_regulator_probe(struct platform_device *pdev) 323 { 324 struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]); 325 struct regulator_dev *rdev; 326 327 rdev = regulator_register(®ulators[pdev->id], &pdev->dev, 328 pdev->dev.platform_data, wm8400); 329 330 if (IS_ERR(rdev)) 331 return PTR_ERR(rdev); 332 333 platform_set_drvdata(pdev, rdev); 334 335 return 0; 336 } 337 338 static int __devexit wm8400_regulator_remove(struct platform_device *pdev) 339 { 340 struct regulator_dev *rdev = platform_get_drvdata(pdev); 341 342 platform_set_drvdata(pdev, NULL); 343 regulator_unregister(rdev); 344 345 return 0; 346 } 347 348 static struct platform_driver wm8400_regulator_driver = { 349 .driver = { 350 .name = "wm8400-regulator", 351 }, 352 .probe = wm8400_regulator_probe, 353 .remove = __devexit_p(wm8400_regulator_remove), 354 }; 355 356 /** 357 * wm8400_register_regulator - enable software control of a WM8400 regulator 358 * 359 * This function enables software control of a WM8400 regulator via 360 * the regulator API. It is intended to be called from the 361 * platform_init() callback of the WM8400 MFD driver. 362 * 363 * @param dev The WM8400 device to operate on. 364 * @param reg The regulator to control. 365 * @param initdata Regulator initdata for the regulator. 366 */ 367 int wm8400_register_regulator(struct device *dev, int reg, 368 struct regulator_init_data *initdata) 369 { 370 struct wm8400 *wm8400 = dev_get_drvdata(dev); 371 372 if (wm8400->regulators[reg].name) 373 return -EBUSY; 374 375 initdata->driver_data = wm8400; 376 377 wm8400->regulators[reg].name = "wm8400-regulator"; 378 wm8400->regulators[reg].id = reg; 379 wm8400->regulators[reg].dev.parent = dev; 380 wm8400->regulators[reg].dev.platform_data = initdata; 381 382 return platform_device_register(&wm8400->regulators[reg]); 383 } 384 EXPORT_SYMBOL_GPL(wm8400_register_regulator); 385 386 static int __init wm8400_regulator_init(void) 387 { 388 return platform_driver_register(&wm8400_regulator_driver); 389 } 390 subsys_initcall(wm8400_regulator_init); 391 392 static void __exit wm8400_regulator_exit(void) 393 { 394 platform_driver_unregister(&wm8400_regulator_driver); 395 } 396 module_exit(wm8400_regulator_exit); 397 398 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 399 MODULE_DESCRIPTION("WM8400 regulator driver"); 400 MODULE_LICENSE("GPL"); 401 MODULE_ALIAS("platform:wm8400-regulator"); 402