2 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
3 * Copyright (C) 2011 Missing Link Electronics
4 * Joachim Foerster <joachim@missinglinkelectronics.com>
6 * SPDX-License-Identifier: GPL-2.0+
16 DECLARE_GLOBAL_DATA_PTR
;
18 struct altera_pio_regs
{
19 u32 data
; /* Data register */
20 u32 direction
; /* Direction register */
23 struct altera_pio_platdata
{
24 struct altera_pio_regs
*regs
;
26 const char *bank_name
;
29 static int altera_pio_direction_input(struct udevice
*dev
, unsigned pin
)
31 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
32 struct altera_pio_regs
*const regs
= plat
->regs
;
34 clrbits_le32(®s
->direction
, 1 << pin
);
39 static int altera_pio_direction_output(struct udevice
*dev
, unsigned pin
,
42 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
43 struct altera_pio_regs
*const regs
= plat
->regs
;
46 setbits_le32(®s
->data
, 1 << pin
);
48 clrbits_le32(®s
->data
, 1 << pin
);
49 /* change the data first, then the direction. to avoid glitch */
50 setbits_le32(®s
->direction
, 1 << pin
);
55 static int altera_pio_get_value(struct udevice
*dev
, unsigned pin
)
57 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
58 struct altera_pio_regs
*const regs
= plat
->regs
;
60 return readl(®s
->data
) & (1 << pin
);
64 static int altera_pio_set_value(struct udevice
*dev
, unsigned pin
, int val
)
66 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
67 struct altera_pio_regs
*const regs
= plat
->regs
;
70 setbits_le32(®s
->data
, 1 << pin
);
72 clrbits_le32(®s
->data
, 1 << pin
);
77 static int altera_pio_probe(struct udevice
*dev
)
79 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
80 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
82 uc_priv
->gpio_count
= plat
->gpio_count
;
83 uc_priv
->bank_name
= plat
->bank_name
;
88 static int altera_pio_ofdata_to_platdata(struct udevice
*dev
)
90 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
92 plat
->regs
= map_physmem(dev_get_addr(dev
),
93 sizeof(struct altera_pio_regs
),
95 plat
->gpio_count
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
,
96 "altr,gpio-bank-width", 32);
97 plat
->bank_name
= fdt_getprop(gd
->fdt_blob
, dev
->of_offset
,
98 "gpio-bank-name", NULL
);
103 static const struct dm_gpio_ops altera_pio_ops
= {
104 .direction_input
= altera_pio_direction_input
,
105 .direction_output
= altera_pio_direction_output
,
106 .get_value
= altera_pio_get_value
,
107 .set_value
= altera_pio_set_value
,
110 static const struct udevice_id altera_pio_ids
[] = {
111 { .compatible
= "altr,pio-1.0" },
115 U_BOOT_DRIVER(altera_pio
) = {
116 .name
= "altera_pio",
118 .of_match
= altera_pio_ids
,
119 .ops
= &altera_pio_ops
,
120 .ofdata_to_platdata
= altera_pio_ofdata_to_platdata
,
121 .platdata_auto_alloc_size
= sizeof(struct altera_pio_platdata
),
122 .probe
= altera_pio_probe
,