[U-Boot] [PATCH v2 0/6] sunxi: Add driver-model support for axp pmic gpio pins

Hi Simon, Ian,
Here is a new series to replace the 2 patches which added support for axp gpio-s to the sunxi_gpio.c driver-model code. As requested this series instead adds a new driver-model axp_gpio driver instead of bolting it on to the sunxi_gpio code.
Patches 1-5 are intended to slot into the original series for moving all sunxi boards over to the driver-model for gpio and enet, at the same place as were the 2 original patches sit.
Patch 6 is intended to be tagged on to the end, and removes the ugly bolt-on axp-gpio code from the non driver-model sunxi-gpio code, leaving sunxi_gpio.c almost entirely free of axp related code (there is one bit of special casing in sunxi_name_to_gpio left).
Some of the interrim patches are not the prettiest, doing things like forward declaring struct udevice, this all gets removed later on. I've done things this way as that was the easiest way to do the conversion while keeping all intermediate steps 100% working on all boards for bisectability.
Regards,
Hans

Change the axp_gpio_foo function prototypes to match the gpio uclass op prototypes, this is a preparation patch for moving the axp gpio code to a separate driver-model gpio driver.
Note that the ugly calls with a NULL udev pointer in drivers/gpio/sunxi_gpio.c this adds are removed in a later patch.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/gpio/sunxi_gpio.c | 8 ++++---- drivers/power/axp209.c | 10 +++++----- drivers/power/axp221.c | 10 +++++----- include/axp209.h | 10 ++++++---- include/axp221.h | 10 ++++++---- 5 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 91af1a5..0774b70 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -81,7 +81,7 @@ int gpio_direction_input(unsigned gpio) { #ifdef AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_direction_input(gpio - SUNXI_GPIO_AXP0_START); + return axp_gpio_direction_input(NULL, gpio - SUNXI_GPIO_AXP0_START); #endif sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
@@ -92,7 +92,7 @@ int gpio_direction_output(unsigned gpio, int value) { #ifdef AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_direction_output(gpio - SUNXI_GPIO_AXP0_START, + return axp_gpio_direction_output(NULL, gpio - SUNXI_GPIO_AXP0_START, value); #endif sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT); @@ -104,7 +104,7 @@ int gpio_get_value(unsigned gpio) { #ifdef AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_get_value(gpio - SUNXI_GPIO_AXP0_START); + return axp_gpio_get_value(NULL, gpio - SUNXI_GPIO_AXP0_START); #endif return sunxi_gpio_input(gpio); } @@ -113,7 +113,7 @@ int gpio_set_value(unsigned gpio, int value) { #ifdef AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_set_value(gpio - SUNXI_GPIO_AXP0_START, value); + return axp_gpio_set_value(NULL, gpio - SUNXI_GPIO_AXP0_START, value); #endif return sunxi_gpio_output(gpio, value); } diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c index 1d7be49..98c214f 100644 --- a/drivers/power/axp209.c +++ b/drivers/power/axp209.c @@ -167,7 +167,7 @@ static u8 axp209_get_gpio_ctrl_reg(unsigned int pin) return 0; }
-int axp_gpio_direction_input(unsigned int pin) +int axp_gpio_direction_input(struct udevice *dev, unsigned pin) { if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) return 0; @@ -179,7 +179,7 @@ int axp_gpio_direction_input(unsigned int pin) return axp209_write(reg, val); }
-int axp_gpio_direction_output(unsigned int pin, unsigned int val) +int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) { u8 reg = axp209_get_gpio_ctrl_reg(pin);
@@ -194,7 +194,7 @@ int axp_gpio_direction_output(unsigned int pin, unsigned int val) return axp209_write(reg, val); }
-int axp_gpio_get_value(unsigned int pin) +int axp_gpio_get_value(struct udevice *dev, unsigned pin) { u8 val, mask; int rc; @@ -215,7 +215,7 @@ int axp_gpio_get_value(unsigned int pin) return (val & mask) ? 1 : 0; }
-int axp_gpio_set_value(unsigned int pin, unsigned int val) +int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { - return axp_gpio_direction_output(pin, val); + return axp_gpio_direction_output(dev, pin, val); } diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index dc3a7f1..4970ab4 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -386,7 +386,7 @@ int axp221_get_sid(unsigned int *sid) return 0; }
-int axp_gpio_direction_input(unsigned int pin) +int axp_gpio_direction_input(struct udevice *dev, unsigned pin) { switch (pin) { case SUNXI_GPIO_AXP0_VBUS_DETECT: @@ -396,7 +396,7 @@ int axp_gpio_direction_input(unsigned int pin) } }
-int axp_gpio_direction_output(unsigned int pin, unsigned int val) +int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) { int ret;
@@ -407,13 +407,13 @@ int axp_gpio_direction_output(unsigned int pin, unsigned int val) if (ret) return ret;
- return axp_gpio_set_value(pin, val); + return axp_gpio_set_value(dev, pin, val); default: return -EINVAL; } }
-int axp_gpio_get_value(unsigned int pin) +int axp_gpio_get_value(struct udevice *dev, unsigned pin) { int ret; u8 val; @@ -430,7 +430,7 @@ int axp_gpio_get_value(unsigned int pin) } }
-int axp_gpio_set_value(unsigned int pin, unsigned int val) +int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { int ret;
diff --git a/include/axp209.h b/include/axp209.h index d36da41..fe4a169 100644 --- a/include/axp209.h +++ b/include/axp209.h @@ -4,6 +4,8 @@ * SPDX-License-Identifier: GPL-2.0+ */
+struct udevice; + enum axp209_reg { AXP209_POWER_STATUS = 0x00, AXP209_CHIP_VERSION = 0x03, @@ -53,7 +55,7 @@ extern int axp209_init(void); extern int axp209_poweron_by_dc(void); extern int axp209_power_button(void);
-extern int axp_gpio_direction_input(unsigned int pin); -extern int axp_gpio_direction_output(unsigned int pin, unsigned int val); -extern int axp_gpio_get_value(unsigned int pin); -extern int axp_gpio_set_value(unsigned int pin, unsigned int val); +extern int axp_gpio_direction_input(struct udevice *dev, unsigned offset); +extern int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); +extern int axp_gpio_get_value(struct udevice *dev, unsigned offset); +extern int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val); diff --git a/include/axp221.h b/include/axp221.h index 0aac04d..e826ca8 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -6,6 +6,8 @@ * SPDX-License-Identifier: GPL-2.0+ */
+struct udevice; + #define AXP221_CHIP_ADDR 0x68 #define AXP221_CTRL_ADDR 0x3e #define AXP221_INIT_DATA 0x3e @@ -80,7 +82,7 @@ int axp221_set_eldo(int eldo_num, unsigned int mvolt); int axp221_init(void); int axp221_get_sid(unsigned int *sid);
-int axp_gpio_direction_input(unsigned int pin); -int axp_gpio_direction_output(unsigned int pin, unsigned int val); -int axp_gpio_get_value(unsigned int pin); -int axp_gpio_set_value(unsigned int pin, unsigned int val); +int axp_gpio_direction_input(struct udevice *dev, unsigned offset); +int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); +int axp_gpio_get_value(struct udevice *dev, unsigned offset); +int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);

On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Change the axp_gpio_foo function prototypes to match the gpio uclass op prototypes, this is a preparation patch for moving the axp gpio code to a separate driver-model gpio driver.
Note that the ugly calls with a NULL udev pointer in drivers/gpio/sunxi_gpio.c this adds are removed in a later patch.
Signed-off-by: Hans de Goede hdegoede@redhat.com
drivers/gpio/sunxi_gpio.c | 8 ++++---- drivers/power/axp209.c | 10 +++++----- drivers/power/axp221.c | 10 +++++----- include/axp209.h | 10 ++++++---- include/axp221.h | 10 ++++++---- 5 files changed, 26 insertions(+), 22 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Sun, 2015-04-26 at 11:51 +0200, Hans de Goede wrote:
Change the axp_gpio_foo function prototypes to match the gpio uclass op prototypes, this is a preparation patch for moving the axp gpio code to a separate driver-model gpio driver.
Note that the ugly calls with a NULL udev pointer in drivers/gpio/sunxi_gpio.c this adds are removed in a later patch.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

