Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: add new regulator driver for lp872x

This driver supports TI/National LP8720, LP8725 PMIC.

Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Reviewed-by: Axel Lin <axel.lin@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Kim, Milo and committed by
Mark Brown
af8b5fc3 e90a8447

+1055
+7
drivers/regulator/Kconfig
··· 224 224 Say Y here to support the voltage regulators and convertors 225 225 on National Semiconductors LP3972 PMIC 226 226 227 + config REGULATOR_LP872X 228 + tristate "TI/National Semiconductor LP8720/LP8725 voltage regulators" 229 + depends on I2C 230 + select REGMAP_I2C 231 + help 232 + This driver supports LP8720/LP8725 PMIC 233 + 227 234 config REGULATOR_PCF50633 228 235 tristate "NXP PCF50633 regulator driver" 229 236 depends on MFD_PCF50633
+1
drivers/regulator/Makefile
··· 23 23 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o 24 24 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o 25 25 obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o 26 + obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o 26 27 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o 27 28 obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o 28 29 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
+957
drivers/regulator/lp872x.c
··· 1 + /* 2 + * Copyright 2012 Texas Instruments 3 + * 4 + * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/slab.h> 14 + #include <linux/i2c.h> 15 + #include <linux/regmap.h> 16 + #include <linux/err.h> 17 + #include <linux/gpio.h> 18 + #include <linux/regulator/lp872x.h> 19 + #include <linux/regulator/driver.h> 20 + #include <linux/platform_device.h> 21 + 22 + /* Registers : LP8720/8725 shared */ 23 + #define LP872X_GENERAL_CFG 0x00 24 + #define LP872X_LDO1_VOUT 0x01 25 + #define LP872X_LDO2_VOUT 0x02 26 + #define LP872X_LDO3_VOUT 0x03 27 + #define LP872X_LDO4_VOUT 0x04 28 + #define LP872X_LDO5_VOUT 0x05 29 + 30 + /* Registers : LP8720 */ 31 + #define LP8720_BUCK_VOUT1 0x06 32 + #define LP8720_BUCK_VOUT2 0x07 33 + #define LP8720_ENABLE 0x08 34 + 35 + /* Registers : LP8725 */ 36 + #define LP8725_LILO1_VOUT 0x06 37 + #define LP8725_LILO2_VOUT 0x07 38 + #define LP8725_BUCK1_VOUT1 0x08 39 + #define LP8725_BUCK1_VOUT2 0x09 40 + #define LP8725_BUCK2_VOUT1 0x0A 41 + #define LP8725_BUCK2_VOUT2 0x0B 42 + #define LP8725_BUCK_CTRL 0x0C 43 + #define LP8725_LDO_CTRL 0x0D 44 + 45 + /* Mask/shift : LP8720/LP8725 shared */ 46 + #define LP872X_VOUT_M 0x1F 47 + #define LP872X_START_DELAY_M 0xE0 48 + #define LP872X_START_DELAY_S 5 49 + #define LP872X_EN_LDO1_M BIT(0) 50 + #define LP872X_EN_LDO2_M BIT(1) 51 + #define LP872X_EN_LDO3_M BIT(2) 52 + #define LP872X_EN_LDO4_M BIT(3) 53 + #define LP872X_EN_LDO5_M BIT(4) 54 + 55 + /* Mask/shift : LP8720 */ 56 + #define LP8720_TIMESTEP_S 0 /* Addr 00h */ 57 + #define LP8720_TIMESTEP_M BIT(0) 58 + #define LP8720_EXT_DVS_M BIT(2) 59 + #define LP8720_BUCK_FPWM_S 5 /* Addr 07h */ 60 + #define LP8720_BUCK_FPWM_M BIT(5) 61 + #define LP8720_EN_BUCK_M BIT(5) /* Addr 08h */ 62 + #define LP8720_DVS_SEL_M BIT(7) 63 + 64 + /* Mask/shift : LP8725 */ 65 + #define LP8725_TIMESTEP_M 0xC0 /* Addr 00h */ 66 + #define LP8725_TIMESTEP_S 6 67 + #define LP8725_BUCK1_EN_M BIT(0) 68 + #define LP8725_DVS1_M BIT(2) 69 + #define LP8725_DVS2_M BIT(3) 70 + #define LP8725_BUCK2_EN_M BIT(4) 71 + #define LP8725_BUCK_CL_M 0xC0 /* Addr 09h, 0Bh */ 72 + #define LP8725_BUCK_CL_S 6 73 + #define LP8725_BUCK1_FPWM_S 1 /* Addr 0Ch */ 74 + #define LP8725_BUCK1_FPWM_M BIT(1) 75 + #define LP8725_BUCK2_FPWM_S 5 76 + #define LP8725_BUCK2_FPWM_M BIT(5) 77 + #define LP8725_EN_LILO1_M BIT(5) /* Addr 0Dh */ 78 + #define LP8725_EN_LILO2_M BIT(6) 79 + 80 + /* PWM mode */ 81 + #define LP872X_FORCE_PWM 1 82 + #define LP872X_AUTO_PWM 0 83 + 84 + #define LP8720_NUM_REGULATORS 6 85 + #define LP8725_NUM_REGULATORS 9 86 + #define EXTERN_DVS_USED 0 87 + #define MAX_DELAY 6 88 + 89 + /* dump registers in regmap-debugfs */ 90 + #define MAX_REGISTERS 0x0F 91 + 92 + enum lp872x_id { 93 + LP8720, 94 + LP8725, 95 + }; 96 + 97 + struct lp872x { 98 + struct regmap *regmap; 99 + struct device *dev; 100 + enum lp872x_id chipid; 101 + struct lp872x_platform_data *pdata; 102 + struct regulator_dev **regulators; 103 + int num_regulators; 104 + enum lp872x_dvs_state dvs_pin; 105 + int dvs_gpio; 106 + }; 107 + 108 + /* LP8720/LP8725 shared voltage table for LDOs */ 109 + static const unsigned int lp872x_ldo_vtbl[] = { 110 + 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000, 111 + 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 2000000, 112 + 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2650000, 2700000, 113 + 2750000, 2800000, 2850000, 2900000, 2950000, 3000000, 3100000, 3300000, 114 + }; 115 + 116 + /* LP8720 LDO4 voltage table */ 117 + static const unsigned int lp8720_ldo4_vtbl[] = { 118 + 800000, 850000, 900000, 1000000, 1100000, 1200000, 1250000, 1300000, 119 + 1350000, 1400000, 1450000, 1500000, 1550000, 1600000, 1650000, 1700000, 120 + 1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000, 121 + 2400000, 2500000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, 122 + }; 123 + 124 + /* LP8725 LILO(Low Input Low Output) voltage table */ 125 + static const unsigned int lp8725_lilo_vtbl[] = { 126 + 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, 127 + 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000, 128 + 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 129 + 2600000, 2700000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000, 130 + }; 131 + 132 + /* LP8720 BUCK voltage table */ 133 + #define EXT_R 0 /* external resistor divider */ 134 + static const unsigned int lp8720_buck_vtbl[] = { 135 + EXT_R, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 136 + 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 137 + 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 138 + 1950000, 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 139 + }; 140 + 141 + /* LP8725 BUCK voltage table */ 142 + static const unsigned int lp8725_buck_vtbl[] = { 143 + 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, 144 + 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000, 145 + 1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000, 146 + 2400000, 2500000, 2600000, 2700000, 2800000, 2850000, 2900000, 3000000, 147 + }; 148 + 149 + /* LP8725 BUCK current limit */ 150 + static const unsigned int lp8725_buck_uA[] = { 151 + 460000, 780000, 1050000, 1370000, 152 + }; 153 + 154 + static int lp872x_read_byte(struct lp872x *lp, u8 addr, u8 *data) 155 + { 156 + int ret; 157 + unsigned int val; 158 + 159 + ret = regmap_read(lp->regmap, addr, &val); 160 + if (ret < 0) { 161 + dev_err(lp->dev, "failed to read 0x%.2x\n", addr); 162 + return ret; 163 + } 164 + 165 + *data = (u8)val; 166 + return 0; 167 + } 168 + 169 + static inline int lp872x_write_byte(struct lp872x *lp, u8 addr, u8 data) 170 + { 171 + return regmap_write(lp->regmap, addr, data); 172 + } 173 + 174 + static inline int lp872x_update_bits(struct lp872x *lp, u8 addr, 175 + unsigned int mask, u8 data) 176 + { 177 + return regmap_update_bits(lp->regmap, addr, mask, data); 178 + } 179 + 180 + static int _rdev_to_offset(struct regulator_dev *rdev) 181 + { 182 + enum lp872x_regulator_id id = rdev_get_id(rdev); 183 + 184 + switch (id) { 185 + case LP8720_ID_LDO1 ... LP8720_ID_BUCK: 186 + return id; 187 + case LP8725_ID_LDO1 ... LP8725_ID_BUCK2: 188 + return id - LP8725_ID_BASE; 189 + default: 190 + return -EINVAL; 191 + } 192 + } 193 + 194 + static int lp872x_get_timestep_usec(struct lp872x *lp) 195 + { 196 + enum lp872x_id chip = lp->chipid; 197 + u8 val, mask, shift; 198 + int *time_usec, size, ret; 199 + int lp8720_time_usec[] = { 25, 50 }; 200 + int lp8725_time_usec[] = { 32, 64, 128, 256 }; 201 + 202 + switch (chip) { 203 + case LP8720: 204 + mask = LP8720_TIMESTEP_M; 205 + shift = LP8720_TIMESTEP_S; 206 + time_usec = &lp8720_time_usec[0]; 207 + size = ARRAY_SIZE(lp8720_time_usec); 208 + break; 209 + case LP8725: 210 + mask = LP8725_TIMESTEP_M; 211 + shift = LP8725_TIMESTEP_S; 212 + time_usec = &lp8725_time_usec[0]; 213 + size = ARRAY_SIZE(lp8725_time_usec); 214 + break; 215 + default: 216 + return -EINVAL; 217 + } 218 + 219 + ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); 220 + if (ret) 221 + return -EINVAL; 222 + 223 + val = (val & mask) >> shift; 224 + if (val >= size) 225 + return -EINVAL; 226 + 227 + return *(time_usec + val); 228 + } 229 + 230 + static int lp872x_regulator_enable_time(struct regulator_dev *rdev) 231 + { 232 + struct lp872x *lp = rdev_get_drvdata(rdev); 233 + enum lp872x_regulator_id regulator = rdev_get_id(rdev); 234 + int time_step_us = lp872x_get_timestep_usec(lp); 235 + int ret, offset; 236 + u8 addr, val; 237 + 238 + if (time_step_us < 0) 239 + return -EINVAL; 240 + 241 + switch (regulator) { 242 + case LP8720_ID_LDO1 ... LP8720_ID_LDO5: 243 + case LP8725_ID_LDO1 ... LP8725_ID_LILO2: 244 + offset = _rdev_to_offset(rdev); 245 + if (offset < 0) 246 + return -EINVAL; 247 + 248 + addr = LP872X_LDO1_VOUT + offset; 249 + break; 250 + case LP8720_ID_BUCK: 251 + addr = LP8720_BUCK_VOUT1; 252 + break; 253 + case LP8725_ID_BUCK1: 254 + addr = LP8725_BUCK1_VOUT1; 255 + break; 256 + case LP8725_ID_BUCK2: 257 + addr = LP8725_BUCK2_VOUT1; 258 + break; 259 + default: 260 + return -EINVAL; 261 + } 262 + 263 + ret = lp872x_read_byte(lp, addr, &val); 264 + if (ret) 265 + return ret; 266 + 267 + val = (val & LP872X_START_DELAY_M) >> LP872X_START_DELAY_S; 268 + 269 + return val > MAX_DELAY ? 0 : val * time_step_us; 270 + } 271 + 272 + static void lp872x_set_dvs(struct lp872x *lp, int gpio) 273 + { 274 + enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel; 275 + enum lp872x_dvs_state state; 276 + 277 + state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW; 278 + gpio_set_value(gpio, state); 279 + lp->dvs_pin = state; 280 + } 281 + 282 + static u8 lp872x_select_buck_vout_addr(struct lp872x *lp, 283 + enum lp872x_regulator_id buck) 284 + { 285 + u8 val, addr; 286 + 287 + if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val)) 288 + return 0; 289 + 290 + switch (buck) { 291 + case LP8720_ID_BUCK: 292 + if (val & LP8720_EXT_DVS_M) { 293 + addr = (lp->dvs_pin == DVS_HIGH) ? 294 + LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; 295 + } else { 296 + if (lp872x_read_byte(lp, LP8720_ENABLE, &val)) 297 + return 0; 298 + 299 + addr = val & LP8720_DVS_SEL_M ? 300 + LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; 301 + } 302 + break; 303 + case LP8725_ID_BUCK1: 304 + if (val & LP8725_DVS1_M) 305 + addr = LP8725_BUCK1_VOUT1; 306 + else 307 + addr = (lp->dvs_pin == DVS_HIGH) ? 308 + LP8725_BUCK1_VOUT1 : LP8725_BUCK1_VOUT2; 309 + break; 310 + case LP8725_ID_BUCK2: 311 + addr = val & LP8725_DVS2_M ? 312 + LP8725_BUCK2_VOUT1 : LP8725_BUCK2_VOUT2; 313 + break; 314 + default: 315 + return 0; 316 + } 317 + 318 + return addr; 319 + } 320 + 321 + static bool lp872x_is_valid_buck_addr(u8 addr) 322 + { 323 + switch (addr) { 324 + case LP8720_BUCK_VOUT1: 325 + case LP8720_BUCK_VOUT2: 326 + case LP8725_BUCK1_VOUT1: 327 + case LP8725_BUCK1_VOUT2: 328 + case LP8725_BUCK2_VOUT1: 329 + case LP8725_BUCK2_VOUT2: 330 + return true; 331 + default: 332 + return false; 333 + } 334 + } 335 + 336 + static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev, 337 + unsigned selector) 338 + { 339 + struct lp872x *lp = rdev_get_drvdata(rdev); 340 + enum lp872x_regulator_id buck = rdev_get_id(rdev); 341 + u8 addr, mask = LP872X_VOUT_M; 342 + struct lp872x_dvs *dvs = lp->pdata->dvs; 343 + 344 + if (dvs && gpio_is_valid(dvs->gpio)) 345 + lp872x_set_dvs(lp, dvs->gpio); 346 + 347 + addr = lp872x_select_buck_vout_addr(lp, buck); 348 + if (!lp872x_is_valid_buck_addr(addr)) 349 + return -EINVAL; 350 + 351 + return lp872x_update_bits(lp, addr, mask, selector); 352 + } 353 + 354 + static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev) 355 + { 356 + struct lp872x *lp = rdev_get_drvdata(rdev); 357 + enum lp872x_regulator_id buck = rdev_get_id(rdev); 358 + u8 addr, val; 359 + int ret; 360 + 361 + addr = lp872x_select_buck_vout_addr(lp, buck); 362 + if (!lp872x_is_valid_buck_addr(addr)) 363 + return -EINVAL; 364 + 365 + ret = lp872x_read_byte(lp, addr, &val); 366 + if (ret) 367 + return ret; 368 + 369 + return val & LP872X_VOUT_M; 370 + } 371 + 372 + static int lp8725_buck_set_current_limit(struct regulator_dev *rdev, 373 + int min_uA, int max_uA) 374 + { 375 + struct lp872x *lp = rdev_get_drvdata(rdev); 376 + enum lp872x_regulator_id buck = rdev_get_id(rdev); 377 + int i, max = ARRAY_SIZE(lp8725_buck_uA); 378 + u8 addr, val; 379 + 380 + switch (buck) { 381 + case LP8725_ID_BUCK1: 382 + addr = LP8725_BUCK1_VOUT2; 383 + break; 384 + case LP8725_ID_BUCK2: 385 + addr = LP8725_BUCK2_VOUT2; 386 + break; 387 + default: 388 + return -EINVAL; 389 + } 390 + 391 + for (i = 0 ; i < max ; i++) 392 + if (lp8725_buck_uA[i] >= min_uA && 393 + lp8725_buck_uA[i] <= max_uA) 394 + break; 395 + 396 + if (i == max) 397 + return -EINVAL; 398 + 399 + val = i << LP8725_BUCK_CL_S; 400 + 401 + return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val); 402 + } 403 + 404 + static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) 405 + { 406 + struct lp872x *lp = rdev_get_drvdata(rdev); 407 + enum lp872x_regulator_id buck = rdev_get_id(rdev); 408 + u8 addr, val; 409 + int ret; 410 + 411 + switch (buck) { 412 + case LP8725_ID_BUCK1: 413 + addr = LP8725_BUCK1_VOUT2; 414 + break; 415 + case LP8725_ID_BUCK2: 416 + addr = LP8725_BUCK2_VOUT2; 417 + break; 418 + default: 419 + return -EINVAL; 420 + } 421 + 422 + ret = lp872x_read_byte(lp, addr, &val); 423 + if (ret) 424 + return ret; 425 + 426 + val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S; 427 + 428 + return (val < ARRAY_SIZE(lp8725_buck_uA)) ? 429 + lp8725_buck_uA[val] : -EINVAL; 430 + } 431 + 432 + static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) 433 + { 434 + struct lp872x *lp = rdev_get_drvdata(rdev); 435 + enum lp872x_regulator_id buck = rdev_get_id(rdev); 436 + u8 addr, mask, shift, val; 437 + 438 + switch (buck) { 439 + case LP8720_ID_BUCK: 440 + addr = LP8720_BUCK_VOUT2; 441 + mask = LP8720_BUCK_FPWM_M; 442 + shift = LP8720_BUCK_FPWM_S; 443 + break; 444 + case LP8725_ID_BUCK1: 445 + addr = LP8725_BUCK_CTRL; 446 + mask = LP8725_BUCK1_FPWM_M; 447 + shift = LP8725_BUCK1_FPWM_S; 448 + break; 449 + case LP8725_ID_BUCK2: 450 + addr = LP8725_BUCK_CTRL; 451 + mask = LP8725_BUCK2_FPWM_M; 452 + shift = LP8725_BUCK2_FPWM_S; 453 + break; 454 + default: 455 + return -EINVAL; 456 + } 457 + 458 + if (mode == REGULATOR_MODE_FAST) 459 + val = LP872X_FORCE_PWM << shift; 460 + else if (mode == REGULATOR_MODE_NORMAL) 461 + val = LP872X_AUTO_PWM << shift; 462 + else 463 + return -EINVAL; 464 + 465 + return lp872x_update_bits(lp, addr, mask, val); 466 + } 467 + 468 + static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) 469 + { 470 + struct lp872x *lp = rdev_get_drvdata(rdev); 471 + enum lp872x_regulator_id buck = rdev_get_id(rdev); 472 + u8 addr, mask, val; 473 + int ret; 474 + 475 + switch (buck) { 476 + case LP8720_ID_BUCK: 477 + addr = LP8720_BUCK_VOUT2; 478 + mask = LP8720_BUCK_FPWM_M; 479 + break; 480 + case LP8725_ID_BUCK1: 481 + addr = LP8725_BUCK_CTRL; 482 + mask = LP8725_BUCK1_FPWM_M; 483 + break; 484 + case LP8725_ID_BUCK2: 485 + addr = LP8725_BUCK_CTRL; 486 + mask = LP8725_BUCK2_FPWM_M; 487 + break; 488 + default: 489 + return -EINVAL; 490 + } 491 + 492 + ret = lp872x_read_byte(lp, addr, &val); 493 + if (ret) 494 + return ret; 495 + 496 + return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; 497 + } 498 + 499 + static struct regulator_ops lp872x_ldo_ops = { 500 + .list_voltage = regulator_list_voltage_table, 501 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 502 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 503 + .enable = regulator_enable_regmap, 504 + .disable = regulator_disable_regmap, 505 + .is_enabled = regulator_is_enabled_regmap, 506 + .enable_time = lp872x_regulator_enable_time, 507 + }; 508 + 509 + static struct regulator_ops lp8720_buck_ops = { 510 + .list_voltage = regulator_list_voltage_table, 511 + .set_voltage_sel = lp872x_buck_set_voltage_sel, 512 + .get_voltage_sel = lp872x_buck_get_voltage_sel, 513 + .enable = regulator_enable_regmap, 514 + .disable = regulator_disable_regmap, 515 + .is_enabled = regulator_is_enabled_regmap, 516 + .enable_time = lp872x_regulator_enable_time, 517 + .set_mode = lp872x_buck_set_mode, 518 + .get_mode = lp872x_buck_get_mode, 519 + }; 520 + 521 + static struct regulator_ops lp8725_buck_ops = { 522 + .list_voltage = regulator_list_voltage_table, 523 + .set_voltage_sel = lp872x_buck_set_voltage_sel, 524 + .get_voltage_sel = lp872x_buck_get_voltage_sel, 525 + .enable = regulator_enable_regmap, 526 + .disable = regulator_disable_regmap, 527 + .is_enabled = regulator_is_enabled_regmap, 528 + .enable_time = lp872x_regulator_enable_time, 529 + .set_mode = lp872x_buck_set_mode, 530 + .get_mode = lp872x_buck_get_mode, 531 + .set_current_limit = lp8725_buck_set_current_limit, 532 + .get_current_limit = lp8725_buck_get_current_limit, 533 + }; 534 + 535 + static struct regulator_desc lp8720_regulator_desc[] = { 536 + { 537 + .name = "ldo1", 538 + .id = LP8720_ID_LDO1, 539 + .ops = &lp872x_ldo_ops, 540 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 541 + .volt_table = lp872x_ldo_vtbl, 542 + .type = REGULATOR_VOLTAGE, 543 + .owner = THIS_MODULE, 544 + .vsel_reg = LP872X_LDO1_VOUT, 545 + .vsel_mask = LP872X_VOUT_M, 546 + .enable_reg = LP8720_ENABLE, 547 + .enable_mask = LP872X_EN_LDO1_M, 548 + }, 549 + { 550 + .name = "ldo2", 551 + .id = LP8720_ID_LDO2, 552 + .ops = &lp872x_ldo_ops, 553 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 554 + .volt_table = lp872x_ldo_vtbl, 555 + .type = REGULATOR_VOLTAGE, 556 + .owner = THIS_MODULE, 557 + .vsel_reg = LP872X_LDO2_VOUT, 558 + .vsel_mask = LP872X_VOUT_M, 559 + .enable_reg = LP8720_ENABLE, 560 + .enable_mask = LP872X_EN_LDO2_M, 561 + }, 562 + { 563 + .name = "ldo3", 564 + .id = LP8720_ID_LDO3, 565 + .ops = &lp872x_ldo_ops, 566 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 567 + .volt_table = lp872x_ldo_vtbl, 568 + .type = REGULATOR_VOLTAGE, 569 + .owner = THIS_MODULE, 570 + .vsel_reg = LP872X_LDO3_VOUT, 571 + .vsel_mask = LP872X_VOUT_M, 572 + .enable_reg = LP8720_ENABLE, 573 + .enable_mask = LP872X_EN_LDO3_M, 574 + }, 575 + { 576 + .name = "ldo4", 577 + .id = LP8720_ID_LDO4, 578 + .ops = &lp872x_ldo_ops, 579 + .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), 580 + .volt_table = lp8720_ldo4_vtbl, 581 + .type = REGULATOR_VOLTAGE, 582 + .owner = THIS_MODULE, 583 + .vsel_reg = LP872X_LDO4_VOUT, 584 + .vsel_mask = LP872X_VOUT_M, 585 + .enable_reg = LP8720_ENABLE, 586 + .enable_mask = LP872X_EN_LDO4_M, 587 + }, 588 + { 589 + .name = "ldo5", 590 + .id = LP8720_ID_LDO5, 591 + .ops = &lp872x_ldo_ops, 592 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 593 + .volt_table = lp872x_ldo_vtbl, 594 + .type = REGULATOR_VOLTAGE, 595 + .owner = THIS_MODULE, 596 + .vsel_reg = LP872X_LDO5_VOUT, 597 + .vsel_mask = LP872X_VOUT_M, 598 + .enable_reg = LP8720_ENABLE, 599 + .enable_mask = LP872X_EN_LDO5_M, 600 + }, 601 + { 602 + .name = "buck", 603 + .id = LP8720_ID_BUCK, 604 + .ops = &lp8720_buck_ops, 605 + .n_voltages = ARRAY_SIZE(lp8720_buck_vtbl), 606 + .volt_table = lp8720_buck_vtbl, 607 + .type = REGULATOR_VOLTAGE, 608 + .owner = THIS_MODULE, 609 + .enable_reg = LP8720_ENABLE, 610 + .enable_mask = LP8720_EN_BUCK_M, 611 + }, 612 + }; 613 + 614 + static struct regulator_desc lp8725_regulator_desc[] = { 615 + { 616 + .name = "ldo1", 617 + .id = LP8725_ID_LDO1, 618 + .ops = &lp872x_ldo_ops, 619 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 620 + .volt_table = lp872x_ldo_vtbl, 621 + .type = REGULATOR_VOLTAGE, 622 + .owner = THIS_MODULE, 623 + .vsel_reg = LP872X_LDO1_VOUT, 624 + .vsel_mask = LP872X_VOUT_M, 625 + .enable_reg = LP8725_LDO_CTRL, 626 + .enable_mask = LP872X_EN_LDO1_M, 627 + }, 628 + { 629 + .name = "ldo2", 630 + .id = LP8725_ID_LDO2, 631 + .ops = &lp872x_ldo_ops, 632 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 633 + .volt_table = lp872x_ldo_vtbl, 634 + .type = REGULATOR_VOLTAGE, 635 + .owner = THIS_MODULE, 636 + .vsel_reg = LP872X_LDO2_VOUT, 637 + .vsel_mask = LP872X_VOUT_M, 638 + .enable_reg = LP8725_LDO_CTRL, 639 + .enable_mask = LP872X_EN_LDO2_M, 640 + }, 641 + { 642 + .name = "ldo3", 643 + .id = LP8725_ID_LDO3, 644 + .ops = &lp872x_ldo_ops, 645 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 646 + .volt_table = lp872x_ldo_vtbl, 647 + .type = REGULATOR_VOLTAGE, 648 + .owner = THIS_MODULE, 649 + .vsel_reg = LP872X_LDO3_VOUT, 650 + .vsel_mask = LP872X_VOUT_M, 651 + .enable_reg = LP8725_LDO_CTRL, 652 + .enable_mask = LP872X_EN_LDO3_M, 653 + }, 654 + { 655 + .name = "ldo4", 656 + .id = LP8725_ID_LDO4, 657 + .ops = &lp872x_ldo_ops, 658 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 659 + .volt_table = lp872x_ldo_vtbl, 660 + .type = REGULATOR_VOLTAGE, 661 + .owner = THIS_MODULE, 662 + .vsel_reg = LP872X_LDO4_VOUT, 663 + .vsel_mask = LP872X_VOUT_M, 664 + .enable_reg = LP8725_LDO_CTRL, 665 + .enable_mask = LP872X_EN_LDO4_M, 666 + }, 667 + { 668 + .name = "ldo5", 669 + .id = LP8725_ID_LDO5, 670 + .ops = &lp872x_ldo_ops, 671 + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), 672 + .volt_table = lp872x_ldo_vtbl, 673 + .type = REGULATOR_VOLTAGE, 674 + .owner = THIS_MODULE, 675 + .vsel_reg = LP872X_LDO5_VOUT, 676 + .vsel_mask = LP872X_VOUT_M, 677 + .enable_reg = LP8725_LDO_CTRL, 678 + .enable_mask = LP872X_EN_LDO5_M, 679 + }, 680 + { 681 + .name = "lilo1", 682 + .id = LP8725_ID_LILO1, 683 + .ops = &lp872x_ldo_ops, 684 + .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), 685 + .volt_table = lp8725_lilo_vtbl, 686 + .type = REGULATOR_VOLTAGE, 687 + .owner = THIS_MODULE, 688 + .vsel_reg = LP8725_LILO1_VOUT, 689 + .vsel_mask = LP872X_VOUT_M, 690 + .enable_reg = LP8725_LDO_CTRL, 691 + .enable_mask = LP8725_EN_LILO1_M, 692 + }, 693 + { 694 + .name = "lilo2", 695 + .id = LP8725_ID_LILO2, 696 + .ops = &lp872x_ldo_ops, 697 + .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), 698 + .volt_table = lp8725_lilo_vtbl, 699 + .type = REGULATOR_VOLTAGE, 700 + .owner = THIS_MODULE, 701 + .vsel_reg = LP8725_LILO2_VOUT, 702 + .vsel_mask = LP872X_VOUT_M, 703 + .enable_reg = LP8725_LDO_CTRL, 704 + .enable_mask = LP8725_EN_LILO2_M, 705 + }, 706 + { 707 + .name = "buck1", 708 + .id = LP8725_ID_BUCK1, 709 + .ops = &lp8725_buck_ops, 710 + .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), 711 + .volt_table = lp8725_buck_vtbl, 712 + .type = REGULATOR_VOLTAGE, 713 + .owner = THIS_MODULE, 714 + .enable_reg = LP872X_GENERAL_CFG, 715 + .enable_mask = LP8725_BUCK1_EN_M, 716 + }, 717 + { 718 + .name = "buck2", 719 + .id = LP8725_ID_BUCK2, 720 + .ops = &lp8725_buck_ops, 721 + .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), 722 + .volt_table = lp8725_buck_vtbl, 723 + .type = REGULATOR_VOLTAGE, 724 + .owner = THIS_MODULE, 725 + .enable_reg = LP872X_GENERAL_CFG, 726 + .enable_mask = LP8725_BUCK2_EN_M, 727 + }, 728 + }; 729 + 730 + static int lp872x_check_dvs_validity(struct lp872x *lp) 731 + { 732 + struct lp872x_dvs *dvs = lp->pdata->dvs; 733 + u8 val = 0; 734 + int ret; 735 + 736 + ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); 737 + if (ret) 738 + return ret; 739 + 740 + ret = 0; 741 + if (lp->chipid == LP8720) { 742 + if (val & LP8720_EXT_DVS_M) 743 + ret = dvs ? 0 : -EINVAL; 744 + } else { 745 + if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED) 746 + ret = dvs ? 0 : -EINVAL; 747 + } 748 + 749 + return ret; 750 + } 751 + 752 + static int lp872x_init_dvs(struct lp872x *lp) 753 + { 754 + int ret, gpio; 755 + struct lp872x_dvs *dvs = lp->pdata->dvs; 756 + enum lp872x_dvs_state pinstate; 757 + 758 + ret = lp872x_check_dvs_validity(lp); 759 + if (ret) { 760 + dev_warn(lp->dev, "invalid dvs data: %d\n", ret); 761 + return ret; 762 + } 763 + 764 + gpio = dvs->gpio; 765 + if (!gpio_is_valid(gpio)) { 766 + dev_err(lp->dev, "invalid gpio: %d\n", gpio); 767 + return -EINVAL; 768 + } 769 + 770 + pinstate = dvs->init_state; 771 + ret = devm_gpio_request_one(lp->dev, gpio, pinstate, "LP872X DVS"); 772 + if (ret) { 773 + dev_err(lp->dev, "gpio request err: %d\n", ret); 774 + return ret; 775 + } 776 + 777 + lp->dvs_pin = pinstate; 778 + lp->dvs_gpio = gpio; 779 + 780 + return 0; 781 + } 782 + 783 + static int lp872x_config(struct lp872x *lp) 784 + { 785 + struct lp872x_platform_data *pdata = lp->pdata; 786 + int ret; 787 + 788 + if (!pdata) { 789 + dev_warn(lp->dev, "no platform data\n"); 790 + return 0; 791 + } 792 + 793 + if (!pdata->update_config) 794 + return 0; 795 + 796 + ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config); 797 + if (ret) 798 + return ret; 799 + 800 + return lp872x_init_dvs(lp); 801 + } 802 + 803 + static struct regulator_init_data 804 + *lp872x_find_regulator_init_data(int idx, struct lp872x *lp) 805 + { 806 + int i, base, id, max_regulators; 807 + 808 + switch (lp->chipid) { 809 + case LP8720: 810 + base = LP8720_ID_BASE; 811 + max_regulators = LP8720_NUM_REGULATORS; 812 + break; 813 + case LP8725: 814 + base = LP8725_ID_BASE; 815 + max_regulators = LP8725_NUM_REGULATORS; 816 + break; 817 + default: 818 + return NULL; 819 + } 820 + 821 + id = base + idx; 822 + for (i = 0 ; i < max_regulators ; i++) 823 + if (lp->pdata->regulator_data[i].id == id) 824 + break; 825 + 826 + return (i == max_regulators) ? NULL : 827 + lp->pdata->regulator_data[i].init_data; 828 + } 829 + 830 + static int lp872x_regulator_register(struct lp872x *lp) 831 + { 832 + struct regulator_desc *desc; 833 + struct regulator_config cfg = { }; 834 + struct regulator_dev *rdev; 835 + int i, ret; 836 + 837 + for (i = 0 ; i < lp->num_regulators ; i++) { 838 + desc = (lp->chipid == LP8720) ? &lp8720_regulator_desc[i] : 839 + &lp8725_regulator_desc[i]; 840 + 841 + cfg.dev = lp->dev; 842 + cfg.init_data = lp872x_find_regulator_init_data(i, lp); 843 + cfg.driver_data = lp; 844 + cfg.regmap = lp->regmap; 845 + 846 + rdev = regulator_register(desc, &cfg); 847 + if (IS_ERR(rdev)) { 848 + dev_err(lp->dev, "regulator register err"); 849 + ret = PTR_ERR(rdev); 850 + goto err; 851 + } 852 + 853 + *(lp->regulators + i) = rdev; 854 + } 855 + 856 + return 0; 857 + err: 858 + while (--i >= 0) { 859 + rdev = *(lp->regulators + i); 860 + regulator_unregister(rdev); 861 + } 862 + return ret; 863 + } 864 + 865 + static void lp872x_regulator_unregister(struct lp872x *lp) 866 + { 867 + struct regulator_dev *rdev; 868 + int i; 869 + 870 + for (i = 0 ; i < lp->num_regulators ; i++) { 871 + rdev = *(lp->regulators + i); 872 + regulator_unregister(rdev); 873 + } 874 + } 875 + 876 + static const struct regmap_config lp872x_regmap_config = { 877 + .reg_bits = 8, 878 + .val_bits = 8, 879 + .max_register = MAX_REGISTERS, 880 + }; 881 + 882 + static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 883 + { 884 + struct lp872x *lp; 885 + struct lp872x_platform_data *pdata = cl->dev.platform_data; 886 + int ret, size, num_regulators; 887 + const int lp872x_num_regulators[] = { 888 + [LP8720] = LP8720_NUM_REGULATORS, 889 + [LP8725] = LP8725_NUM_REGULATORS, 890 + }; 891 + 892 + lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); 893 + if (!lp) 894 + goto err_mem; 895 + 896 + num_regulators = lp872x_num_regulators[id->driver_data]; 897 + size = sizeof(struct regulator_dev *) * num_regulators; 898 + 899 + lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL); 900 + if (!lp->regulators) 901 + goto err_mem; 902 + 903 + lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); 904 + if (IS_ERR(lp->regmap)) { 905 + ret = PTR_ERR(lp->regmap); 906 + dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); 907 + goto err_dev; 908 + } 909 + 910 + lp->dev = &cl->dev; 911 + lp->pdata = pdata; 912 + lp->chipid = id->driver_data; 913 + lp->num_regulators = num_regulators; 914 + i2c_set_clientdata(cl, lp); 915 + 916 + ret = lp872x_config(lp); 917 + if (ret) 918 + goto err_dev; 919 + 920 + return lp872x_regulator_register(lp); 921 + 922 + err_mem: 923 + return -ENOMEM; 924 + err_dev: 925 + return ret; 926 + } 927 + 928 + static int __devexit lp872x_remove(struct i2c_client *cl) 929 + { 930 + struct lp872x *lp = i2c_get_clientdata(cl); 931 + 932 + lp872x_regulator_unregister(lp); 933 + return 0; 934 + } 935 + 936 + static const struct i2c_device_id lp872x_ids[] = { 937 + {"lp8720", LP8720}, 938 + {"lp8725", LP8725}, 939 + { } 940 + }; 941 + MODULE_DEVICE_TABLE(i2c, lp872x_ids); 942 + 943 + static struct i2c_driver lp872x_driver = { 944 + .driver = { 945 + .name = "lp872x", 946 + .owner = THIS_MODULE, 947 + }, 948 + .probe = lp872x_probe, 949 + .remove = __devexit_p(lp872x_remove), 950 + .id_table = lp872x_ids, 951 + }; 952 + 953 + module_i2c_driver(lp872x_driver); 954 + 955 + MODULE_DESCRIPTION("TI/National Semiconductor LP872x PMU Regulator Driver"); 956 + MODULE_AUTHOR("Milo Kim"); 957 + MODULE_LICENSE("GPL");
+90
include/linux/regulator/lp872x.h
··· 1 + /* 2 + * Copyright 2012 Texas Instruments 3 + * 4 + * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + */ 11 + 12 + #ifndef __LP872X_REGULATOR_H__ 13 + #define __LP872X_REGULATOR_H__ 14 + 15 + #include <linux/regulator/machine.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/gpio.h> 18 + 19 + #define LP872X_MAX_REGULATORS 9 20 + 21 + enum lp872x_regulator_id { 22 + LP8720_ID_BASE, 23 + LP8720_ID_LDO1 = LP8720_ID_BASE, 24 + LP8720_ID_LDO2, 25 + LP8720_ID_LDO3, 26 + LP8720_ID_LDO4, 27 + LP8720_ID_LDO5, 28 + LP8720_ID_BUCK, 29 + 30 + LP8725_ID_BASE, 31 + LP8725_ID_LDO1 = LP8725_ID_BASE, 32 + LP8725_ID_LDO2, 33 + LP8725_ID_LDO3, 34 + LP8725_ID_LDO4, 35 + LP8725_ID_LDO5, 36 + LP8725_ID_LILO1, 37 + LP8725_ID_LILO2, 38 + LP8725_ID_BUCK1, 39 + LP8725_ID_BUCK2, 40 + 41 + LP872X_ID_MAX, 42 + }; 43 + 44 + enum lp872x_dvs_state { 45 + DVS_LOW = GPIOF_OUT_INIT_LOW, 46 + DVS_HIGH = GPIOF_OUT_INIT_HIGH, 47 + }; 48 + 49 + enum lp872x_dvs_sel { 50 + SEL_V1, 51 + SEL_V2, 52 + }; 53 + 54 + /** 55 + * lp872x_dvs 56 + * @gpio : gpio pin number for dvs control 57 + * @vsel : dvs selector for buck v1 or buck v2 register 58 + * @init_state : initial dvs pin state 59 + */ 60 + struct lp872x_dvs { 61 + int gpio; 62 + enum lp872x_dvs_sel vsel; 63 + enum lp872x_dvs_state init_state; 64 + }; 65 + 66 + /** 67 + * lp872x_regdata 68 + * @id : regulator id 69 + * @init_data : init data for each regulator 70 + */ 71 + struct lp872x_regulator_data { 72 + enum lp872x_regulator_id id; 73 + struct regulator_init_data *init_data; 74 + }; 75 + 76 + /** 77 + * lp872x_platform_data 78 + * @general_config : the value of LP872X_GENERAL_CFG register 79 + * @update_config : if LP872X_GENERAL_CFG register is updated, set true 80 + * @regulator_data : platform regulator id and init data 81 + * @dvs : dvs data for buck voltage control 82 + */ 83 + struct lp872x_platform_data { 84 + u8 general_config; 85 + bool update_config; 86 + struct lp872x_regulator_data regulator_data[LP872X_MAX_REGULATORS]; 87 + struct lp872x_dvs *dvs; 88 + }; 89 + 90 + #endif