xref: /openbmc/u-boot/drivers/gpio/axp_gpio.c (revision 2fcf033d)
1*2fcf033dSHans de Goede /*
2*2fcf033dSHans de Goede  * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
3*2fcf033dSHans de Goede  *
4*2fcf033dSHans de Goede  * X-Powers AXP Power Management ICs gpio driver
5*2fcf033dSHans de Goede  *
6*2fcf033dSHans de Goede  * SPDX-License-Identifier:	GPL-2.0+
7*2fcf033dSHans de Goede  */
8*2fcf033dSHans de Goede 
9*2fcf033dSHans de Goede #include <common.h>
10*2fcf033dSHans de Goede #include <asm/arch/gpio.h>
11*2fcf033dSHans de Goede #include <asm/arch/pmic_bus.h>
12*2fcf033dSHans de Goede #include <errno.h>
13*2fcf033dSHans de Goede 
14*2fcf033dSHans de Goede #ifdef CONFIG_AXP152_POWER
15*2fcf033dSHans de Goede #include <axp152.h>
16*2fcf033dSHans de Goede #elif defined CONFIG_AXP209_POWER
17*2fcf033dSHans de Goede #include <axp209.h>
18*2fcf033dSHans de Goede #elif defined CONFIG_AXP221_POWER
19*2fcf033dSHans de Goede #include <axp221.h>
20*2fcf033dSHans de Goede #else
21*2fcf033dSHans de Goede #error Unknown AXP model
22*2fcf033dSHans de Goede #endif
23*2fcf033dSHans de Goede 
24*2fcf033dSHans de Goede static u8 axp_get_gpio_ctrl_reg(unsigned pin)
25*2fcf033dSHans de Goede {
26*2fcf033dSHans de Goede 	switch (pin) {
27*2fcf033dSHans de Goede 	case 0: return AXP_GPIO0_CTRL;
28*2fcf033dSHans de Goede 	case 1: return AXP_GPIO1_CTRL;
29*2fcf033dSHans de Goede #ifdef AXP_GPIO2_CTRL
30*2fcf033dSHans de Goede 	case 2: return AXP_GPIO2_CTRL;
31*2fcf033dSHans de Goede #endif
32*2fcf033dSHans de Goede #ifdef AXP_GPIO3_CTRL
33*2fcf033dSHans de Goede 	case 3: return AXP_GPIO3_CTRL;
34*2fcf033dSHans de Goede #endif
35*2fcf033dSHans de Goede 	}
36*2fcf033dSHans de Goede 	return 0;
37*2fcf033dSHans de Goede }
38*2fcf033dSHans de Goede 
39*2fcf033dSHans de Goede int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
40*2fcf033dSHans de Goede {
41*2fcf033dSHans de Goede 	u8 reg;
42*2fcf033dSHans de Goede 
43*2fcf033dSHans de Goede 	switch (pin) {
44*2fcf033dSHans de Goede #ifndef CONFIG_AXP152_POWER /* NA on axp152 */
45*2fcf033dSHans de Goede 	case SUNXI_GPIO_AXP0_VBUS_DETECT:
46*2fcf033dSHans de Goede 		return 0;
47*2fcf033dSHans de Goede #endif
48*2fcf033dSHans de Goede 	default:
49*2fcf033dSHans de Goede 		reg = axp_get_gpio_ctrl_reg(pin);
50*2fcf033dSHans de Goede 		if (reg == 0)
51*2fcf033dSHans de Goede 			return -EINVAL;
52*2fcf033dSHans de Goede 
53*2fcf033dSHans de Goede 		return pmic_bus_write(reg, AXP_GPIO_CTRL_INPUT);
54*2fcf033dSHans de Goede 	}
55*2fcf033dSHans de Goede }
56*2fcf033dSHans de Goede 
57*2fcf033dSHans de Goede int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val)
58*2fcf033dSHans de Goede {
59*2fcf033dSHans de Goede 	__maybe_unused int ret;
60*2fcf033dSHans de Goede 	u8 reg;
61*2fcf033dSHans de Goede 
62*2fcf033dSHans de Goede 	switch (pin) {
63*2fcf033dSHans de Goede #ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
64*2fcf033dSHans de Goede 	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
65*2fcf033dSHans de Goede 		ret = pmic_bus_clrbits(AXP221_MISC_CTRL,
66*2fcf033dSHans de Goede 				       AXP221_MISC_CTRL_N_VBUSEN_FUNC);
67*2fcf033dSHans de Goede 		if (ret)
68*2fcf033dSHans de Goede 			return ret;
69*2fcf033dSHans de Goede 
70*2fcf033dSHans de Goede 		return axp_gpio_set_value(dev, pin, val);
71*2fcf033dSHans de Goede #endif
72*2fcf033dSHans de Goede 	default:
73*2fcf033dSHans de Goede 		reg = axp_get_gpio_ctrl_reg(pin);
74*2fcf033dSHans de Goede 		if (reg == 0)
75*2fcf033dSHans de Goede 			return -EINVAL;
76*2fcf033dSHans de Goede 
77*2fcf033dSHans de Goede 		return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
78*2fcf033dSHans de Goede 						 AXP_GPIO_CTRL_OUTPUT_LOW);
79*2fcf033dSHans de Goede 	}
80*2fcf033dSHans de Goede }
81*2fcf033dSHans de Goede 
82*2fcf033dSHans de Goede int axp_gpio_get_value(struct udevice *dev, unsigned pin)
83*2fcf033dSHans de Goede {
84*2fcf033dSHans de Goede 	u8 reg, val, mask;
85*2fcf033dSHans de Goede 	int ret;
86*2fcf033dSHans de Goede 
87*2fcf033dSHans de Goede 	switch (pin) {
88*2fcf033dSHans de Goede #ifndef CONFIG_AXP152_POWER /* NA on axp152 */
89*2fcf033dSHans de Goede 	case SUNXI_GPIO_AXP0_VBUS_DETECT:
90*2fcf033dSHans de Goede 		ret = pmic_bus_read(AXP_POWER_STATUS, &val);
91*2fcf033dSHans de Goede 		mask = AXP_POWER_STATUS_VBUS_PRESENT;
92*2fcf033dSHans de Goede 		break;
93*2fcf033dSHans de Goede #endif
94*2fcf033dSHans de Goede #ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
95*2fcf033dSHans de Goede 	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
96*2fcf033dSHans de Goede 		ret = pmic_bus_read(AXP221_VBUS_IPSOUT, &val);
97*2fcf033dSHans de Goede 		mask = AXP221_VBUS_IPSOUT_DRIVEBUS;
98*2fcf033dSHans de Goede 		break;
99*2fcf033dSHans de Goede #endif
100*2fcf033dSHans de Goede 	default:
101*2fcf033dSHans de Goede 		reg = axp_get_gpio_ctrl_reg(pin);
102*2fcf033dSHans de Goede 		if (reg == 0)
103*2fcf033dSHans de Goede 			return -EINVAL;
104*2fcf033dSHans de Goede 
105*2fcf033dSHans de Goede 		ret = pmic_bus_read(AXP_GPIO_STATE, &val);
106*2fcf033dSHans de Goede 		mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
107*2fcf033dSHans de Goede 	}
108*2fcf033dSHans de Goede 	if (ret)
109*2fcf033dSHans de Goede 		return ret;
110*2fcf033dSHans de Goede 
111*2fcf033dSHans de Goede 	return (val & mask) ? 1 : 0;
112*2fcf033dSHans de Goede }
113*2fcf033dSHans de Goede 
114*2fcf033dSHans de Goede int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
115*2fcf033dSHans de Goede {
116*2fcf033dSHans de Goede 	u8 reg;
117*2fcf033dSHans de Goede 
118*2fcf033dSHans de Goede 	switch (pin) {
119*2fcf033dSHans de Goede #ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
120*2fcf033dSHans de Goede 	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
121*2fcf033dSHans de Goede 		if (val)
122*2fcf033dSHans de Goede 			return pmic_bus_setbits(AXP221_VBUS_IPSOUT,
123*2fcf033dSHans de Goede 						AXP221_VBUS_IPSOUT_DRIVEBUS);
124*2fcf033dSHans de Goede 		else
125*2fcf033dSHans de Goede 			return pmic_bus_clrbits(AXP221_VBUS_IPSOUT,
126*2fcf033dSHans de Goede 						AXP221_VBUS_IPSOUT_DRIVEBUS);
127*2fcf033dSHans de Goede #endif
128*2fcf033dSHans de Goede 	default:
129*2fcf033dSHans de Goede 		reg = axp_get_gpio_ctrl_reg(pin);
130*2fcf033dSHans de Goede 		if (reg == 0)
131*2fcf033dSHans de Goede 			return -EINVAL;
132*2fcf033dSHans de Goede 
133*2fcf033dSHans de Goede 		return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
134*2fcf033dSHans de Goede 						 AXP_GPIO_CTRL_OUTPUT_LOW);
135*2fcf033dSHans de Goede 	}
136*2fcf033dSHans de Goede }
137*2fcf033dSHans de Goede 
138*2fcf033dSHans de Goede int axp_gpio_init(void)
139*2fcf033dSHans de Goede {
140*2fcf033dSHans de Goede 	int ret;
141*2fcf033dSHans de Goede 
142*2fcf033dSHans de Goede 	ret = pmic_bus_init();
143*2fcf033dSHans de Goede 	if (ret)
144*2fcf033dSHans de Goede 		return ret;
145*2fcf033dSHans de Goede 
146*2fcf033dSHans de Goede 	return 0;
147*2fcf033dSHans de Goede }
148