Move the register helpers used to access the registers via p2wi resp. rsb bus on the otherwise identical axp221 and axp223 pmics to a separate file, so that they can be used by the upcoming standalone axp gpio driver too.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/Makefile | 2 + arch/arm/cpu/armv7/sunxi/pmic_bus.c | 93 ++++++++++++++++ arch/arm/include/asm/arch-sunxi/pmic_bus.h | 18 +++ drivers/power/axp221.c | 172 +++++++++-------------------- include/axp221.h | 7 -- 5 files changed, 166 insertions(+), 126 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/pmic_bus.c create mode 100644 arch/arm/include/asm/arch-sunxi/pmic_bus.h
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 6213eb3..50791e0 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -32,6 +32,8 @@ obj-$(CONFIG_MACH_SUN8I_A23) += clock_sun6i.o obj-$(CONFIG_MACH_SUN8I_A33) += clock_sun6i.o obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o
+obj-$(CONFIG_AXP221_POWER) += pmic_bus.o + ifndef CONFIG_SPL_BUILD ifdef CONFIG_ARMV7_PSCI obj-y += psci.o diff --git a/arch/arm/cpu/armv7/sunxi/pmic_bus.c b/arch/arm/cpu/armv7/sunxi/pmic_bus.c new file mode 100644 index 0000000..389144b --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/pmic_bus.c @@ -0,0 +1,93 @@ +/* + * (C) Copyright 2015 Hans de Goede hdegoede@redhat.com + * + * Sunxi PMIC bus access helpers + * + * The axp152 & axp209 use an i2c bus, the axp221 uses the p2wi bus and the + * axp223 uses the rsb bus, these functions abstract this. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/p2wi.h> +#include <asm/arch/rsb.h> +#include <asm/arch/pmic_bus.h> + +#define AXP221_CHIP_ADDR 0x68 +#define AXP221_CTRL_ADDR 0x3e +#define AXP221_INIT_DATA 0x3e + +#define AXP223_DEVICE_ADDR 0x3a3 +#define AXP223_RUNTIME_ADDR 0x2d + +int pmic_bus_init(void) +{ + /* This cannot be 0 because it is used in SPL before BSS is ready */ + static int needs_init = 1; + int ret; + + if (!needs_init) + return 0; + +#ifdef CONFIG_MACH_SUN6I + p2wi_init(); + ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, + AXP221_INIT_DATA); +#else + ret = rsb_init(); + if (ret) + return ret; + + ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR); +#endif + if (ret) + return ret; + + needs_init = 0; + return 0; +} + +int pmic_bus_read(u8 reg, u8 *data) +{ +#ifdef CONFIG_MACH_SUN6I + return p2wi_read(reg, data); +#else + return rsb_read(AXP223_RUNTIME_ADDR, reg, data); +#endif +} + +int pmic_bus_write(u8 reg, u8 data) +{ +#ifdef CONFIG_MACH_SUN6I + return p2wi_write(reg, data); +#else + return rsb_write(AXP223_RUNTIME_ADDR, reg, data); +#endif +} + +int pmic_bus_setbits(u8 reg, u8 bits) +{ + int ret; + u8 val; + + ret = pmic_bus_read(reg, &val); + if (ret) + return ret; + + val |= bits; + return pmic_bus_write(reg, val); +} + +int pmic_bus_clrbits(u8 reg, u8 bits) +{ + int ret; + u8 val; + + ret = pmic_bus_read(reg, &val); + if (ret) + return ret; + + val &= ~bits; + return pmic_bus_write(reg, val); +} diff --git a/arch/arm/include/asm/arch-sunxi/pmic_bus.h b/arch/arm/include/asm/arch-sunxi/pmic_bus.h new file mode 100644 index 0000000..9c4372a --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/pmic_bus.h @@ -0,0 +1,18 @@ +/* + * (C) Copyright 2015 Hans de Goede hdegoede@redhat.com + * + * Sunxi PMIC bus access helpers header + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_PMIC_BUS_H +#define _SUNXI_PMIS_BUS_H + +int pmic_bus_init(void); +int pmic_bus_read(u8 reg, u8 *data); +int pmic_bus_write(u8 reg, u8 data); +int pmic_bus_setbits(u8 reg, u8 bits); +int pmic_bus_clrbits(u8 reg, u8 bits); + +#endif diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index 4970ab4..d49de86 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -12,50 +12,10 @@
#include <common.h> #include <errno.h> -#include <asm/arch/p2wi.h> -#include <asm/arch/rsb.h> #include <asm/arch/gpio.h> +#include <asm/arch/pmic_bus.h> #include <axp221.h>
-/* - * The axp221 uses the p2wi bus, the axp223 is identical (for all registers - * used sofar) but uses the rsb bus. These functions abstract this. - */ -static int pmic_bus_init(void) -{ -#ifdef CONFIG_MACH_SUN6I - p2wi_init(); - return p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, - AXP221_INIT_DATA); -#else - int ret; - - ret = rsb_init(); - if (ret) - return ret; - - return rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR); -#endif -} - -static int pmic_bus_read(const u8 addr, u8 *data) -{ -#ifdef CONFIG_MACH_SUN6I - return p2wi_read(addr, data); -#else - return rsb_read(AXP223_RUNTIME_ADDR, addr, data); -#endif -} - -static int pmic_bus_write(const u8 addr, u8 data) -{ -#ifdef CONFIG_MACH_SUN6I - return p2wi_write(addr, data); -#else - return rsb_write(AXP223_RUNTIME_ADDR, addr, data); -#endif -} - static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div) { if (mvolt < min) @@ -66,52 +26,26 @@ static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div) return (mvolt - min) / div; }
-static int axp221_setbits(u8 reg, u8 bits) -{ - int ret; - u8 val; - - ret = pmic_bus_read(reg, &val); - if (ret) - return ret; - - val |= bits; - return pmic_bus_write(reg, val); -} - -static int axp221_clrbits(u8 reg, u8 bits) -{ - int ret; - u8 val; - - ret = pmic_bus_read(reg, &val); - if (ret) - return ret; - - val &= ~bits; - return pmic_bus_write(reg, val); -} - int axp221_set_dcdc1(unsigned int mvolt) { int ret; u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC1_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC1_EN);
ret = pmic_bus_write(AXP221_DCDC1_CTRL, cfg); if (ret) return ret;
- ret = axp221_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DCDC1SW_EN); + ret = pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DCDC1SW_EN); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC1_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC1_EN); }
int axp221_set_dcdc2(unsigned int mvolt) @@ -120,15 +54,15 @@ int axp221_set_dcdc2(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC2_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC2_EN);
ret = pmic_bus_write(AXP221_DCDC2_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC2_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC2_EN); }
int axp221_set_dcdc3(unsigned int mvolt) @@ -137,15 +71,15 @@ int axp221_set_dcdc3(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC3_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC3_EN);
ret = pmic_bus_write(AXP221_DCDC3_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC3_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC3_EN); }
int axp221_set_dcdc4(unsigned int mvolt) @@ -154,15 +88,15 @@ int axp221_set_dcdc4(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC4_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC4_EN);
ret = pmic_bus_write(AXP221_DCDC4_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC4_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC4_EN); }
int axp221_set_dcdc5(unsigned int mvolt) @@ -171,15 +105,15 @@ int axp221_set_dcdc5(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC5_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC5_EN);
ret = pmic_bus_write(AXP221_DCDC5_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_DCDC5_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_DCDC5_EN); }
int axp221_set_dldo1(unsigned int mvolt) @@ -188,15 +122,15 @@ int axp221_set_dldo1(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO1_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO1_EN);
ret = pmic_bus_write(AXP221_DLDO1_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO1_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO1_EN); }
int axp221_set_dldo2(unsigned int mvolt) @@ -205,15 +139,15 @@ int axp221_set_dldo2(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO2_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO2_EN);
ret = pmic_bus_write(AXP221_DLDO2_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO2_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO2_EN); }
int axp221_set_dldo3(unsigned int mvolt) @@ -222,15 +156,15 @@ int axp221_set_dldo3(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO3_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO3_EN);
ret = pmic_bus_write(AXP221_DLDO3_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO3_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO3_EN); }
int axp221_set_dldo4(unsigned int mvolt) @@ -239,15 +173,15 @@ int axp221_set_dldo4(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO4_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO4_EN);
ret = pmic_bus_write(AXP221_DLDO4_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO4_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO4_EN); }
int axp221_set_aldo1(unsigned int mvolt) @@ -256,15 +190,15 @@ int axp221_set_aldo1(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_ALDO1_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_ALDO1_EN);
ret = pmic_bus_write(AXP221_ALDO1_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_ALDO1_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_ALDO1_EN); }
int axp221_set_aldo2(unsigned int mvolt) @@ -273,15 +207,15 @@ int axp221_set_aldo2(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_ALDO2_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_ALDO2_EN);
ret = pmic_bus_write(AXP221_ALDO2_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1, - AXP221_OUTPUT_CTRL1_ALDO2_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL1, + AXP221_OUTPUT_CTRL1_ALDO2_EN); }
int axp221_set_aldo3(unsigned int mvolt) @@ -290,15 +224,15 @@ int axp221_set_aldo3(unsigned int mvolt) u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL3, - AXP221_OUTPUT_CTRL3_ALDO3_EN); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL3, + AXP221_OUTPUT_CTRL3_ALDO3_EN);
ret = pmic_bus_write(AXP221_ALDO3_CTRL, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL3, - AXP221_OUTPUT_CTRL3_ALDO3_EN); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL3, + AXP221_OUTPUT_CTRL3_ALDO3_EN); }
int axp221_set_eldo(int eldo_num, unsigned int mvolt) @@ -325,13 +259,13 @@ int axp221_set_eldo(int eldo_num, unsigned int mvolt) }
if (mvolt == 0) - return axp221_clrbits(AXP221_OUTPUT_CTRL2, bits); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, bits);
ret = pmic_bus_write(addr, cfg); if (ret) return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2, bits); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, bits); }
int axp221_init(void) diff --git a/include/axp221.h b/include/axp221.h index e826ca8..f62f708 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -8,13 +8,6 @@
struct udevice;
-#define AXP221_CHIP_ADDR 0x68 -#define AXP221_CTRL_ADDR 0x3e -#define AXP221_INIT_DATA 0x3e - -#define AXP223_DEVICE_ADDR 0x3a3 -#define AXP223_RUNTIME_ADDR 0x2d - /* Page 0 addresses */ #define AXP221_POWER_STATUS 0x00 #define AXP221_POWER_STATUS_VBUS_AVAIL (1 << 5)

