root/drivers/regulator/max77650-regulator.c

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

DEFINITIONS

This source file includes following definitions.
  1. max77650_regulator_is_enabled
  2. max77650_regulator_enable
  3. max77650_regulator_disable
  4. max77650_regulator_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Copyright (C) 2018 BayLibre SAS
   4 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
   5 //
   6 // Regulator driver for MAXIM 77650/77651 charger/power-supply.
   7 
   8 #include <linux/of.h>
   9 #include <linux/mfd/max77650.h>
  10 #include <linux/module.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/regmap.h>
  13 #include <linux/regulator/driver.h>
  14 
  15 #define MAX77650_REGULATOR_EN_CTRL_MASK         GENMASK(3, 0)
  16 #define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \
  17                 ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK)
  18 #define MAX77650_REGULATOR_ENABLED              GENMASK(2, 1)
  19 #define MAX77650_REGULATOR_DISABLED             BIT(2)
  20 
  21 #define MAX77650_REGULATOR_V_LDO_MASK           GENMASK(6, 0)
  22 #define MAX77650_REGULATOR_V_SBB_MASK           GENMASK(5, 0)
  23 #define MAX77651_REGULATOR_V_SBB1_MASK          GENMASK(5, 2)
  24 #define MAX77651_REGULATOR_V_SBB1_RANGE_MASK    GENMASK(1, 0)
  25 
  26 #define MAX77650_REGULATOR_AD_MASK              BIT(3)
  27 #define MAX77650_REGULATOR_AD_DISABLED          0x00
  28 #define MAX77650_REGULATOR_AD_ENABLED           BIT(3)
  29 
  30 #define MAX77650_REGULATOR_CURR_LIM_MASK        GENMASK(7, 6)
  31 
  32 enum {
  33         MAX77650_REGULATOR_ID_LDO = 0,
  34         MAX77650_REGULATOR_ID_SBB0,
  35         MAX77650_REGULATOR_ID_SBB1,
  36         MAX77650_REGULATOR_ID_SBB2,
  37         MAX77650_REGULATOR_NUM_REGULATORS,
  38 };
  39 
  40 struct max77650_regulator_desc {
  41         struct regulator_desc desc;
  42         unsigned int regA;
  43         unsigned int regB;
  44 };
  45 
  46 static struct max77650_regulator_desc max77651_SBB1_desc;
  47 
  48 static const unsigned int max77651_sbb1_volt_range_sel[] = {
  49         0x0, 0x1, 0x2, 0x3
  50 };
  51 
  52 static const struct regulator_linear_range max77651_sbb1_volt_ranges[] = {
  53         /* range index 0 */
  54         REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
  55         /* range index 1 */
  56         REGULATOR_LINEAR_RANGE(3200000, 0x00, 0x0f, 50000),
  57         /* range index 2 */
  58         REGULATOR_LINEAR_RANGE(4000000, 0x00, 0x0f, 50000),
  59         /* range index 3 */
  60         REGULATOR_LINEAR_RANGE(4800000, 0x00, 0x09, 50000),
  61 };
  62 
  63 static const unsigned int max77650_current_limit_table[] = {
  64         1000000, 866000, 707000, 500000,
  65 };
  66 
  67 static int max77650_regulator_is_enabled(struct regulator_dev *rdev)
  68 {
  69         struct max77650_regulator_desc *rdesc;
  70         struct regmap *map;
  71         int val, rv, en;
  72 
  73         rdesc = rdev_get_drvdata(rdev);
  74         map = rdev_get_regmap(rdev);
  75 
  76         rv = regmap_read(map, rdesc->regB, &val);
  77         if (rv)
  78                 return rv;
  79 
  80         en = MAX77650_REGULATOR_EN_CTRL_BITS(val);
  81 
  82         return en != MAX77650_REGULATOR_DISABLED;
  83 }
  84 
  85 static int max77650_regulator_enable(struct regulator_dev *rdev)
  86 {
  87         struct max77650_regulator_desc *rdesc;
  88         struct regmap *map;
  89 
  90         rdesc = rdev_get_drvdata(rdev);
  91         map = rdev_get_regmap(rdev);
  92 
  93         return regmap_update_bits(map, rdesc->regB,
  94                                   MAX77650_REGULATOR_EN_CTRL_MASK,
  95                                   MAX77650_REGULATOR_ENABLED);
  96 }
  97 
  98 static int max77650_regulator_disable(struct regulator_dev *rdev)
  99 {
 100         struct max77650_regulator_desc *rdesc;
 101         struct regmap *map;
 102 
 103         rdesc = rdev_get_drvdata(rdev);
 104         map = rdev_get_regmap(rdev);
 105 
 106         return regmap_update_bits(map, rdesc->regB,
 107                                   MAX77650_REGULATOR_EN_CTRL_MASK,
 108                                   MAX77650_REGULATOR_DISABLED);
 109 }
 110 
 111 static const struct regulator_ops max77650_regulator_LDO_ops = {
 112         .is_enabled             = max77650_regulator_is_enabled,
 113         .enable                 = max77650_regulator_enable,
 114         .disable                = max77650_regulator_disable,
 115         .list_voltage           = regulator_list_voltage_linear,
 116         .map_voltage            = regulator_map_voltage_linear,
 117         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
 118         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
 119         .set_active_discharge   = regulator_set_active_discharge_regmap,
 120 };
 121 
 122 static const struct regulator_ops max77650_regulator_SBB_ops = {
 123         .is_enabled             = max77650_regulator_is_enabled,
 124         .enable                 = max77650_regulator_enable,
 125         .disable                = max77650_regulator_disable,
 126         .list_voltage           = regulator_list_voltage_linear,
 127         .map_voltage            = regulator_map_voltage_linear,
 128         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
 129         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
 130         .get_current_limit      = regulator_get_current_limit_regmap,
 131         .set_current_limit      = regulator_set_current_limit_regmap,
 132         .set_active_discharge   = regulator_set_active_discharge_regmap,
 133 };
 134 
 135 /* Special case for max77651 SBB1 - pickable linear-range voltage mapping. */
 136 static const struct regulator_ops max77651_SBB1_regulator_ops = {
 137         .is_enabled             = max77650_regulator_is_enabled,
 138         .enable                 = max77650_regulator_enable,
 139         .disable                = max77650_regulator_disable,
 140         .list_voltage           = regulator_list_voltage_pickable_linear_range,
 141         .get_voltage_sel        = regulator_get_voltage_sel_pickable_regmap,
 142         .set_voltage_sel        = regulator_set_voltage_sel_pickable_regmap,
 143         .get_current_limit      = regulator_get_current_limit_regmap,
 144         .set_current_limit      = regulator_set_current_limit_regmap,
 145         .set_active_discharge   = regulator_set_active_discharge_regmap,
 146 };
 147 
 148 static struct max77650_regulator_desc max77650_LDO_desc = {
 149         .desc = {
 150                 .name                   = "ldo",
 151                 .of_match               = of_match_ptr("ldo"),
 152                 .regulators_node        = of_match_ptr("regulators"),
 153                 .supply_name            = "in-ldo",
 154                 .id                     = MAX77650_REGULATOR_ID_LDO,
 155                 .ops                    = &max77650_regulator_LDO_ops,
 156                 .min_uV                 = 1350000,
 157                 .uV_step                = 12500,
 158                 .n_voltages             = 128,
 159                 .vsel_step              = 1,
 160                 .vsel_mask              = MAX77650_REGULATOR_V_LDO_MASK,
 161                 .vsel_reg               = MAX77650_REG_CNFG_LDO_A,
 162                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
 163                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
 164                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
 165                 .active_discharge_reg   = MAX77650_REG_CNFG_LDO_B,
 166                 .enable_time            = 100,
 167                 .type                   = REGULATOR_VOLTAGE,
 168                 .owner                  = THIS_MODULE,
 169         },
 170         .regA           = MAX77650_REG_CNFG_LDO_A,
 171         .regB           = MAX77650_REG_CNFG_LDO_B,
 172 };
 173 
 174 static struct max77650_regulator_desc max77650_SBB0_desc = {
 175         .desc = {
 176                 .name                   = "sbb0",
 177                 .of_match               = of_match_ptr("sbb0"),
 178                 .regulators_node        = of_match_ptr("regulators"),
 179                 .supply_name            = "in-sbb0",
 180                 .id                     = MAX77650_REGULATOR_ID_SBB0,
 181                 .ops                    = &max77650_regulator_SBB_ops,
 182                 .min_uV                 = 800000,
 183                 .uV_step                = 25000,
 184                 .n_voltages             = 64,
 185                 .vsel_step              = 1,
 186                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
 187                 .vsel_reg               = MAX77650_REG_CNFG_SBB0_A,
 188                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
 189                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
 190                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
 191                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB0_B,
 192                 .enable_time            = 100,
 193                 .type                   = REGULATOR_VOLTAGE,
 194                 .owner                  = THIS_MODULE,
 195                 .csel_reg               = MAX77650_REG_CNFG_SBB0_A,
 196                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
 197                 .curr_table             = max77650_current_limit_table,
 198                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
 199         },
 200         .regA           = MAX77650_REG_CNFG_SBB0_A,
 201         .regB           = MAX77650_REG_CNFG_SBB0_B,
 202 };
 203 
 204 static struct max77650_regulator_desc max77650_SBB1_desc = {
 205         .desc = {
 206                 .name                   = "sbb1",
 207                 .of_match               = of_match_ptr("sbb1"),
 208                 .regulators_node        = of_match_ptr("regulators"),
 209                 .supply_name            = "in-sbb1",
 210                 .id                     = MAX77650_REGULATOR_ID_SBB1,
 211                 .ops                    = &max77650_regulator_SBB_ops,
 212                 .min_uV                 = 800000,
 213                 .uV_step                = 12500,
 214                 .n_voltages             = 64,
 215                 .vsel_step              = 1,
 216                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
 217                 .vsel_reg               = MAX77650_REG_CNFG_SBB1_A,
 218                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
 219                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
 220                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
 221                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB1_B,
 222                 .enable_time            = 100,
 223                 .type                   = REGULATOR_VOLTAGE,
 224                 .owner                  = THIS_MODULE,
 225                 .csel_reg               = MAX77650_REG_CNFG_SBB1_A,
 226                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
 227                 .curr_table             = max77650_current_limit_table,
 228                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
 229         },
 230         .regA           = MAX77650_REG_CNFG_SBB1_A,
 231         .regB           = MAX77650_REG_CNFG_SBB1_B,
 232 };
 233 
 234 static struct max77650_regulator_desc max77651_SBB1_desc = {
 235         .desc = {
 236                 .name                   = "sbb1",
 237                 .of_match               = of_match_ptr("sbb1"),
 238                 .regulators_node        = of_match_ptr("regulators"),
 239                 .supply_name            = "in-sbb1",
 240                 .id                     = MAX77650_REGULATOR_ID_SBB1,
 241                 .ops                    = &max77651_SBB1_regulator_ops,
 242                 .linear_range_selectors = max77651_sbb1_volt_range_sel,
 243                 .linear_ranges          = max77651_sbb1_volt_ranges,
 244                 .n_linear_ranges        = ARRAY_SIZE(max77651_sbb1_volt_ranges),
 245                 .n_voltages             = 58,
 246                 .vsel_step              = 1,
 247                 .vsel_range_mask        = MAX77651_REGULATOR_V_SBB1_RANGE_MASK,
 248                 .vsel_range_reg         = MAX77650_REG_CNFG_SBB1_A,
 249                 .vsel_mask              = MAX77651_REGULATOR_V_SBB1_MASK,
 250                 .vsel_reg               = MAX77650_REG_CNFG_SBB1_A,
 251                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
 252                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
 253                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
 254                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB1_B,
 255                 .enable_time            = 100,
 256                 .type                   = REGULATOR_VOLTAGE,
 257                 .owner                  = THIS_MODULE,
 258                 .csel_reg               = MAX77650_REG_CNFG_SBB1_A,
 259                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
 260                 .curr_table             = max77650_current_limit_table,
 261                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
 262         },
 263         .regA           = MAX77650_REG_CNFG_SBB1_A,
 264         .regB           = MAX77650_REG_CNFG_SBB1_B,
 265 };
 266 
 267 static struct max77650_regulator_desc max77650_SBB2_desc = {
 268         .desc = {
 269                 .name                   = "sbb2",
 270                 .of_match               = of_match_ptr("sbb2"),
 271                 .regulators_node        = of_match_ptr("regulators"),
 272                 .supply_name            = "in-sbb0",
 273                 .id                     = MAX77650_REGULATOR_ID_SBB2,
 274                 .ops                    = &max77650_regulator_SBB_ops,
 275                 .min_uV                 = 800000,
 276                 .uV_step                = 50000,
 277                 .n_voltages             = 64,
 278                 .vsel_step              = 1,
 279                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
 280                 .vsel_reg               = MAX77650_REG_CNFG_SBB2_A,
 281                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
 282                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
 283                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
 284                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB2_B,
 285                 .enable_time            = 100,
 286                 .type                   = REGULATOR_VOLTAGE,
 287                 .owner                  = THIS_MODULE,
 288                 .csel_reg               = MAX77650_REG_CNFG_SBB2_A,
 289                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
 290                 .curr_table             = max77650_current_limit_table,
 291                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
 292         },
 293         .regA           = MAX77650_REG_CNFG_SBB2_A,
 294         .regB           = MAX77650_REG_CNFG_SBB2_B,
 295 };
 296 
 297 static struct max77650_regulator_desc max77651_SBB2_desc = {
 298         .desc = {
 299                 .name                   = "sbb2",
 300                 .of_match               = of_match_ptr("sbb2"),
 301                 .regulators_node        = of_match_ptr("regulators"),
 302                 .supply_name            = "in-sbb0",
 303                 .id                     = MAX77650_REGULATOR_ID_SBB2,
 304                 .ops                    = &max77650_regulator_SBB_ops,
 305                 .min_uV                 = 2400000,
 306                 .uV_step                = 50000,
 307                 .n_voltages             = 64,
 308                 .vsel_step              = 1,
 309                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
 310                 .vsel_reg               = MAX77650_REG_CNFG_SBB2_A,
 311                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
 312                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
 313                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
 314                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB2_B,
 315                 .enable_time            = 100,
 316                 .type                   = REGULATOR_VOLTAGE,
 317                 .owner                  = THIS_MODULE,
 318                 .csel_reg               = MAX77650_REG_CNFG_SBB2_A,
 319                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
 320                 .curr_table             = max77650_current_limit_table,
 321                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
 322         },
 323         .regA           = MAX77650_REG_CNFG_SBB2_A,
 324         .regB           = MAX77650_REG_CNFG_SBB2_B,
 325 };
 326 
 327 static int max77650_regulator_probe(struct platform_device *pdev)
 328 {
 329         struct max77650_regulator_desc **rdescs;
 330         struct max77650_regulator_desc *rdesc;
 331         struct regulator_config config = { };
 332         struct device *dev, *parent;
 333         struct regulator_dev *rdev;
 334         struct regmap *map;
 335         unsigned int val;
 336         int i, rv;
 337 
 338         dev = &pdev->dev;
 339         parent = dev->parent;
 340 
 341         if (!dev->of_node)
 342                 dev->of_node = parent->of_node;
 343 
 344         rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
 345                               sizeof(*rdescs), GFP_KERNEL);
 346         if (!rdescs)
 347                 return -ENOMEM;
 348 
 349         map = dev_get_regmap(parent, NULL);
 350         if (!map)
 351                 return -ENODEV;
 352 
 353         rv = regmap_read(map, MAX77650_REG_CID, &val);
 354         if (rv)
 355                 return rv;
 356 
 357         rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc;
 358         rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc;
 359 
 360         switch (MAX77650_CID_BITS(val)) {
 361         case MAX77650_CID_77650A:
 362         case MAX77650_CID_77650C:
 363                 rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc;
 364                 rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc;
 365                 break;
 366         case MAX77650_CID_77651A:
 367         case MAX77650_CID_77651B:
 368                 rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc;
 369                 rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc;
 370                 break;
 371         default:
 372                 return -ENODEV;
 373         }
 374 
 375         config.dev = parent;
 376 
 377         for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) {
 378                 rdesc = rdescs[i];
 379                 config.driver_data = rdesc;
 380 
 381                 rdev = devm_regulator_register(dev, &rdesc->desc, &config);
 382                 if (IS_ERR(rdev))
 383                         return PTR_ERR(rdev);
 384         }
 385 
 386         return 0;
 387 }
 388 
 389 static struct platform_driver max77650_regulator_driver = {
 390         .driver = {
 391                 .name = "max77650-regulator",
 392         },
 393         .probe = max77650_regulator_probe,
 394 };
 395 module_platform_driver(max77650_regulator_driver);
 396 
 397 MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
 398 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
 399 MODULE_LICENSE("GPL v2");
 400 MODULE_ALIAS("platform:max77650-regulator");

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