2 * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
4 * X-Powers AXP Power Management ICs gpio driver
6 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/arch/gpio.h>
11 #include <asm/arch/pmic_bus.h>
15 #include <dm/device-internal.h>
20 static int axp_gpio_set_value(struct udevice
*dev
, unsigned pin
, int val
);
22 static u8
axp_get_gpio_ctrl_reg(unsigned pin
)
25 case 0: return AXP_GPIO0_CTRL
;
26 case 1: return AXP_GPIO1_CTRL
;
28 case 2: return AXP_GPIO2_CTRL
;
31 case 3: return AXP_GPIO3_CTRL
;
37 static int axp_gpio_direction_input(struct udevice
*dev
, unsigned pin
)
42 #ifndef CONFIG_AXP152_POWER /* NA on axp152 */
43 case SUNXI_GPIO_AXP0_VBUS_DETECT
:
47 reg
= axp_get_gpio_ctrl_reg(pin
);
51 return pmic_bus_write(reg
, AXP_GPIO_CTRL_INPUT
);
55 static int axp_gpio_direction_output(struct udevice
*dev
, unsigned pin
,
58 __maybe_unused
int ret
;
62 #ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC
63 /* Only available on later PMICs */
64 case SUNXI_GPIO_AXP0_VBUS_ENABLE
:
65 ret
= pmic_bus_clrbits(AXP_MISC_CTRL
,
66 AXP_MISC_CTRL_N_VBUSEN_FUNC
);
70 return axp_gpio_set_value(dev
, pin
, val
);
73 reg
= axp_get_gpio_ctrl_reg(pin
);
77 return pmic_bus_write(reg
, val
? AXP_GPIO_CTRL_OUTPUT_HIGH
:
78 AXP_GPIO_CTRL_OUTPUT_LOW
);
82 static int axp_gpio_get_value(struct udevice
*dev
, unsigned pin
)
88 #ifndef CONFIG_AXP152_POWER /* NA on axp152 */
89 case SUNXI_GPIO_AXP0_VBUS_DETECT
:
90 ret
= pmic_bus_read(AXP_POWER_STATUS
, &val
);
91 mask
= AXP_POWER_STATUS_VBUS_PRESENT
;
94 #ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC
95 /* Only available on later PMICs */
96 case SUNXI_GPIO_AXP0_VBUS_ENABLE
:
97 ret
= pmic_bus_read(AXP_VBUS_IPSOUT
, &val
);
98 mask
= AXP_VBUS_IPSOUT_DRIVEBUS
;
102 reg
= axp_get_gpio_ctrl_reg(pin
);
106 ret
= pmic_bus_read(AXP_GPIO_STATE
, &val
);
107 mask
= 1 << (pin
+ AXP_GPIO_STATE_OFFSET
);
112 return (val
& mask
) ? 1 : 0;
115 static int axp_gpio_set_value(struct udevice
*dev
, unsigned pin
, int val
)
120 #ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC
121 /* Only available on later PMICs */
122 case SUNXI_GPIO_AXP0_VBUS_ENABLE
:
124 return pmic_bus_setbits(AXP_VBUS_IPSOUT
,
125 AXP_VBUS_IPSOUT_DRIVEBUS
);
127 return pmic_bus_clrbits(AXP_VBUS_IPSOUT
,
128 AXP_VBUS_IPSOUT_DRIVEBUS
);
131 reg
= axp_get_gpio_ctrl_reg(pin
);
135 return pmic_bus_write(reg
, val
? AXP_GPIO_CTRL_OUTPUT_HIGH
:
136 AXP_GPIO_CTRL_OUTPUT_LOW
);
140 static const struct dm_gpio_ops gpio_axp_ops
= {
141 .direction_input
= axp_gpio_direction_input
,
142 .direction_output
= axp_gpio_direction_output
,
143 .get_value
= axp_gpio_get_value
,
144 .set_value
= axp_gpio_set_value
,
147 static int gpio_axp_probe(struct udevice
*dev
)
149 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
151 /* Tell the uclass how many GPIOs we have */
152 uc_priv
->bank_name
= strdup(SUNXI_GPIO_AXP0_PREFIX
);
153 uc_priv
->gpio_count
= SUNXI_GPIO_AXP0_GPIO_COUNT
;
158 U_BOOT_DRIVER(gpio_axp
) = {
161 .ops
= &gpio_axp_ops
,
162 .probe
= gpio_axp_probe
,
165 int axp_gpio_init(void)
170 ret
= pmic_bus_init();
174 /* There is no devicetree support for the axp yet, so bind directly */
175 ret
= device_bind_driver(dm_root(), "gpio_axp", "AXP-gpio", &dev
);