1 // SPDX-License-Identifier: GPL-2.0+
4 * Bhuvanchandra DV, Toradex, Inc.
12 #include <asm/mach-imx/iomux-v3.h>
16 DECLARE_GLOBAL_DATA_PTR
;
20 struct vybrid_gpio_regs
*reg
;
23 static int vybrid_gpio_direction_input(struct udevice
*dev
, unsigned gpio
)
25 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
27 gpio
= gpio
+ (gpios
->chip
* VYBRID_GPIO_COUNT
);
28 imx_iomux_gpio_set_direction(gpio
, VF610_GPIO_DIRECTION_IN
);
33 static int vybrid_gpio_direction_output(struct udevice
*dev
, unsigned gpio
,
36 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
38 gpio
= gpio
+ (gpios
->chip
* VYBRID_GPIO_COUNT
);
39 gpio_set_value(gpio
, value
);
40 imx_iomux_gpio_set_direction(gpio
, VF610_GPIO_DIRECTION_OUT
);
45 static int vybrid_gpio_get_value(struct udevice
*dev
, unsigned gpio
)
47 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
49 return ((readl(&gpios
->reg
->gpio_pdir
) & (1 << gpio
))) ? 1 : 0;
52 static int vybrid_gpio_set_value(struct udevice
*dev
, unsigned gpio
,
55 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
57 writel((1 << gpio
), &gpios
->reg
->gpio_psor
);
59 writel((1 << gpio
), &gpios
->reg
->gpio_pcor
);
64 static int vybrid_gpio_get_function(struct udevice
*dev
, unsigned gpio
)
66 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
69 gpio
= gpio
+ (gpios
->chip
* VYBRID_GPIO_COUNT
);
71 imx_iomux_gpio_get_function(gpio
, &g_state
);
73 if (((g_state
& (0x07 << PAD_MUX_MODE_SHIFT
)) >> PAD_MUX_MODE_SHIFT
) > 0)
75 if (g_state
& PAD_CTL_OBE_ENABLE
)
77 if (g_state
& PAD_CTL_IBE_ENABLE
)
79 if (!(g_state
& PAD_CTL_OBE_IBE_ENABLE
))
85 static const struct dm_gpio_ops gpio_vybrid_ops
= {
86 .direction_input
= vybrid_gpio_direction_input
,
87 .direction_output
= vybrid_gpio_direction_output
,
88 .get_value
= vybrid_gpio_get_value
,
89 .set_value
= vybrid_gpio_set_value
,
90 .get_function
= vybrid_gpio_get_function
,
93 static int vybrid_gpio_probe(struct udevice
*dev
)
95 struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
96 struct vybrid_gpio_platdata
*plat
= dev_get_platdata(dev
);
97 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
99 uc_priv
->bank_name
= plat
->port_name
;
100 uc_priv
->gpio_count
= VYBRID_GPIO_COUNT
;
101 gpios
->reg
= (struct vybrid_gpio_regs
*)plat
->base
;
102 gpios
->chip
= plat
->chip
;
107 static int vybrid_gpio_odata_to_platdata(struct udevice
*dev
)
109 struct vybrid_gpio_platdata
*plat
= dev_get_platdata(dev
);
110 fdt_addr_t base_addr
;
112 base_addr
= devfdt_get_addr(dev
);
113 if (base_addr
== FDT_ADDR_T_NONE
)
116 plat
->base
= base_addr
;
117 plat
->chip
= dev
->req_seq
;
118 plat
->port_name
= fdt_get_name(gd
->fdt_blob
, dev_of_offset(dev
), NULL
);
123 static const struct udevice_id vybrid_gpio_ids
[] = {
124 { .compatible
= "fsl,vf610-gpio" },
128 U_BOOT_DRIVER(gpio_vybrid
) = {
129 .name
= "gpio_vybrid",
131 .ops
= &gpio_vybrid_ops
,
132 .of_match
= vybrid_gpio_ids
,
133 .ofdata_to_platdata
= vybrid_gpio_odata_to_platdata
,
134 .probe
= vybrid_gpio_probe
,
135 .priv_auto_alloc_size
= sizeof(struct vybrid_gpios
),
136 .platdata_auto_alloc_size
= sizeof(struct vybrid_gpio_platdata
),