1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2015 Google, Inc
5 * (C) Copyright 2008-2014 Rockchip Electronics
6 * Peter, Software Engineering, <superpeter.cai@gmail.com>.
12 #include <linux/errno.h>
15 #include <asm/arch/clock.h>
16 #include <dm/pinctrl.h>
17 #include <dt-bindings/clock/rk3288-cru.h>
20 ROCKCHIP_GPIOS_PER_BANK
= 32,
23 #define OFFSET_TO_BIT(bit) (1UL << (bit))
25 struct rockchip_gpio_priv
{
26 struct rockchip_gpio_regs
*regs
;
27 struct udevice
*pinctrl
;
32 static int rockchip_gpio_direction_input(struct udevice
*dev
, unsigned offset
)
34 struct rockchip_gpio_priv
*priv
= dev_get_priv(dev
);
35 struct rockchip_gpio_regs
*regs
= priv
->regs
;
37 clrbits_le32(®s
->swport_ddr
, OFFSET_TO_BIT(offset
));
42 static int rockchip_gpio_direction_output(struct udevice
*dev
, unsigned offset
,
45 struct rockchip_gpio_priv
*priv
= dev_get_priv(dev
);
46 struct rockchip_gpio_regs
*regs
= priv
->regs
;
47 int mask
= OFFSET_TO_BIT(offset
);
49 clrsetbits_le32(®s
->swport_dr
, mask
, value
? mask
: 0);
50 setbits_le32(®s
->swport_ddr
, mask
);
55 static int rockchip_gpio_get_value(struct udevice
*dev
, unsigned offset
)
57 struct rockchip_gpio_priv
*priv
= dev_get_priv(dev
);
58 struct rockchip_gpio_regs
*regs
= priv
->regs
;
60 return readl(®s
->ext_port
) & OFFSET_TO_BIT(offset
) ? 1 : 0;
63 static int rockchip_gpio_set_value(struct udevice
*dev
, unsigned offset
,
66 struct rockchip_gpio_priv
*priv
= dev_get_priv(dev
);
67 struct rockchip_gpio_regs
*regs
= priv
->regs
;
68 int mask
= OFFSET_TO_BIT(offset
);
70 clrsetbits_le32(®s
->swport_dr
, mask
, value
? mask
: 0);
75 static int rockchip_gpio_get_function(struct udevice
*dev
, unsigned offset
)
77 #ifdef CONFIG_SPL_BUILD
80 struct rockchip_gpio_priv
*priv
= dev_get_priv(dev
);
81 struct rockchip_gpio_regs
*regs
= priv
->regs
;
85 ret
= pinctrl_get_gpio_mux(priv
->pinctrl
, priv
->bank
, offset
);
88 is_output
= readl(®s
->swport_ddr
) & OFFSET_TO_BIT(offset
);
90 return is_output
? GPIOF_OUTPUT
: GPIOF_INPUT
;
94 /* Simple SPL interface to GPIOs */
95 #ifdef CONFIG_SPL_BUILD
103 int spl_gpio_set_pull(void *vregs
, uint gpio
, int pull
)
108 regs
+= gpio
>> GPIO_BANK_SHIFT
;
109 gpio
&= GPIO_OFFSET_MASK
;
117 case GPIO_PULL_NORMAL
:
122 clrsetbits_le32(regs
, 3 << (gpio
* 2), val
<< (gpio
* 2));
127 int spl_gpio_output(void *vregs
, uint gpio
, int value
)
129 struct rockchip_gpio_regs
* const regs
= vregs
;
131 clrsetbits_le32(®s
->swport_dr
, 1 << gpio
, value
<< gpio
);
134 clrsetbits_le32(®s
->swport_ddr
, 1 << gpio
, 1 << gpio
);
138 #endif /* CONFIG_SPL_BUILD */
140 static int rockchip_gpio_probe(struct udevice
*dev
)
142 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
143 struct rockchip_gpio_priv
*priv
= dev_get_priv(dev
);
147 priv
->regs
= dev_read_addr_ptr(dev
);
148 ret
= uclass_first_device_err(UCLASS_PINCTRL
, &priv
->pinctrl
);
152 uc_priv
->gpio_count
= ROCKCHIP_GPIOS_PER_BANK
;
153 end
= strrchr(dev
->name
, '@');
154 priv
->bank
= trailing_strtoln(dev
->name
, end
);
155 priv
->name
[0] = 'A' + priv
->bank
;
156 uc_priv
->bank_name
= priv
->name
;
161 static const struct dm_gpio_ops gpio_rockchip_ops
= {
162 .direction_input
= rockchip_gpio_direction_input
,
163 .direction_output
= rockchip_gpio_direction_output
,
164 .get_value
= rockchip_gpio_get_value
,
165 .set_value
= rockchip_gpio_set_value
,
166 .get_function
= rockchip_gpio_get_function
,
169 static const struct udevice_id rockchip_gpio_ids
[] = {
170 { .compatible
= "rockchip,gpio-bank" },
174 U_BOOT_DRIVER(gpio_rockchip
) = {
175 .name
= "gpio_rockchip",
177 .of_match
= rockchip_gpio_ids
,
178 .ops
= &gpio_rockchip_ops
,
179 .priv_auto_alloc_size
= sizeof(struct rockchip_gpio_priv
),
180 .probe
= rockchip_gpio_probe
,