3 * Bhuvanchandra DV, Toradex, Inc.
5 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/imx-common/iomux-v3.h>
17 DECLARE_GLOBAL_DATA_PTR
;
21 struct vybrid_gpio_regs
*reg
;
24 static int vybrid_gpio_direction_input(struct udevice
*dev
, unsigned gpio
)
26 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
28 gpio
= gpio
+ (gpios
->chip
* VYBRID_GPIO_COUNT
);
29 imx_iomux_gpio_set_direction(gpio
, VF610_GPIO_DIRECTION_IN
);
34 static int vybrid_gpio_direction_output(struct udevice
*dev
, unsigned gpio
,
37 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
39 gpio
= gpio
+ (gpios
->chip
* VYBRID_GPIO_COUNT
);
40 gpio_set_value(gpio
, value
);
41 imx_iomux_gpio_set_direction(gpio
, VF610_GPIO_DIRECTION_OUT
);
46 static int vybrid_gpio_get_value(struct udevice
*dev
, unsigned gpio
)
48 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
50 return ((readl(&gpios
->reg
->gpio_pdir
) & (1 << gpio
))) ? 1 : 0;
53 static int vybrid_gpio_set_value(struct udevice
*dev
, unsigned gpio
,
56 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
58 writel((1 << gpio
), &gpios
->reg
->gpio_psor
);
60 writel((1 << gpio
), &gpios
->reg
->gpio_pcor
);
65 static int vybrid_gpio_get_function(struct udevice
*dev
, unsigned gpio
)
67 const struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
70 gpio
= gpio
+ (gpios
->chip
* VYBRID_GPIO_COUNT
);
72 imx_iomux_gpio_get_function(gpio
, &g_state
);
74 if (((g_state
& (0x07 << PAD_MUX_MODE_SHIFT
)) >> PAD_MUX_MODE_SHIFT
) > 0)
76 if (g_state
& PAD_CTL_OBE_ENABLE
)
78 if (g_state
& PAD_CTL_IBE_ENABLE
)
80 if (!(g_state
& PAD_CTL_OBE_IBE_ENABLE
))
86 static const struct dm_gpio_ops gpio_vybrid_ops
= {
87 .direction_input
= vybrid_gpio_direction_input
,
88 .direction_output
= vybrid_gpio_direction_output
,
89 .get_value
= vybrid_gpio_get_value
,
90 .set_value
= vybrid_gpio_set_value
,
91 .get_function
= vybrid_gpio_get_function
,
94 static int vybrid_gpio_probe(struct udevice
*dev
)
96 struct vybrid_gpios
*gpios
= dev_get_priv(dev
);
97 struct vybrid_gpio_platdata
*plat
= dev_get_platdata(dev
);
98 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
100 uc_priv
->bank_name
= plat
->port_name
;
101 uc_priv
->gpio_count
= VYBRID_GPIO_COUNT
;
102 gpios
->reg
= (struct vybrid_gpio_regs
*)plat
->base
;
103 gpios
->chip
= plat
->chip
;
108 static int vybrid_gpio_bind(struct udevice
*dev
)
110 struct vybrid_gpio_platdata
*plat
= dev
->platdata
;
111 fdt_addr_t base_addr
;
116 base_addr
= dev_get_addr(dev
);
117 if (base_addr
== FDT_ADDR_T_NONE
)
122 * When every board is converted to driver model and DT is
123 * supported, this can be done by auto-alloc feature, but
124 * not using calloc to alloc memory for platdata.
126 plat
= calloc(1, sizeof(*plat
));
130 plat
->base
= base_addr
;
131 plat
->chip
= dev
->req_seq
;
132 plat
->port_name
= fdt_get_name(gd
->fdt_blob
, dev_of_offset(dev
), NULL
);
133 dev
->platdata
= plat
;
138 static const struct udevice_id vybrid_gpio_ids
[] = {
139 { .compatible
= "fsl,vf610-gpio" },
143 U_BOOT_DRIVER(gpio_vybrid
) = {
144 .name
= "gpio_vybrid",
146 .ops
= &gpio_vybrid_ops
,
147 .probe
= vybrid_gpio_probe
,
148 .priv_auto_alloc_size
= sizeof(struct vybrid_gpios
),
149 .of_match
= vybrid_gpio_ids
,
150 .bind
= vybrid_gpio_bind
,