2 * Copyright 2016 Freescale Semiconductor, Inc.
4 * RGPIO2P driver for the Freescale i.MX7ULP.
6 * SPDX-License-Identifier: GPL-2.0+
17 DECLARE_GLOBAL_DATA_PTR
;
19 enum imx_rgpio2p_direction
{
20 IMX_RGPIO2P_DIRECTION_IN
,
21 IMX_RGPIO2P_DIRECTION_OUT
,
24 #define GPIO_PER_BANK 32
26 struct imx_rgpio2p_data
{
27 struct gpio_regs
*regs
;
30 struct imx_rgpio2p_plat
{
32 struct gpio_regs
*regs
;
35 static int imx_rgpio2p_is_output(struct gpio_regs
*regs
, int offset
)
39 val
= readl(®s
->gpio_pddr
);
41 return val
& (1 << offset
) ? 1 : 0;
44 static void imx_rgpio2p_bank_direction(struct gpio_regs
*regs
, int offset
,
45 enum imx_rgpio2p_direction direction
)
49 l
= readl(®s
->gpio_pddr
);
52 case IMX_RGPIO2P_DIRECTION_OUT
:
55 case IMX_RGPIO2P_DIRECTION_IN
:
58 writel(l
, ®s
->gpio_pddr
);
61 static void imx_rgpio2p_bank_set_value(struct gpio_regs
*regs
, int offset
,
65 writel((1 << offset
), ®s
->gpio_psor
);
67 writel((1 << offset
), ®s
->gpio_pcor
);
70 static int imx_rgpio2p_bank_get_value(struct gpio_regs
*regs
, int offset
)
72 return (readl(®s
->gpio_pdir
) >> offset
) & 0x01;
75 static int imx_rgpio2p_direction_input(struct udevice
*dev
, unsigned offset
)
77 struct imx_rgpio2p_data
*bank
= dev_get_priv(dev
);
79 /* Configure GPIO direction as input. */
80 imx_rgpio2p_bank_direction(bank
->regs
, offset
, IMX_RGPIO2P_DIRECTION_IN
);
85 static int imx_rgpio2p_direction_output(struct udevice
*dev
, unsigned offset
,
88 struct imx_rgpio2p_data
*bank
= dev_get_priv(dev
);
90 /* Configure GPIO output value. */
91 imx_rgpio2p_bank_set_value(bank
->regs
, offset
, value
);
93 /* Configure GPIO direction as output. */
94 imx_rgpio2p_bank_direction(bank
->regs
, offset
, IMX_RGPIO2P_DIRECTION_OUT
);
99 static int imx_rgpio2p_get_value(struct udevice
*dev
, unsigned offset
)
101 struct imx_rgpio2p_data
*bank
= dev_get_priv(dev
);
103 return imx_rgpio2p_bank_get_value(bank
->regs
, offset
);
106 static int imx_rgpio2p_set_value(struct udevice
*dev
, unsigned offset
,
109 struct imx_rgpio2p_data
*bank
= dev_get_priv(dev
);
111 imx_rgpio2p_bank_set_value(bank
->regs
, offset
, value
);
116 static int imx_rgpio2p_get_function(struct udevice
*dev
, unsigned offset
)
118 struct imx_rgpio2p_data
*bank
= dev_get_priv(dev
);
120 /* GPIOF_FUNC is not implemented yet */
121 if (imx_rgpio2p_is_output(bank
->regs
, offset
))
127 static const struct dm_gpio_ops imx_rgpio2p_ops
= {
128 .direction_input
= imx_rgpio2p_direction_input
,
129 .direction_output
= imx_rgpio2p_direction_output
,
130 .get_value
= imx_rgpio2p_get_value
,
131 .set_value
= imx_rgpio2p_set_value
,
132 .get_function
= imx_rgpio2p_get_function
,
135 static int imx_rgpio2p_probe(struct udevice
*dev
)
137 struct imx_rgpio2p_data
*bank
= dev_get_priv(dev
);
138 struct imx_rgpio2p_plat
*plat
= dev_get_platdata(dev
);
139 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
143 banknum
= plat
->bank_index
;
144 sprintf(name
, "GPIO%d_", banknum
+ 1);
148 uc_priv
->bank_name
= str
;
149 uc_priv
->gpio_count
= GPIO_PER_BANK
;
150 bank
->regs
= plat
->regs
;
155 static int imx_rgpio2p_bind(struct udevice
*dev
)
157 struct imx_rgpio2p_plat
*plat
= dev
->platdata
;
161 * If platdata already exsits, directly return.
162 * Actually only when DT is not supported, platdata
163 * is statically initialized in U_BOOT_DEVICES.Here
169 addr
= devfdt_get_addr_index(dev
, 1);
170 if (addr
== FDT_ADDR_T_NONE
)
175 * When every board is converted to driver model and DT is supported,
176 * this can be done by auto-alloc feature, but not using calloc
177 * to alloc memory for platdata.
179 plat
= calloc(1, sizeof(*plat
));
183 plat
->regs
= (struct gpio_regs
*)addr
;
184 plat
->bank_index
= dev
->req_seq
;
185 dev
->platdata
= plat
;
191 static const struct udevice_id imx_rgpio2p_ids
[] = {
192 { .compatible
= "fsl,imx7ulp-gpio" },
196 U_BOOT_DRIVER(imx_rgpio2p
) = {
197 .name
= "imx_rgpio2p",
199 .ops
= &imx_rgpio2p_ops
,
200 .probe
= imx_rgpio2p_probe
,
201 .priv_auto_alloc_size
= sizeof(struct imx_rgpio2p_plat
),
202 .of_match
= imx_rgpio2p_ids
,
203 .bind
= imx_rgpio2p_bind
,
206 #if !CONFIG_IS_ENABLED(OF_CONTROL)
207 static const struct imx_rgpio2p_plat imx_plat
[] = {
208 { 0, (struct gpio_regs
*)RGPIO2P_GPIO1_BASE_ADDR
},
209 { 1, (struct gpio_regs
*)RGPIO2P_GPIO2_BASE_ADDR
},
210 { 2, (struct gpio_regs
*)RGPIO2P_GPIO3_BASE_ADDR
},
211 { 3, (struct gpio_regs
*)RGPIO2P_GPIO4_BASE_ADDR
},
212 { 4, (struct gpio_regs
*)RGPIO2P_GPIO5_BASE_ADDR
},
213 { 5, (struct gpio_regs
*)RGPIO2P_GPIO6_BASE_ADDR
},
216 U_BOOT_DEVICES(imx_rgpio2ps
) = {
217 { "imx_rgpio2p", &imx_plat
[0] },
218 { "imx_rgpio2p", &imx_plat
[1] },
219 { "imx_rgpio2p", &imx_plat
[2] },
220 { "imx_rgpio2p", &imx_plat
[3] },
221 { "imx_rgpio2p", &imx_plat
[4] },
222 { "imx_rgpio2p", &imx_plat
[5] },