root/drivers/regulator/bd70528-regulator.c

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

DEFINITIONS

This source file includes following definitions.
  1. bd70528_set_ramp_delay
  2. bd70528_led_set_voltage_sel
  3. bd70528_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (C) 2018 ROHM Semiconductors
   3 // bd70528-regulator.c ROHM BD70528MWV regulator driver
   4 
   5 #include <linux/delay.h>
   6 #include <linux/err.h>
   7 #include <linux/interrupt.h>
   8 #include <linux/kernel.h>
   9 #include <linux/mfd/rohm-bd70528.h>
  10 #include <linux/module.h>
  11 #include <linux/of.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/regmap.h>
  14 #include <linux/regulator/driver.h>
  15 #include <linux/regulator/machine.h>
  16 #include <linux/regulator/of_regulator.h>
  17 #include <linux/slab.h>
  18 
  19 #define BUCK_RAMPRATE_250MV 0
  20 #define BUCK_RAMPRATE_125MV 1
  21 #define BUCK_RAMP_MAX 250
  22 
  23 static const struct regulator_linear_range bd70528_buck1_volts[] = {
  24         REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
  25         REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
  26 };
  27 static const struct regulator_linear_range bd70528_buck2_volts[] = {
  28         REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
  29         REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
  30         REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
  31 };
  32 static const struct regulator_linear_range bd70528_buck3_volts[] = {
  33         REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
  34         REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
  35 };
  36 
  37 /* All LDOs have same voltage ranges */
  38 static const struct regulator_linear_range bd70528_ldo_volts[] = {
  39         REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
  40         REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
  41         REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
  42         REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0),
  43 };
  44 
  45 /* Also both LEDs support same voltages */
  46 static const unsigned int led_volts[] = {
  47         20000, 30000
  48 };
  49 
  50 static int bd70528_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
  51 {
  52         if (ramp_delay > 0 && ramp_delay <= BUCK_RAMP_MAX) {
  53                 unsigned int ramp_value = BUCK_RAMPRATE_250MV;
  54 
  55                 if (ramp_delay <= 125)
  56                         ramp_value = BUCK_RAMPRATE_125MV;
  57 
  58                 return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
  59                                   BD70528_MASK_BUCK_RAMP,
  60                                   ramp_value << BD70528_SIFT_BUCK_RAMP);
  61         }
  62         dev_err(&rdev->dev, "%s: ramp_delay: %d not supported\n",
  63                 rdev->desc->name, ramp_delay);
  64         return -EINVAL;
  65 }
  66 
  67 static int bd70528_led_set_voltage_sel(struct regulator_dev *rdev,
  68                                        unsigned int sel)
  69 {
  70         int ret;
  71 
  72         ret = regulator_is_enabled_regmap(rdev);
  73         if (ret < 0)
  74                 return ret;
  75 
  76         if (ret == 0)
  77                 return regulator_set_voltage_sel_regmap(rdev, sel);
  78 
  79         dev_err(&rdev->dev,
  80                 "LED voltage change not allowed when led is enabled\n");
  81 
  82         return -EBUSY;
  83 }
  84 
  85 static const struct regulator_ops bd70528_buck_ops = {
  86         .enable = regulator_enable_regmap,
  87         .disable = regulator_disable_regmap,
  88         .is_enabled = regulator_is_enabled_regmap,
  89         .list_voltage = regulator_list_voltage_linear_range,
  90         .set_voltage_sel = regulator_set_voltage_sel_regmap,
  91         .get_voltage_sel = regulator_get_voltage_sel_regmap,
  92         .set_voltage_time_sel = regulator_set_voltage_time_sel,
  93         .set_ramp_delay = bd70528_set_ramp_delay,
  94 };
  95 
  96 static const struct regulator_ops bd70528_ldo_ops = {
  97         .enable = regulator_enable_regmap,
  98         .disable = regulator_disable_regmap,
  99         .is_enabled = regulator_is_enabled_regmap,
 100         .list_voltage = regulator_list_voltage_linear_range,
 101         .set_voltage_sel = regulator_set_voltage_sel_regmap,
 102         .get_voltage_sel = regulator_get_voltage_sel_regmap,
 103         .set_voltage_time_sel = regulator_set_voltage_time_sel,
 104 };
 105 
 106 static const struct regulator_ops bd70528_led_ops = {
 107         .enable = regulator_enable_regmap,
 108         .disable = regulator_disable_regmap,
 109         .is_enabled = regulator_is_enabled_regmap,
 110         .list_voltage = regulator_list_voltage_table,
 111         .set_voltage_sel = bd70528_led_set_voltage_sel,
 112         .get_voltage_sel = regulator_get_voltage_sel_regmap,
 113 };
 114 
 115 static const struct regulator_desc bd70528_desc[] = {
 116         {
 117                 .name = "buck1",
 118                 .of_match = of_match_ptr("BUCK1"),
 119                 .regulators_node = of_match_ptr("regulators"),
 120                 .id = BD70528_BUCK1,
 121                 .ops = &bd70528_buck_ops,
 122                 .type = REGULATOR_VOLTAGE,
 123                 .linear_ranges = bd70528_buck1_volts,
 124                 .n_linear_ranges = ARRAY_SIZE(bd70528_buck1_volts),
 125                 .n_voltages = BD70528_BUCK_VOLTS,
 126                 .enable_reg = BD70528_REG_BUCK1_EN,
 127                 .enable_mask = BD70528_MASK_RUN_EN,
 128                 .vsel_reg = BD70528_REG_BUCK1_VOLT,
 129                 .vsel_mask = BD70528_MASK_BUCK_VOLT,
 130                 .owner = THIS_MODULE,
 131         },
 132         {
 133                 .name = "buck2",
 134                 .of_match = of_match_ptr("BUCK2"),
 135                 .regulators_node = of_match_ptr("regulators"),
 136                 .id = BD70528_BUCK2,
 137                 .ops = &bd70528_buck_ops,
 138                 .type = REGULATOR_VOLTAGE,
 139                 .linear_ranges = bd70528_buck2_volts,
 140                 .n_linear_ranges = ARRAY_SIZE(bd70528_buck2_volts),
 141                 .n_voltages = BD70528_BUCK_VOLTS,
 142                 .enable_reg = BD70528_REG_BUCK2_EN,
 143                 .enable_mask = BD70528_MASK_RUN_EN,
 144                 .vsel_reg = BD70528_REG_BUCK2_VOLT,
 145                 .vsel_mask = BD70528_MASK_BUCK_VOLT,
 146                 .owner = THIS_MODULE,
 147         },
 148         {
 149                 .name = "buck3",
 150                 .of_match = of_match_ptr("BUCK3"),
 151                 .regulators_node = of_match_ptr("regulators"),
 152                 .id = BD70528_BUCK3,
 153                 .ops = &bd70528_buck_ops,
 154                 .type = REGULATOR_VOLTAGE,
 155                 .linear_ranges = bd70528_buck3_volts,
 156                 .n_linear_ranges = ARRAY_SIZE(bd70528_buck3_volts),
 157                 .n_voltages = BD70528_BUCK_VOLTS,
 158                 .enable_reg = BD70528_REG_BUCK3_EN,
 159                 .enable_mask = BD70528_MASK_RUN_EN,
 160                 .vsel_reg = BD70528_REG_BUCK3_VOLT,
 161                 .vsel_mask = BD70528_MASK_BUCK_VOLT,
 162                 .owner = THIS_MODULE,
 163         },
 164         {
 165                 .name = "ldo1",
 166                 .of_match = of_match_ptr("LDO1"),
 167                 .regulators_node = of_match_ptr("regulators"),
 168                 .id = BD70528_LDO1,
 169                 .ops = &bd70528_ldo_ops,
 170                 .type = REGULATOR_VOLTAGE,
 171                 .linear_ranges = bd70528_ldo_volts,
 172                 .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
 173                 .n_voltages = BD70528_LDO_VOLTS,
 174                 .enable_reg = BD70528_REG_LDO1_EN,
 175                 .enable_mask = BD70528_MASK_RUN_EN,
 176                 .vsel_reg = BD70528_REG_LDO1_VOLT,
 177                 .vsel_mask = BD70528_MASK_LDO_VOLT,
 178                 .owner = THIS_MODULE,
 179         },
 180         {
 181                 .name = "ldo2",
 182                 .of_match = of_match_ptr("LDO2"),
 183                 .regulators_node = of_match_ptr("regulators"),
 184                 .id = BD70528_LDO2,
 185                 .ops = &bd70528_ldo_ops,
 186                 .type = REGULATOR_VOLTAGE,
 187                 .linear_ranges = bd70528_ldo_volts,
 188                 .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
 189                 .n_voltages = BD70528_LDO_VOLTS,
 190                 .enable_reg = BD70528_REG_LDO2_EN,
 191                 .enable_mask = BD70528_MASK_RUN_EN,
 192                 .vsel_reg = BD70528_REG_LDO2_VOLT,
 193                 .vsel_mask = BD70528_MASK_LDO_VOLT,
 194                 .owner = THIS_MODULE,
 195         },
 196         {
 197                 .name = "ldo3",
 198                 .of_match = of_match_ptr("LDO3"),
 199                 .regulators_node = of_match_ptr("regulators"),
 200                 .id = BD70528_LDO3,
 201                 .ops = &bd70528_ldo_ops,
 202                 .type = REGULATOR_VOLTAGE,
 203                 .linear_ranges = bd70528_ldo_volts,
 204                 .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
 205                 .n_voltages = BD70528_LDO_VOLTS,
 206                 .enable_reg = BD70528_REG_LDO3_EN,
 207                 .enable_mask = BD70528_MASK_RUN_EN,
 208                 .vsel_reg = BD70528_REG_LDO3_VOLT,
 209                 .vsel_mask = BD70528_MASK_LDO_VOLT,
 210                 .owner = THIS_MODULE,
 211         },
 212         {
 213                 .name = "ldo_led1",
 214                 .of_match = of_match_ptr("LDO_LED1"),
 215                 .regulators_node = of_match_ptr("regulators"),
 216                 .id = BD70528_LED1,
 217                 .ops = &bd70528_led_ops,
 218                 .type = REGULATOR_VOLTAGE,
 219                 .volt_table = &led_volts[0],
 220                 .n_voltages = ARRAY_SIZE(led_volts),
 221                 .enable_reg = BD70528_REG_LED_EN,
 222                 .enable_mask = BD70528_MASK_LED1_EN,
 223                 .vsel_reg = BD70528_REG_LED_VOLT,
 224                 .vsel_mask = BD70528_MASK_LED1_VOLT,
 225                 .owner = THIS_MODULE,
 226         },
 227         {
 228                 .name = "ldo_led2",
 229                 .of_match = of_match_ptr("LDO_LED2"),
 230                 .regulators_node = of_match_ptr("regulators"),
 231                 .id = BD70528_LED2,
 232                 .ops = &bd70528_led_ops,
 233                 .type = REGULATOR_VOLTAGE,
 234                 .volt_table = &led_volts[0],
 235                 .n_voltages = ARRAY_SIZE(led_volts),
 236                 .enable_reg = BD70528_REG_LED_EN,
 237                 .enable_mask = BD70528_MASK_LED2_EN,
 238                 .vsel_reg = BD70528_REG_LED_VOLT,
 239                 .vsel_mask = BD70528_MASK_LED2_VOLT,
 240                 .owner = THIS_MODULE,
 241         },
 242 
 243 };
 244 
 245 static int bd70528_probe(struct platform_device *pdev)
 246 {
 247         struct rohm_regmap_dev *bd70528;
 248         int i;
 249         struct regulator_config config = {
 250                 .dev = pdev->dev.parent,
 251         };
 252 
 253         bd70528 = dev_get_drvdata(pdev->dev.parent);
 254         if (!bd70528) {
 255                 dev_err(&pdev->dev, "No MFD driver data\n");
 256                 return -EINVAL;
 257         }
 258 
 259         config.regmap = bd70528->regmap;
 260 
 261         for (i = 0; i < ARRAY_SIZE(bd70528_desc); i++) {
 262                 struct regulator_dev *rdev;
 263 
 264                 rdev = devm_regulator_register(&pdev->dev, &bd70528_desc[i],
 265                                                &config);
 266                 if (IS_ERR(rdev)) {
 267                         dev_err(&pdev->dev,
 268                                 "failed to register %s regulator\n",
 269                                 bd70528_desc[i].name);
 270                         return PTR_ERR(rdev);
 271                 }
 272         }
 273         return 0;
 274 }
 275 
 276 static struct platform_driver bd70528_regulator = {
 277         .driver = {
 278                 .name = "bd70528-pmic"
 279         },
 280         .probe = bd70528_probe,
 281 };
 282 
 283 module_platform_driver(bd70528_regulator);
 284 
 285 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
 286 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
 287 MODULE_LICENSE("GPL");
 288 MODULE_ALIAS("platform:bd70528-pmic");

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