1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
4 * Copyright (C) 2011 Missing Link Electronics
5 * Joachim Foerster <joachim@missinglinkelectronics.com>
15 DECLARE_GLOBAL_DATA_PTR
;
17 struct altera_pio_regs
{
18 u32 data
; /* Data register */
19 u32 direction
; /* Direction register */
22 struct altera_pio_platdata
{
23 struct altera_pio_regs
*regs
;
25 const char *bank_name
;
28 static int altera_pio_direction_input(struct udevice
*dev
, unsigned pin
)
30 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
31 struct altera_pio_regs
*const regs
= plat
->regs
;
33 clrbits_le32(®s
->direction
, 1 << pin
);
38 static int altera_pio_direction_output(struct udevice
*dev
, unsigned pin
,
41 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
42 struct altera_pio_regs
*const regs
= plat
->regs
;
45 setbits_le32(®s
->data
, 1 << pin
);
47 clrbits_le32(®s
->data
, 1 << pin
);
48 /* change the data first, then the direction. to avoid glitch */
49 setbits_le32(®s
->direction
, 1 << pin
);
54 static int altera_pio_get_value(struct udevice
*dev
, unsigned pin
)
56 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
57 struct altera_pio_regs
*const regs
= plat
->regs
;
59 return readl(®s
->data
) & (1 << pin
);
63 static int altera_pio_set_value(struct udevice
*dev
, unsigned pin
, int val
)
65 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
66 struct altera_pio_regs
*const regs
= plat
->regs
;
69 setbits_le32(®s
->data
, 1 << pin
);
71 clrbits_le32(®s
->data
, 1 << pin
);
76 static int altera_pio_probe(struct udevice
*dev
)
78 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
79 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
81 uc_priv
->gpio_count
= plat
->gpio_count
;
82 uc_priv
->bank_name
= plat
->bank_name
;
87 static int altera_pio_ofdata_to_platdata(struct udevice
*dev
)
89 struct altera_pio_platdata
*plat
= dev_get_platdata(dev
);
91 plat
->regs
= map_physmem(devfdt_get_addr(dev
),
92 sizeof(struct altera_pio_regs
),
94 plat
->gpio_count
= fdtdec_get_int(gd
->fdt_blob
, dev_of_offset(dev
),
95 "altr,gpio-bank-width", 32);
96 plat
->bank_name
= fdt_getprop(gd
->fdt_blob
, dev_of_offset(dev
),
97 "gpio-bank-name", NULL
);
102 static const struct dm_gpio_ops altera_pio_ops
= {
103 .direction_input
= altera_pio_direction_input
,
104 .direction_output
= altera_pio_direction_output
,
105 .get_value
= altera_pio_get_value
,
106 .set_value
= altera_pio_set_value
,
109 static const struct udevice_id altera_pio_ids
[] = {
110 { .compatible
= "altr,pio-1.0" },
114 U_BOOT_DRIVER(altera_pio
) = {
115 .name
= "altera_pio",
117 .of_match
= altera_pio_ids
,
118 .ops
= &altera_pio_ops
,
119 .ofdata_to_platdata
= altera_pio_ofdata_to_platdata
,
120 .platdata_auto_alloc_size
= sizeof(struct altera_pio_platdata
),
121 .probe
= altera_pio_probe
,