sunxi: add support for 4.1
[openwrt.git] / target / linux / sunxi / patches-4.1 / 102-regulator-axp20x-add-support-for-axp22.patch
1 From c3f89434c9d778572cf09e8327bd047b11d48b90 Mon Sep 17 00:00:00 2001
2 From: Boris BREZILLON <boris.brezillon@free-electrons.com>
3 Date: Fri, 10 Apr 2015 12:09:04 +0800
4 Subject: [PATCH] regulator: axp20x: Add support for AXP22X regulators
5
6 Add AXP22X regulator definitions and variant id associations.
7 This introduces a new "switch" type output for one of the regulators.
8 It is a switchable secondary output of one regulator, with the same
9 voltage level as the primary output.
10
11 Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
12 [wens@csie.org: Moved variant choosing to multi family support patch]
13 [wens@csie.org: Add dc-dc work frequency range]
14 [wens@csie.org: Add "switch" type output regulator DC1SW]
15 Signed-off-by: Chen-Yu Tsai <wens@csie.org>
16 Reviewed-by: Mark Brown <broonie@kernel.org>
17 Signed-off-by: Lee Jones <lee.jones@linaro.org>
18 ---
19  drivers/regulator/axp20x-regulator.c | 96 ++++++++++++++++++++++++++++++++++++
20  1 file changed, 96 insertions(+)
21
22 diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
23 index 50ae0b5..6468291 100644
24 --- a/drivers/regulator/axp20x-regulator.c
25 +++ b/drivers/regulator/axp20x-regulator.c
26 @@ -27,8 +27,12 @@
27  #define AXP20X_IO_ENABLED              0x03
28  #define AXP20X_IO_DISABLED             0x07
29  
30 +#define AXP22X_IO_ENABLED              0x04
31 +#define AXP22X_IO_DISABLED             0x03
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 @@ -74,6 +78,26 @@
40                 .ops            = &axp20x_ops,                                  \
41         }
42  
43 +#define AXP_DESC_SW(_family, _id, _match, _supply, _min, _max, _step, _vreg,   \
44 +                   _vmask, _ereg, _emask)                                      \
45 +       [_family##_##_id] = {                                                   \
46 +               .name           = #_id,                                         \
47 +               .supply_name    = (_supply),                                    \
48 +               .of_match       = of_match_ptr(_match),                         \
49 +               .regulators_node = of_match_ptr("regulators"),                  \
50 +               .type           = REGULATOR_VOLTAGE,                            \
51 +               .id             = _family##_##_id,                              \
52 +               .n_voltages     = (((_max) - (_min)) / (_step) + 1),            \
53 +               .owner          = THIS_MODULE,                                  \
54 +               .min_uV         = (_min) * 1000,                                \
55 +               .uV_step        = (_step) * 1000,                               \
56 +               .vsel_reg       = (_vreg),                                      \
57 +               .vsel_mask      = (_vmask),                                     \
58 +               .enable_reg     = (_ereg),                                      \
59 +               .enable_mask    = (_emask),                                     \
60 +               .ops            = &axp20x_ops_sw,                               \
61 +       }
62 +
63  #define AXP_DESC_FIXED(_family, _id, _match, _supply, _volt)                   \
64         [_family##_##_id] = {                                                   \
65                 .name           = #_id,                                         \
66 @@ -135,6 +159,14 @@ static struct regulator_ops axp20x_ops = {
67         .is_enabled             = regulator_is_enabled_regmap,
68  };
69  
70 +static struct regulator_ops axp20x_ops_sw = {
71 +       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
72 +       .list_voltage           = regulator_list_voltage_linear,
73 +       .enable                 = regulator_enable_regmap,
74 +       .disable                = regulator_disable_regmap,
75 +       .is_enabled             = regulator_is_enabled_regmap,
76 +};
77 +
78  static const struct regulator_desc axp20x_regulators[] = {
79         AXP_DESC(AXP20X, DCDC2, "dcdc2", "vin2", 700, 2275, 25,
80                  AXP20X_DCDC2_V_OUT, 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
81 @@ -152,6 +184,52 @@ static const struct regulator_desc axp20x_regulators[] = {
82                     AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
83  };
84  
85 +static const struct regulator_desc axp22x_regulators[] = {
86 +       AXP_DESC(AXP22X, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
87 +                AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
88 +       AXP_DESC(AXP22X, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
89 +                AXP22X_DCDC2_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(2)),
90 +       AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
91 +                AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
92 +       AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20,
93 +                AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
94 +       AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
95 +                AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(4)),
96 +       /* secondary switchable output of DCDC1 */
97 +       AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", "dcdc1", 1600, 3400, 100,
98 +                   AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(7)),
99 +       /* LDO regulator internally chained to DCDC5 */
100 +       AXP_DESC(AXP22X, DC5LDO, "dc5ldo", "dcdc5", 700, 1400, 100,
101 +                AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)),
102 +       AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
103 +                AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)),
104 +       AXP_DESC(AXP22X, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
105 +                AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
106 +       AXP_DESC(AXP22X, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
107 +                AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
108 +       AXP_DESC(AXP22X, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
109 +                AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
110 +       AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
111 +                AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(4)),
112 +       AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
113 +                AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
114 +       AXP_DESC(AXP22X, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
115 +                AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
116 +       AXP_DESC(AXP22X, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
117 +                AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
118 +       AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
119 +                AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
120 +       AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
121 +                AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
122 +       AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 1800, 3300, 100,
123 +                   AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
124 +                   AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
125 +       AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 1800, 3300, 100,
126 +                   AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
127 +                   AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
128 +       AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
129 +};
130 +
131  static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
132  {
133         struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
134 @@ -165,6 +243,12 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
135                 def = 1500;
136                 step = 75;
137                 break;
138 +       case AXP221_ID:
139 +               min = 1800;
140 +               max = 4050;
141 +               def = 3000;
142 +               step = 150;
143 +               break;
144         default:
145                 dev_err(&pdev->dev,
146                         "Setting DCDC frequency for unsupported AXP variant\n");
147 @@ -237,6 +321,14 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
148                 workmode <<= ffs(mask) - 1;
149                 break;
150  
151 +       case AXP221_ID:
152 +               if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
153 +                       return -EINVAL;
154 +
155 +               mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP22X_DCDC1);
156 +               workmode <<= id - AXP22X_DCDC1;
157 +               break;
158 +
159         default:
160                 /* should not happen */
161                 WARN_ON(1);
162 @@ -265,6 +357,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
163                 regulators = axp20x_regulators;
164                 nregulators = AXP20X_REG_ID_MAX;
165                 break;
166 +       case AXP221_ID:
167 +               regulators = axp22x_regulators;
168 +               nregulators = AXP22X_REG_ID_MAX;
169 +               break;
170         default:
171                 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
172                         axp20x->variant);