On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Move the register helpers used to access the registers via p2wi resp. rsb bus on the otherwise identical axp221 and axp223 pmics to a separate file, so that they can be used by the upcoming standalone axp gpio driver too.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/Makefile | 2 + arch/arm/cpu/armv7/sunxi/pmic_bus.c | 93 ++++++++++++++++ arch/arm/include/asm/arch-sunxi/pmic_bus.h | 18 +++ drivers/power/axp221.c | 172 +++++++++-------------------- include/axp221.h | 7 -- 5 files changed, 166 insertions(+), 126 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/pmic_bus.c create mode 100644 arch/arm/include/asm/arch-sunxi/pmic_bus.h
Reviewed-by: Simon Glass sjg@chromium.org

On Sun, 2015-04-26 at 11:51 +0200, Hans de Goede wrote:
Move the register helpers used to access the registers via p2wi resp. rsb bus on the otherwise identical axp221 and axp223 pmics to a separate file, so that they can be used by the upcoming standalone axp gpio driver too.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Assuming this is just moving + renaming things:
Acked-by: Ian Campbell ijc@hellion.org.uk

Add support for the axp152 and axp209 PMICs to the pmic register access helpers. This is a preparation patch for moving the axp gpio code to a separate gpio driver.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/pmic_bus.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 50791e0..5221902 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -32,6 +32,8 @@ obj-$(CONFIG_MACH_SUN8I_A23) += clock_sun6i.o obj-$(CONFIG_MACH_SUN8I_A33) += clock_sun6i.o obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o
+obj-$(CONFIG_AXP152_POWER) += pmic_bus.o +obj-$(CONFIG_AXP209_POWER) += pmic_bus.o obj-$(CONFIG_AXP221_POWER) += pmic_bus.o
ifndef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/sunxi/pmic_bus.c b/arch/arm/cpu/armv7/sunxi/pmic_bus.c index 389144b..9e05127 100644 --- a/arch/arm/cpu/armv7/sunxi/pmic_bus.c +++ b/arch/arm/cpu/armv7/sunxi/pmic_bus.c @@ -12,8 +12,13 @@ #include <common.h> #include <asm/arch/p2wi.h> #include <asm/arch/rsb.h> +#include <i2c.h> #include <asm/arch/pmic_bus.h>
+#define AXP152_I2C_ADDR 0x30 + +#define AXP209_I2C_ADDR 0x34 + #define AXP221_CHIP_ADDR 0x68 #define AXP221_CTRL_ADDR 0x3e #define AXP221_INIT_DATA 0x3e @@ -25,24 +30,26 @@ int pmic_bus_init(void) { /* This cannot be 0 because it is used in SPL before BSS is ready */ static int needs_init = 1; - int ret; + __maybe_unused int ret;
if (!needs_init) return 0;
-#ifdef CONFIG_MACH_SUN6I +#ifdef CONFIG_AXP221_POWER +# ifdef CONFIG_MACH_SUN6I p2wi_init(); ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, AXP221_INIT_DATA); -#else +# else ret = rsb_init(); if (ret) return ret;
ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR); -#endif +# endif if (ret) return ret; +#endif
needs_init = 0; return 0; @@ -50,19 +57,31 @@ int pmic_bus_init(void)
int pmic_bus_read(u8 reg, u8 *data) { -#ifdef CONFIG_MACH_SUN6I +#ifdef CONFIG_AXP152_POWER + return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1); +#elif defined CONFIG_AXP209_POWER + return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); +#elif defined CONFIG_AXP221_POWER +# ifdef CONFIG_MACH_SUN6I return p2wi_read(reg, data); -#else +# else return rsb_read(AXP223_RUNTIME_ADDR, reg, data); +# endif #endif }
int pmic_bus_write(u8 reg, u8 data) { -#ifdef CONFIG_MACH_SUN6I +#ifdef CONFIG_AXP152_POWER + return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1); +#elif defined CONFIG_AXP209_POWER + return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1); +#elif defined CONFIG_AXP221_POWER +# ifdef CONFIG_MACH_SUN6I return p2wi_write(reg, data); -#else +# else return rsb_write(AXP223_RUNTIME_ADDR, reg, data); +# endif #endif }

On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Add support for the axp152 and axp209 PMICs to the pmic register access helpers. This is a preparation patch for moving the axp gpio code to a separate gpio driver.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/pmic_bus.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Sun, 2015-04-26 at 11:51 +0200, Hans de Goede wrote:
Add support for the axp152 and axp209 PMICs to the pmic register access helpers. This is a preparation patch for moving the axp gpio code to a separate gpio driver.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

Move the axp-gpio code out of the drivers/power/axp*.c code, and into a new separate axpi-gpio driver.
This change drops supports for the gpio3 pin on the axp209, as that requires special handling, and no boards are using it.
Besides cleaning things up by moving the code to a separate driver, as a bonus this change also adds support for the (non vusb) gpio pins on the axp221 and the gpio pins on the axp152.
The new axp-gpio driver gets its own Kconfig option, and is only enabled on boards which need it. Besides that it only gets enabled in the regular u-boot build and not for the SPL as we never need it in the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/include/asm/arch-sunxi/gpio.h | 13 +++ board/sunxi/Kconfig | 6 ++ board/sunxi/board.c | 6 +- configs/A13-OLinuXino_defconfig | 1 + configs/Ainol_AW1_defconfig | 1 + configs/Ampe_A76_defconfig | 1 + configs/Astar_MID756_defconfig | 1 + configs/Ippo_q8h_v1_2_a33_1024x600_defconfig | 1 + configs/Ippo_q8h_v1_2_defconfig | 1 + configs/Ippo_q8h_v5_defconfig | 1 + configs/TZX-Q8-713B7_defconfig | 1 + configs/UTOO_P66_defconfig | 1 + configs/Yones_Toptech_BD1078_defconfig | 1 + configs/forfun_q88db_defconfig | 1 + configs/iNet_86VS_defconfig | 1 + drivers/gpio/Makefile | 1 + drivers/gpio/axp_gpio.c | 147 +++++++++++++++++++++++++++ drivers/gpio/sunxi_gpio.c | 17 ++-- drivers/power/axp209.c | 64 ------------ drivers/power/axp221.c | 64 ------------ include/axp152.h | 11 ++ include/axp209.h | 33 ++---- include/axp221.h | 21 ++-- 23 files changed, 222 insertions(+), 173 deletions(-) create mode 100644 drivers/gpio/axp_gpio.c
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index c9bfb4c..902e95b 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -217,4 +217,17 @@ int sunxi_name_to_gpio_bank(const char *name); int sunxi_name_to_gpio(const char *name); #define name_to_gpio(name) sunxi_name_to_gpio(name)
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO +int axp_gpio_init(void); +#else +static inline int axp_gpio_init(void) { return 0; } +#endif + +struct udevice; + +int axp_gpio_direction_input(struct udevice *dev, unsigned offset); +int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); +int axp_gpio_get_value(struct udevice *dev, unsigned offset); +int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val); + #endif /* _SUNXI_GPIO_H */ diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 3997637..a37b19e 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -328,6 +328,12 @@ config I2C4_ENABLE See I2C0_ENABLE help text. endif
+config AXP_GPIO + boolean "Enable support for gpio-s on axp PMICs" + default n + ---help--- + Say Y here to enable support for the gpio pins of the axp PMIC ICs. + config VIDEO boolean "Enable graphical uboot console on HDMI, LCD or VGA" default y diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 6b93f92..ee66f98 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -80,7 +80,7 @@ DECLARE_GLOBAL_DATA_PTR; /* add board specific code here */ int board_init(void) { - int id_pfr1; + int id_pfr1, ret;
gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
@@ -93,6 +93,10 @@ int board_init(void) asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000)); }
+ ret = axp_gpio_init(); + if (ret) + return ret; + /* Uses dm gpio code so do this here and not in i2c_init_board() */ return soft_i2c_board_init(); } diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 7fb466c..7b7b116 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -10,6 +10,7 @@ CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_AXP_GPIO=y CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y diff --git a/configs/Ainol_AW1_defconfig b/configs/Ainol_AW1_defconfig index a91a598..ff41444 100644 --- a/configs/Ainol_AW1_defconfig +++ b/configs/Ainol_AW1_defconfig @@ -10,6 +10,7 @@ CONFIG_MMC0_CD_PIN="PH1" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PB9" CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:40000,le:87,ri:112,up:38,lo:141,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="PH8" CONFIG_VIDEO_LCD_BL_EN="PH7" diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig index 7bceb50..375cc68 100644 --- a/configs/Ampe_A76_defconfig +++ b/configs/Ampe_A76_defconfig @@ -9,6 +9,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo: CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_AXP_GPIO=y CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y diff --git a/configs/Astar_MID756_defconfig b/configs/Astar_MID756_defconfig index ab55cbf..0072ab8 100644 --- a/configs/Astar_MID756_defconfig +++ b/configs/Astar_MID756_defconfig @@ -8,6 +8,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-astar-mid756" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_POWER="PH7" diff --git a/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig b/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig index a07c625..f54e2ee 100644 --- a/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig +++ b/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig @@ -6,6 +6,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-ippo-q8h-v1.2-lcd1024x600" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_POWER="PH7" diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig index 606472b..a6d58e7 100644 --- a/configs/Ippo_q8h_v1_2_defconfig +++ b/configs/Ippo_q8h_v1_2_defconfig @@ -4,6 +4,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-ippo-q8h-v1.2" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_POWER="PH7" diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig index f75737e..7f6e4ce 100644 --- a/configs/Ippo_q8h_v5_defconfig +++ b/configs/Ippo_q8h_v5_defconfig @@ -4,6 +4,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-ippo-q8h-v5" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_POWER="PH7" diff --git a/configs/TZX-Q8-713B7_defconfig b/configs/TZX-Q8-713B7_defconfig index 1c1fbaa..3484a2f 100644 --- a/configs/TZX-Q8-713B7_defconfig +++ b/configs/TZX-Q8-713B7_defconfig @@ -9,6 +9,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo: CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_AXP_GPIO=y CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y diff --git a/configs/UTOO_P66_defconfig b/configs/UTOO_P66_defconfig index a449936..ee44b51 100644 --- a/configs/UTOO_P66_defconfig +++ b/configs/UTOO_P66_defconfig @@ -11,6 +11,7 @@ CONFIG_VIDEO_LCD_RESET="PG11" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_VIDEO_LCD_TL059WV5C0=y +CONFIG_AXP_GPIO=y CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_MMC0_CD_PIN="PG0" CONFIG_ARM=y diff --git a/configs/Yones_Toptech_BD1078_defconfig b/configs/Yones_Toptech_BD1078_defconfig index 6f6e89d..b675726 100644 --- a/configs/Yones_Toptech_BD1078_defconfig +++ b/configs/Yones_Toptech_BD1078_defconfig @@ -14,6 +14,7 @@ CONFIG_MMC1_PINS="PH" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PB9" CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:24,pclk_khz:63000,le:32,ri:287,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_PANEL_LVDS=y diff --git a/configs/forfun_q88db_defconfig b/configs/forfun_q88db_defconfig index bafbed9..7722915 100644 --- a/configs/forfun_q88db_defconfig +++ b/configs/forfun_q88db_defconfig @@ -8,6 +8,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo: CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_AXP_GPIO=y CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y diff --git a/configs/iNet_86VS_defconfig b/configs/iNet_86VS_defconfig index 869a6d7..0646f9f 100644 --- a/configs/iNet_86VS_defconfig +++ b/configs/iNet_86VS_defconfig @@ -8,6 +8,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:209,up:22,lo CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_AXP_GPIO=y CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 8ca8b05..4a09302 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -7,6 +7,7 @@
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_DM_GPIO) += gpio-uclass.o +obj-$(CONFIG_AXP_GPIO) += axp_gpio.o endif /* TODO(sjg@chromium.org): Only tegra supports driver model in SPL */ ifdef CONFIG_TEGRA_GPIO diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c new file mode 100644 index 0000000..d04ec22 --- /dev/null +++ b/drivers/gpio/axp_gpio.c @@ -0,0 +1,147 @@ +/* + * (C) Copyright 2015 Hans de Goede hdegoede@redhat.com + * + * X-Powers AXP Power Management ICs gpio driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pmic_bus.h> +#include <errno.h> + +#ifdef CONFIG_AXP152_POWER +#include <axp152.h> +#elif defined CONFIG_AXP209_POWER +#include <axp209.h> +#elif defined CONFIG_AXP221_POWER +#include <axp221.h> +#else +#error Unknown AXP model +#endif + +static u8 axp_get_gpio_ctrl_reg(unsigned pin) +{ + switch (pin) { + case 0: return AXP_GPIO0_CTRL; + case 1: return AXP_GPIO1_CTRL; +#ifdef AXP_GPIO2_CTRL + case 2: return AXP_GPIO2_CTRL; +#endif +#ifdef AXP_GPIO3_CTRL + case 3: return AXP_GPIO3_CTRL; +#endif + } + return 0; +} + +int axp_gpio_direction_input(struct udevice *dev, unsigned pin) +{ + u8 reg; + + switch (pin) { +#ifndef CONFIG_AXP152_POWER /* NA on axp152 */ + case SUNXI_GPIO_AXP0_VBUS_DETECT: + return 0; +#endif + default: + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; + + return pmic_bus_write(reg, AXP_GPIO_CTRL_INPUT); + } +} + +int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) +{ + __maybe_unused int ret; + u8 reg; + + switch (pin) { +#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */ + case SUNXI_GPIO_AXP0_VBUS_ENABLE: + ret = pmic_bus_clrbits(AXP221_MISC_CTRL, + AXP221_MISC_CTRL_N_VBUSEN_FUNC); + if (ret) + return ret; + + return axp_gpio_set_value(dev, pin, val); +#endif + default: + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; + + return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH : + AXP_GPIO_CTRL_OUTPUT_LOW); + } +} + +int axp_gpio_get_value(struct udevice *dev, unsigned pin) +{ + u8 reg, val, mask; + int ret; + + switch (pin) { +#ifndef CONFIG_AXP152_POWER /* NA on axp152 */ + case SUNXI_GPIO_AXP0_VBUS_DETECT: + ret = pmic_bus_read(AXP_POWER_STATUS, &val); + mask = AXP_POWER_STATUS_VBUS_PRESENT; + break; +#endif +#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */ + case SUNXI_GPIO_AXP0_VBUS_ENABLE: + ret = pmic_bus_read(AXP221_VBUS_IPSOUT, &val); + mask = AXP221_VBUS_IPSOUT_DRIVEBUS; + break; +#endif + default: + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; + + ret = pmic_bus_read(AXP_GPIO_STATE, &val); + mask = 1 << (pin + AXP_GPIO_STATE_OFFSET); + } + if (ret) + return ret; + + return (val & mask) ? 1 : 0; +} + +int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) +{ + u8 reg; + + switch (pin) { +#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */ + case SUNXI_GPIO_AXP0_VBUS_ENABLE: + if (val) + return pmic_bus_setbits(AXP221_VBUS_IPSOUT, + AXP221_VBUS_IPSOUT_DRIVEBUS); + else + return pmic_bus_clrbits(AXP221_VBUS_IPSOUT, + AXP221_VBUS_IPSOUT_DRIVEBUS); +#endif + default: + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; + + return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH : + AXP_GPIO_CTRL_OUTPUT_LOW); + } +} + +int axp_gpio_init(void) +{ + int ret; + + ret = pmic_bus_init(); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 0774b70..5a0b5e4 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -15,15 +15,10 @@ #include <errno.h> #include <fdtdec.h> #include <malloc.h> +#include <asm/arch/gpio.h> #include <asm/io.h> #include <asm/gpio.h> #include <dm/device-internal.h> -#ifdef CONFIG_AXP209_POWER -#include <axp209.h> -#endif -#ifdef CONFIG_AXP221_POWER -#include <axp221.h> -#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -79,7 +74,7 @@ int gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio) { -#ifdef AXP_GPIO +#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) return axp_gpio_direction_input(NULL, gpio - SUNXI_GPIO_AXP0_START); #endif @@ -90,7 +85,7 @@ int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value) { -#ifdef AXP_GPIO +#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) return axp_gpio_direction_output(NULL, gpio - SUNXI_GPIO_AXP0_START, value); @@ -102,7 +97,7 @@ int gpio_direction_output(unsigned gpio, int value)
int gpio_get_value(unsigned gpio) { -#ifdef AXP_GPIO +#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) return axp_gpio_get_value(NULL, gpio - SUNXI_GPIO_AXP0_START); #endif @@ -111,7 +106,7 @@ int gpio_get_value(unsigned gpio)
int gpio_set_value(unsigned gpio, int value) { -#ifdef AXP_GPIO +#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO if (gpio >= SUNXI_GPIO_AXP0_START) return axp_gpio_set_value(NULL, gpio - SUNXI_GPIO_AXP0_START, value); #endif @@ -125,7 +120,7 @@ int sunxi_name_to_gpio(const char *name) long pin; char *eptr;
-#ifdef AXP_GPIO +#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO if (strncasecmp(name, "AXP0-", 5) == 0) { name += 5; if (strcmp(name, "VBUS-DETECT") == 0) diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c index 98c214f..5161bc1 100644 --- a/drivers/power/axp209.c +++ b/drivers/power/axp209.c @@ -155,67 +155,3 @@ int axp209_power_button(void)
return v & AXP209_IRQ5_PEK_DOWN; } - -static u8 axp209_get_gpio_ctrl_reg(unsigned int pin) -{ - switch (pin) { - case 0: return AXP209_GPIO0_CTRL; - case 1: return AXP209_GPIO1_CTRL; - case 2: return AXP209_GPIO2_CTRL; - case 3: return AXP209_GPIO3_CTRL; - } - return 0; -} - -int axp_gpio_direction_input(struct udevice *dev, unsigned pin) -{ - if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) - return 0; - - u8 reg = axp209_get_gpio_ctrl_reg(pin); - /* GPIO3 is "special" */ - u8 val = (pin == 3) ? AXP209_GPIO3_INPUT : AXP209_GPIO_INPUT; - - return axp209_write(reg, val); -} - -int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) -{ - u8 reg = axp209_get_gpio_ctrl_reg(pin); - - if (val) { - val = (pin == 3) ? AXP209_GPIO3_OUTPUT_HIGH : - AXP209_GPIO_OUTPUT_HIGH; - } else { - val = (pin == 3) ? AXP209_GPIO3_OUTPUT_LOW : - AXP209_GPIO_OUTPUT_LOW; - } - - return axp209_write(reg, val); -} - -int axp_gpio_get_value(struct udevice *dev, unsigned pin) -{ - u8 val, mask; - int rc; - - if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) { - rc = axp209_read(AXP209_POWER_STATUS, &val); - mask = AXP209_POWER_STATUS_VBUS_USABLE; - } else if (pin == 3) { - rc = axp209_read(AXP209_GPIO3_CTRL, &val); - mask = 1; - } else { - rc = axp209_read(AXP209_GPIO_STATE, &val); - mask = 1 << (pin + 4); - } - if (rc) - return rc; - - return (val & mask) ? 1 : 0; -} - -int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) -{ - return axp_gpio_direction_output(dev, pin, val); -} diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index d49de86..7bbaec8 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -319,67 +319,3 @@ int axp221_get_sid(unsigned int *sid)
return 0; } - -int axp_gpio_direction_input(struct udevice *dev, unsigned pin) -{ - switch (pin) { - case SUNXI_GPIO_AXP0_VBUS_DETECT: - return 0; - default: - return -EINVAL; - } -} - -int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) -{ - int ret; - - switch (pin) { - case SUNXI_GPIO_AXP0_VBUS_ENABLE: - ret = axp221_clrbits(AXP221_MISC_CTRL, - AXP221_MISC_CTRL_N_VBUSEN_FUNC); - if (ret) - return ret; - - return axp_gpio_set_value(dev, pin, val); - default: - return -EINVAL; - } -} - -int axp_gpio_get_value(struct udevice *dev, unsigned pin) -{ - int ret; - u8 val; - - switch (pin) { - case SUNXI_GPIO_AXP0_VBUS_DETECT: - ret = pmic_bus_read(AXP221_POWER_STATUS, &val); - if (ret) - return ret; - - return !!(val & AXP221_POWER_STATUS_VBUS_AVAIL); - default: - return -EINVAL; - } -} - -int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) -{ - int ret; - - switch (pin) { - case SUNXI_GPIO_AXP0_VBUS_ENABLE: - if (val) - ret = axp221_setbits(AXP221_VBUS_IPSOUT, - AXP221_VBUS_IPSOUT_DRIVEBUS); - else - ret = axp221_clrbits(AXP221_VBUS_IPSOUT, - AXP221_VBUS_IPSOUT_DRIVEBUS); - - if (ret) - return ret; - } - - return 0; -} diff --git a/include/axp152.h b/include/axp152.h index 9d205f8..c3aef77 100644 --- a/include/axp152.h +++ b/include/axp152.h @@ -15,6 +15,17 @@ enum axp152_reg {
#define AXP152_POWEROFF (1 << 7)
+/* For axp_gpio.c */ +#define AXP_GPIO0_CTRL 0x90 +#define AXP_GPIO1_CTRL 0x91 +#define AXP_GPIO2_CTRL 0x92 +#define AXP_GPIO3_CTRL 0x93 +#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */ +#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */ +#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ +#define AXP_GPIO_STATE 0x97 +#define AXP_GPIO_STATE_OFFSET 0 + int axp152_set_dcdc2(int mvolt); int axp152_set_dcdc3(int mvolt); int axp152_set_dcdc4(int mvolt); diff --git a/include/axp209.h b/include/axp209.h index fe4a169..6170202 100644 --- a/include/axp209.h +++ b/include/axp209.h @@ -4,8 +4,6 @@ * SPDX-License-Identifier: GPL-2.0+ */
-struct udevice; - enum axp209_reg { AXP209_POWER_STATUS = 0x00, AXP209_CHIP_VERSION = 0x03, @@ -20,11 +18,6 @@ enum axp209_reg { AXP209_IRQ_ENABLE5 = 0x44, AXP209_IRQ_STATUS5 = 0x4c, AXP209_SHUTDOWN = 0x32, - AXP209_GPIO0_CTRL = 0x90, - AXP209_GPIO1_CTRL = 0x92, - AXP209_GPIO2_CTRL = 0x93, - AXP209_GPIO_STATE = 0x94, - AXP209_GPIO3_CTRL = 0x95, };
#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0) @@ -35,16 +28,17 @@ enum axp209_reg {
#define AXP209_POWEROFF (1 << 7)
-#define AXP209_GPIO_OUTPUT_LOW 0x00 /* Drive pin low */ -#define AXP209_GPIO_OUTPUT_HIGH 0x01 /* Drive pin high */ -#define AXP209_GPIO_INPUT 0x02 /* Float pin */ - -/* GPIO3 is different from the others */ -#define AXP209_GPIO3_OUTPUT_LOW 0x00 /* Drive pin low, Output mode */ -#define AXP209_GPIO3_OUTPUT_HIGH 0x02 /* Float pin, Output mode */ -#define AXP209_GPIO3_INPUT 0x06 /* Float pin, Input mode */ - -#define AXP_GPIO +/* For axp_gpio.c */ +#define AXP_POWER_STATUS 0x00 +#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#define AXP_GPIO0_CTRL 0x90 +#define AXP_GPIO1_CTRL 0x92 +#define AXP_GPIO2_CTRL 0x93 +#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */ +#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */ +#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ +#define AXP_GPIO_STATE 0x94 +#define AXP_GPIO_STATE_OFFSET 4
extern int axp209_set_dcdc2(int mvolt); extern int axp209_set_dcdc3(int mvolt); @@ -54,8 +48,3 @@ extern int axp209_set_ldo4(int mvolt); extern int axp209_init(void); extern int axp209_poweron_by_dc(void); extern int axp209_power_button(void); - -extern int axp_gpio_direction_input(struct udevice *dev, unsigned offset); -extern int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); -extern int axp_gpio_get_value(struct udevice *dev, unsigned offset); -extern int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val); diff --git a/include/axp221.h b/include/axp221.h index f62f708..9c87162 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -6,12 +6,7 @@ * SPDX-License-Identifier: GPL-2.0+ */
-struct udevice; - /* Page 0 addresses */ -#define AXP221_POWER_STATUS 0x00 -#define AXP221_POWER_STATUS_VBUS_AVAIL (1 << 5) -#define AXP221_POWER_STATUS_VBUS_USABLE (1 << 4) #define AXP221_CHIP_ID 0x03 #define AXP221_OUTPUT_CTRL1 0x10 #define AXP221_OUTPUT_CTRL1_DCDC0_EN (1 << 0) @@ -57,7 +52,16 @@ struct udevice; /* Page 1 addresses */ #define AXP221_SID 0x20
-#define AXP_GPIO +/* For axp_gpio.c */ +#define AXP_POWER_STATUS 0x00 +#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#define AXP_GPIO0_CTRL 0x90 +#define AXP_GPIO1_CTRL 0x92 +#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */ +#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */ +#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ +#define AXP_GPIO_STATE 0x94 +#define AXP_GPIO_STATE_OFFSET 0
int axp221_set_dcdc1(unsigned int mvolt); int axp221_set_dcdc2(unsigned int mvolt); @@ -74,8 +78,3 @@ int axp221_set_aldo3(unsigned int mvolt); int axp221_set_eldo(int eldo_num, unsigned int mvolt); int axp221_init(void); int axp221_get_sid(unsigned int *sid); - -int axp_gpio_direction_input(struct udevice *dev, unsigned offset); -int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); -int axp_gpio_get_value(struct udevice *dev, unsigned offset); -int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);

