1 /* 2 * max8907-regulator.c -- support regulators in max8907 3 * 4 * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com> 5 * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved. 6 * 7 * Portions based on drivers/regulator/tps65910-regulator.c, 8 * Copyright 2010 Texas Instruments Inc. 9 * Author: Graeme Gregory <gg@slimlogic.co.uk> 10 * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License version 2 as 14 * published by the Free Software Foundation. 15 */ 16 17 #include <linux/err.h> 18 #include <linux/init.h> 19 #include <linux/mfd/core.h> 20 #include <linux/mfd/max8907.h> 21 #include <linux/module.h> 22 #include <linux/of.h> 23 #include <linux/platform_device.h> 24 #include <linux/regulator/driver.h> 25 #include <linux/regulator/machine.h> 26 #include <linux/regulator/of_regulator.h> 27 #include <linux/regmap.h> 28 #include <linux/slab.h> 29 30 #define MAX8907_II2RR_VERSION_MASK 0xF0 31 #define MAX8907_II2RR_VERSION_REV_A 0x00 32 #define MAX8907_II2RR_VERSION_REV_B 0x10 33 #define MAX8907_II2RR_VERSION_REV_C 0x30 34 35 struct max8907_regulator { 36 struct regulator_desc desc[MAX8907_NUM_REGULATORS]; 37 struct regulator_dev *rdev[MAX8907_NUM_REGULATORS]; 38 }; 39 40 #define REG_MBATT() \ 41 [MAX8907_MBATT] = { \ 42 .name = "MBATT", \ 43 .supply_name = "mbatt", \ 44 .id = MAX8907_MBATT, \ 45 .ops = &max8907_mbatt_ops, \ 46 .type = REGULATOR_VOLTAGE, \ 47 .owner = THIS_MODULE, \ 48 } 49 50 #define REG_LDO(ids, supply, base, min, max, step) \ 51 [MAX8907_##ids] = { \ 52 .name = #ids, \ 53 .supply_name = supply, \ 54 .id = MAX8907_##ids, \ 55 .n_voltages = ((max) - (min)) / (step) + 1, \ 56 .ops = &max8907_ldo_ops, \ 57 .type = REGULATOR_VOLTAGE, \ 58 .owner = THIS_MODULE, \ 59 .min_uV = (min), \ 60 .uV_step = (step), \ 61 .vsel_reg = (base) + MAX8907_VOUT, \ 62 .vsel_mask = 0x3f, \ 63 .enable_reg = (base) + MAX8907_CTL, \ 64 .enable_mask = MAX8907_MASK_LDO_EN, \ 65 } 66 67 #define REG_FIXED(ids, supply, voltage) \ 68 [MAX8907_##ids] = { \ 69 .name = #ids, \ 70 .supply_name = supply, \ 71 .id = MAX8907_##ids, \ 72 .n_voltages = 1, \ 73 .ops = &max8907_fixed_ops, \ 74 .type = REGULATOR_VOLTAGE, \ 75 .owner = THIS_MODULE, \ 76 .min_uV = (voltage), \ 77 } 78 79 #define REG_OUT5V(ids, supply, base, voltage) \ 80 [MAX8907_##ids] = { \ 81 .name = #ids, \ 82 .supply_name = supply, \ 83 .id = MAX8907_##ids, \ 84 .n_voltages = 1, \ 85 .ops = &max8907_out5v_ops, \ 86 .type = REGULATOR_VOLTAGE, \ 87 .owner = THIS_MODULE, \ 88 .min_uV = (voltage), \ 89 .enable_reg = (base), \ 90 .enable_mask = MAX8907_MASK_OUT5V_EN, \ 91 } 92 93 #define REG_BBAT(ids, supply, base, min, max, step) \ 94 [MAX8907_##ids] = { \ 95 .name = #ids, \ 96 .supply_name = supply, \ 97 .id = MAX8907_##ids, \ 98 .n_voltages = ((max) - (min)) / (step) + 1, \ 99 .ops = &max8907_bbat_ops, \ 100 .type = REGULATOR_VOLTAGE, \ 101 .owner = THIS_MODULE, \ 102 .min_uV = (min), \ 103 .uV_step = (step), \ 104 .vsel_reg = (base), \ 105 .vsel_mask = MAX8907_MASK_VBBATTCV, \ 106 } 107 108 #define LDO_750_50(id, supply, base) REG_LDO(id, supply, (base), \ 109 750000, 3900000, 50000) 110 #define LDO_650_25(id, supply, base) REG_LDO(id, supply, (base), \ 111 650000, 2225000, 25000) 112 113 static struct regulator_ops max8907_mbatt_ops = { 114 }; 115 116 static struct regulator_ops max8907_ldo_ops = { 117 .list_voltage = regulator_list_voltage_linear, 118 .set_voltage_sel = regulator_set_voltage_sel_regmap, 119 .get_voltage_sel = regulator_get_voltage_sel_regmap, 120 .enable = regulator_enable_regmap, 121 .disable = regulator_disable_regmap, 122 .is_enabled = regulator_is_enabled_regmap, 123 }; 124 125 static struct regulator_ops max8907_ldo_hwctl_ops = { 126 .list_voltage = regulator_list_voltage_linear, 127 .set_voltage_sel = regulator_set_voltage_sel_regmap, 128 .get_voltage_sel = regulator_get_voltage_sel_regmap, 129 }; 130 131 static struct regulator_ops max8907_fixed_ops = { 132 .list_voltage = regulator_list_voltage_linear, 133 }; 134 135 static struct regulator_ops max8907_out5v_ops = { 136 .list_voltage = regulator_list_voltage_linear, 137 .enable = regulator_enable_regmap, 138 .disable = regulator_disable_regmap, 139 .is_enabled = regulator_is_enabled_regmap, 140 }; 141 142 static struct regulator_ops max8907_out5v_hwctl_ops = { 143 .list_voltage = regulator_list_voltage_linear, 144 }; 145 146 static struct regulator_ops max8907_bbat_ops = { 147 .list_voltage = regulator_list_voltage_linear, 148 .set_voltage_sel = regulator_set_voltage_sel_regmap, 149 .get_voltage_sel = regulator_get_voltage_sel_regmap, 150 }; 151 152 static struct regulator_desc max8907_regulators[] = { 153 REG_MBATT(), 154 REG_LDO(SD1, "in-v1", MAX8907_REG_SDCTL1, 650000, 2225000, 25000), 155 REG_LDO(SD2, "in-v2", MAX8907_REG_SDCTL2, 637500, 1425000, 12500), 156 REG_LDO(SD3, "in-v3", MAX8907_REG_SDCTL3, 750000, 3900000, 50000), 157 LDO_750_50(LDO1, "in1", MAX8907_REG_LDOCTL1), 158 LDO_650_25(LDO2, "in2", MAX8907_REG_LDOCTL2), 159 LDO_650_25(LDO3, "in3", MAX8907_REG_LDOCTL3), 160 LDO_750_50(LDO4, "in4", MAX8907_REG_LDOCTL4), 161 LDO_750_50(LDO5, "in5", MAX8907_REG_LDOCTL5), 162 LDO_750_50(LDO6, "in6", MAX8907_REG_LDOCTL6), 163 LDO_750_50(LDO7, "in7", MAX8907_REG_LDOCTL7), 164 LDO_750_50(LDO8, "in8", MAX8907_REG_LDOCTL8), 165 LDO_750_50(LDO9, "in9", MAX8907_REG_LDOCTL9), 166 LDO_750_50(LDO10, "in10", MAX8907_REG_LDOCTL10), 167 LDO_750_50(LDO11, "in11", MAX8907_REG_LDOCTL11), 168 LDO_750_50(LDO12, "in12", MAX8907_REG_LDOCTL12), 169 LDO_750_50(LDO13, "in13", MAX8907_REG_LDOCTL13), 170 LDO_750_50(LDO14, "in14", MAX8907_REG_LDOCTL14), 171 LDO_750_50(LDO15, "in15", MAX8907_REG_LDOCTL15), 172 LDO_750_50(LDO16, "in16", MAX8907_REG_LDOCTL16), 173 LDO_650_25(LDO17, "in17", MAX8907_REG_LDOCTL17), 174 LDO_650_25(LDO18, "in18", MAX8907_REG_LDOCTL18), 175 LDO_750_50(LDO19, "in19", MAX8907_REG_LDOCTL19), 176 LDO_750_50(LDO20, "in20", MAX8907_REG_LDOCTL20), 177 REG_OUT5V(OUT5V, "mbatt", MAX8907_REG_OUT5VEN, 5000000), 178 REG_OUT5V(OUT33V, "mbatt", MAX8907_REG_OUT33VEN, 3300000), 179 REG_BBAT(BBAT, "MBATT", MAX8907_REG_BBAT_CNFG, 180 2400000, 3000000, 200000), 181 REG_FIXED(SDBY, "MBATT", 1200000), 182 REG_FIXED(VRTC, "MBATT", 3300000), 183 }; 184 185 #ifdef CONFIG_OF 186 187 #define MATCH(_name, _id) \ 188 [MAX8907_##_id] = { \ 189 .name = #_name, \ 190 .driver_data = (void *)&max8907_regulators[MAX8907_##_id], \ 191 } 192 193 static struct of_regulator_match max8907_matches[] = { 194 MATCH(mbatt, MBATT), 195 MATCH(sd1, SD1), 196 MATCH(sd2, SD2), 197 MATCH(sd3, SD3), 198 MATCH(ldo1, LDO1), 199 MATCH(ldo2, LDO2), 200 MATCH(ldo3, LDO3), 201 MATCH(ldo4, LDO4), 202 MATCH(ldo5, LDO5), 203 MATCH(ldo6, LDO6), 204 MATCH(ldo7, LDO7), 205 MATCH(ldo8, LDO8), 206 MATCH(ldo9, LDO9), 207 MATCH(ldo10, LDO10), 208 MATCH(ldo11, LDO11), 209 MATCH(ldo12, LDO12), 210 MATCH(ldo13, LDO13), 211 MATCH(ldo14, LDO14), 212 MATCH(ldo15, LDO15), 213 MATCH(ldo16, LDO16), 214 MATCH(ldo17, LDO17), 215 MATCH(ldo18, LDO18), 216 MATCH(ldo19, LDO19), 217 MATCH(ldo20, LDO20), 218 MATCH(out5v, OUT5V), 219 MATCH(out33v, OUT33V), 220 MATCH(bbat, BBAT), 221 MATCH(sdby, SDBY), 222 MATCH(vrtc, VRTC), 223 }; 224 225 static int max8907_regulator_parse_dt(struct platform_device *pdev) 226 { 227 struct device_node *np = pdev->dev.parent->of_node; 228 struct device_node *regulators; 229 int ret; 230 231 if (!pdev->dev.parent->of_node) 232 return 0; 233 234 regulators = of_find_node_by_name(np, "regulators"); 235 if (!regulators) { 236 dev_err(&pdev->dev, "regulators node not found\n"); 237 return -EINVAL; 238 } 239 240 ret = of_regulator_match(pdev->dev.parent, regulators, 241 max8907_matches, 242 ARRAY_SIZE(max8907_matches)); 243 if (ret < 0) { 244 dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", 245 ret); 246 return ret; 247 } 248 249 return 0; 250 } 251 #else 252 static int max8907_regulator_parse_dt(struct platform_device *pdev) 253 { 254 return 0; 255 } 256 #endif 257 258 static __devinit int max8907_regulator_probe(struct platform_device *pdev) 259 { 260 struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent); 261 struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev); 262 int ret; 263 struct max8907_regulator *pmic; 264 unsigned int val; 265 int i; 266 struct regulator_config config = {}; 267 struct regulator_init_data *idata; 268 const char *mbatt_rail_name = NULL; 269 270 ret = max8907_regulator_parse_dt(pdev); 271 if (ret) 272 return ret; 273 274 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); 275 if (!pmic) { 276 dev_err(&pdev->dev, "Failed to alloc pmic\n"); 277 return -ENOMEM; 278 } 279 platform_set_drvdata(pdev, pmic); 280 281 memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); 282 283 /* Backwards compatibility with MAX8907B; SD1 uses different voltages */ 284 regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val); 285 if ((val & MAX8907_II2RR_VERSION_MASK) == 286 MAX8907_II2RR_VERSION_REV_B) { 287 pmic->desc[MAX8907_SD1].min_uV = 637500; 288 pmic->desc[MAX8907_SD1].uV_step = 12500; 289 pmic->desc[MAX8907_SD1].n_voltages = 290 (1425000 - 637500) / 12500 + 1; 291 } 292 293 for (i = 0; i < MAX8907_NUM_REGULATORS; i++) { 294 config.dev = pdev->dev.parent; 295 if (pdata) 296 idata = pdata->init_data[i]; 297 else 298 idata = max8907_matches[i].init_data; 299 config.init_data = idata; 300 config.driver_data = pmic; 301 config.regmap = max8907->regmap_gen; 302 config.of_node = max8907_matches[i].of_node; 303 304 switch (pmic->desc[i].id) { 305 case MAX8907_MBATT: 306 mbatt_rail_name = idata->constraints.name; 307 break; 308 case MAX8907_BBAT: 309 case MAX8907_SDBY: 310 case MAX8907_VRTC: 311 idata->supply_regulator = mbatt_rail_name; 312 break; 313 } 314 315 if (pmic->desc[i].ops == &max8907_ldo_ops) { 316 regmap_read(config.regmap, pmic->desc[i].enable_reg, 317 &val); 318 if ((val & MAX8907_MASK_LDO_SEQ) != 319 MAX8907_MASK_LDO_SEQ) 320 pmic->desc[i].ops = &max8907_ldo_hwctl_ops; 321 } else if (pmic->desc[i].ops == &max8907_out5v_ops) { 322 regmap_read(config.regmap, pmic->desc[i].enable_reg, 323 &val); 324 if ((val & (MAX8907_MASK_OUT5V_VINEN | 325 MAX8907_MASK_OUT5V_ENSRC)) != 326 MAX8907_MASK_OUT5V_ENSRC) 327 pmic->desc[i].ops = &max8907_out5v_hwctl_ops; 328 } 329 330 pmic->rdev[i] = regulator_register(&pmic->desc[i], &config); 331 if (IS_ERR(pmic->rdev[i])) { 332 dev_err(&pdev->dev, 333 "failed to register %s regulator\n", 334 pmic->desc[i].name); 335 ret = PTR_ERR(pmic->rdev[i]); 336 goto err_unregister_regulator; 337 } 338 } 339 340 return 0; 341 342 err_unregister_regulator: 343 while (--i >= 0) 344 regulator_unregister(pmic->rdev[i]); 345 return ret; 346 } 347 348 static __devexit int max8907_regulator_remove(struct platform_device *pdev) 349 { 350 struct max8907_regulator *pmic; 351 int i; 352 353 for (i = 0; i < MAX8907_NUM_REGULATORS; i++) 354 regulator_unregister(pmic->rdev[i]); 355 356 return 0; 357 } 358 359 static struct platform_driver max8907_regulator_driver = { 360 .driver = { 361 .name = "max8907-regulator", 362 .owner = THIS_MODULE, 363 }, 364 .probe = max8907_regulator_probe, 365 .remove = __devexit_p(max8907_regulator_remove), 366 }; 367 368 static int __init max8907_regulator_init(void) 369 { 370 return platform_driver_register(&max8907_regulator_driver); 371 } 372 373 subsys_initcall(max8907_regulator_init); 374 375 static void __exit max8907_reg_exit(void) 376 { 377 platform_driver_unregister(&max8907_regulator_driver); 378 } 379 380 module_exit(max8907_reg_exit); 381 382 MODULE_DESCRIPTION("MAX8907 regulator driver"); 383 MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>"); 384 MODULE_LICENSE("GPL v2"); 385