1 From 697eb56ed8c9b3814ddbd87ae0c6e749ccafc9e3 Mon Sep 17 00:00:00 2001
2 From: Samuel Holland <samuel@sholland.org>
3 Date: Sat, 28 Aug 2021 00:27:19 -0500
4 Subject: [PATCH 50/90] gpio: axp: Select variant from compatible at runtime
6 There are three major variants of the AXP PMIC GPIO functionality (plus
7 PMICs with no GPIOs at all). Except for GPIO3 on the AXP209, which uses
8 a different register layout, it is straightforward to support all three
9 variants with a single driver. Do this, and in the process remove the
10 GPIO-related definitions from the PMIC-specific headers, and therefore
11 the dependency on AXP_PMIC_BUS.
13 Signed-off-by: Samuel Holland <samuel@sholland.org>
15 drivers/gpio/Kconfig | 1 -
16 drivers/gpio/axp_gpio.c | 137 +++++++++++++++++++++-------------------
17 drivers/power/axp209.c | 6 +-
18 drivers/power/axp221.c | 4 +-
19 include/axp152.h | 10 ---
20 include/axp209.h | 16 ++---
21 include/axp221.h | 13 ++--
22 include/axp809.h | 8 ---
23 include/axp818.h | 8 ---
24 9 files changed, 89 insertions(+), 114 deletions(-)
26 --- a/drivers/gpio/Kconfig
27 +++ b/drivers/gpio/Kconfig
28 @@ -107,7 +107,6 @@ config ALTERA_PIO
30 bool "X-Powers AXP PMICs GPIO driver"
31 depends on DM_GPIO && PMIC_AXP
32 - depends on AXP_PMIC_BUS
34 This driver supports the GPIO pins on
35 X-Powers AXP152, AXP2xx, and AXP8xx PMICs.
36 --- a/drivers/gpio/axp_gpio.c
37 +++ b/drivers/gpio/axp_gpio.c
42 -#include <axp_pmic.h>
44 +#include <dm/device-internal.h>
46 #include <power/pmic.h>
48 #define AXP_GPIO_PREFIX "AXP0-"
49 #define AXP_GPIO_COUNT 4
51 -static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
53 -static u8 axp_get_gpio_ctrl_reg(unsigned pin)
56 - case 0: return AXP_GPIO0_CTRL;
57 - case 1: return AXP_GPIO1_CTRL;
58 -#ifdef AXP_GPIO2_CTRL
59 - case 2: return AXP_GPIO2_CTRL;
61 -#ifdef AXP_GPIO3_CTRL
62 - case 3: return AXP_GPIO3_CTRL;
68 -static int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
72 - reg = axp_get_gpio_ctrl_reg(pin);
76 - return pmic_reg_write(dev->parent, reg, AXP_GPIO_CTRL_INPUT);
79 -static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
84 - reg = axp_get_gpio_ctrl_reg(pin);
88 - return pmic_reg_write(dev->parent, reg,
89 - val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
90 - AXP_GPIO_CTRL_OUTPUT_LOW);
92 +#define AXP_GPIO_CTRL_MASK 0x7
93 +#define AXP_GPIO_CTRL_OUTPUT_LOW 0
94 +#define AXP_GPIO_CTRL_OUTPUT_HIGH 1
96 +struct axp_gpio_desc {
104 static int axp_gpio_get_value(struct udevice *dev, unsigned pin)
107 + const struct axp_gpio_desc *desc = dev_get_priv(dev);
110 - reg = axp_get_gpio_ctrl_reg(pin);
114 - ret = pmic_reg_read(dev->parent, AXP_GPIO_STATE);
115 + ret = pmic_reg_read(dev->parent, desc->status_reg);
119 - mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
121 - return (ret & mask) ? 1 : 0;
122 + return !!(ret & BIT(desc->status_offset + pin));
125 -static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
126 +static int axp_gpio_set_flags(struct udevice *dev, unsigned pin, ulong flags)
129 + const struct axp_gpio_desc *desc = dev_get_priv(dev);
132 - reg = axp_get_gpio_ctrl_reg(pin);
134 + if (flags & (GPIOD_MASK_DSTYPE | GPIOD_MASK_PULL))
137 - return pmic_reg_write(dev->parent, reg,
138 - val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
139 - AXP_GPIO_CTRL_OUTPUT_LOW);
140 + if (flags & GPIOD_IS_IN)
141 + mux = desc->input_mux;
142 + else if (flags & GPIOD_IS_OUT_ACTIVE)
143 + mux = AXP_GPIO_CTRL_OUTPUT_HIGH;
145 + mux = AXP_GPIO_CTRL_OUTPUT_LOW;
147 + return pmic_clrsetbits(dev->parent, desc->pins[pin],
148 + AXP_GPIO_CTRL_MASK, mux);
151 static const struct dm_gpio_ops axp_gpio_ops = {
152 - .direction_input = axp_gpio_direction_input,
153 - .direction_output = axp_gpio_direction_output,
154 .get_value = axp_gpio_get_value,
155 - .set_value = axp_gpio_set_value,
156 + .xlate = gpio_xlate_offs_flags,
157 + .set_flags = axp_gpio_set_flags,
160 static int axp_gpio_probe(struct udevice *dev)
162 + struct axp_gpio_desc *desc = (void *)dev_get_driver_data(dev);
163 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
165 + dev_set_priv(dev, desc);
167 /* Tell the uclass how many GPIOs we have */
168 uc_priv->bank_name = AXP_GPIO_PREFIX;
169 - uc_priv->gpio_count = AXP_GPIO_COUNT;
170 + uc_priv->gpio_count = desc->npins;
175 +static const u8 axp152_gpio_pins[] = {
176 + 0x90, 0x91, 0x92, 0x93,
179 +static const struct axp_gpio_desc axp152_gpio_desc = {
180 + .pins = axp152_gpio_pins,
181 + .npins = ARRAY_SIZE(axp152_gpio_pins),
182 + .status_reg = 0x97,
183 + .status_offset = 4,
187 +static const u8 axp209_gpio_pins[] = {
191 +static const struct axp_gpio_desc axp209_gpio_desc = {
192 + .pins = axp209_gpio_pins,
193 + .npins = ARRAY_SIZE(axp209_gpio_pins),
194 + .status_reg = 0x94,
195 + .status_offset = 4,
199 +static const u8 axp221_gpio_pins[] = {
203 +static const struct axp_gpio_desc axp221_gpio_desc = {
204 + .pins = axp221_gpio_pins,
205 + .npins = ARRAY_SIZE(axp221_gpio_pins),
206 + .status_reg = 0x94,
210 static const struct udevice_id axp_gpio_ids[] = {
211 - { .compatible = "x-powers,axp152-gpio" },
212 - { .compatible = "x-powers,axp209-gpio" },
213 - { .compatible = "x-powers,axp221-gpio" },
214 - { .compatible = "x-powers,axp813-gpio" },
215 + { .compatible = "x-powers,axp152-gpio", .data = (ulong)&axp152_gpio_desc },
216 + { .compatible = "x-powers,axp209-gpio", .data = (ulong)&axp209_gpio_desc },
217 + { .compatible = "x-powers,axp221-gpio", .data = (ulong)&axp221_gpio_desc },
218 + { .compatible = "x-powers,axp813-gpio", .data = (ulong)&axp221_gpio_desc },
222 --- a/drivers/power/axp209.c
223 +++ b/drivers/power/axp209.c
224 @@ -215,15 +215,15 @@ int axp_init(void)
225 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
226 * from android these are sometimes on.
228 - rc = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
229 + rc = pmic_bus_write(AXP209_GPIO0_CTRL, AXP209_GPIO_CTRL_INPUT);
233 - rc = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
234 + rc = pmic_bus_write(AXP209_GPIO1_CTRL, AXP209_GPIO_CTRL_INPUT);
238 - rc = pmic_bus_write(AXP_GPIO2_CTRL, AXP_GPIO_CTRL_INPUT);
239 + rc = pmic_bus_write(AXP209_GPIO2_CTRL, AXP209_GPIO_CTRL_INPUT);
243 --- a/drivers/power/axp221.c
244 +++ b/drivers/power/axp221.c
245 @@ -226,11 +226,11 @@ int axp_init(void)
246 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
247 * from android these are sometimes on.
249 - ret = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
250 + ret = pmic_bus_write(AXP221_GPIO0_CTRL, AXP221_GPIO_CTRL_INPUT);
254 - ret = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
255 + ret = pmic_bus_write(AXP221_GPIO1_CTRL, AXP221_GPIO_CTRL_INPUT);
259 --- a/include/axp152.h
260 +++ b/include/axp152.h
261 @@ -14,17 +14,7 @@ enum axp152_reg {
263 #define AXP152_POWEROFF (1 << 7)
265 -/* For axp_gpio.c */
266 #ifdef CONFIG_AXP152_POWER
267 #define AXP_POWER_STATUS 0x00
268 #define AXP_POWER_STATUS_ALDO_IN BIT(0)
269 -#define AXP_GPIO0_CTRL 0x90
270 -#define AXP_GPIO1_CTRL 0x91
271 -#define AXP_GPIO2_CTRL 0x92
272 -#define AXP_GPIO3_CTRL 0x93
273 -#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
274 -#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
275 -#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
276 -#define AXP_GPIO_STATE 0x97
277 -#define AXP_GPIO_STATE_OFFSET 0
279 --- a/include/axp209.h
280 +++ b/include/axp209.h
281 @@ -21,6 +21,9 @@ enum axp209_reg {
282 AXP209_IRQ_ENABLE5 = 0x44,
283 AXP209_IRQ_STATUS5 = 0x4c,
284 AXP209_SHUTDOWN = 0x32,
285 + AXP209_GPIO0_CTRL = 0x90,
286 + AXP209_GPIO1_CTRL = 0x92,
287 + AXP209_GPIO2_CTRL = 0x93,
290 #define AXP209_POWER_STATUS_ON_BY_DC BIT(0)
291 @@ -73,16 +76,11 @@ enum axp209_reg {
293 #define AXP209_POWEROFF BIT(7)
295 -/* For axp_gpio.c */
296 +#define AXP209_GPIO_CTRL_OUTPUT_LOW 0x00
297 +#define AXP209_GPIO_CTRL_OUTPUT_HIGH 0x01
298 +#define AXP209_GPIO_CTRL_INPUT 0x02
300 #ifdef CONFIG_AXP209_POWER
301 #define AXP_POWER_STATUS 0x00
302 #define AXP_POWER_STATUS_ALDO_IN BIT(0)
303 -#define AXP_GPIO0_CTRL 0x90
304 -#define AXP_GPIO1_CTRL 0x92
305 -#define AXP_GPIO2_CTRL 0x93
306 -#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
307 -#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
308 -#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
309 -#define AXP_GPIO_STATE 0x94
310 -#define AXP_GPIO_STATE_OFFSET 4
312 --- a/include/axp221.h
313 +++ b/include/axp221.h
315 #define AXP221_ALDO3_CTRL 0x2a
316 #define AXP221_SHUTDOWN 0x32
317 #define AXP221_SHUTDOWN_POWEROFF (1 << 7)
318 +#define AXP221_GPIO0_CTRL 0x90
319 +#define AXP221_GPIO1_CTRL 0x92
320 +#define AXP221_GPIO_CTRL_OUTPUT_LOW 0x00
321 +#define AXP221_GPIO_CTRL_OUTPUT_HIGH 0x01
322 +#define AXP221_GPIO_CTRL_INPUT 0x02
323 #define AXP221_PAGE 0xff
325 /* Page 1 addresses */
326 #define AXP221_SID 0x20
328 -/* For axp_gpio.c */
329 #ifdef CONFIG_AXP221_POWER
330 #define AXP_POWER_STATUS 0x00
331 #define AXP_POWER_STATUS_ALDO_IN BIT(0)
332 -#define AXP_GPIO0_CTRL 0x90
333 -#define AXP_GPIO1_CTRL 0x92
334 -#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
335 -#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
336 -#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
337 -#define AXP_GPIO_STATE 0x94
338 -#define AXP_GPIO_STATE_OFFSET 0
340 --- a/include/axp809.h
341 +++ b/include/axp809.h
343 #define AXP809_SHUTDOWN 0x32
344 #define AXP809_SHUTDOWN_POWEROFF (1 << 7)
346 -/* For axp_gpio.c */
347 #ifdef CONFIG_AXP809_POWER
348 #define AXP_POWER_STATUS 0x00
349 #define AXP_POWER_STATUS_ALDO_IN BIT(0)
350 -#define AXP_GPIO0_CTRL 0x90
351 -#define AXP_GPIO1_CTRL 0x92
352 -#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
353 -#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
354 -#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
355 -#define AXP_GPIO_STATE 0x94
356 -#define AXP_GPIO_STATE_OFFSET 0
358 --- a/include/axp818.h
359 +++ b/include/axp818.h
361 #define AXP818_SHUTDOWN 0x32
362 #define AXP818_SHUTDOWN_POWEROFF (1 << 7)
364 -/* For axp_gpio.c */
365 #ifdef CONFIG_AXP818_POWER
366 #define AXP_POWER_STATUS 0x00
367 #define AXP_POWER_STATUS_ALDO_IN BIT(0)
368 -#define AXP_GPIO0_CTRL 0x90
369 -#define AXP_GPIO1_CTRL 0x92
370 -#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
371 -#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
372 -#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
373 -#define AXP_GPIO_STATE 0x94
374 -#define AXP_GPIO_STATE_OFFSET 0