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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.12-rc5 539 lines 16 kB view raw
1/* 2 * max77686.c - Regulator driver for the Maxim 77686 3 * 4 * Copyright (C) 2012 Samsung Electronics 5 * Chiwoong Byun <woong.byun@smasung.com> 6 * Jonghwa Lee <jonghwa3.lee@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 * This driver is based on max8997.c 23 */ 24 25#include <linux/kernel.h> 26#include <linux/bug.h> 27#include <linux/err.h> 28#include <linux/gpio.h> 29#include <linux/slab.h> 30#include <linux/platform_device.h> 31#include <linux/regulator/driver.h> 32#include <linux/regulator/machine.h> 33#include <linux/regulator/of_regulator.h> 34#include <linux/mfd/max77686.h> 35#include <linux/mfd/max77686-private.h> 36 37#define MAX77686_LDO_MINUV 800000 38#define MAX77686_LDO_UVSTEP 50000 39#define MAX77686_LDO_LOW_MINUV 800000 40#define MAX77686_LDO_LOW_UVSTEP 25000 41#define MAX77686_BUCK_MINUV 750000 42#define MAX77686_BUCK_UVSTEP 50000 43#define MAX77686_RAMP_DELAY 100000 /* uV/us */ 44#define MAX77686_DVS_RAMP_DELAY 27500 /* uV/us */ 45#define MAX77686_DVS_MINUV 600000 46#define MAX77686_DVS_UVSTEP 12500 47 48#define MAX77686_OPMODE_SHIFT 6 49#define MAX77686_OPMODE_BUCK234_SHIFT 4 50#define MAX77686_OPMODE_MASK 0x3 51 52#define MAX77686_VSEL_MASK 0x3F 53#define MAX77686_DVS_VSEL_MASK 0xFF 54 55#define MAX77686_RAMP_RATE_MASK 0xC0 56 57#define MAX77686_REGULATORS MAX77686_REG_MAX 58#define MAX77686_LDOS 26 59 60enum max77686_ramp_rate { 61 RAMP_RATE_13P75MV, 62 RAMP_RATE_27P5MV, 63 RAMP_RATE_55MV, 64 RAMP_RATE_NO_CTRL, /* 100mV/us */ 65}; 66 67struct max77686_data { 68 struct regulator_dev *rdev[MAX77686_REGULATORS]; 69 unsigned int opmode[MAX77686_REGULATORS]; 70}; 71 72/* Some BUCKS supports Normal[ON/OFF] mode during suspend */ 73static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev) 74{ 75 unsigned int val; 76 struct max77686_data *max77686 = rdev_get_drvdata(rdev); 77 int ret, id = rdev_get_id(rdev); 78 79 if (id == MAX77686_BUCK1) 80 val = 0x1; 81 else 82 val = 0x1 << MAX77686_OPMODE_BUCK234_SHIFT; 83 84 ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 85 rdev->desc->enable_mask, val); 86 if (ret) 87 return ret; 88 89 max77686->opmode[id] = val; 90 return 0; 91} 92 93/* Some LDOs supports [LPM/Normal]ON mode during suspend state */ 94static int max77686_set_suspend_mode(struct regulator_dev *rdev, 95 unsigned int mode) 96{ 97 struct max77686_data *max77686 = rdev_get_drvdata(rdev); 98 unsigned int val; 99 int ret, id = rdev_get_id(rdev); 100 101 /* BUCK[5-9] doesn't support this feature */ 102 if (id >= MAX77686_BUCK5) 103 return 0; 104 105 switch (mode) { 106 case REGULATOR_MODE_IDLE: /* ON in LP Mode */ 107 val = 0x2 << MAX77686_OPMODE_SHIFT; 108 break; 109 case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ 110 val = 0x3 << MAX77686_OPMODE_SHIFT; 111 break; 112 default: 113 pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", 114 rdev->desc->name, mode); 115 return -EINVAL; 116 } 117 118 ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 119 rdev->desc->enable_mask, val); 120 if (ret) 121 return ret; 122 123 max77686->opmode[id] = val; 124 return 0; 125} 126 127/* Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state */ 128static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, 129 unsigned int mode) 130{ 131 unsigned int val; 132 struct max77686_data *max77686 = rdev_get_drvdata(rdev); 133 int ret; 134 135 switch (mode) { 136 case REGULATOR_MODE_STANDBY: /* switch off */ 137 val = 0x1 << MAX77686_OPMODE_SHIFT; 138 break; 139 case REGULATOR_MODE_IDLE: /* ON in LP Mode */ 140 val = 0x2 << MAX77686_OPMODE_SHIFT; 141 break; 142 case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ 143 val = 0x3 << MAX77686_OPMODE_SHIFT; 144 break; 145 default: 146 pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", 147 rdev->desc->name, mode); 148 return -EINVAL; 149 } 150 151 ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 152 rdev->desc->enable_mask, val); 153 if (ret) 154 return ret; 155 156 max77686->opmode[rdev_get_id(rdev)] = val; 157 return 0; 158} 159 160static int max77686_enable(struct regulator_dev *rdev) 161{ 162 struct max77686_data *max77686 = rdev_get_drvdata(rdev); 163 164 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 165 rdev->desc->enable_mask, 166 max77686->opmode[rdev_get_id(rdev)]); 167} 168 169static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 170{ 171 unsigned int ramp_value = RAMP_RATE_NO_CTRL; 172 173 switch (ramp_delay) { 174 case 1 ... 13750: 175 ramp_value = RAMP_RATE_13P75MV; 176 break; 177 case 13751 ... 27500: 178 ramp_value = RAMP_RATE_27P5MV; 179 break; 180 case 27501 ... 55000: 181 ramp_value = RAMP_RATE_55MV; 182 break; 183 case 55001 ... 100000: 184 break; 185 default: 186 pr_warn("%s: ramp_delay: %d not supported, setting 100000\n", 187 rdev->desc->name, ramp_delay); 188 } 189 190 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 191 MAX77686_RAMP_RATE_MASK, ramp_value << 6); 192} 193 194static struct regulator_ops max77686_ops = { 195 .list_voltage = regulator_list_voltage_linear, 196 .map_voltage = regulator_map_voltage_linear, 197 .is_enabled = regulator_is_enabled_regmap, 198 .enable = max77686_enable, 199 .disable = regulator_disable_regmap, 200 .get_voltage_sel = regulator_get_voltage_sel_regmap, 201 .set_voltage_sel = regulator_set_voltage_sel_regmap, 202 .set_voltage_time_sel = regulator_set_voltage_time_sel, 203 .set_suspend_mode = max77686_set_suspend_mode, 204}; 205 206static struct regulator_ops max77686_ldo_ops = { 207 .list_voltage = regulator_list_voltage_linear, 208 .map_voltage = regulator_map_voltage_linear, 209 .is_enabled = regulator_is_enabled_regmap, 210 .enable = max77686_enable, 211 .disable = regulator_disable_regmap, 212 .get_voltage_sel = regulator_get_voltage_sel_regmap, 213 .set_voltage_sel = regulator_set_voltage_sel_regmap, 214 .set_voltage_time_sel = regulator_set_voltage_time_sel, 215 .set_suspend_mode = max77686_ldo_set_suspend_mode, 216}; 217 218static struct regulator_ops max77686_buck1_ops = { 219 .list_voltage = regulator_list_voltage_linear, 220 .map_voltage = regulator_map_voltage_linear, 221 .is_enabled = regulator_is_enabled_regmap, 222 .enable = max77686_enable, 223 .disable = regulator_disable_regmap, 224 .get_voltage_sel = regulator_get_voltage_sel_regmap, 225 .set_voltage_sel = regulator_set_voltage_sel_regmap, 226 .set_voltage_time_sel = regulator_set_voltage_time_sel, 227 .set_suspend_disable = max77686_buck_set_suspend_disable, 228}; 229 230static struct regulator_ops max77686_buck_dvs_ops = { 231 .list_voltage = regulator_list_voltage_linear, 232 .map_voltage = regulator_map_voltage_linear, 233 .is_enabled = regulator_is_enabled_regmap, 234 .enable = max77686_enable, 235 .disable = regulator_disable_regmap, 236 .get_voltage_sel = regulator_get_voltage_sel_regmap, 237 .set_voltage_sel = regulator_set_voltage_sel_regmap, 238 .set_voltage_time_sel = regulator_set_voltage_time_sel, 239 .set_ramp_delay = max77686_set_ramp_delay, 240 .set_suspend_disable = max77686_buck_set_suspend_disable, 241}; 242 243#define regulator_desc_ldo(num) { \ 244 .name = "LDO"#num, \ 245 .id = MAX77686_LDO##num, \ 246 .ops = &max77686_ops, \ 247 .type = REGULATOR_VOLTAGE, \ 248 .owner = THIS_MODULE, \ 249 .min_uV = MAX77686_LDO_MINUV, \ 250 .uV_step = MAX77686_LDO_UVSTEP, \ 251 .ramp_delay = MAX77686_RAMP_DELAY, \ 252 .n_voltages = MAX77686_VSEL_MASK + 1, \ 253 .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 254 .vsel_mask = MAX77686_VSEL_MASK, \ 255 .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 256 .enable_mask = MAX77686_OPMODE_MASK \ 257 << MAX77686_OPMODE_SHIFT, \ 258} 259#define regulator_desc_lpm_ldo(num) { \ 260 .name = "LDO"#num, \ 261 .id = MAX77686_LDO##num, \ 262 .ops = &max77686_ldo_ops, \ 263 .type = REGULATOR_VOLTAGE, \ 264 .owner = THIS_MODULE, \ 265 .min_uV = MAX77686_LDO_MINUV, \ 266 .uV_step = MAX77686_LDO_UVSTEP, \ 267 .ramp_delay = MAX77686_RAMP_DELAY, \ 268 .n_voltages = MAX77686_VSEL_MASK + 1, \ 269 .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 270 .vsel_mask = MAX77686_VSEL_MASK, \ 271 .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 272 .enable_mask = MAX77686_OPMODE_MASK \ 273 << MAX77686_OPMODE_SHIFT, \ 274} 275#define regulator_desc_ldo_low(num) { \ 276 .name = "LDO"#num, \ 277 .id = MAX77686_LDO##num, \ 278 .ops = &max77686_ldo_ops, \ 279 .type = REGULATOR_VOLTAGE, \ 280 .owner = THIS_MODULE, \ 281 .min_uV = MAX77686_LDO_LOW_MINUV, \ 282 .uV_step = MAX77686_LDO_LOW_UVSTEP, \ 283 .ramp_delay = MAX77686_RAMP_DELAY, \ 284 .n_voltages = MAX77686_VSEL_MASK + 1, \ 285 .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 286 .vsel_mask = MAX77686_VSEL_MASK, \ 287 .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 288 .enable_mask = MAX77686_OPMODE_MASK \ 289 << MAX77686_OPMODE_SHIFT, \ 290} 291#define regulator_desc_ldo1_low(num) { \ 292 .name = "LDO"#num, \ 293 .id = MAX77686_LDO##num, \ 294 .ops = &max77686_ops, \ 295 .type = REGULATOR_VOLTAGE, \ 296 .owner = THIS_MODULE, \ 297 .min_uV = MAX77686_LDO_LOW_MINUV, \ 298 .uV_step = MAX77686_LDO_LOW_UVSTEP, \ 299 .ramp_delay = MAX77686_RAMP_DELAY, \ 300 .n_voltages = MAX77686_VSEL_MASK + 1, \ 301 .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 302 .vsel_mask = MAX77686_VSEL_MASK, \ 303 .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ 304 .enable_mask = MAX77686_OPMODE_MASK \ 305 << MAX77686_OPMODE_SHIFT, \ 306} 307#define regulator_desc_buck(num) { \ 308 .name = "BUCK"#num, \ 309 .id = MAX77686_BUCK##num, \ 310 .ops = &max77686_ops, \ 311 .type = REGULATOR_VOLTAGE, \ 312 .owner = THIS_MODULE, \ 313 .min_uV = MAX77686_BUCK_MINUV, \ 314 .uV_step = MAX77686_BUCK_UVSTEP, \ 315 .ramp_delay = MAX77686_RAMP_DELAY, \ 316 .n_voltages = MAX77686_VSEL_MASK + 1, \ 317 .vsel_reg = MAX77686_REG_BUCK5OUT + (num - 5) * 2, \ 318 .vsel_mask = MAX77686_VSEL_MASK, \ 319 .enable_reg = MAX77686_REG_BUCK5CTRL + (num - 5) * 2, \ 320 .enable_mask = MAX77686_OPMODE_MASK, \ 321} 322#define regulator_desc_buck1(num) { \ 323 .name = "BUCK"#num, \ 324 .id = MAX77686_BUCK##num, \ 325 .ops = &max77686_buck1_ops, \ 326 .type = REGULATOR_VOLTAGE, \ 327 .owner = THIS_MODULE, \ 328 .min_uV = MAX77686_BUCK_MINUV, \ 329 .uV_step = MAX77686_BUCK_UVSTEP, \ 330 .ramp_delay = MAX77686_RAMP_DELAY, \ 331 .n_voltages = MAX77686_VSEL_MASK + 1, \ 332 .vsel_reg = MAX77686_REG_BUCK1OUT, \ 333 .vsel_mask = MAX77686_VSEL_MASK, \ 334 .enable_reg = MAX77686_REG_BUCK1CTRL, \ 335 .enable_mask = MAX77686_OPMODE_MASK, \ 336} 337#define regulator_desc_buck_dvs(num) { \ 338 .name = "BUCK"#num, \ 339 .id = MAX77686_BUCK##num, \ 340 .ops = &max77686_buck_dvs_ops, \ 341 .type = REGULATOR_VOLTAGE, \ 342 .owner = THIS_MODULE, \ 343 .min_uV = MAX77686_DVS_MINUV, \ 344 .uV_step = MAX77686_DVS_UVSTEP, \ 345 .ramp_delay = MAX77686_DVS_RAMP_DELAY, \ 346 .n_voltages = MAX77686_DVS_VSEL_MASK + 1, \ 347 .vsel_reg = MAX77686_REG_BUCK2DVS1 + (num - 2) * 10, \ 348 .vsel_mask = MAX77686_DVS_VSEL_MASK, \ 349 .enable_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \ 350 .enable_mask = MAX77686_OPMODE_MASK \ 351 << MAX77686_OPMODE_BUCK234_SHIFT, \ 352} 353 354static struct regulator_desc regulators[] = { 355 regulator_desc_ldo1_low(1), 356 regulator_desc_ldo_low(2), 357 regulator_desc_ldo(3), 358 regulator_desc_ldo(4), 359 regulator_desc_ldo(5), 360 regulator_desc_ldo_low(6), 361 regulator_desc_ldo_low(7), 362 regulator_desc_ldo_low(8), 363 regulator_desc_ldo(9), 364 regulator_desc_lpm_ldo(10), 365 regulator_desc_lpm_ldo(11), 366 regulator_desc_lpm_ldo(12), 367 regulator_desc_ldo(13), 368 regulator_desc_lpm_ldo(14), 369 regulator_desc_ldo_low(15), 370 regulator_desc_lpm_ldo(16), 371 regulator_desc_ldo(17), 372 regulator_desc_ldo(18), 373 regulator_desc_ldo(19), 374 regulator_desc_ldo(20), 375 regulator_desc_ldo(21), 376 regulator_desc_ldo(22), 377 regulator_desc_ldo(23), 378 regulator_desc_ldo(24), 379 regulator_desc_ldo(25), 380 regulator_desc_ldo(26), 381 regulator_desc_buck1(1), 382 regulator_desc_buck_dvs(2), 383 regulator_desc_buck_dvs(3), 384 regulator_desc_buck_dvs(4), 385 regulator_desc_buck(5), 386 regulator_desc_buck(6), 387 regulator_desc_buck(7), 388 regulator_desc_buck(8), 389 regulator_desc_buck(9), 390}; 391 392#ifdef CONFIG_OF 393static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, 394 struct max77686_platform_data *pdata) 395{ 396 struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 397 struct device_node *pmic_np, *regulators_np; 398 struct max77686_regulator_data *rdata; 399 struct of_regulator_match rmatch; 400 unsigned int i; 401 402 pmic_np = iodev->dev->of_node; 403 regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators"); 404 if (!regulators_np) { 405 dev_err(&pdev->dev, "could not find regulators sub-node\n"); 406 return -EINVAL; 407 } 408 409 pdata->num_regulators = ARRAY_SIZE(regulators); 410 rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * 411 pdata->num_regulators, GFP_KERNEL); 412 if (!rdata) { 413 dev_err(&pdev->dev, 414 "could not allocate memory for regulator data\n"); 415 return -ENOMEM; 416 } 417 418 for (i = 0; i < pdata->num_regulators; i++) { 419 rmatch.name = regulators[i].name; 420 rmatch.init_data = NULL; 421 rmatch.of_node = NULL; 422 of_regulator_match(&pdev->dev, regulators_np, &rmatch, 1); 423 rdata[i].initdata = rmatch.init_data; 424 rdata[i].of_node = rmatch.of_node; 425 } 426 427 pdata->regulators = rdata; 428 429 return 0; 430} 431#else 432static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, 433 struct max77686_platform_data *pdata) 434{ 435 return 0; 436} 437#endif /* CONFIG_OF */ 438 439static int max77686_pmic_probe(struct platform_device *pdev) 440{ 441 struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 442 struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); 443 struct max77686_data *max77686; 444 int i, ret = 0; 445 struct regulator_config config = { }; 446 447 dev_dbg(&pdev->dev, "%s\n", __func__); 448 449 if (!pdata) { 450 dev_err(&pdev->dev, "no platform data found for regulator\n"); 451 return -ENODEV; 452 } 453 454 if (iodev->dev->of_node) { 455 ret = max77686_pmic_dt_parse_pdata(pdev, pdata); 456 if (ret) 457 return ret; 458 } 459 460 if (pdata->num_regulators != MAX77686_REGULATORS) { 461 dev_err(&pdev->dev, 462 "Invalid initial data for regulator's initialiation\n"); 463 return -EINVAL; 464 } 465 466 max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data), 467 GFP_KERNEL); 468 if (!max77686) 469 return -ENOMEM; 470 471 config.dev = &pdev->dev; 472 config.regmap = iodev->regmap; 473 config.driver_data = max77686; 474 platform_set_drvdata(pdev, max77686); 475 476 for (i = 0; i < MAX77686_REGULATORS; i++) { 477 config.init_data = pdata->regulators[i].initdata; 478 config.of_node = pdata->regulators[i].of_node; 479 480 max77686->opmode[i] = regulators[i].enable_mask; 481 max77686->rdev[i] = regulator_register(&regulators[i], &config); 482 if (IS_ERR(max77686->rdev[i])) { 483 ret = PTR_ERR(max77686->rdev[i]); 484 dev_err(&pdev->dev, 485 "regulator init failed for %d\n", i); 486 max77686->rdev[i] = NULL; 487 goto err; 488 } 489 } 490 491 return 0; 492err: 493 while (--i >= 0) 494 regulator_unregister(max77686->rdev[i]); 495 return ret; 496} 497 498static int max77686_pmic_remove(struct platform_device *pdev) 499{ 500 struct max77686_data *max77686 = platform_get_drvdata(pdev); 501 int i; 502 503 for (i = 0; i < MAX77686_REGULATORS; i++) 504 regulator_unregister(max77686->rdev[i]); 505 506 return 0; 507} 508 509static const struct platform_device_id max77686_pmic_id[] = { 510 {"max77686-pmic", 0}, 511 { }, 512}; 513MODULE_DEVICE_TABLE(platform, max77686_pmic_id); 514 515static struct platform_driver max77686_pmic_driver = { 516 .driver = { 517 .name = "max77686-pmic", 518 .owner = THIS_MODULE, 519 }, 520 .probe = max77686_pmic_probe, 521 .remove = max77686_pmic_remove, 522 .id_table = max77686_pmic_id, 523}; 524 525static int __init max77686_pmic_init(void) 526{ 527 return platform_driver_register(&max77686_pmic_driver); 528} 529subsys_initcall(max77686_pmic_init); 530 531static void __exit max77686_pmic_cleanup(void) 532{ 533 platform_driver_unregister(&max77686_pmic_driver); 534} 535module_exit(max77686_pmic_cleanup); 536 537MODULE_DESCRIPTION("MAXIM 77686 Regulator Driver"); 538MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>"); 539MODULE_LICENSE("GPL");