2 * Copyright (c) 2010-2016, NVIDIA CORPORATION.
3 * (based on tegra_gpio.c)
5 * SPDX-License-Identifier: GPL-2.0
14 #include <asm/bitops.h>
16 #include <dm/device-internal.h>
17 #include <dt-bindings/gpio/gpio.h>
18 #include "tegra186_gpio_priv.h"
20 DECLARE_GLOBAL_DATA_PTR
;
22 struct tegra186_gpio_port_data
{
27 struct tegra186_gpio_ctlr_data
{
28 const struct tegra186_gpio_port_data
*ports
;
32 struct tegra186_gpio_platdata
{
37 static uint32_t *tegra186_gpio_reg(struct udevice
*dev
, uint32_t reg
,
40 struct tegra186_gpio_platdata
*plat
= dev
->platdata
;
41 uint32_t index
= (reg
+ (gpio
* TEGRA186_GPIO_PER_GPIO_STRIDE
)) / 4;
43 return &(plat
->regs
[index
]);
46 static int tegra186_gpio_set_out(struct udevice
*dev
, unsigned offset
,
52 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_OUTPUT_CONTROL
, offset
);
55 rval
&= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED
;
57 rval
|= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED
;
60 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_ENABLE_CONFIG
, offset
);
63 rval
|= TEGRA186_GPIO_ENABLE_CONFIG_OUT
;
65 rval
&= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT
;
66 rval
|= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE
;
72 static int tegra186_gpio_set_val(struct udevice
*dev
, unsigned offset
, bool val
)
77 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_OUTPUT_VALUE
, offset
);
80 rval
|= TEGRA186_GPIO_OUTPUT_VALUE_HIGH
;
82 rval
&= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH
;
88 static int tegra186_gpio_direction_input(struct udevice
*dev
, unsigned offset
)
90 return tegra186_gpio_set_out(dev
, offset
, false);
93 static int tegra186_gpio_direction_output(struct udevice
*dev
, unsigned offset
,
98 ret
= tegra186_gpio_set_val(dev
, offset
, value
!= 0);
101 return tegra186_gpio_set_out(dev
, offset
, true);
104 static int tegra186_gpio_get_value(struct udevice
*dev
, unsigned offset
)
109 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_ENABLE_CONFIG
, offset
);
112 if (rval
& TEGRA186_GPIO_ENABLE_CONFIG_OUT
)
113 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_OUTPUT_VALUE
,
116 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_INPUT
, offset
);
122 static int tegra186_gpio_set_value(struct udevice
*dev
, unsigned offset
,
125 return tegra186_gpio_set_val(dev
, offset
, value
!= 0);
128 static int tegra186_gpio_get_function(struct udevice
*dev
, unsigned offset
)
133 reg
= tegra186_gpio_reg(dev
, TEGRA186_GPIO_ENABLE_CONFIG
, offset
);
135 if (rval
& TEGRA186_GPIO_ENABLE_CONFIG_OUT
)
141 static int tegra186_gpio_xlate(struct udevice
*dev
, struct gpio_desc
*desc
,
142 struct fdtdec_phandle_args
*args
)
146 gpio
= args
->args
[0];
147 port
= gpio
/ TEGRA186_GPIO_PER_GPIO_COUNT
;
148 ret
= device_get_child(dev
, port
, &desc
->dev
);
151 desc
->offset
= gpio
% TEGRA186_GPIO_PER_GPIO_COUNT
;
152 desc
->flags
= args
->args
[1] & GPIO_ACTIVE_LOW
? GPIOD_ACTIVE_LOW
: 0;
157 static const struct dm_gpio_ops tegra186_gpio_ops
= {
158 .direction_input
= tegra186_gpio_direction_input
,
159 .direction_output
= tegra186_gpio_direction_output
,
160 .get_value
= tegra186_gpio_get_value
,
161 .set_value
= tegra186_gpio_set_value
,
162 .get_function
= tegra186_gpio_get_function
,
163 .xlate
= tegra186_gpio_xlate
,
167 * We have a top-level GPIO device with no actual GPIOs. It has a child device
168 * for each port within the controller.
170 static int tegra186_gpio_bind(struct udevice
*parent
)
172 struct tegra186_gpio_platdata
*parent_plat
= parent
->platdata
;
173 struct tegra186_gpio_ctlr_data
*ctlr_data
=
174 (struct tegra186_gpio_ctlr_data
*)dev_get_driver_data(parent
);
178 /* If this is a child device, there is nothing to do here */
182 regs
= (uint32_t *)dev_get_addr_name(parent
, "gpio");
183 if (regs
== (uint32_t *)FDT_ADDR_T_NONE
)
186 for (port
= 0; port
< ctlr_data
->port_count
; port
++) {
187 struct tegra186_gpio_platdata
*plat
;
190 plat
= calloc(1, sizeof(*plat
));
193 plat
->name
= ctlr_data
->ports
[port
].name
;
194 plat
->regs
= &(regs
[ctlr_data
->ports
[port
].offset
/ 4]);
196 ret
= device_bind(parent
, parent
->driver
, plat
->name
, plat
,
200 dev_set_of_offset(dev
, dev_of_offset(parent
));
206 static int tegra186_gpio_probe(struct udevice
*dev
)
208 struct tegra186_gpio_platdata
*plat
= dev
->platdata
;
209 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
211 /* Only child devices have ports */
215 uc_priv
->gpio_count
= TEGRA186_GPIO_PER_GPIO_COUNT
;
216 uc_priv
->bank_name
= plat
->name
;
221 static const struct tegra186_gpio_port_data tegra186_gpio_main_ports
[] = {
247 static const struct tegra186_gpio_ctlr_data tegra186_gpio_main_data
= {
248 .ports
= tegra186_gpio_main_ports
,
249 .port_count
= ARRAY_SIZE(tegra186_gpio_main_ports
),
252 static const struct tegra186_gpio_port_data tegra186_gpio_aon_ports
[] = {
263 static const struct tegra186_gpio_ctlr_data tegra186_gpio_aon_data
= {
264 .ports
= tegra186_gpio_aon_ports
,
265 .port_count
= ARRAY_SIZE(tegra186_gpio_aon_ports
),
268 static const struct udevice_id tegra186_gpio_ids
[] = {
270 .compatible
= "nvidia,tegra186-gpio",
271 .data
= (ulong
)&tegra186_gpio_main_data
,
274 .compatible
= "nvidia,tegra186-gpio-aon",
275 .data
= (ulong
)&tegra186_gpio_aon_data
,
280 U_BOOT_DRIVER(tegra186_gpio
) = {
281 .name
= "tegra186_gpio",
283 .of_match
= tegra186_gpio_ids
,
284 .bind
= tegra186_gpio_bind
,
285 .probe
= tegra186_gpio_probe
,
286 .ops
= &tegra186_gpio_ops
,
287 .flags
= DM_FLAG_PRE_RELOC
,