root/drivers/regulator/max8907-regulator.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. max8907_regulator_parse_dt
  2. match_init_data
  3. match_of_node
  4. max8907_regulator_parse_dt
  5. match_init_data
  6. match_of_node
  7. max8907_regulator_probe
  8. max8907_regulator_init
  9. max8907_reg_exit

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

/* [<][>][^][v][top][bottom][index][help] */