linux/drivers/regulator/axp20x-regulator.c
<<
>>
Prefs
   1/*
   2 * AXP20x regulators driver.
   3 *
   4 * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
   5 *
   6 * This file is subject to the terms and conditions of the GNU General
   7 * Public License. See the file "COPYING" in the main directory of this
   8 * archive for more details.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/err.h>
  17#include <linux/init.h>
  18#include <linux/module.h>
  19#include <linux/of.h>
  20#include <linux/of_device.h>
  21#include <linux/platform_device.h>
  22#include <linux/regmap.h>
  23#include <linux/mfd/axp20x.h>
  24#include <linux/regulator/driver.h>
  25#include <linux/regulator/of_regulator.h>
  26
  27#define AXP20X_IO_ENABLED               0x03
  28#define AXP20X_IO_DISABLED              0x07
  29
  30#define AXP22X_IO_ENABLED               0x03
  31#define AXP22X_IO_DISABLED              0x04
  32
  33#define AXP20X_WORKMODE_DCDC2_MASK      BIT(2)
  34#define AXP20X_WORKMODE_DCDC3_MASK      BIT(1)
  35#define AXP22X_WORKMODE_DCDCX_MASK(x)   BIT(x)
  36
  37#define AXP20X_FREQ_DCDC_MASK           0x0f
  38
  39#define AXP22X_MISC_N_VBUSEN_FUNC       BIT(4)
  40
  41#define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg,    \
  42                    _vmask, _ereg, _emask, _enable_val, _disable_val)           \
  43        [_family##_##_id] = {                                                   \
  44                .name           = (_match),                                     \
  45                .supply_name    = (_supply),                                    \
  46                .of_match       = of_match_ptr(_match),                         \
  47                .regulators_node = of_match_ptr("regulators"),                  \
  48                .type           = REGULATOR_VOLTAGE,                            \
  49                .id             = _family##_##_id,                              \
  50                .n_voltages     = (((_max) - (_min)) / (_step) + 1),            \
  51                .owner          = THIS_MODULE,                                  \
  52                .min_uV         = (_min) * 1000,                                \
  53                .uV_step        = (_step) * 1000,                               \
  54                .vsel_reg       = (_vreg),                                      \
  55                .vsel_mask      = (_vmask),                                     \
  56                .enable_reg     = (_ereg),                                      \
  57                .enable_mask    = (_emask),                                     \
  58                .enable_val     = (_enable_val),                                \
  59                .disable_val    = (_disable_val),                               \
  60                .ops            = &axp20x_ops,                                  \
  61        }
  62
  63#define AXP_DESC(_family, _id, _match, _supply, _min, _max, _step, _vreg,       \
  64                 _vmask, _ereg, _emask)                                         \
  65        [_family##_##_id] = {                                                   \
  66                .name           = (_match),                                     \
  67                .supply_name    = (_supply),                                    \
  68                .of_match       = of_match_ptr(_match),                         \
  69                .regulators_node = of_match_ptr("regulators"),                  \
  70                .type           = REGULATOR_VOLTAGE,                            \
  71                .id             = _family##_##_id,                              \
  72                .n_voltages     = (((_max) - (_min)) / (_step) + 1),            \
  73                .owner          = THIS_MODULE,                                  \
  74                .min_uV         = (_min) * 1000,                                \
  75                .uV_step        = (_step) * 1000,                               \
  76                .vsel_reg       = (_vreg),                                      \
  77                .vsel_mask      = (_vmask),                                     \
  78                .enable_reg     = (_ereg),                                      \
  79                .enable_mask    = (_emask),                                     \
  80                .ops            = &axp20x_ops,                                  \
  81        }
  82
  83#define AXP_DESC_SW(_family, _id, _match, _supply, _ereg, _emask)               \
  84        [_family##_##_id] = {                                                   \
  85                .name           = (_match),                                     \
  86                .supply_name    = (_supply),                                    \
  87                .of_match       = of_match_ptr(_match),                         \
  88                .regulators_node = of_match_ptr("regulators"),                  \
  89                .type           = REGULATOR_VOLTAGE,                            \
  90                .id             = _family##_##_id,                              \
  91                .owner          = THIS_MODULE,                                  \
  92                .enable_reg     = (_ereg),                                      \
  93                .enable_mask    = (_emask),                                     \
  94                .ops            = &axp20x_ops_sw,                               \
  95        }
  96
  97#define AXP_DESC_FIXED(_family, _id, _match, _supply, _volt)                    \
  98        [_family##_##_id] = {                                                   \
  99                .name           = (_match),                                     \
 100                .supply_name    = (_supply),                                    \
 101                .of_match       = of_match_ptr(_match),                         \
 102                .regulators_node = of_match_ptr("regulators"),                  \
 103                .type           = REGULATOR_VOLTAGE,                            \
 104                .id             = _family##_##_id,                              \
 105                .n_voltages     = 1,                                            \
 106                .owner          = THIS_MODULE,                                  \
 107                .min_uV         = (_volt) * 1000,                               \
 108                .ops            = &axp20x_ops_fixed                             \
 109        }
 110
 111#define AXP_DESC_RANGES(_family, _id, _match, _supply, _ranges, _n_voltages,    \
 112                        _vreg, _vmask, _ereg, _emask)                           \
 113        [_family##_##_id] = {                                                   \
 114                .name           = (_match),                                     \
 115                .supply_name    = (_supply),                                    \
 116                .of_match       = of_match_ptr(_match),                         \
 117                .regulators_node = of_match_ptr("regulators"),                  \
 118                .type           = REGULATOR_VOLTAGE,                            \
 119                .id             = _family##_##_id,                              \
 120                .n_voltages     = (_n_voltages),                                \
 121                .owner          = THIS_MODULE,                                  \
 122                .vsel_reg       = (_vreg),                                      \
 123                .vsel_mask      = (_vmask),                                     \
 124                .enable_reg     = (_ereg),                                      \
 125                .enable_mask    = (_emask),                                     \
 126                .linear_ranges  = (_ranges),                                    \
 127                .n_linear_ranges = ARRAY_SIZE(_ranges),                         \
 128                .ops            = &axp20x_ops_range,                            \
 129        }
 130
 131static const struct regulator_ops axp20x_ops_fixed = {
 132        .list_voltage           = regulator_list_voltage_linear,
 133};
 134
 135static const struct regulator_ops axp20x_ops_range = {
 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_range,
 139        .enable                 = regulator_enable_regmap,
 140        .disable                = regulator_disable_regmap,
 141        .is_enabled             = regulator_is_enabled_regmap,
 142};
 143
 144static const struct regulator_ops axp20x_ops = {
 145        .set_voltage_sel        = regulator_set_voltage_sel_regmap,
 146        .get_voltage_sel        = regulator_get_voltage_sel_regmap,
 147        .list_voltage           = regulator_list_voltage_linear,
 148        .enable                 = regulator_enable_regmap,
 149        .disable                = regulator_disable_regmap,
 150        .is_enabled             = regulator_is_enabled_regmap,
 151};
 152
 153static const struct regulator_ops axp20x_ops_sw = {
 154        .enable                 = regulator_enable_regmap,
 155        .disable                = regulator_disable_regmap,
 156        .is_enabled             = regulator_is_enabled_regmap,
 157};
 158
 159static const struct regulator_linear_range axp20x_ldo4_ranges[] = {
 160        REGULATOR_LINEAR_RANGE(1250000, 0x0, 0x0, 0),
 161        REGULATOR_LINEAR_RANGE(1300000, 0x1, 0x8, 100000),
 162        REGULATOR_LINEAR_RANGE(2500000, 0x9, 0x9, 0),
 163        REGULATOR_LINEAR_RANGE(2700000, 0xa, 0xb, 100000),
 164        REGULATOR_LINEAR_RANGE(3000000, 0xc, 0xf, 100000),
 165};
 166
 167static const struct regulator_desc axp20x_regulators[] = {
 168        AXP_DESC(AXP20X, DCDC2, "dcdc2", "vin2", 700, 2275, 25,
 169                 AXP20X_DCDC2_V_OUT, 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
 170        AXP_DESC(AXP20X, DCDC3, "dcdc3", "vin3", 700, 3500, 25,
 171                 AXP20X_DCDC3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
 172        AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 1300),
 173        AXP_DESC(AXP20X, LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
 174                 AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
 175        AXP_DESC(AXP20X, LDO3, "ldo3", "ldo3in", 700, 3500, 25,
 176                 AXP20X_LDO3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x40),
 177        AXP_DESC_RANGES(AXP20X, LDO4, "ldo4", "ldo24in", axp20x_ldo4_ranges,
 178                        16, AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL,
 179                        0x08),
 180        AXP_DESC_IO(AXP20X, LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
 181                    AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07,
 182                    AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
 183};
 184
 185static const struct regulator_desc axp22x_regulators[] = {
 186        AXP_DESC(AXP22X, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
 187                 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
 188        AXP_DESC(AXP22X, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
 189                 AXP22X_DCDC2_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(2)),
 190        AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
 191                 AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
 192        AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20,
 193                 AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(4)),
 194        AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
 195                 AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)),
 196        /* secondary switchable output of DCDC1 */
 197        AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", NULL, AXP22X_PWR_OUT_CTRL2,
 198                    BIT(7)),
 199        /* LDO regulator internally chained to DCDC5 */
 200        AXP_DESC(AXP22X, DC5LDO, "dc5ldo", NULL, 700, 1400, 100,
 201                 AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)),
 202        AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
 203                 AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)),
 204        AXP_DESC(AXP22X, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
 205                 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
 206        AXP_DESC(AXP22X, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
 207                 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
 208        AXP_DESC(AXP22X, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
 209                 AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
 210        AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
 211                 AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(4)),
 212        AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
 213                 AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
 214        AXP_DESC(AXP22X, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
 215                 AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
 216        AXP_DESC(AXP22X, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
 217                 AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
 218        AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
 219                 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
 220        AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
 221                 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
 222        /* Note the datasheet only guarantees reliable operation up to
 223         * 3.3V, this needs to be enforced via dts provided constraints */
 224        AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 700, 3800, 100,
 225                    AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
 226                    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 227        /* Note the datasheet only guarantees reliable operation up to
 228         * 3.3V, this needs to be enforced via dts provided constraints */
 229        AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 700, 3800, 100,
 230                    AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
 231                    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 232        AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
 233};
 234
 235static const struct regulator_desc axp22x_drivevbus_regulator = {
 236        .name           = "drivevbus",
 237        .supply_name    = "drivevbus",
 238        .of_match       = of_match_ptr("drivevbus"),
 239        .regulators_node = of_match_ptr("regulators"),
 240        .type           = REGULATOR_VOLTAGE,
 241        .owner          = THIS_MODULE,
 242        .enable_reg     = AXP20X_VBUS_IPSOUT_MGMT,
 243        .enable_mask    = BIT(2),
 244        .ops            = &axp20x_ops_sw,
 245};
 246
 247static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
 248        REGULATOR_LINEAR_RANGE(500000, 0x0, 0x46, 10000),
 249        REGULATOR_LINEAR_RANGE(1220000, 0x47, 0x4b, 20000),
 250};
 251
 252static const struct regulator_linear_range axp803_dcdc5_ranges[] = {
 253        REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 10000),
 254        REGULATOR_LINEAR_RANGE(1140000, 0x21, 0x44, 20000),
 255};
 256
 257static const struct regulator_linear_range axp803_dcdc6_ranges[] = {
 258        REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
 259        REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
 260};
 261
 262/* AXP806's CLDO2 and AXP809's DLDO1 shares the same range */
 263static const struct regulator_linear_range axp803_dldo2_ranges[] = {
 264        REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000),
 265        REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000),
 266};
 267
 268static const struct regulator_desc axp803_regulators[] = {
 269        AXP_DESC(AXP803, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
 270                 AXP803_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(0)),
 271        AXP_DESC_RANGES(AXP803, DCDC2, "dcdc2", "vin2", axp803_dcdc234_ranges,
 272                        76, AXP803_DCDC2_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
 273                        BIT(1)),
 274        AXP_DESC_RANGES(AXP803, DCDC3, "dcdc3", "vin3", axp803_dcdc234_ranges,
 275                        76, AXP803_DCDC3_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
 276                        BIT(2)),
 277        AXP_DESC_RANGES(AXP803, DCDC4, "dcdc4", "vin4", axp803_dcdc234_ranges,
 278                        76, AXP803_DCDC4_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
 279                        BIT(3)),
 280        AXP_DESC_RANGES(AXP803, DCDC5, "dcdc5", "vin5", axp803_dcdc5_ranges,
 281                        68, AXP803_DCDC5_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
 282                        BIT(4)),
 283        AXP_DESC_RANGES(AXP803, DCDC6, "dcdc6", "vin6", axp803_dcdc6_ranges,
 284                        72, AXP803_DCDC6_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
 285                        BIT(5)),
 286        /* secondary switchable output of DCDC1 */
 287        AXP_DESC_SW(AXP803, DC1SW, "dc1sw", NULL, AXP22X_PWR_OUT_CTRL2,
 288                    BIT(7)),
 289        AXP_DESC(AXP803, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
 290                 AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(5)),
 291        AXP_DESC(AXP803, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
 292                 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(6)),
 293        AXP_DESC(AXP803, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
 294                 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
 295        AXP_DESC(AXP803, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
 296                 AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
 297        AXP_DESC_RANGES(AXP803, DLDO2, "dldo2", "dldoin", axp803_dldo2_ranges,
 298                        32, AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
 299                        BIT(4)),
 300        AXP_DESC(AXP803, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
 301                 AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
 302        AXP_DESC(AXP803, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
 303                 AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
 304        AXP_DESC(AXP803, ELDO1, "eldo1", "eldoin", 700, 1900, 50,
 305                 AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
 306        AXP_DESC(AXP803, ELDO2, "eldo2", "eldoin", 700, 1900, 50,
 307                 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
 308        AXP_DESC(AXP803, ELDO3, "eldo3", "eldoin", 700, 1900, 50,
 309                 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
 310        AXP_DESC(AXP803, FLDO1, "fldo1", "fldoin", 700, 1450, 50,
 311                 AXP803_FLDO1_V_OUT, 0x0f, AXP22X_PWR_OUT_CTRL3, BIT(2)),
 312        AXP_DESC(AXP803, FLDO2, "fldo2", "fldoin", 700, 1450, 50,
 313                 AXP803_FLDO2_V_OUT, 0x0f, AXP22X_PWR_OUT_CTRL3, BIT(3)),
 314        AXP_DESC_IO(AXP803, LDO_IO0, "ldo-io0", "ips", 700, 3300, 100,
 315                    AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
 316                    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 317        AXP_DESC_IO(AXP803, LDO_IO1, "ldo-io1", "ips", 700, 3300, 100,
 318                    AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
 319                    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 320        AXP_DESC_FIXED(AXP803, RTC_LDO, "rtc-ldo", "ips", 3000),
 321};
 322
 323static const struct regulator_linear_range axp806_dcdca_ranges[] = {
 324        REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
 325        REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
 326};
 327
 328static const struct regulator_linear_range axp806_dcdcd_ranges[] = {
 329        REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2d, 20000),
 330        REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000),
 331};
 332
 333static const struct regulator_desc axp806_regulators[] = {
 334        AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges,
 335                        72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
 336                        BIT(0)),
 337        AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50,
 338                 AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(1)),
 339        AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc", axp806_dcdca_ranges,
 340                        72, AXP806_DCDCC_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
 341                        BIT(2)),
 342        AXP_DESC_RANGES(AXP806, DCDCD, "dcdcd", "vind", axp806_dcdcd_ranges,
 343                        64, AXP806_DCDCD_V_CTRL, 0x3f, AXP806_PWR_OUT_CTRL1,
 344                        BIT(3)),
 345        AXP_DESC(AXP806, DCDCE, "dcdce", "vine", 1100, 3400, 100,
 346                 AXP806_DCDCE_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(4)),
 347        AXP_DESC(AXP806, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
 348                 AXP806_ALDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(5)),
 349        AXP_DESC(AXP806, ALDO2, "aldo2", "aldoin", 700, 3400, 100,
 350                 AXP806_ALDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(6)),
 351        AXP_DESC(AXP806, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
 352                 AXP806_ALDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(7)),
 353        AXP_DESC(AXP806, BLDO1, "bldo1", "bldoin", 700, 1900, 100,
 354                 AXP806_BLDO1_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(0)),
 355        AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100,
 356                 AXP806_BLDO2_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(1)),
 357        AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100,
 358                 AXP806_BLDO3_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(2)),
 359        AXP_DESC(AXP806, BLDO4, "bldo4", "bldoin", 700, 1900, 100,
 360                 AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)),
 361        AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
 362                 AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)),
 363        AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp803_dldo2_ranges,
 364                        32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2,
 365                        BIT(5)),
 366        AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
 367                 AXP806_CLDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(6)),
 368        AXP_DESC_SW(AXP806, SW, "sw", "swin", AXP806_PWR_OUT_CTRL2, BIT(7)),
 369};
 370
 371static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
 372        REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000),
 373        REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000),
 374};
 375
 376static const struct regulator_desc axp809_regulators[] = {
 377        AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
 378                 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
 379        AXP_DESC(AXP809, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
 380                 AXP22X_DCDC2_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(2)),
 381        AXP_DESC(AXP809, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
 382                 AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
 383        AXP_DESC_RANGES(AXP809, DCDC4, "dcdc4", "vin4", axp809_dcdc4_ranges,
 384                        57, AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1,
 385                        BIT(4)),
 386        AXP_DESC(AXP809, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
 387                 AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)),
 388        /* secondary switchable output of DCDC1 */
 389        AXP_DESC_SW(AXP809, DC1SW, "dc1sw", NULL, AXP22X_PWR_OUT_CTRL2,
 390                    BIT(7)),
 391        /* LDO regulator internally chained to DCDC5 */
 392        AXP_DESC(AXP809, DC5LDO, "dc5ldo", NULL, 700, 1400, 100,
 393                 AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)),
 394        AXP_DESC(AXP809, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
 395                 AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)),
 396        AXP_DESC(AXP809, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
 397                 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
 398        AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
 399                 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
 400        AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp803_dldo2_ranges,
 401                        32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
 402                        BIT(3)),
 403        AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
 404                 AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(4)),
 405        AXP_DESC(AXP809, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
 406                 AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
 407        AXP_DESC(AXP809, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
 408                 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
 409        AXP_DESC(AXP809, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
 410                 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
 411        /*
 412         * Note the datasheet only guarantees reliable operation up to
 413         * 3.3V, this needs to be enforced via dts provided constraints
 414         */
 415        AXP_DESC_IO(AXP809, LDO_IO0, "ldo_io0", "ips", 700, 3800, 100,
 416                    AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
 417                    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 418        /*
 419         * Note the datasheet only guarantees reliable operation up to
 420         * 3.3V, this needs to be enforced via dts provided constraints
 421         */
 422        AXP_DESC_IO(AXP809, LDO_IO1, "ldo_io1", "ips", 700, 3800, 100,
 423                    AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
 424                    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 425        AXP_DESC_FIXED(AXP809, RTC_LDO, "rtc_ldo", "ips", 1800),
 426        AXP_DESC_SW(AXP809, SW, "sw", "swin", AXP22X_PWR_OUT_CTRL2, BIT(6)),
 427};
 428
 429static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
 430{
 431        struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
 432        unsigned int reg = AXP20X_DCDC_FREQ;
 433        u32 min, max, def, step;
 434
 435        switch (axp20x->variant) {
 436        case AXP202_ID:
 437        case AXP209_ID:
 438                min = 750;
 439                max = 1875;
 440                def = 1500;
 441                step = 75;
 442                break;
 443        case AXP803_ID:
 444                /*
 445                 * AXP803 DCDC work frequency setting has the same range and
 446                 * step as AXP22X, but at a different register.
 447                 * Fall through to the check below.
 448                 * (See include/linux/mfd/axp20x.h)
 449                 */
 450                reg = AXP803_DCDC_FREQ_CTRL;
 451        case AXP806_ID:
 452                /*
 453                 * AXP806 also have DCDC work frequency setting register at a
 454                 * different position.
 455                 */
 456                if (axp20x->variant == AXP806_ID)
 457                        reg = AXP806_DCDC_FREQ_CTRL;
 458        case AXP221_ID:
 459        case AXP223_ID:
 460        case AXP809_ID:
 461                min = 1800;
 462                max = 4050;
 463                def = 3000;
 464                step = 150;
 465                break;
 466        default:
 467                dev_err(&pdev->dev,
 468                        "Setting DCDC frequency for unsupported AXP variant\n");
 469                return -EINVAL;
 470        }
 471
 472        if (dcdcfreq == 0)
 473                dcdcfreq = def;
 474
 475        if (dcdcfreq < min) {
 476                dcdcfreq = min;
 477                dev_warn(&pdev->dev, "DCDC frequency too low. Set to %ukHz\n",
 478                         min);
 479        }
 480
 481        if (dcdcfreq > max) {
 482                dcdcfreq = max;
 483                dev_warn(&pdev->dev, "DCDC frequency too high. Set to %ukHz\n",
 484                         max);
 485        }
 486
 487        dcdcfreq = (dcdcfreq - min) / step;
 488
 489        return regmap_update_bits(axp20x->regmap, reg,
 490                                  AXP20X_FREQ_DCDC_MASK, dcdcfreq);
 491}
 492
 493static int axp20x_regulator_parse_dt(struct platform_device *pdev)
 494{
 495        struct device_node *np, *regulators;
 496        int ret;
 497        u32 dcdcfreq = 0;
 498
 499        np = of_node_get(pdev->dev.parent->of_node);
 500        if (!np)
 501                return 0;
 502
 503        regulators = of_get_child_by_name(np, "regulators");
 504        if (!regulators) {
 505                dev_warn(&pdev->dev, "regulators node not found\n");
 506        } else {
 507                of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
 508                ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
 509                if (ret < 0) {
 510                        dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
 511                        return ret;
 512                }
 513
 514                of_node_put(regulators);
 515        }
 516
 517        return 0;
 518}
 519
 520static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
 521{
 522        struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
 523        unsigned int reg = AXP20X_DCDC_MODE;
 524        unsigned int mask;
 525
 526        switch (axp20x->variant) {
 527        case AXP202_ID:
 528        case AXP209_ID:
 529                if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
 530                        return -EINVAL;
 531
 532                mask = AXP20X_WORKMODE_DCDC2_MASK;
 533                if (id == AXP20X_DCDC3)
 534                        mask = AXP20X_WORKMODE_DCDC3_MASK;
 535
 536                workmode <<= ffs(mask) - 1;
 537                break;
 538
 539        case AXP806_ID:
 540                reg = AXP806_DCDC_MODE_CTRL2;
 541                /*
 542                 * AXP806 DCDC regulator IDs have the same range as AXP22X.
 543                 * Fall through to the check below.
 544                 * (See include/linux/mfd/axp20x.h)
 545                 */
 546        case AXP221_ID:
 547        case AXP223_ID:
 548        case AXP809_ID:
 549                if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
 550                        return -EINVAL;
 551
 552                mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP22X_DCDC1);
 553                workmode <<= id - AXP22X_DCDC1;
 554                break;
 555
 556        case AXP803_ID:
 557                if (id < AXP803_DCDC1 || id > AXP803_DCDC6)
 558                        return -EINVAL;
 559
 560                mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP803_DCDC1);
 561                workmode <<= id - AXP803_DCDC1;
 562                break;
 563
 564        default:
 565                /* should not happen */
 566                WARN_ON(1);
 567                return -EINVAL;
 568        }
 569
 570        return regmap_update_bits(rdev->regmap, reg, mask, workmode);
 571}
 572
 573/*
 574 * This function checks whether a regulator is part of a poly-phase
 575 * output setup based on the registers settings. Returns true if it is.
 576 */
 577static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
 578{
 579        u32 reg = 0;
 580
 581        /*
 582         * Currently in our supported AXP variants, only AXP803 and AXP806
 583         * have polyphase regulators.
 584         */
 585        switch (axp20x->variant) {
 586        case AXP803_ID:
 587                regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, &reg);
 588
 589                switch (id) {
 590                case AXP803_DCDC3:
 591                        return !!(reg & BIT(6));
 592                case AXP803_DCDC6:
 593                        return !!(reg & BIT(7));
 594                }
 595                break;
 596
 597        case AXP806_ID:
 598                regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg);
 599
 600                switch (id) {
 601                case AXP806_DCDCB:
 602                        return (((reg & GENMASK(7, 6)) == BIT(6)) ||
 603                                ((reg & GENMASK(7, 6)) == BIT(7)));
 604                case AXP806_DCDCC:
 605                        return ((reg & GENMASK(7, 6)) == BIT(7));
 606                case AXP806_DCDCE:
 607                        return !!(reg & BIT(5));
 608                }
 609                break;
 610
 611        default:
 612                return false;
 613        }
 614
 615        return false;
 616}
 617
 618static int axp20x_regulator_probe(struct platform_device *pdev)
 619{
 620        struct regulator_dev *rdev;
 621        struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
 622        const struct regulator_desc *regulators;
 623        struct regulator_config config = {
 624                .dev = pdev->dev.parent,
 625                .regmap = axp20x->regmap,
 626                .driver_data = axp20x,
 627        };
 628        int ret, i, nregulators;
 629        u32 workmode;
 630        const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
 631        const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
 632        bool drivevbus = false;
 633
 634        switch (axp20x->variant) {
 635        case AXP202_ID:
 636        case AXP209_ID:
 637                regulators = axp20x_regulators;
 638                nregulators = AXP20X_REG_ID_MAX;
 639                break;
 640        case AXP221_ID:
 641        case AXP223_ID:
 642                regulators = axp22x_regulators;
 643                nregulators = AXP22X_REG_ID_MAX;
 644                drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
 645                                                  "x-powers,drive-vbus-en");
 646                break;
 647        case AXP803_ID:
 648                regulators = axp803_regulators;
 649                nregulators = AXP803_REG_ID_MAX;
 650                break;
 651        case AXP806_ID:
 652                regulators = axp806_regulators;
 653                nregulators = AXP806_REG_ID_MAX;
 654                break;
 655        case AXP809_ID:
 656                regulators = axp809_regulators;
 657                nregulators = AXP809_REG_ID_MAX;
 658                break;
 659        default:
 660                dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
 661                        axp20x->variant);
 662                return -EINVAL;
 663        }
 664
 665        /* This only sets the dcdc freq. Ignore any errors */
 666        axp20x_regulator_parse_dt(pdev);
 667
 668        for (i = 0; i < nregulators; i++) {
 669                const struct regulator_desc *desc = &regulators[i];
 670                struct regulator_desc *new_desc;
 671
 672                /*
 673                 * If this regulator is a slave in a poly-phase setup,
 674                 * skip it, as its controls are bound to the master
 675                 * regulator and won't work.
 676                 */
 677                if (axp20x_is_polyphase_slave(axp20x, i))
 678                        continue;
 679
 680                /*
 681                 * Regulators DC1SW and DC5LDO are connected internally,
 682                 * so we have to handle their supply names separately.
 683                 *
 684                 * We always register the regulators in proper sequence,
 685                 * so the supply names are correctly read. See the last
 686                 * part of this loop to see where we save the DT defined
 687                 * name.
 688                 */
 689                if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
 690                    (regulators == axp803_regulators && i == AXP803_DC1SW) ||
 691                    (regulators == axp809_regulators && i == AXP809_DC1SW)) {
 692                        new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
 693                                                GFP_KERNEL);
 694                        *new_desc = regulators[i];
 695                        new_desc->supply_name = dcdc1_name;
 696                        desc = new_desc;
 697                }
 698
 699                if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
 700                    (regulators == axp809_regulators && i == AXP809_DC5LDO)) {
 701                        new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
 702                                                GFP_KERNEL);
 703                        *new_desc = regulators[i];
 704                        new_desc->supply_name = dcdc5_name;
 705                        desc = new_desc;
 706                }
 707
 708                rdev = devm_regulator_register(&pdev->dev, desc, &config);
 709                if (IS_ERR(rdev)) {
 710                        dev_err(&pdev->dev, "Failed to register %s\n",
 711                                regulators[i].name);
 712
 713                        return PTR_ERR(rdev);
 714                }
 715
 716                ret = of_property_read_u32(rdev->dev.of_node,
 717                                           "x-powers,dcdc-workmode",
 718                                           &workmode);
 719                if (!ret) {
 720                        if (axp20x_set_dcdc_workmode(rdev, i, workmode))
 721                                dev_err(&pdev->dev, "Failed to set workmode on %s\n",
 722                                        rdev->desc->name);
 723                }
 724
 725                /*
 726                 * Save AXP22X DCDC1 / DCDC5 regulator names for later.
 727                 */
 728                if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) ||
 729                    (regulators == axp809_regulators && i == AXP809_DCDC1))
 730                        of_property_read_string(rdev->dev.of_node,
 731                                                "regulator-name",
 732                                                &dcdc1_name);
 733
 734                if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) ||
 735                    (regulators == axp809_regulators && i == AXP809_DCDC5))
 736                        of_property_read_string(rdev->dev.of_node,
 737                                                "regulator-name",
 738                                                &dcdc5_name);
 739        }
 740
 741        if (drivevbus) {
 742                /* Change N_VBUSEN sense pin to DRIVEVBUS output pin */
 743                regmap_update_bits(axp20x->regmap, AXP20X_OVER_TMP,
 744                                   AXP22X_MISC_N_VBUSEN_FUNC, 0);
 745                rdev = devm_regulator_register(&pdev->dev,
 746                                               &axp22x_drivevbus_regulator,
 747                                               &config);
 748                if (IS_ERR(rdev)) {
 749                        dev_err(&pdev->dev, "Failed to register drivevbus\n");
 750                        return PTR_ERR(rdev);
 751                }
 752        }
 753
 754        return 0;
 755}
 756
 757static struct platform_driver axp20x_regulator_driver = {
 758        .probe  = axp20x_regulator_probe,
 759        .driver = {
 760                .name           = "axp20x-regulator",
 761        },
 762};
 763
 764module_platform_driver(axp20x_regulator_driver);
 765
 766MODULE_LICENSE("GPL v2");
 767MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
 768MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
 769MODULE_ALIAS("platform:axp20x-regulator");
 770