1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/gpio.h>
4 #include <linux/of_gpio.h>
6 #include <linux/platform_device.h>
7 #include <linux/basic_mmio_gpio.h>
9 #define ETRAX_FS_rw_pa_dout 0
10 #define ETRAX_FS_r_pa_din 4
11 #define ETRAX_FS_rw_pa_oe 8
12 #define ETRAX_FS_rw_intr_cfg 12
13 #define ETRAX_FS_rw_intr_mask 16
14 #define ETRAX_FS_rw_ack_intr 20
15 #define ETRAX_FS_r_intr 24
16 #define ETRAX_FS_rw_pb_dout 32
17 #define ETRAX_FS_r_pb_din 36
18 #define ETRAX_FS_rw_pb_oe 40
19 #define ETRAX_FS_rw_pc_dout 48
20 #define ETRAX_FS_r_pc_din 52
21 #define ETRAX_FS_rw_pc_oe 56
22 #define ETRAX_FS_rw_pd_dout 64
23 #define ETRAX_FS_r_pd_din 68
24 #define ETRAX_FS_rw_pd_oe 72
25 #define ETRAX_FS_rw_pe_dout 80
26 #define ETRAX_FS_r_pe_din 84
27 #define ETRAX_FS_rw_pe_oe 88
29 struct etraxfs_gpio_port
{
37 struct etraxfs_gpio_info
{
38 unsigned int num_ports
;
39 const struct etraxfs_gpio_port
*ports
;
42 static const struct etraxfs_gpio_port etraxfs_gpio_etraxfs_ports
[] = {
46 .oe
= ETRAX_FS_rw_pa_oe
,
47 .dout
= ETRAX_FS_rw_pa_dout
,
48 .din
= ETRAX_FS_r_pa_din
,
53 .oe
= ETRAX_FS_rw_pb_oe
,
54 .dout
= ETRAX_FS_rw_pb_dout
,
55 .din
= ETRAX_FS_r_pb_din
,
60 .oe
= ETRAX_FS_rw_pc_oe
,
61 .dout
= ETRAX_FS_rw_pc_dout
,
62 .din
= ETRAX_FS_r_pc_din
,
67 .oe
= ETRAX_FS_rw_pd_oe
,
68 .dout
= ETRAX_FS_rw_pd_dout
,
69 .din
= ETRAX_FS_r_pd_din
,
74 .oe
= ETRAX_FS_rw_pe_oe
,
75 .dout
= ETRAX_FS_rw_pe_dout
,
76 .din
= ETRAX_FS_r_pe_din
,
80 static const struct etraxfs_gpio_info etraxfs_gpio_etraxfs
= {
81 .num_ports
= ARRAY_SIZE(etraxfs_gpio_etraxfs_ports
),
82 .ports
= etraxfs_gpio_etraxfs_ports
,
85 static int etraxfs_gpio_of_xlate(struct gpio_chip
*gc
,
86 const struct of_phandle_args
*gpiospec
,
90 * Port numbers are A to E, and the properties are integers, so we
91 * specify them as 0xA - 0xE.
93 if (gc
->label
[0] - 'A' + 0xA != gpiospec
->args
[2])
96 return of_gpio_simple_xlate(gc
, gpiospec
, flags
);
99 static const struct of_device_id etraxfs_gpio_of_table
[] = {
101 .compatible
= "axis,etraxfs-gio",
102 .data
= &etraxfs_gpio_etraxfs
,
107 static int etraxfs_gpio_probe(struct platform_device
*pdev
)
109 struct device
*dev
= &pdev
->dev
;
110 const struct etraxfs_gpio_info
*info
;
111 const struct of_device_id
*match
;
112 struct bgpio_chip
*chips
;
113 struct resource
*res
;
118 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
119 regs
= devm_ioremap_resource(dev
, res
);
123 match
= of_match_node(etraxfs_gpio_of_table
, dev
->of_node
);
129 chips
= devm_kzalloc(dev
, sizeof(*chips
) * info
->num_ports
, GFP_KERNEL
);
133 for (i
= 0; i
< info
->num_ports
; i
++) {
134 struct bgpio_chip
*bgc
= &chips
[i
];
135 const struct etraxfs_gpio_port
*port
= &info
->ports
[i
];
137 ret
= bgpio_init(bgc
, dev
, 4,
138 regs
+ port
->din
, /* dat */
139 regs
+ port
->dout
, /* set */
141 regs
+ port
->oe
, /* dirout */
143 BGPIOF_UNREADABLE_REG_SET
);
147 bgc
->gc
.ngpio
= port
->ngpio
;
148 bgc
->gc
.label
= port
->label
;
150 bgc
->gc
.of_node
= dev
->of_node
;
151 bgc
->gc
.of_gpio_n_cells
= 3;
152 bgc
->gc
.of_xlate
= etraxfs_gpio_of_xlate
;
154 ret
= gpiochip_add(&bgc
->gc
);
156 dev_err(dev
, "Unable to register port %s\n",
163 static struct platform_driver etraxfs_gpio_driver
= {
165 .name
= "etraxfs-gpio",
166 .of_match_table
= of_match_ptr(etraxfs_gpio_of_table
),
168 .probe
= etraxfs_gpio_probe
,
171 static int __init
etraxfs_gpio_init(void)
173 return platform_driver_register(&etraxfs_gpio_driver
);
176 device_initcall(etraxfs_gpio_init
);