2 * (C) Copyright 2015 Marek Vasut <marex@denx.de>
4 * DesignWare APB GPIO driver
6 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/arch/gpio.h>
15 #include <dm/device-internal.h>
20 DECLARE_GLOBAL_DATA_PTR
;
22 #define GPIO_SWPORTA_DR 0x00
23 #define GPIO_SWPORTA_DDR 0x04
24 #define GPIO_INTEN 0x30
25 #define GPIO_INTMASK 0x34
26 #define GPIO_INTTYPE_LEVEL 0x38
27 #define GPIO_INT_POLARITY 0x3c
28 #define GPIO_INTSTATUS 0x40
29 #define GPIO_PORTA_DEBOUNCE 0x48
30 #define GPIO_PORTA_EOI 0x4c
31 #define GPIO_EXT_PORTA 0x50
33 struct gpio_dwapb_platdata
{
40 static int dwapb_gpio_direction_input(struct udevice
*dev
, unsigned pin
)
42 struct gpio_dwapb_platdata
*plat
= dev_get_platdata(dev
);
44 clrbits_le32(plat
->base
+ GPIO_SWPORTA_DDR
, 1 << pin
);
48 static int dwapb_gpio_direction_output(struct udevice
*dev
, unsigned pin
,
51 struct gpio_dwapb_platdata
*plat
= dev_get_platdata(dev
);
53 setbits_le32(plat
->base
+ GPIO_SWPORTA_DDR
, 1 << pin
);
56 setbits_le32(plat
->base
+ GPIO_SWPORTA_DR
, 1 << pin
);
58 clrbits_le32(plat
->base
+ GPIO_SWPORTA_DR
, 1 << pin
);
63 static int dwapb_gpio_get_value(struct udevice
*dev
, unsigned pin
)
65 struct gpio_dwapb_platdata
*plat
= dev_get_platdata(dev
);
66 return !!(readl(plat
->base
+ GPIO_EXT_PORTA
) & (1 << pin
));
70 static int dwapb_gpio_set_value(struct udevice
*dev
, unsigned pin
, int val
)
72 struct gpio_dwapb_platdata
*plat
= dev_get_platdata(dev
);
75 setbits_le32(plat
->base
+ GPIO_SWPORTA_DR
, 1 << pin
);
77 clrbits_le32(plat
->base
+ GPIO_SWPORTA_DR
, 1 << pin
);
82 static const struct dm_gpio_ops gpio_dwapb_ops
= {
83 .direction_input
= dwapb_gpio_direction_input
,
84 .direction_output
= dwapb_gpio_direction_output
,
85 .get_value
= dwapb_gpio_get_value
,
86 .set_value
= dwapb_gpio_set_value
,
89 static int gpio_dwapb_probe(struct udevice
*dev
)
91 struct gpio_dev_priv
*priv
= dev_get_uclass_priv(dev
);
92 struct gpio_dwapb_platdata
*plat
= dev
->platdata
;
97 priv
->gpio_count
= plat
->pins
;
98 priv
->bank_name
= plat
->name
;
103 static int gpio_dwapb_bind(struct udevice
*dev
)
105 struct gpio_dwapb_platdata
*plat
= dev_get_platdata(dev
);
106 const void *blob
= gd
->fdt_blob
;
107 struct udevice
*subdev
;
109 int ret
, node
, bank
= 0;
111 /* If this is a child device, there is nothing to do here */
115 base
= fdtdec_get_addr(blob
, dev
->of_offset
, "reg");
116 if (base
== FDT_ADDR_T_NONE
) {
117 debug("Can't get the GPIO register base address\n");
121 for (node
= fdt_first_subnode(blob
, dev
->of_offset
);
123 node
= fdt_next_subnode(blob
, node
)) {
124 if (!fdtdec_get_bool(blob
, node
, "gpio-controller"))
128 plat
= calloc(1, sizeof(*plat
));
134 plat
->pins
= fdtdec_get_int(blob
, node
, "snps,nr-gpios", 0);
135 ret
= fdt_get_string(blob
, node
, "bank-name", &plat
->name
);
139 ret
= device_bind(dev
, dev
->driver
, plat
->name
,
144 subdev
->of_offset
= node
;
155 static const struct udevice_id gpio_dwapb_ids
[] = {
156 { .compatible
= "snps,dw-apb-gpio" },
160 U_BOOT_DRIVER(gpio_dwapb
) = {
161 .name
= "gpio-dwapb",
163 .of_match
= gpio_dwapb_ids
,
164 .ops
= &gpio_dwapb_ops
,
165 .bind
= gpio_dwapb_bind
,
166 .probe
= gpio_dwapb_probe
,