blob: 181c53bfe7221989de9d89609d27ce3c3f56a070 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Hans de Goede3ae1d132015-04-25 17:25:14 +02002/*
3 * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
4 *
5 * X-Powers AXP Power Management ICs gpio driver
Hans de Goede3ae1d132015-04-25 17:25:14 +02006 */
7
Hans de Goede3ae1d132015-04-25 17:25:14 +02008#include <asm/arch/pmic_bus.h>
Hans de Goede08607d12015-04-22 11:31:22 +02009#include <asm/gpio.h>
Hans de Goeded9ee84b2015-10-03 15:18:33 +020010#include <axp_pmic.h>
Hans de Goede08607d12015-04-22 11:31:22 +020011#include <dm.h>
12#include <dm/device-internal.h>
13#include <dm/lists.h>
14#include <dm/root.h>
Hans de Goede3ae1d132015-04-25 17:25:14 +020015#include <errno.h>
Andre Przywaraf944a612022-09-06 10:36:38 +010016#include <sunxi_gpio.h>
Hans de Goede3ae1d132015-04-25 17:25:14 +020017
Samuel Holland8e33d402023-10-31 01:39:55 -050018#define AXP_GPIO_PREFIX "AXP0-"
19#define AXP_GPIO_COUNT 4
20
Hans de Goede66bf5082015-04-26 11:19:37 +020021static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
22
Hans de Goede3ae1d132015-04-25 17:25:14 +020023static u8 axp_get_gpio_ctrl_reg(unsigned pin)
24{
25 switch (pin) {
26 case 0: return AXP_GPIO0_CTRL;
27 case 1: return AXP_GPIO1_CTRL;
28#ifdef AXP_GPIO2_CTRL
29 case 2: return AXP_GPIO2_CTRL;
30#endif
31#ifdef AXP_GPIO3_CTRL
32 case 3: return AXP_GPIO3_CTRL;
33#endif
34 }
35 return 0;
36}
37
Hans de Goede66bf5082015-04-26 11:19:37 +020038static int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
Hans de Goede3ae1d132015-04-25 17:25:14 +020039{
40 u8 reg;
41
Samuel Holland5f9c8442023-01-22 17:46:22 -060042 reg = axp_get_gpio_ctrl_reg(pin);
43 if (reg == 0)
44 return -EINVAL;
Hans de Goede3ae1d132015-04-25 17:25:14 +020045
Samuel Holland5f9c8442023-01-22 17:46:22 -060046 return pmic_bus_write(reg, AXP_GPIO_CTRL_INPUT);
Hans de Goede3ae1d132015-04-25 17:25:14 +020047}
48
Hans de Goede66bf5082015-04-26 11:19:37 +020049static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
50 int val)
Hans de Goede3ae1d132015-04-25 17:25:14 +020051{
Hans de Goede3ae1d132015-04-25 17:25:14 +020052 u8 reg;
53
Samuel Holland8e33d402023-10-31 01:39:55 -050054 reg = axp_get_gpio_ctrl_reg(pin);
55 if (reg == 0)
56 return -EINVAL;
Hans de Goede3ae1d132015-04-25 17:25:14 +020057
Samuel Holland8e33d402023-10-31 01:39:55 -050058 return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
59 AXP_GPIO_CTRL_OUTPUT_LOW);
Hans de Goede3ae1d132015-04-25 17:25:14 +020060}
61
Hans de Goede66bf5082015-04-26 11:19:37 +020062static int axp_gpio_get_value(struct udevice *dev, unsigned pin)
Hans de Goede3ae1d132015-04-25 17:25:14 +020063{
64 u8 reg, val, mask;
65 int ret;
66
Samuel Holland8e33d402023-10-31 01:39:55 -050067 reg = axp_get_gpio_ctrl_reg(pin);
68 if (reg == 0)
69 return -EINVAL;
Hans de Goede3ae1d132015-04-25 17:25:14 +020070
Samuel Holland8e33d402023-10-31 01:39:55 -050071 ret = pmic_bus_read(AXP_GPIO_STATE, &val);
Hans de Goede3ae1d132015-04-25 17:25:14 +020072 if (ret)
73 return ret;
74
Samuel Holland8e33d402023-10-31 01:39:55 -050075 mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
76
Hans de Goede3ae1d132015-04-25 17:25:14 +020077 return (val & mask) ? 1 : 0;
78}
79
Hans de Goede66bf5082015-04-26 11:19:37 +020080static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
Hans de Goede3ae1d132015-04-25 17:25:14 +020081{
82 u8 reg;
83
Samuel Holland8e33d402023-10-31 01:39:55 -050084 reg = axp_get_gpio_ctrl_reg(pin);
85 if (reg == 0)
86 return -EINVAL;
Hans de Goede3ae1d132015-04-25 17:25:14 +020087
Samuel Holland8e33d402023-10-31 01:39:55 -050088 return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
89 AXP_GPIO_CTRL_OUTPUT_LOW);
Hans de Goede3ae1d132015-04-25 17:25:14 +020090}
91
Hans de Goede08607d12015-04-22 11:31:22 +020092static const struct dm_gpio_ops gpio_axp_ops = {
93 .direction_input = axp_gpio_direction_input,
94 .direction_output = axp_gpio_direction_output,
95 .get_value = axp_gpio_get_value,
96 .set_value = axp_gpio_set_value,
97};
98
99static int gpio_axp_probe(struct udevice *dev)
100{
101 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
102
103 /* Tell the uclass how many GPIOs we have */
Samuel Holland8e33d402023-10-31 01:39:55 -0500104 uc_priv->bank_name = AXP_GPIO_PREFIX;
105 uc_priv->gpio_count = AXP_GPIO_COUNT;
Hans de Goede08607d12015-04-22 11:31:22 +0200106
107 return 0;
108}
109
110U_BOOT_DRIVER(gpio_axp) = {
111 .name = "gpio_axp",
112 .id = UCLASS_GPIO,
113 .ops = &gpio_axp_ops,
114 .probe = gpio_axp_probe,
115};
Hans de Goede08607d12015-04-22 11:31:22 +0200116
Hans de Goede3ae1d132015-04-25 17:25:14 +0200117int axp_gpio_init(void)
118{
Hans de Goede66bf5082015-04-26 11:19:37 +0200119 struct udevice *dev;
Hans de Goede3ae1d132015-04-25 17:25:14 +0200120 int ret;
121
122 ret = pmic_bus_init();
123 if (ret)
124 return ret;
Hans de Goede08607d12015-04-22 11:31:22 +0200125
Hans de Goede08607d12015-04-22 11:31:22 +0200126 /* There is no devicetree support for the axp yet, so bind directly */
127 ret = device_bind_driver(dm_root(), "gpio_axp", "AXP-gpio", &dev);
128 if (ret)
129 return ret;
Hans de Goede3ae1d132015-04-25 17:25:14 +0200130
131 return 0;
132}