On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Move the axp-gpio code out of the drivers/power/axp*.c code, and into a new separate axpi-gpio driver.
This change drops supports for the gpio3 pin on the axp209, as that requires special handling, and no boards are using it.
Besides cleaning things up by moving the code to a separate driver, as a bonus this change also adds support for the (non vusb) gpio pins on the axp221 and the gpio pins on the axp152.
The new axp-gpio driver gets its own Kconfig option, and is only enabled on boards which need it. Besides that it only gets enabled in the regular u-boot build and not for the SPL as we never need it in the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Reviewed-by: Simon Glass sjg@chromium.org

On Sun, 2015-04-26 at 11:51 +0200, Hans de Goede wrote:
Move the axp-gpio code out of the drivers/power/axp*.c code, and into a new separate axpi-gpio driver.
This change drops supports for the gpio3 pin on the axp209, as that requires special handling, and no boards are using it.
Besides cleaning things up by moving the code to a separate driver, as a bonus this change also adds support for the (non vusb) gpio pins on the axp221 and the gpio pins on the axp152.
The new axp-gpio driver gets its own Kconfig option, and is only enabled on boards which need it. Besides that it only gets enabled in the regular u-boot build and not for the SPL as we never need it in the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

Add driver-model support to the axp_gpio code, note that this needs a small tweak to the driver-model version of sunxi_name_to_gpio to deal with the vbus detect and enable pins which are not standard numbered gpios.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/include/asm/arch-sunxi/gpio.h | 6 ++++-- drivers/gpio/axp_gpio.c | 39 ++++++++++++++++++++++++++++++++++ drivers/gpio/sunxi_gpio.c | 14 +++++++++++- 3 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 902e95b..2d66077 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -204,8 +204,10 @@ enum sunxi_gpio_number { #define SUNXI_GPIO_PULL_DOWN 2
/* Virtual AXP0 GPIOs */ -#define SUNXI_GPIO_AXP0_VBUS_DETECT 8 -#define SUNXI_GPIO_AXP0_VBUS_ENABLE 9 +#define SUNXI_GPIO_AXP0_PREFIX "AXP0-" +#define SUNXI_GPIO_AXP0_VBUS_DETECT 4 +#define SUNXI_GPIO_AXP0_VBUS_ENABLE 5 +#define SUNXI_GPIO_AXP0_GPIO_COUNT 6
void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val); void sunxi_gpio_set_cfgpin(u32 pin, u32 val); diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index d04ec22..17358e6 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -9,6 +9,10 @@ #include <common.h> #include <asm/arch/gpio.h> #include <asm/arch/pmic_bus.h> +#include <asm/gpio.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/root.h> #include <errno.h>
#ifdef CONFIG_AXP152_POWER @@ -135,13 +139,48 @@ int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) } }
+#ifdef CONFIG_DM_GPIO +static const struct dm_gpio_ops gpio_axp_ops = { + .direction_input = axp_gpio_direction_input, + .direction_output = axp_gpio_direction_output, + .get_value = axp_gpio_get_value, + .set_value = axp_gpio_set_value, +}; + +static int gpio_axp_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + /* Tell the uclass how many GPIOs we have */ + uc_priv->bank_name = strdup(SUNXI_GPIO_AXP0_PREFIX); + uc_priv->gpio_count = SUNXI_GPIO_AXP0_GPIO_COUNT; + + return 0; +} + +struct driver gpio_axp_driver = { + .name = "gpio_axp", + .id = UCLASS_GPIO, + .ops = &gpio_axp_ops, + .probe = gpio_axp_probe, +}; +#endif + int axp_gpio_init(void) { + __maybe_unused struct udevice *dev; int ret;
ret = pmic_bus_init(); if (ret) return ret;
+#ifdef CONFIG_DM_GPIO + /* There is no devicetree support for the axp yet, so bind directly */ + ret = device_bind(dm_root(), &gpio_axp_driver, "AXP", NULL, -1, &dev); + if (ret) + return ret; +#endif + return 0; } diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 5a0b5e4..21c3ff1 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -172,7 +172,19 @@ int sunxi_name_to_gpio(const char *name) { unsigned int gpio; int ret; - +#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO + char lookup[8]; + + if (strcasecmp(name, "AXP0-VBUS-DETECT") == 0) { + sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d", + SUNXI_GPIO_AXP0_VBUS_DETECT); + name = lookup; + } else if (strcasecmp(name, "AXP0-VBUS-ENABLE") == 0) { + sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d", + SUNXI_GPIO_AXP0_VBUS_ENABLE); + name = lookup; + } +#endif ret = gpio_lookup_name(name, NULL, NULL, &gpio);
return ret ? ret : gpio;

