root/drivers/regulator/anatop-regulator.c

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

DEFINITIONS

This source file includes following definitions.
  1. anatop_regmap_set_voltage_time_sel
  2. anatop_regmap_enable
  3. anatop_regmap_disable
  4. anatop_regmap_is_enabled
  5. anatop_regmap_core_set_voltage_sel
  6. anatop_regmap_core_get_voltage_sel
  7. anatop_regmap_get_bypass
  8. anatop_regmap_set_bypass
  9. anatop_regulator_probe
  10. anatop_regulator_init
  11. anatop_regulator_exit

   1 // SPDX-License-Identifier: GPL-2.0+
   2 //
   3 // Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
   4 
   5 #include <linux/slab.h>
   6 #include <linux/device.h>
   7 #include <linux/module.h>
   8 #include <linux/mfd/syscon.h>
   9 #include <linux/err.h>
  10 #include <linux/io.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/of.h>
  13 #include <linux/of_address.h>
  14 #include <linux/regmap.h>
  15 #include <linux/regulator/driver.h>
  16 #include <linux/regulator/of_regulator.h>
  17 #include <linux/regulator/machine.h>
  18 
  19 #define LDO_RAMP_UP_UNIT_IN_CYCLES      64 /* 64 cycles per step */
  20 #define LDO_RAMP_UP_FREQ_IN_MHZ         24 /* cycle based on 24M OSC */
  21 
  22 #define LDO_POWER_GATE                  0x00
  23 #define LDO_FET_FULL_ON                 0x1f
  24 
  25 struct anatop_regulator {
  26         u32 delay_reg;
  27         int delay_bit_shift;
  28         int delay_bit_width;
  29         struct regulator_desc rdesc;
  30         bool bypass;
  31         int sel;
  32 };
  33 
  34 static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg,
  35         unsigned int old_sel,
  36         unsigned int new_sel)
  37 {
  38         struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  39         u32 val;
  40         int ret = 0;
  41 
  42         /* check whether need to care about LDO ramp up speed */
  43         if (anatop_reg->delay_bit_width && new_sel > old_sel) {
  44                 /*
  45                  * the delay for LDO ramp up time is
  46                  * based on the register setting, we need
  47                  * to calculate how many steps LDO need to
  48                  * ramp up, and how much delay needed. (us)
  49                  */
  50                 regmap_read(reg->regmap, anatop_reg->delay_reg, &val);
  51                 val = (val >> anatop_reg->delay_bit_shift) &
  52                         ((1 << anatop_reg->delay_bit_width) - 1);
  53                 ret = (new_sel - old_sel) * (LDO_RAMP_UP_UNIT_IN_CYCLES <<
  54                         val) / LDO_RAMP_UP_FREQ_IN_MHZ + 1;
  55         }
  56 
  57         return ret;
  58 }
  59 
  60 static int anatop_regmap_enable(struct regulator_dev *reg)
  61 {
  62         struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  63         int sel;
  64 
  65         sel = anatop_reg->bypass ? LDO_FET_FULL_ON : anatop_reg->sel;
  66         return regulator_set_voltage_sel_regmap(reg, sel);
  67 }
  68 
  69 static int anatop_regmap_disable(struct regulator_dev *reg)
  70 {
  71         return regulator_set_voltage_sel_regmap(reg, LDO_POWER_GATE);
  72 }
  73 
  74 static int anatop_regmap_is_enabled(struct regulator_dev *reg)
  75 {
  76         return regulator_get_voltage_sel_regmap(reg) != LDO_POWER_GATE;
  77 }
  78 
  79 static int anatop_regmap_core_set_voltage_sel(struct regulator_dev *reg,
  80                                               unsigned selector)
  81 {
  82         struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  83         int ret;
  84 
  85         if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) {
  86                 anatop_reg->sel = selector;
  87                 return 0;
  88         }
  89 
  90         ret = regulator_set_voltage_sel_regmap(reg, selector);
  91         if (!ret)
  92                 anatop_reg->sel = selector;
  93         return ret;
  94 }
  95 
  96 static int anatop_regmap_core_get_voltage_sel(struct regulator_dev *reg)
  97 {
  98         struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  99 
 100         if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg))
 101                 return anatop_reg->sel;
 102 
 103         return regulator_get_voltage_sel_regmap(reg);
 104 }
 105 
 106 static int anatop_regmap_get_bypass(struct regulator_dev *reg, bool *enable)
 107 {
 108         struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
 109         int sel;
 110 
 111         sel = regulator_get_voltage_sel_regmap(reg);
 112         if (sel == LDO_FET_FULL_ON)
 113                 WARN_ON(!anatop_reg->bypass);
 114         else if (sel != LDO_POWER_GATE)
 115                 WARN_ON(anatop_reg->bypass);
 116 
 117         *enable = anatop_reg->bypass;
 118         return 0;
 119 }
 120 
 121 static int anatop_regmap_set_bypass(struct regulator_dev *reg, bool enable)
 122 {
 123         struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
 124         int sel;
 125 
 126         if (enable == anatop_reg->bypass)
 127                 return 0;
 128 
 129         sel = enable ? LDO_FET_FULL_ON : anatop_reg->sel;
 130         anatop_reg->bypass = enable;
 131 
 132         return regulator_set_voltage_sel_regmap(reg, sel);
 133 }
 134 
 135 static struct regulator_ops anatop_rops = {
 136         .set_voltage_sel = regulator_set_voltage_sel_regmap,
 137         .get_voltage_sel = regulator_get_voltage_sel_regmap,
 138         .list_voltage = regulator_list_voltage_linear,
 139         .map_voltage = regulator_map_voltage_linear,
 140 };
 141 
 142 static struct regulator_ops anatop_core_rops = {
 143         .enable = anatop_regmap_enable,
 144         .disable = anatop_regmap_disable,
 145         .is_enabled = anatop_regmap_is_enabled,
 146         .set_voltage_sel = anatop_regmap_core_set_voltage_sel,
 147         .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel,
 148         .get_voltage_sel = anatop_regmap_core_get_voltage_sel,
 149         .list_voltage = regulator_list_voltage_linear,
 150         .map_voltage = regulator_map_voltage_linear,
 151         .get_bypass = anatop_regmap_get_bypass,
 152         .set_bypass = anatop_regmap_set_bypass,
 153 };
 154 
 155 static int anatop_regulator_probe(struct platform_device *pdev)
 156 {
 157         struct device *dev = &pdev->dev;
 158         struct device_node *np = dev->of_node;
 159         struct device_node *anatop_np;
 160         struct regulator_desc *rdesc;
 161         struct regulator_dev *rdev;
 162         struct anatop_regulator *sreg;
 163         struct regulator_init_data *initdata;
 164         struct regulator_config config = { };
 165         struct regmap *regmap;
 166         u32 control_reg;
 167         u32 vol_bit_shift;
 168         u32 vol_bit_width;
 169         u32 min_bit_val;
 170         u32 min_voltage;
 171         u32 max_voltage;
 172         int ret = 0;
 173         u32 val;
 174 
 175         sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
 176         if (!sreg)
 177                 return -ENOMEM;
 178 
 179         rdesc = &sreg->rdesc;
 180         rdesc->type = REGULATOR_VOLTAGE;
 181         rdesc->owner = THIS_MODULE;
 182 
 183         of_property_read_string(np, "regulator-name", &rdesc->name);
 184         if (!rdesc->name) {
 185                 dev_err(dev, "failed to get a regulator-name\n");
 186                 return -EINVAL;
 187         }
 188 
 189         initdata = of_get_regulator_init_data(dev, np, rdesc);
 190         if (!initdata)
 191                 return -ENOMEM;
 192 
 193         initdata->supply_regulator = "vin";
 194 
 195         anatop_np = of_get_parent(np);
 196         if (!anatop_np)
 197                 return -ENODEV;
 198         regmap = syscon_node_to_regmap(anatop_np);
 199         of_node_put(anatop_np);
 200         if (IS_ERR(regmap))
 201                 return PTR_ERR(regmap);
 202 
 203         ret = of_property_read_u32(np, "anatop-reg-offset", &control_reg);
 204         if (ret) {
 205                 dev_err(dev, "no anatop-reg-offset property set\n");
 206                 return ret;
 207         }
 208         ret = of_property_read_u32(np, "anatop-vol-bit-width", &vol_bit_width);
 209         if (ret) {
 210                 dev_err(dev, "no anatop-vol-bit-width property set\n");
 211                 return ret;
 212         }
 213         ret = of_property_read_u32(np, "anatop-vol-bit-shift", &vol_bit_shift);
 214         if (ret) {
 215                 dev_err(dev, "no anatop-vol-bit-shift property set\n");
 216                 return ret;
 217         }
 218         ret = of_property_read_u32(np, "anatop-min-bit-val", &min_bit_val);
 219         if (ret) {
 220                 dev_err(dev, "no anatop-min-bit-val property set\n");
 221                 return ret;
 222         }
 223         ret = of_property_read_u32(np, "anatop-min-voltage", &min_voltage);
 224         if (ret) {
 225                 dev_err(dev, "no anatop-min-voltage property set\n");
 226                 return ret;
 227         }
 228         ret = of_property_read_u32(np, "anatop-max-voltage", &max_voltage);
 229         if (ret) {
 230                 dev_err(dev, "no anatop-max-voltage property set\n");
 231                 return ret;
 232         }
 233 
 234         /* read LDO ramp up setting, only for core reg */
 235         of_property_read_u32(np, "anatop-delay-reg-offset",
 236                              &sreg->delay_reg);
 237         of_property_read_u32(np, "anatop-delay-bit-width",
 238                              &sreg->delay_bit_width);
 239         of_property_read_u32(np, "anatop-delay-bit-shift",
 240                              &sreg->delay_bit_shift);
 241 
 242         rdesc->n_voltages = (max_voltage - min_voltage) / 25000 + 1
 243                             + min_bit_val;
 244         rdesc->min_uV = min_voltage;
 245         rdesc->uV_step = 25000;
 246         rdesc->linear_min_sel = min_bit_val;
 247         rdesc->vsel_reg = control_reg;
 248         rdesc->vsel_mask = ((1 << vol_bit_width) - 1) << vol_bit_shift;
 249         rdesc->min_dropout_uV = 125000;
 250 
 251         config.dev = &pdev->dev;
 252         config.init_data = initdata;
 253         config.driver_data = sreg;
 254         config.of_node = pdev->dev.of_node;
 255         config.regmap = regmap;
 256 
 257         /* Only core regulators have the ramp up delay configuration. */
 258         if (control_reg && sreg->delay_bit_width) {
 259                 rdesc->ops = &anatop_core_rops;
 260 
 261                 ret = regmap_read(config.regmap, rdesc->vsel_reg, &val);
 262                 if (ret) {
 263                         dev_err(dev, "failed to read initial state\n");
 264                         return ret;
 265                 }
 266 
 267                 sreg->sel = (val & rdesc->vsel_mask) >> vol_bit_shift;
 268                 if (sreg->sel == LDO_FET_FULL_ON) {
 269                         sreg->sel = 0;
 270                         sreg->bypass = true;
 271                 }
 272 
 273                 /*
 274                  * In case vddpu was disabled by the bootloader, we need to set
 275                  * a sane default until imx6-cpufreq was probed and changes the
 276                  * voltage to the correct value. In this case we set 1.25V.
 277                  */
 278                 if (!sreg->sel && !strcmp(rdesc->name, "vddpu"))
 279                         sreg->sel = 22;
 280 
 281                 /* set the default voltage of the pcie phy to be 1.100v */
 282                 if (!sreg->sel && !strcmp(rdesc->name, "vddpcie"))
 283                         sreg->sel = 0x10;
 284 
 285                 if (!sreg->bypass && !sreg->sel) {
 286                         dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
 287                         return -EINVAL;
 288                 }
 289         } else {
 290                 u32 enable_bit;
 291 
 292                 rdesc->ops = &anatop_rops;
 293 
 294                 if (!of_property_read_u32(np, "anatop-enable-bit",
 295                                           &enable_bit)) {
 296                         anatop_rops.enable  = regulator_enable_regmap;
 297                         anatop_rops.disable = regulator_disable_regmap;
 298                         anatop_rops.is_enabled = regulator_is_enabled_regmap;
 299 
 300                         rdesc->enable_reg = control_reg;
 301                         rdesc->enable_mask = BIT(enable_bit);
 302                 }
 303         }
 304 
 305         /* register regulator */
 306         rdev = devm_regulator_register(dev, rdesc, &config);
 307         if (IS_ERR(rdev)) {
 308                 dev_err(dev, "failed to register %s\n",
 309                         rdesc->name);
 310                 return PTR_ERR(rdev);
 311         }
 312 
 313         platform_set_drvdata(pdev, rdev);
 314 
 315         return 0;
 316 }
 317 
 318 static const struct of_device_id of_anatop_regulator_match_tbl[] = {
 319         { .compatible = "fsl,anatop-regulator", },
 320         { /* end */ }
 321 };
 322 MODULE_DEVICE_TABLE(of, of_anatop_regulator_match_tbl);
 323 
 324 static struct platform_driver anatop_regulator_driver = {
 325         .driver = {
 326                 .name   = "anatop_regulator",
 327                 .of_match_table = of_anatop_regulator_match_tbl,
 328         },
 329         .probe  = anatop_regulator_probe,
 330 };
 331 
 332 static int __init anatop_regulator_init(void)
 333 {
 334         return platform_driver_register(&anatop_regulator_driver);
 335 }
 336 postcore_initcall(anatop_regulator_init);
 337 
 338 static void __exit anatop_regulator_exit(void)
 339 {
 340         platform_driver_unregister(&anatop_regulator_driver);
 341 }
 342 module_exit(anatop_regulator_exit);
 343 
 344 MODULE_AUTHOR("Nancy Chen <Nancy.Chen@freescale.com>");
 345 MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
 346 MODULE_DESCRIPTION("ANATOP Regulator driver");
 347 MODULE_LICENSE("GPL v2");
 348 MODULE_ALIAS("platform:anatop_regulator");

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