root/drivers/regulator/hi6421v530-regulator.c

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

DEFINITIONS

This source file includes following definitions.
  1. hi6421v530_regulator_ldo_get_mode
  2. hi6421v530_regulator_ldo_set_mode
  3. hi6421v530_regulator_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Device driver for regulators in Hi6421V530 IC
   4 //
   5 // Copyright (c) <2017> HiSilicon Technologies Co., Ltd.
   6 //              http://www.hisilicon.com
   7 // Copyright (c) <2017> Linaro Ltd.
   8 //              http://www.linaro.org
   9 //
  10 // Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com>
  11 //         Guodong Xu <guodong.xu@linaro.org>
  12 
  13 #include <linux/mfd/hi6421-pmic.h>
  14 #include <linux/module.h>
  15 #include <linux/of.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/regmap.h>
  18 #include <linux/regulator/driver.h>
  19 
  20 /*
  21  * struct hi6421v530_regulator_info - hi6421v530 regulator information
  22  * @desc: regulator description
  23  * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep
  24  * @eco_microamp: eco mode load upper limit (in uA), valid for LDOs only
  25  */
  26 struct hi6421v530_regulator_info {
  27         struct regulator_desc rdesc;
  28         u8 mode_mask;
  29         u32 eco_microamp;
  30 };
  31 
  32 /* HI6421v530 regulators */
  33 enum hi6421v530_regulator_id {
  34         HI6421V530_LDO3,
  35         HI6421V530_LDO9,
  36         HI6421V530_LDO11,
  37         HI6421V530_LDO15,
  38         HI6421V530_LDO16,
  39 };
  40 
  41 static const unsigned int ldo_3_voltages[] = {
  42         1800000, 1825000, 1850000, 1875000,
  43         1900000, 1925000, 1950000, 1975000,
  44         2000000, 2025000, 2050000, 2075000,
  45         2100000, 2125000, 2150000, 2200000,
  46 };
  47 
  48 static const unsigned int ldo_9_11_voltages[] = {
  49         1750000, 1800000, 1825000, 2800000,
  50         2850000, 2950000, 3000000, 3300000,
  51 };
  52 
  53 static const unsigned int ldo_15_16_voltages[] = {
  54         1750000, 1800000, 2400000, 2600000,
  55         2700000, 2850000, 2950000, 3000000,
  56 };
  57 
  58 static const struct regulator_ops hi6421v530_ldo_ops;
  59 
  60 #define HI6421V530_LDO_ENABLE_TIME (350)
  61 
  62 /*
  63  * _id - LDO id name string
  64  * v_table - voltage table
  65  * vreg - voltage select register
  66  * vmask - voltage select mask
  67  * ereg - enable register
  68  * emask - enable mask
  69  * odelay - off/on delay time in uS
  70  * ecomask - eco mode mask
  71  * ecoamp - eco mode load uppler limit in uA
  72  */
  73 #define HI6421V530_LDO(_ID, v_table, vreg, vmask, ereg, emask,          \
  74                    odelay, ecomask, ecoamp) {                           \
  75         .rdesc = {                                                      \
  76                 .name            = #_ID,                                \
  77                 .of_match        = of_match_ptr(#_ID),                  \
  78                 .regulators_node = of_match_ptr("regulators"),          \
  79                 .ops             = &hi6421v530_ldo_ops,                 \
  80                 .type            = REGULATOR_VOLTAGE,                   \
  81                 .id              = HI6421V530_##_ID,                    \
  82                 .owner           = THIS_MODULE,                         \
  83                 .n_voltages      = ARRAY_SIZE(v_table),                 \
  84                 .volt_table      = v_table,                             \
  85                 .vsel_reg        = HI6421_REG_TO_BUS_ADDR(vreg),        \
  86                 .vsel_mask       = vmask,                               \
  87                 .enable_reg      = HI6421_REG_TO_BUS_ADDR(ereg),        \
  88                 .enable_mask     = emask,                               \
  89                 .enable_time     = HI6421V530_LDO_ENABLE_TIME,          \
  90                 .off_on_delay    = odelay,                              \
  91         },                                                              \
  92         .mode_mask      = ecomask,                                      \
  93         .eco_microamp   = ecoamp,                                       \
  94 }
  95 
  96 /* HI6421V530 regulator information */
  97 
  98 static struct hi6421v530_regulator_info hi6421v530_regulator_info[] = {
  99         HI6421V530_LDO(LDO3, ldo_3_voltages, 0x061, 0xf, 0x060, 0x2,
 100                    20000, 0x6, 8000),
 101         HI6421V530_LDO(LDO9, ldo_9_11_voltages, 0x06b, 0x7, 0x06a, 0x2,
 102                    40000, 0x6, 8000),
 103         HI6421V530_LDO(LDO11, ldo_9_11_voltages, 0x06f, 0x7, 0x06e, 0x2,
 104                    40000, 0x6, 8000),
 105         HI6421V530_LDO(LDO15, ldo_15_16_voltages, 0x077, 0x7, 0x076, 0x2,
 106                    40000, 0x6, 8000),
 107         HI6421V530_LDO(LDO16, ldo_15_16_voltages, 0x079, 0x7, 0x078, 0x2,
 108                    40000, 0x6, 8000),
 109 };
 110 
 111 static unsigned int hi6421v530_regulator_ldo_get_mode(
 112                                         struct regulator_dev *rdev)
 113 {
 114         struct hi6421v530_regulator_info *info;
 115         unsigned int reg_val;
 116 
 117         info = rdev_get_drvdata(rdev);
 118         regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
 119 
 120         if (reg_val & (info->mode_mask))
 121                 return REGULATOR_MODE_IDLE;
 122 
 123         return REGULATOR_MODE_NORMAL;
 124 }
 125 
 126 static int hi6421v530_regulator_ldo_set_mode(struct regulator_dev *rdev,
 127                                                 unsigned int mode)
 128 {
 129         struct hi6421v530_regulator_info *info;
 130         unsigned int new_mode;
 131 
 132         info = rdev_get_drvdata(rdev);
 133         switch (mode) {
 134         case REGULATOR_MODE_NORMAL:
 135                 new_mode = 0;
 136                 break;
 137         case REGULATOR_MODE_IDLE:
 138                 new_mode = info->mode_mask;
 139                 break;
 140         default:
 141                 return -EINVAL;
 142         }
 143 
 144         regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
 145                            info->mode_mask, new_mode);
 146 
 147         return 0;
 148 }
 149 
 150 
 151 static const struct regulator_ops hi6421v530_ldo_ops = {
 152         .is_enabled = regulator_is_enabled_regmap,
 153         .enable = regulator_enable_regmap,
 154         .disable = regulator_disable_regmap,
 155         .list_voltage = regulator_list_voltage_table,
 156         .map_voltage = regulator_map_voltage_ascend,
 157         .get_voltage_sel = regulator_get_voltage_sel_regmap,
 158         .set_voltage_sel = regulator_set_voltage_sel_regmap,
 159         .get_mode = hi6421v530_regulator_ldo_get_mode,
 160         .set_mode = hi6421v530_regulator_ldo_set_mode,
 161 };
 162 
 163 static int hi6421v530_regulator_probe(struct platform_device *pdev)
 164 {
 165         struct hi6421_pmic *pmic;
 166         struct regulator_dev *rdev;
 167         struct regulator_config config = { };
 168         unsigned int i;
 169 
 170         pmic = dev_get_drvdata(pdev->dev.parent);
 171         if (!pmic) {
 172                 dev_err(&pdev->dev, "no pmic in the regulator parent node\n");
 173                 return -ENODEV;
 174         }
 175 
 176         for (i = 0; i < ARRAY_SIZE(hi6421v530_regulator_info); i++) {
 177                 config.dev = pdev->dev.parent;
 178                 config.regmap = pmic->regmap;
 179                 config.driver_data = &hi6421v530_regulator_info[i];
 180 
 181                 rdev = devm_regulator_register(&pdev->dev,
 182                                 &hi6421v530_regulator_info[i].rdesc,
 183                                 &config);
 184                 if (IS_ERR(rdev)) {
 185                         dev_err(&pdev->dev, "failed to register regulator %s\n",
 186                                 hi6421v530_regulator_info[i].rdesc.name);
 187                         return PTR_ERR(rdev);
 188                 }
 189         }
 190         return 0;
 191 }
 192 
 193 static const struct platform_device_id hi6421v530_regulator_table[] = {
 194         { .name = "hi6421v530-regulator" },
 195         {},
 196 };
 197 MODULE_DEVICE_TABLE(platform, hi6421v530_regulator_table);
 198 
 199 static struct platform_driver hi6421v530_regulator_driver = {
 200         .id_table = hi6421v530_regulator_table,
 201         .driver = {
 202                 .name   = "hi6421v530-regulator",
 203         },
 204         .probe  = hi6421v530_regulator_probe,
 205 };
 206 module_platform_driver(hi6421v530_regulator_driver);
 207 
 208 MODULE_AUTHOR("Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com>");
 209 MODULE_DESCRIPTION("Hi6421v530 regulator driver");
 210 MODULE_LICENSE("GPL v2");

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