Hi Hans,
On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Add driver-model support to the axp_gpio code, note that this needs a small tweak to the driver-model version of sunxi_name_to_gpio to deal with the vbus detect and enable pins which are not standard numbered gpios.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/include/asm/arch-sunxi/gpio.h | 6 ++++-- drivers/gpio/axp_gpio.c | 39 ++++++++++++++++++++++++++++++++++ drivers/gpio/sunxi_gpio.c | 14 +++++++++++- 3 files changed, 56 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 902e95b..2d66077 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -204,8 +204,10 @@ enum sunxi_gpio_number { #define SUNXI_GPIO_PULL_DOWN 2
/* Virtual AXP0 GPIOs */ -#define SUNXI_GPIO_AXP0_VBUS_DETECT 8 -#define SUNXI_GPIO_AXP0_VBUS_ENABLE 9 +#define SUNXI_GPIO_AXP0_PREFIX "AXP0-" +#define SUNXI_GPIO_AXP0_VBUS_DETECT 4 +#define SUNXI_GPIO_AXP0_VBUS_ENABLE 5 +#define SUNXI_GPIO_AXP0_GPIO_COUNT 6
void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val); void sunxi_gpio_set_cfgpin(u32 pin, u32 val); diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index d04ec22..17358e6 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -9,6 +9,10 @@ #include <common.h> #include <asm/arch/gpio.h> #include <asm/arch/pmic_bus.h> +#include <asm/gpio.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/root.h> #include <errno.h>
#ifdef CONFIG_AXP152_POWER @@ -135,13 +139,48 @@ int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) } }
+#ifdef CONFIG_DM_GPIO +static const struct dm_gpio_ops gpio_axp_ops = {
.direction_input = axp_gpio_direction_input,
.direction_output = axp_gpio_direction_output,
.get_value = axp_gpio_get_value,
.set_value = axp_gpio_set_value,
+};
+static int gpio_axp_probe(struct udevice *dev) +{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
/* Tell the uclass how many GPIOs we have */
uc_priv->bank_name = strdup(SUNXI_GPIO_AXP0_PREFIX);
uc_priv->gpio_count = SUNXI_GPIO_AXP0_GPIO_COUNT;
return 0;
+}
U_BOOT_DRIVER()
+struct driver gpio_axp_driver = {
.name = "gpio_axp",
.id = UCLASS_GPIO,
.ops = &gpio_axp_ops,
.probe = gpio_axp_probe,
+}; +#endif
int axp_gpio_init(void) {
__maybe_unused struct udevice *dev; int ret; ret = pmic_bus_init(); if (ret) return ret;
+#ifdef CONFIG_DM_GPIO
/* There is no devicetree support for the axp yet, so bind directly */
ret = device_bind(dm_root(), &gpio_axp_driver, "AXP", NULL, -1, &dev);
if (ret)
return ret;
+#endif
return 0;
} diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 5a0b5e4..21c3ff1 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -172,7 +172,19 @@ int sunxi_name_to_gpio(const char *name) { unsigned int gpio; int ret;
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
char lookup[8];
if (strcasecmp(name, "AXP0-VBUS-DETECT") == 0) {
sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d",
SUNXI_GPIO_AXP0_VBUS_DETECT);
name = lookup;
} else if (strcasecmp(name, "AXP0-VBUS-ENABLE") == 0) {
sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d",
SUNXI_GPIO_AXP0_VBUS_ENABLE);
name = lookup;
}
+#endif ret = gpio_lookup_name(name, NULL, NULL, &gpio);
return ret ? ret : gpio;
-- 2.3.5
Regards, Simon

On Sun, 2015-04-26 at 11:51 +0200, Hans de Goede wrote:
Add driver-model support to the axp_gpio code, note that this needs a small tweak to the driver-model version of sunxi_name_to_gpio to deal with the vbus detect and enable pins which are not standard numbered gpios.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Modulo Simon's one comment:
Acked-by: Ian Campbell ijc@hellion.org.uk

Now that all sunxi boards are using driver-model for gpio (*), we can remove the non driver-model support from the axp gpio code, and the glue to call into the axp gpio code from the sunxi_gpio non driver-model code.
*) For the regular u-boot build, SPL still uses non driver-model gpio for now, but the SPL never uses axp gpios support and we were already not building axp-gpio support for the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/include/asm/arch-sunxi/gpio.h | 7 ------- drivers/gpio/axp_gpio.c | 17 ++++++++--------- drivers/gpio/sunxi_gpio.c | 32 -------------------------------- 3 files changed, 8 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 2d66077..081e7d1 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -225,11 +225,4 @@ int axp_gpio_init(void); static inline int axp_gpio_init(void) { return 0; } #endif
-struct udevice; - -int axp_gpio_direction_input(struct udevice *dev, unsigned offset); -int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); -int axp_gpio_get_value(struct udevice *dev, unsigned offset); -int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val); - #endif /* _SUNXI_GPIO_H */ diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index 17358e6..956bb84 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -25,6 +25,8 @@ #error Unknown AXP model #endif
+static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val); + static u8 axp_get_gpio_ctrl_reg(unsigned pin) { switch (pin) { @@ -40,7 +42,7 @@ static u8 axp_get_gpio_ctrl_reg(unsigned pin) return 0; }
-int axp_gpio_direction_input(struct udevice *dev, unsigned pin) +static int axp_gpio_direction_input(struct udevice *dev, unsigned pin) { u8 reg;
@@ -58,7 +60,8 @@ int axp_gpio_direction_input(struct udevice *dev, unsigned pin) } }
-int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_direction_output(struct udevice *dev, unsigned pin, + int val) { __maybe_unused int ret; u8 reg; @@ -83,7 +86,7 @@ int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) } }
-int axp_gpio_get_value(struct udevice *dev, unsigned pin) +static int axp_gpio_get_value(struct udevice *dev, unsigned pin) { u8 reg, val, mask; int ret; @@ -115,7 +118,7 @@ int axp_gpio_get_value(struct udevice *dev, unsigned pin) return (val & mask) ? 1 : 0; }
-int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { u8 reg;
@@ -139,7 +142,6 @@ int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) } }
-#ifdef CONFIG_DM_GPIO static const struct dm_gpio_ops gpio_axp_ops = { .direction_input = axp_gpio_direction_input, .direction_output = axp_gpio_direction_output, @@ -164,23 +166,20 @@ struct driver gpio_axp_driver = { .ops = &gpio_axp_ops, .probe = gpio_axp_probe, }; -#endif
int axp_gpio_init(void) { - __maybe_unused struct udevice *dev; + struct udevice *dev; int ret;
ret = pmic_bus_init(); if (ret) return ret;
-#ifdef CONFIG_DM_GPIO /* There is no devicetree support for the axp yet, so bind directly */ ret = device_bind(dm_root(), &gpio_axp_driver, "AXP", NULL, -1, &dev); if (ret) return ret; -#endif
return 0; } diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 21c3ff1..f988130 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -74,10 +74,6 @@ int gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO - if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_direction_input(NULL, gpio - SUNXI_GPIO_AXP0_START); -#endif sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
return 0; @@ -85,11 +81,6 @@ int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO - if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_direction_output(NULL, gpio - SUNXI_GPIO_AXP0_START, - value); -#endif sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
return sunxi_gpio_output(gpio, value); @@ -97,19 +88,11 @@ int gpio_direction_output(unsigned gpio, int value)
int gpio_get_value(unsigned gpio) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO - if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_get_value(NULL, gpio - SUNXI_GPIO_AXP0_START); -#endif return sunxi_gpio_input(gpio); }
int gpio_set_value(unsigned gpio, int value) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO - if (gpio >= SUNXI_GPIO_AXP0_START) - return axp_gpio_set_value(NULL, gpio - SUNXI_GPIO_AXP0_START, value); -#endif return sunxi_gpio_output(gpio, value); }
@@ -120,21 +103,6 @@ int sunxi_name_to_gpio(const char *name) long pin; char *eptr;
-#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO - if (strncasecmp(name, "AXP0-", 5) == 0) { - name += 5; - if (strcmp(name, "VBUS-DETECT") == 0) - return SUNXI_GPIO_AXP0_START + - SUNXI_GPIO_AXP0_VBUS_DETECT; - if (strcmp(name, "VBUS-ENABLE") == 0) - return SUNXI_GPIO_AXP0_START + - SUNXI_GPIO_AXP0_VBUS_ENABLE; - pin = simple_strtol(name, &eptr, 10); - if (!*name || *eptr) - return -1; - return SUNXI_GPIO_AXP0_START + pin; - } -#endif if (*name == 'P' || *name == 'p') name++; if (*name >= 'A') {

Hi Hans,
On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Now that all sunxi boards are using driver-model for gpio (*), we can remove the non driver-model support from the axp gpio code, and the glue to call into the axp gpio code from the sunxi_gpio non driver-model code.
*) For the regular u-boot build, SPL still uses non driver-model gpio for now, but the SPL never uses axp gpios support and we were already not building axp-gpio support for the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/include/asm/arch-sunxi/gpio.h | 7 ------- drivers/gpio/axp_gpio.c | 17 ++++++++--------- drivers/gpio/sunxi_gpio.c | 32 -------------------------------- 3 files changed, 8 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 2d66077..081e7d1 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -225,11 +225,4 @@ int axp_gpio_init(void); static inline int axp_gpio_init(void) { return 0; } #endif
-struct udevice;
-int axp_gpio_direction_input(struct udevice *dev, unsigned offset); -int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); -int axp_gpio_get_value(struct udevice *dev, unsigned offset); -int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);
#endif /* _SUNXI_GPIO_H */ diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index 17358e6..956bb84 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -25,6 +25,8 @@ #error Unknown AXP model #endif
+static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
static u8 axp_get_gpio_ctrl_reg(unsigned pin) { switch (pin) { @@ -40,7 +42,7 @@ static u8 axp_get_gpio_ctrl_reg(unsigned pin) return 0; }
-int axp_gpio_direction_input(struct udevice *dev, unsigned pin) +static int axp_gpio_direction_input(struct udevice *dev, unsigned pin) { u8 reg;
@@ -58,7 +60,8 @@ int axp_gpio_direction_input(struct udevice *dev, unsigned pin) } }
-int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
int val)
{ __maybe_unused int ret; u8 reg; @@ -83,7 +86,7 @@ int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) } }
-int axp_gpio_get_value(struct udevice *dev, unsigned pin) +static int axp_gpio_get_value(struct udevice *dev, unsigned pin) { u8 reg, val, mask; int ret; @@ -115,7 +118,7 @@ int axp_gpio_get_value(struct udevice *dev, unsigned pin) return (val & mask) ? 1 : 0; }
-int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { u8 reg;
@@ -139,7 +142,6 @@ int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) } }
-#ifdef CONFIG_DM_GPIO static const struct dm_gpio_ops gpio_axp_ops = { .direction_input = axp_gpio_direction_input, .direction_output = axp_gpio_direction_output, @@ -164,23 +166,20 @@ struct driver gpio_axp_driver = { .ops = &gpio_axp_ops, .probe = gpio_axp_probe, }; -#endif
int axp_gpio_init(void) {
__maybe_unused struct udevice *dev;
struct udevice *dev; int ret; ret = pmic_bus_init(); if (ret) return ret;
-#ifdef CONFIG_DM_GPIO /* There is no devicetree support for the axp yet, so bind directly */ ret = device_bind(dm_root(), &gpio_axp_driver, "AXP", NULL, -1, &dev);
Is there really no compatible string you can use?
device_bind_driver(dm_root(), "gpio_axp", "AXP", &dev)
if (ret) return ret;
-#endif
return 0;
} diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 21c3ff1..f988130 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -74,10 +74,6 @@ int gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
if (gpio >= SUNXI_GPIO_AXP0_START)
return axp_gpio_direction_input(NULL, gpio - SUNXI_GPIO_AXP0_START);
-#endif sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
return 0;
@@ -85,11 +81,6 @@ int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
if (gpio >= SUNXI_GPIO_AXP0_START)
return axp_gpio_direction_output(NULL, gpio - SUNXI_GPIO_AXP0_START,
value);
-#endif sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
return sunxi_gpio_output(gpio, value);
@@ -97,19 +88,11 @@ int gpio_direction_output(unsigned gpio, int value)
int gpio_get_value(unsigned gpio) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
if (gpio >= SUNXI_GPIO_AXP0_START)
return axp_gpio_get_value(NULL, gpio - SUNXI_GPIO_AXP0_START);
-#endif return sunxi_gpio_input(gpio); }
int gpio_set_value(unsigned gpio, int value) { -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
if (gpio >= SUNXI_GPIO_AXP0_START)
return axp_gpio_set_value(NULL, gpio - SUNXI_GPIO_AXP0_START, value);
-#endif return sunxi_gpio_output(gpio, value); }
@@ -120,21 +103,6 @@ int sunxi_name_to_gpio(const char *name) long pin; char *eptr;
-#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
if (strncasecmp(name, "AXP0-", 5) == 0) {
name += 5;
if (strcmp(name, "VBUS-DETECT") == 0)
return SUNXI_GPIO_AXP0_START +
SUNXI_GPIO_AXP0_VBUS_DETECT;
if (strcmp(name, "VBUS-ENABLE") == 0)
return SUNXI_GPIO_AXP0_START +
SUNXI_GPIO_AXP0_VBUS_ENABLE;
pin = simple_strtol(name, &eptr, 10);
if (!*name || *eptr)
return -1;
return SUNXI_GPIO_AXP0_START + pin;
}
-#endif if (*name == 'P' || *name == 'p') name++; if (*name >= 'A') { -- 2.3.5

Hi Simon,
Thanks for the reviews.
On 28-04-15 05:20, Simon Glass wrote:
Hi Hans,
On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Now that all sunxi boards are using driver-model for gpio (*), we can remove the non driver-model support from the axp gpio code, and the glue to call into the axp gpio code from the sunxi_gpio non driver-model code.
*) For the regular u-boot build, SPL still uses non driver-model gpio for now, but the SPL never uses axp gpios support and we were already not building axp-gpio support for the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/include/asm/arch-sunxi/gpio.h | 7 ------- drivers/gpio/axp_gpio.c | 17 ++++++++--------- drivers/gpio/sunxi_gpio.c | 32 -------------------------------- 3 files changed, 8 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 2d66077..081e7d1 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -225,11 +225,4 @@ int axp_gpio_init(void); static inline int axp_gpio_init(void) { return 0; } #endif
-struct udevice;
-int axp_gpio_direction_input(struct udevice *dev, unsigned offset); -int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); -int axp_gpio_get_value(struct udevice *dev, unsigned offset); -int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);
- #endif /* _SUNXI_GPIO_H */
diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index 17358e6..956bb84 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -25,6 +25,8 @@ #error Unknown AXP model #endif
+static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
- static u8 axp_get_gpio_ctrl_reg(unsigned pin) { switch (pin) {
@@ -40,7 +42,7 @@ static u8 axp_get_gpio_ctrl_reg(unsigned pin) return 0; }
-int axp_gpio_direction_input(struct udevice *dev, unsigned pin) +static int axp_gpio_direction_input(struct udevice *dev, unsigned pin) { u8 reg;
@@ -58,7 +60,8 @@ int axp_gpio_direction_input(struct udevice *dev, unsigned pin) } }
-int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
{ __maybe_unused int ret; u8 reg;int val)
@@ -83,7 +86,7 @@ int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) } }
-int axp_gpio_get_value(struct udevice *dev, unsigned pin) +static int axp_gpio_get_value(struct udevice *dev, unsigned pin) { u8 reg, val, mask; int ret; @@ -115,7 +118,7 @@ int axp_gpio_get_value(struct udevice *dev, unsigned pin) return (val & mask) ? 1 : 0; }
-int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { u8 reg;
@@ -139,7 +142,6 @@ int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) } }
-#ifdef CONFIG_DM_GPIO static const struct dm_gpio_ops gpio_axp_ops = { .direction_input = axp_gpio_direction_input, .direction_output = axp_gpio_direction_output, @@ -164,23 +166,20 @@ struct driver gpio_axp_driver = { .ops = &gpio_axp_ops, .probe = gpio_axp_probe, }; -#endif
int axp_gpio_init(void) {
__maybe_unused struct udevice *dev;
struct udevice *dev; int ret; ret = pmic_bus_init(); if (ret) return ret;
-#ifdef CONFIG_DM_GPIO /* There is no devicetree support for the axp yet, so bind directly */ ret = device_bind(dm_root(), &gpio_axp_driver, "AXP", NULL, -1, &dev);
Is there really no compatible string you can use?
device_bind_driver(dm_root(), "gpio_axp", "AXP", &dev)
That seems like it is a comment on 5/6 not on this patch which only removes the #ifdef and #endif lines here.
I did not know I could do something like the above, I'll look into that for 5/6 and do a v2 of 5/6 I will put a "u-boot" prefix into the compatible so as to not get any conflicts when we do actually get full devicetree support for thus in the upstream kernel and dts files.
Since this is really a comment on 5/6 can I have your Reviewed-by for this one ?
Regards,
Hans

On 28 April 2015 at 00:24, Hans de Goede hdegoede@redhat.com wrote:
Hi Simon,
Thanks for the reviews.
On 28-04-15 05:20, Simon Glass wrote:
Hi Hans,
On 26 April 2015 at 03:51, Hans de Goede hdegoede@redhat.com wrote:
Now that all sunxi boards are using driver-model for gpio (*), we can remove the non driver-model support from the axp gpio code, and the glue to call into the axp gpio code from the sunxi_gpio non driver-model code.
*) For the regular u-boot build, SPL still uses non driver-model gpio for now, but the SPL never uses axp gpios support and we were already not building axp-gpio support for the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/include/asm/arch-sunxi/gpio.h | 7 ------- drivers/gpio/axp_gpio.c | 17 ++++++++--------- drivers/gpio/sunxi_gpio.c | 32
3 files changed, 8 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 2d66077..081e7d1 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -225,11 +225,4 @@ int axp_gpio_init(void); static inline int axp_gpio_init(void) { return 0; } #endif
-struct udevice;
-int axp_gpio_direction_input(struct udevice *dev, unsigned offset); -int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val); -int axp_gpio_get_value(struct udevice *dev, unsigned offset); -int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);
- #endif /* _SUNXI_GPIO_H */
diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index 17358e6..956bb84 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -25,6 +25,8 @@ #error Unknown AXP model #endif
+static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
- static u8 axp_get_gpio_ctrl_reg(unsigned pin) { switch (pin) {
@@ -40,7 +42,7 @@ static u8 axp_get_gpio_ctrl_reg(unsigned pin) return 0; }
-int axp_gpio_direction_input(struct udevice *dev, unsigned pin) +static int axp_gpio_direction_input(struct udevice *dev, unsigned pin) { u8 reg;
@@ -58,7 +60,8 @@ int axp_gpio_direction_input(struct udevice *dev, unsigned pin) } }
-int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
{ __maybe_unused int ret; u8 reg;int val)
@@ -83,7 +86,7 @@ int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) } }
-int axp_gpio_get_value(struct udevice *dev, unsigned pin) +static int axp_gpio_get_value(struct udevice *dev, unsigned pin) { u8 reg, val, mask; int ret; @@ -115,7 +118,7 @@ int axp_gpio_get_value(struct udevice *dev, unsigned pin) return (val & mask) ? 1 : 0; }
-int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) +static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { u8 reg;
@@ -139,7 +142,6 @@ int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) } }
-#ifdef CONFIG_DM_GPIO static const struct dm_gpio_ops gpio_axp_ops = { .direction_input = axp_gpio_direction_input, .direction_output = axp_gpio_direction_output, @@ -164,23 +166,20 @@ struct driver gpio_axp_driver = { .ops = &gpio_axp_ops, .probe = gpio_axp_probe, }; -#endif
int axp_gpio_init(void) {
__maybe_unused struct udevice *dev;
struct udevice *dev; int ret; ret = pmic_bus_init(); if (ret) return ret;
-#ifdef CONFIG_DM_GPIO /* There is no devicetree support for the axp yet, so bind directly */ ret = device_bind(dm_root(), &gpio_axp_driver, "AXP", NULL, -1, &dev);
Is there really no compatible string you can use?
device_bind_driver(dm_root(), "gpio_axp", "AXP", &dev)
That seems like it is a comment on 5/6 not on this patch which only removes the #ifdef and #endif lines here.
I did not know I could do something like the above, I'll look into that for 5/6 and do a v2 of 5/6 I will put a "u-boot" prefix into the compatible so as to not get any conflicts when we do actually get full devicetree support for thus in the upstream kernel and dts files.
Since this is really a comment on 5/6 can I have your Reviewed-by for this one ?
Ah yes I see, sorry.
Reviewed-by: Simon Glass sjg@chromium.org
Regards, Simon

On Sun, 2015-04-26 at 11:51 +0200, Hans de Goede wrote:
Now that all sunxi boards are using driver-model for gpio (*), we can remove the non driver-model support from the axp gpio code, and the glue to call into the axp gpio code from the sunxi_gpio non driver-model code.
*) For the regular u-boot build, SPL still uses non driver-model gpio for now, but the SPL never uses axp gpios support and we were already not building axp-gpio support for the SPL.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk
participants (3)
-
Hans de Goede
-
Ian Campbell
-
Simon Glass