2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright 2020 Michal Meloun <mmel@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
30 * Pin multiplexer driver for Tegra SoCs.
32 #include <sys/param.h>
33 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/malloc.h>
40 #include <machine/bus.h>
42 #include <dev/fdt/fdt_common.h>
43 #include <dev/fdt/fdt_pinctrl.h>
44 #include <dev/ofw/openfirm.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/ofw_bus_subr.h>
48 /* Pin multipexor register. */
49 #define TEGRA_MUX_FUNCTION_MASK 0x03
50 #define TEGRA_MUX_FUNCTION_SHIFT 0
51 #define TEGRA_MUX_PUPD_MASK 0x03
52 #define TEGRA_MUX_PUPD_SHIFT 2
53 #define TEGRA_MUX_TRISTATE_SHIFT 4
54 #define TEGRA_MUX_ENABLE_INPUT_SHIFT 5
55 #define TEGRA_MUX_OPEN_DRAIN_SHIFT 6
56 #define TEGRA_MUX_LOCK_SHIFT 7
57 #define TEGRA_MUX_IORESET_SHIFT 8
58 #define TEGRA_MUX_RCV_SEL_SHIFT 9
61 /* Pin goup register. */
62 #define TEGRA_GRP_HSM_SHIFT 2
63 #define TEGRA_GRP_SCHMT_SHIFT 3
64 #define TEGRA_GRP_DRV_TYPE_SHIFT 6
65 #define TEGRA_GRP_DRV_TYPE_MASK 0x03
66 #define TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT 28
67 #define TEGRA_GRP_DRV_DRVDN_SLWR_MASK 0x03
68 #define TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT 30
69 #define TEGRA_GRP_DRV_DRVUP_SLWF_MASK 0x03
73 struct resource
*pad_mem_res
;
74 struct resource
*mux_mem_res
;
77 static struct ofw_compat_data compat_data
[] = {
78 {"nvidia,tegra210-pinmux", 1},
90 PROP_ID_HIGH_SPEED_MODE
,
92 PROP_ID_LOW_POWER_MODE
,
93 PROP_ID_DRIVE_DOWN_STRENGTH
,
94 PROP_ID_DRIVE_UP_STRENGTH
,
95 PROP_ID_SLEW_RATE_FALLING
,
96 PROP_ID_SLEW_RATE_RISING
,
102 /* Numeric based parameters. */
103 static const struct prop_name
{
107 {"nvidia,pull", PROP_ID_PULL
},
108 {"nvidia,tristate", PROP_ID_TRISTATE
},
109 {"nvidia,enable-input", PROP_ID_ENABLE_INPUT
},
110 {"nvidia,open-drain", PROP_ID_OPEN_DRAIN
},
111 {"nvidia,lock", PROP_ID_LOCK
},
112 {"nvidia,io-reset", PROP_ID_IORESET
},
113 {"nvidia,rcv-sel", PROP_ID_RCV_SEL
},
114 {"nvidia,io-hv", PROP_ID_RCV_SEL
},
115 {"nvidia,high-speed-mode", PROP_ID_HIGH_SPEED_MODE
},
116 {"nvidia,schmitt", PROP_ID_SCHMITT
},
117 {"nvidia,low-power-mode", PROP_ID_LOW_POWER_MODE
},
118 {"nvidia,pull-down-strength", PROP_ID_DRIVE_DOWN_STRENGTH
},
119 {"nvidia,pull-up-strength", PROP_ID_DRIVE_UP_STRENGTH
},
120 {"nvidia,slew-rate-falling", PROP_ID_SLEW_RATE_FALLING
},
121 {"nvidia,slew-rate-rising", PROP_ID_SLEW_RATE_RISING
},
122 {"nvidia,drive-type", PROP_ID_DRIVE_TYPE
},
126 * configuration for one pin group.
130 int params
[PROP_ID_MAX_ID
];
132 #define GPIO_BANK_A 0
133 #define GPIO_BANK_B 1
134 #define GPIO_BANK_C 2
135 #define GPIO_BANK_D 3
136 #define GPIO_BANK_E 4
137 #define GPIO_BANK_F 5
138 #define GPIO_BANK_G 6
139 #define GPIO_BANK_H 7
140 #define GPIO_BANK_I 8
141 #define GPIO_BANK_J 9
142 #define GPIO_BANK_K 10
143 #define GPIO_BANK_L 11
144 #define GPIO_BANK_M 12
145 #define GPIO_BANK_N 13
146 #define GPIO_BANK_O 14
147 #define GPIO_BANK_P 15
148 #define GPIO_BANK_Q 16
149 #define GPIO_BANK_R 17
150 #define GPIO_BANK_S 18
151 #define GPIO_BANK_T 19
152 #define GPIO_BANK_U 20
153 #define GPIO_BANK_V 21
154 #define GPIO_BANK_W 22
155 #define GPIO_BANK_X 23
156 #define GPIO_BANK_Y 24
157 #define GPIO_BANK_Z 25
158 #define GPIO_BANK_AA 26
159 #define GPIO_BANK_BB 27
160 #define GPIO_BANK_CC 28
161 #define GPIO_BANK_DD 29
162 #define GPIO_BANK_EE 30
163 #define GPIO_NUM(b, p) (8 * (b) + (p))
174 #define GRP(r, nm, dn_s, dn_w, up_s, up_w) \
178 .drvdn_shift = dn_s, \
179 .drvdn_mask = (1 << dn_w) - 1, \
180 .drvup_shift = up_s, \
181 .drvup_mask = (1 << up_w) - 1, \
184 /* Use register offsets from TRM */
185 static const struct tegra_grp pin_grp_tbl
[] = {
186 GRP(0x9c0, pa6
, 12, 5, 20, 5),
187 GRP(0x9c4, pcc7
, 12, 5, 20, 5),
188 GRP(0x9c8, pe6
, 12, 5, 20, 5),
189 GRP(0x9cc, pe7
, 12, 5, 20, 5),
190 GRP(0x9d0, ph6
, 12, 5, 20, 5),
191 GRP(0x9d4, pk0
, 0, 0, 0, 0),
192 GRP(0x9d8, pk1
, 0, 0, 0, 0),
193 GRP(0x9dc, pk2
, 0, 0, 0, 0),
194 GRP(0x9e0, pk3
, 0, 0, 0, 0),
195 GRP(0x9e4, pk4
, 0, 0, 0, 0),
196 GRP(0x9e8, pk5
, 0, 0, 0, 0),
197 GRP(0x9ec, pk6
, 0, 0, 0, 0),
198 GRP(0x9f0, pk7
, 0, 0, 0, 0),
199 GRP(0x9f4, pl0
, 0, 0, 0, 0),
200 GRP(0x9f8, pl1
, 0, 0, 0, 0),
201 GRP(0x9fc, pz0
, 12, 7, 20, 7),
202 GRP(0xa00, pz1
, 12, 7, 20, 7),
203 GRP(0xa04, pz2
, 12, 7, 20, 7),
204 GRP(0xa08, pz3
, 12, 7, 20, 7),
205 GRP(0xa0c, pz4
, 12, 7, 20, 7),
206 GRP(0xa10, pz5
, 12, 7, 20, 7),
207 GRP(0xa98, sdmmc1
, 12, 7, 20, 7),
208 GRP(0xa9c, sdmmc2
, 2, 6, 8, 6),
209 GRP(0xab0, sdmmc3
, 12, 7, 20, 7),
210 GRP(0xab4, sdmmc4
, 2, 6, 8, 6),
214 struct tegra_grp grp
;
222 #define GMUX(r, gb, gi, nm, f1, f2, f3, f4, gr, dn_s, dn_w, up_s, up_w) \
226 .gpio_num = GPIO_NUM(GPIO_BANK_##gb, gi), \
227 .functions = {#f1, #f2, #f3, #f4}, \
229 .grp.reg = gr - 0x8D4, \
230 .grp.drvdn_shift = dn_s, \
231 .grp.drvdn_mask = (1 << dn_w) - 1, \
232 .grp.drvup_shift = up_s, \
233 .grp.drvup_mask = (1 << up_w) - 1, \
236 #define FMUX(r, nm, f1, f2, f3, f4, gr, dn_s, dn_w, up_s, up_w) \
241 .functions = {#f1, #f2, #f3, #f4}, \
243 .grp.reg = gr - 0x8D4, \
244 .grp.drvdn_shift = dn_s, \
245 .grp.drvdn_mask = (1 << dn_w) - 1, \
246 .grp.drvup_shift = up_s, \
247 .grp.drvup_mask = (1 << up_w) - 1, \
250 static const struct tegra_mux pin_mux_tbl
[] = {
251 GMUX(0x000, M
, 0, sdmmc1_clk_pm0
, sdmmc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
252 GMUX(0x004, M
, 1, sdmmc1_cmd_pm1
, sdmmc1
, spi3
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
253 GMUX(0x008, M
, 2, sdmmc1_dat3_pm2
, sdmmc1
, spi3
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
254 GMUX(0x00c, M
, 3, sdmmc1_dat2_pm3
, sdmmc1
, spi3
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
255 GMUX(0x010, M
, 4, sdmmc1_dat1_pm4
, sdmmc1
, spi3
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
256 GMUX(0x014, M
, 5, sdmmc1_dat0_pm5
, sdmmc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
257 GMUX(0x01c, P
, 0, sdmmc3_clk_pp0
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
258 GMUX(0x020, P
, 1, sdmmc3_cmd_pp1
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
259 GMUX(0x024, P
, 5, sdmmc3_dat0_pp5
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
260 GMUX(0x028, P
, 4, sdmmc3_dat1_pp4
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
261 GMUX(0x02c, P
, 3, sdmmc3_dat2_pp3
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
262 GMUX(0x030, P
, 2, sdmmc3_dat3_pp2
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
263 GMUX(0x038, A
, 0, pex_l0_rst_n_pa0
, pe0
, rsvd1
, rsvd2
, rsvd3
, 0xa5c, 12, 5, 20, 5),
264 GMUX(0x03c, A
, 1, pex_l0_clkreq_n_pa1
, pe0
, rsvd1
, rsvd2
, rsvd3
, 0xa58, 12, 5, 20, 5),
265 GMUX(0x040, A
, 2, pex_wake_n_pa2
, pe
, rsvd1
, rsvd2
, rsvd3
, 0xa68, 12, 5, 20, 5),
266 GMUX(0x044, A
, 3, pex_l1_rst_n_pa3
, pe1
, rsvd1
, rsvd2
, rsvd3
, 0xa64, 12, 5, 20, 5),
267 GMUX(0x048, A
, 4, pex_l1_clkreq_n_pa4
, pe1
, rsvd1
, rsvd2
, rsvd3
, 0xa60, 12, 5, 20, 5),
268 GMUX(0x04c, A
, 5, sata_led_active_pa5
, sata
, rsvd1
, rsvd2
, rsvd3
, 0xa94, 12, 5, 20, 5),
269 GMUX(0x050, C
, 0, spi1_mosi_pc0
, spi1
, rsvd1
, rsvd2
, rsvd3
, 0xae0, 0, 0, 0, 0),
270 GMUX(0x054, C
, 1, spi1_miso_pc1
, spi1
, rsvd1
, rsvd2
, rsvd3
, 0xadc, 0, 0, 0, 0),
271 GMUX(0x058, C
, 2, spi1_sck_pc2
, spi1
, rsvd1
, rsvd2
, rsvd3
, 0xae4, 0, 0, 0, 0),
272 GMUX(0x05c, C
, 3, spi1_cs0_pc3
, spi1
, rsvd1
, rsvd2
, rsvd3
, 0xad4, 0, 0, 0, 0),
273 GMUX(0x060, C
, 4, spi1_cs1_pc4
, spi1
, rsvd1
, rsvd2
, rsvd3
, 0xad8, 0, 0, 0, 0),
274 GMUX(0x064, B
, 4, spi2_mosi_pb4
, spi2
, dtv
, rsvd2
, rsvd3
, 0xaf4, 0, 0, 0, 0),
275 GMUX(0x068, B
, 5, spi2_miso_pb5
, spi2
, dtv
, rsvd2
, rsvd3
, 0xaf0, 0, 0, 0, 0),
276 GMUX(0x06c, B
, 6, spi2_sck_pb6
, spi2
, dtv
, rsvd2
, rsvd3
, 0xaf8, 0, 0, 0, 0),
277 GMUX(0x070, B
, 7, spi2_cs0_pb7
, spi2
, dtv
, rsvd2
, rsvd3
, 0xae8, 0, 0, 0, 0),
278 GMUX(0x074, DD
, 0, spi2_cs1_pdd0
, spi2
, rsvd1
, rsvd2
, rsvd3
, 0xaec, 0, 0, 0, 0),
279 GMUX(0x078, C
, 7, spi4_mosi_pc7
, spi4
, rsvd1
, rsvd2
, rsvd3
, 0xb04, 0, 0, 0, 0),
280 GMUX(0x07c, D
, 0, spi4_miso_pd0
, spi4
, rsvd1
, rsvd2
, rsvd3
, 0xb00, 0, 0, 0, 0),
281 GMUX(0x080, C
, 5, spi4_sck_pc5
, spi4
, rsvd1
, rsvd2
, rsvd3
, 0xb08, 0, 0, 0, 0),
282 GMUX(0x084, C
, 6, spi4_cs0_pc6
, spi4
, rsvd1
, rsvd2
, rsvd3
, 0xafc, 0, 0, 0, 0),
283 GMUX(0x088, EE
, 0, qspi_sck_pee0
, qspi
, rsvd1
, rsvd2
, rsvd3
, 0xa90, 0, 0, 0, 0),
284 GMUX(0x08c, EE
, 1, qspi_cs_n_pee1
, qspi
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
285 GMUX(0x090, EE
, 2, qspi_io0_pee2
, qspi
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
286 GMUX(0x094, EE
, 3, qspi_io1_pee3
, qspi
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
287 GMUX(0x098, EE
, 4, qspi_io2_pee4
, qspi
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
288 GMUX(0x09c, EE
, 5, qspi_io3_pee5
, qspi
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
289 GMUX(0x0a4, E
, 0, dmic1_clk_pe0
, dmic1
, i2s3
, rsvd2
, rsvd3
, 0x984, 12, 5, 20, 5),
290 GMUX(0x0a8, E
, 1, dmic1_dat_pe1
, dmic1
, i2s3
, rsvd2
, rsvd3
, 0x988, 12, 5, 20, 5),
291 GMUX(0x0ac, E
, 2, dmic2_clk_pe2
, dmic2
, i2s3
, rsvd2
, rsvd3
, 0x98c, 12, 5, 20, 5),
292 GMUX(0x0b0, E
, 3, dmic2_dat_pe3
, dmic2
, i2s3
, rsvd2
, rsvd3
, 0x990, 12, 5, 20, 5),
293 GMUX(0x0b4, E
, 4, dmic3_clk_pe4
, dmic3
, i2s5a
, rsvd2
, rsvd3
, 0x994, 12, 5, 20, 5),
294 GMUX(0x0b8, E
, 5, dmic3_dat_pe5
, dmic3
, i2s5a
, rsvd2
, rsvd3
, 0x998, 12, 5, 20, 5),
295 GMUX(0x0bc, J
, 1, gen1_i2c_scl_pj1
, i2c1
, rsvd1
, rsvd2
, rsvd3
, 0x9a8, 12, 5, 20, 5),
296 GMUX(0x0c0, J
, 0, gen1_i2c_sda_pj0
, i2c1
, rsvd1
, rsvd2
, rsvd3
, 0x9ac, 12, 5, 20, 5),
297 GMUX(0x0c4, J
, 2, gen2_i2c_scl_pj2
, i2c2
, rsvd1
, rsvd2
, rsvd3
, 0x9b0, 12, 5, 20, 5),
298 GMUX(0x0c8, J
, 3, gen2_i2c_sda_pj3
, i2c2
, rsvd1
, rsvd2
, rsvd3
, 0x9b4, 12, 5, 20, 5),
299 GMUX(0x0cc, F
, 0, gen3_i2c_scl_pf0
, i2c3
, rsvd1
, rsvd2
, rsvd3
, 0x9b8, 12, 5, 20, 5),
300 GMUX(0x0d0, F
, 1, gen3_i2c_sda_pf1
, i2c3
, rsvd1
, rsvd2
, rsvd3
, 0x9bc, 12, 5, 20, 5),
301 GMUX(0x0d4, S
, 2, cam_i2c_scl_ps2
, i2c3
, i2cvi
, rsvd2
, rsvd3
, 0x934, 12, 5, 20, 5),
302 GMUX(0x0d8, S
, 3, cam_i2c_sda_ps3
, i2c3
, i2cvi
, rsvd2
, rsvd3
, 0x938, 12, 5, 20, 5),
303 GMUX(0x0dc, Y
, 3, pwr_i2c_scl_py3
, i2cpmu
, rsvd1
, rsvd2
, rsvd3
, 0xa6c, 12, 5, 20, 5),
304 GMUX(0x0e0, Y
, 4, pwr_i2c_sda_py4
, i2cpmu
, rsvd1
, rsvd2
, rsvd3
, 0xa70, 12, 5, 20, 5),
305 GMUX(0x0e4, U
, 0, uart1_tx_pu0
, uarta
, rsvd1
, rsvd2
, rsvd3
, 0xb28, 12, 5, 20, 5),
306 GMUX(0x0e8, U
, 1, uart1_rx_pu1
, uarta
, rsvd1
, rsvd2
, rsvd3
, 0xb24, 12, 5, 20, 5),
307 GMUX(0x0ec, U
, 2, uart1_rts_pu2
, uarta
, rsvd1
, rsvd2
, rsvd3
, 0xb20, 12, 5, 20, 5),
308 GMUX(0x0f0, U
, 3, uart1_cts_pu3
, uarta
, rsvd1
, rsvd2
, rsvd3
, 0xb1c, 12, 5, 20, 5),
309 GMUX(0x0f4, G
, 0, uart2_tx_pg0
, uartb
, i2s4a
, spdif
, uart
, 0xb38, 12, 5, 20, 5),
310 GMUX(0x0f8, G
, 1, uart2_rx_pg1
, uartb
, i2s4a
, spdif
, uart
, 0xb34, 12, 5, 20, 5),
311 GMUX(0x0fc, G
, 2, uart2_rts_pg2
, uartb
, i2s4a
, rsvd2
, uart
, 0xb30, 12, 5, 20, 5),
312 GMUX(0x100, G
, 3, uart2_cts_pg3
, uartb
, i2s4a
, rsvd2
, uart
, 0xb2c, 12, 5, 20, 5),
313 GMUX(0x104, D
, 1, uart3_tx_pd1
, uartc
, spi4
, rsvd2
, rsvd3
, 0xb48, 12, 5, 20, 5),
314 GMUX(0x108, D
, 2, uart3_rx_pd2
, uartc
, spi4
, rsvd2
, rsvd3
, 0xb44, 12, 5, 20, 5),
315 GMUX(0x10c, D
, 3, uart3_rts_pd3
, uartc
, spi4
, rsvd2
, rsvd3
, 0xb40, 12, 5, 20, 5),
316 GMUX(0x110, D
, 4, uart3_cts_pd4
, uartc
, spi4
, rsvd2
, rsvd3
, 0xb3c, 12, 5, 20, 5),
317 GMUX(0x114, I
, 4, uart4_tx_pi4
, uartd
, uart
, rsvd2
, rsvd3
, 0xb58, 12, 5, 20, 5),
318 GMUX(0x118, I
, 5, uart4_rx_pi5
, uartd
, uart
, rsvd2
, rsvd3
, 0xb54, 12, 5, 20, 5),
319 GMUX(0x11c, I
, 6, uart4_rts_pi6
, uartd
, uart
, rsvd2
, rsvd3
, 0xb50, 12, 5, 20, 5),
320 GMUX(0x120, I
, 7, uart4_cts_pi7
, uartd
, uart
, rsvd2
, rsvd3
, 0xb4c, 12, 5, 20, 5),
321 GMUX(0x124, B
, 0, dap1_fs_pb0
, i2s1
, rsvd1
, rsvd2
, rsvd3
, 0x95c, 0, 0, 0, 0),
322 GMUX(0x128, B
, 1, dap1_din_pb1
, i2s1
, rsvd1
, rsvd2
, rsvd3
, 0x954, 0, 0, 0, 0),
323 GMUX(0x12c, B
, 2, dap1_dout_pb2
, i2s1
, rsvd1
, rsvd2
, rsvd3
, 0x958, 0, 0, 0, 0),
324 GMUX(0x130, B
, 3, dap1_sclk_pb3
, i2s1
, rsvd1
, rsvd2
, rsvd3
, 0x960, 0, 0, 0, 0),
325 GMUX(0x134, AA
, 0, dap2_fs_paa0
, i2s2
, rsvd1
, rsvd2
, rsvd3
, 0x96c, 0, 0, 0, 0),
326 GMUX(0x138, AA
, 2, dap2_din_paa2
, i2s2
, rsvd1
, rsvd2
, rsvd3
, 0x964, 0, 0, 0, 0),
327 GMUX(0x13c, AA
, 3, dap2_dout_paa3
, i2s2
, rsvd1
, rsvd2
, rsvd3
, 0x968, 0, 0, 0, 0),
328 GMUX(0x140, AA
, 1, dap2_sclk_paa1
, i2s2
, rsvd1
, rsvd2
, rsvd3
, 0x970, 0, 0, 0, 0),
329 GMUX(0x144, J
, 4, dap4_fs_pj4
, i2s4b
, rsvd1
, rsvd2
, rsvd3
, 0x97c, 12, 5, 20, 5),
330 GMUX(0x148, J
, 5, dap4_din_pj5
, i2s4b
, rsvd1
, rsvd2
, rsvd3
, 0x974, 12, 5, 20, 5),
331 GMUX(0x14c, J
, 6, dap4_dout_pj6
, i2s4b
, rsvd1
, rsvd2
, rsvd3
, 0x978, 12, 5, 20, 5),
332 GMUX(0x150, J
, 7, dap4_sclk_pj7
, i2s4b
, rsvd1
, rsvd2
, rsvd3
, 0x980, 12, 5, 20, 5),
333 GMUX(0x154, S
, 0, cam1_mclk_ps0
, extperiph3
, rsvd1
, rsvd2
, rsvd3
, 0x918, 12, 5, 20, 5),
334 GMUX(0x158, S
, 1, cam2_mclk_ps1
, extperiph3
, rsvd1
, rsvd2
, rsvd3
, 0x924, 12, 5, 20, 5),
335 FMUX(0x15c, jtag_rtck
, jtag
, rsvd1
, rsvd2
, rsvd3
, 0xa2c, 12, 5, 20, 5),
336 FMUX(0x160, clk_32k_in
, clk
, rsvd1
, rsvd2
, rsvd3
, 0x940, 12, 5, 20, 5),
337 GMUX(0x164, Y
, 5, clk_32k_out_py5
, soc
, blink
, rsvd2
, rsvd3
, 0x944, 12, 5, 20, 5),
338 FMUX(0x168, batt_bcl
, bcl
, rsvd1
, rsvd2
, rsvd3
, 0x8f8, 12, 5, 20, 5),
339 FMUX(0x16c, clk_req
, sys
, rsvd1
, rsvd2
, rsvd3
, 0x948, 12, 5, 20, 5),
340 FMUX(0x170, cpu_pwr_req
, cpu
, rsvd1
, rsvd2
, rsvd3
, 0x950, 12, 5, 20, 5),
341 FMUX(0x174, pwr_int_n
, pmi
, rsvd1
, rsvd2
, rsvd3
, 0xa74, 12, 5, 20, 5),
342 FMUX(0x178, shutdown
, shutdown
, rsvd1
, rsvd2
, rsvd3
, 0xac8, 12, 5, 20, 5),
343 FMUX(0x17c, core_pwr_req
, core
, rsvd1
, rsvd2
, rsvd3
, 0x94c, 12, 5, 20, 5),
344 GMUX(0x180, BB
, 0, aud_mclk_pbb0
, aud
, rsvd1
, rsvd2
, rsvd3
, 0x8f4, 12, 5, 20, 5),
345 GMUX(0x184, BB
, 1, dvfs_pwm_pbb1
, rsvd0
, cldvfs
, spi3
, rsvd3
, 0x9a4, 12, 5, 20, 5),
346 GMUX(0x188, BB
, 2, dvfs_clk_pbb2
, rsvd0
, cldvfs
, spi3
, rsvd3
, 0x9a0, 12, 5, 20, 5),
347 GMUX(0x18c, BB
, 3, gpio_x1_aud_pbb3
, rsvd0
, rsvd1
, spi3
, rsvd3
, 0xa14, 12, 5, 20, 5),
348 GMUX(0x190, BB
, 4, gpio_x3_aud_pbb4
, rsvd0
, rsvd1
, spi3
, rsvd3
, 0xa18, 12, 5, 20, 5),
349 GMUX(0x194, CC
, 7, pcc7
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
350 GMUX(0x198, CC
, 0, hdmi_cec_pcc0
, cec
, rsvd1
, rsvd2
, rsvd3
, 0xa24, 12, 5, 20, 5),
351 GMUX(0x19c, CC
, 1, hdmi_int_dp_hpd_pcc1
, dp
, rsvd1
, rsvd2
, rsvd3
, 0xa28, 12, 5, 20, 5),
352 GMUX(0x1a0, CC
, 2, spdif_out_pcc2
, spdif
, rsvd1
, rsvd2
, rsvd3
, 0xad0, 12, 5, 20, 5),
353 GMUX(0x1a4, CC
, 3, spdif_in_pcc3
, spdif
, rsvd1
, rsvd2
, rsvd3
, 0xacc, 12, 5, 20, 5),
354 GMUX(0x1a8, CC
, 4, usb_vbus_en0_pcc4
, usb
, rsvd1
, rsvd2
, rsvd3
, 0xb5c, 12, 5, 20, 5),
355 GMUX(0x1ac, CC
, 5, usb_vbus_en1_pcc5
, usb
, rsvd1
, rsvd2
, rsvd3
, 0xb60, 12, 5, 20, 5),
356 GMUX(0x1b0, CC
, 6, dp_hpd0_pcc6
, dp
, rsvd1
, rsvd2
, rsvd3
, 0x99c, 12, 5, 20, 5),
357 GMUX(0x1b4, H
, 0, wifi_en_ph0
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xb64, 12, 5, 20, 5),
358 GMUX(0x1b8, H
, 1, wifi_rst_ph1
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xb68, 12, 5, 20, 5),
359 GMUX(0x1bc, H
, 2, wifi_wake_ap_ph2
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xb6c, 12, 5, 20, 5),
360 GMUX(0x1c0, H
, 3, ap_wake_bt_ph3
, rsvd0
, uartb
, spdif
, rsvd3
, 0x8ec, 12, 5, 20, 5),
361 GMUX(0x1c4, H
, 4, bt_rst_ph4
, rsvd0
, uartb
, spdif
, rsvd3
, 0x8fc, 12, 5, 20, 5),
362 GMUX(0x1c8, H
, 5, bt_wake_ap_ph5
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x900, 12, 5, 20, 5),
363 GMUX(0x1cc, H
, 7, ap_wake_nfc_ph7
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x8f0, 12, 5, 20, 5),
364 GMUX(0x1d0, I
, 0, nfc_en_pi0
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa50, 12, 5, 20, 5),
365 GMUX(0x1d4, I
, 1, nfc_int_pi1
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa54, 12, 5, 20, 5),
366 GMUX(0x1d8, I
, 2, gps_en_pi2
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa1c, 12, 5, 20, 5),
367 GMUX(0x1dc, I
, 3, gps_rst_pi3
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa20, 12, 5, 20, 5),
368 GMUX(0x1e0, S
, 4, cam_rst_ps4
, vgp1
, rsvd1
, rsvd2
, rsvd3
, 0x93c, 12, 5, 20, 5),
369 GMUX(0x1e4, S
, 5, cam_af_en_ps5
, vimclk
, vgp2
, rsvd2
, rsvd3
, 0x92c, 12, 5, 20, 5),
370 GMUX(0x1e8, S
, 6, cam_flash_en_ps6
, vimclk
, vgp3
, rsvd2
, rsvd3
, 0x930, 12, 5, 20, 5),
371 GMUX(0x1ec, S
, 7, cam1_pwdn_ps7
, vgp4
, rsvd1
, rsvd2
, rsvd3
, 0x91c, 12, 5, 20, 5),
372 GMUX(0x1f0, T
, 0, cam2_pwdn_pt0
, vgp5
, rsvd1
, rsvd2
, rsvd3
, 0x928, 12, 5, 20, 5),
373 GMUX(0x1f4, T
, 1, cam1_strobe_pt1
, vgp6
, rsvd1
, rsvd2
, rsvd3
, 0x920, 12, 5, 20, 5),
374 GMUX(0x1f8, Y
, 2, lcd_te_py2
, displaya
, rsvd1
, rsvd2
, rsvd3
, 0xa44, 12, 5, 20, 5),
375 GMUX(0x1fc, V
, 0, lcd_bl_pwm_pv0
, displaya
, pwm0
, sor0
, rsvd3
, 0xa34, 12, 5, 20, 5),
376 GMUX(0x200, V
, 1, lcd_bl_en_pv1
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa30, 12, 5, 20, 5),
377 GMUX(0x204, V
, 2, lcd_rst_pv2
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa40, 12, 5, 20, 5),
378 GMUX(0x208, V
, 3, lcd_gpio1_pv3
, displayb
, rsvd1
, rsvd2
, rsvd3
, 0xa38, 12, 5, 20, 5),
379 GMUX(0x20c, V
, 4, lcd_gpio2_pv4
, displayb
, pwm1
, rsvd2
, sor1
, 0xa3c, 12, 5, 20, 5),
380 GMUX(0x210, V
, 5, ap_ready_pv5
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x8e8, 12, 5, 20, 5),
381 GMUX(0x214, V
, 6, touch_rst_pv6
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xb18, 12, 5, 20, 5),
382 GMUX(0x218, V
, 7, touch_clk_pv7
, touch
, rsvd1
, rsvd2
, rsvd3
, 0xb10, 12, 5, 20, 5),
383 GMUX(0x21c, X
, 0, modem_wake_ap_px0
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa48, 12, 5, 20, 5),
384 GMUX(0x220, X
, 1, touch_int_px1
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xb14, 12, 5, 20, 5),
385 GMUX(0x224, X
, 2, motion_int_px2
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xa4c, 12, 5, 20, 5),
386 GMUX(0x228, X
, 3, als_prox_int_px3
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x8e4, 12, 5, 20, 5),
387 GMUX(0x22c, X
, 4, temp_alert_px4
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0xb0c, 12, 5, 20, 5),
388 GMUX(0x230, X
, 5, button_power_on_px5
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x908, 12, 5, 20, 5),
389 GMUX(0x234, X
, 6, button_vol_up_px6
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x914, 12, 5, 20, 5),
390 GMUX(0x238, X
, 7, button_vol_down_px7
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x910, 12, 5, 20, 5),
391 GMUX(0x23c, Y
, 0, button_slide_sw_py0
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x90c, 12, 5, 20, 5),
392 GMUX(0x240, Y
, 1, button_home_py1
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, 0x904, 12, 5, 20, 5),
393 GMUX(0x244, A
, 6, pa6
, sata
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
394 GMUX(0x248, E
, 6, pe6
, rsvd0
, i2s5a
, pwm2
, rsvd3
, -1, 0, 0, 0, 0),
395 GMUX(0x24c, E
, 7, pe7
, rsvd0
, i2s5a
, pwm3
, rsvd3
, -1, 0, 0, 0, 0),
396 GMUX(0x250, H
, 6, ph6
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
397 GMUX(0x254, K
, 0, pk0
, iqc0
, i2s5b
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
398 GMUX(0x258, K
, 1, pk1
, iqc0
, i2s5b
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
399 GMUX(0x25c, K
, 2, pk2
, iqc0
, i2s5b
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
400 GMUX(0x260, K
, 3, pk3
, iqc0
, i2s5b
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
401 GMUX(0x264, K
, 4, pk4
, iqc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
402 GMUX(0x268, K
, 5, pk5
, iqc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
403 GMUX(0x26c, K
, 6, pk6
, iqc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
404 GMUX(0x270, K
, 7, pk7
, iqc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
405 GMUX(0x274, L
, 0, pl0
, rsvd0
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
406 GMUX(0x278, L
, 1, pl1
, soc
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
407 GMUX(0x27c, Z
, 0, pz0
, vimclk2
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
408 GMUX(0x280, Z
, 1, pz1
, vimclk2
, sdmmc1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
409 GMUX(0x284, Z
, 2, pz2
, sdmmc3
, ccla
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
410 GMUX(0x288, Z
, 3, pz3
, sdmmc3
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
411 GMUX(0x28c, Z
, 4, pz4
, sdmmc1
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
412 GMUX(0x290, Z
, 5, pz5
, soc
, rsvd1
, rsvd2
, rsvd3
, -1, 0, 0, 0, 0),
416 static const struct tegra_grp
*
417 pinmux_search_grp(char *grp_name
)
421 for (i
= 0; i
< nitems(pin_grp_tbl
); i
++) {
422 if (strcmp(grp_name
, pin_grp_tbl
[i
].name
) == 0)
423 return (&pin_grp_tbl
[i
]);
428 static const struct tegra_mux
*
429 pinmux_search_mux(char *pin_name
)
433 for (i
= 0; i
< nitems(pin_mux_tbl
); i
++) {
434 if (strcmp(pin_name
, pin_mux_tbl
[i
].name
) == 0)
435 return (&pin_mux_tbl
[i
]);
441 pinmux_mux_function(const struct tegra_mux
*mux
, char *fnc_name
)
445 for (i
= 0; i
< 4; i
++) {
446 if (strcmp(fnc_name
, mux
->functions
[i
]) == 0)
453 pinmux_config_mux(struct pinmux_softc
*sc
, char *pin_name
,
454 const struct tegra_mux
*mux
, struct pincfg
*cfg
)
459 reg
= bus_read_4(sc
->mux_mem_res
, mux
->reg
);
461 if (cfg
->function
!= NULL
) {
462 tmp
= pinmux_mux_function(mux
, cfg
->function
);
464 device_printf(sc
->dev
,
465 "Unknown function %s for pin %s\n", cfg
->function
,
469 reg
&= ~(TEGRA_MUX_FUNCTION_MASK
<< TEGRA_MUX_FUNCTION_SHIFT
);
470 reg
|= (tmp
& TEGRA_MUX_FUNCTION_MASK
) <<
471 TEGRA_MUX_FUNCTION_SHIFT
;
473 if (cfg
->params
[PROP_ID_PULL
] != -1) {
474 reg
&= ~(TEGRA_MUX_PUPD_MASK
<< TEGRA_MUX_PUPD_SHIFT
);
475 reg
|= (cfg
->params
[PROP_ID_PULL
] & TEGRA_MUX_PUPD_MASK
) <<
476 TEGRA_MUX_PUPD_SHIFT
;
478 if (cfg
->params
[PROP_ID_TRISTATE
] != -1) {
479 reg
&= ~(1 << TEGRA_MUX_TRISTATE_SHIFT
);
480 reg
|= (cfg
->params
[PROP_ID_TRISTATE
] & 1) <<
481 TEGRA_MUX_TRISTATE_SHIFT
;
483 if (cfg
->params
[TEGRA_MUX_ENABLE_INPUT_SHIFT
] != -1) {
484 reg
&= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT
);
485 reg
|= (cfg
->params
[TEGRA_MUX_ENABLE_INPUT_SHIFT
] & 1) <<
486 TEGRA_MUX_ENABLE_INPUT_SHIFT
;
488 if (cfg
->params
[PROP_ID_ENABLE_INPUT
] != -1) {
489 reg
&= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT
);
490 reg
|= (cfg
->params
[PROP_ID_ENABLE_INPUT
] & 1) <<
491 TEGRA_MUX_ENABLE_INPUT_SHIFT
;
493 if (cfg
->params
[PROP_ID_ENABLE_INPUT
] != -1) {
494 reg
&= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT
);
495 reg
|= (cfg
->params
[PROP_ID_OPEN_DRAIN
] & 1) <<
496 TEGRA_MUX_ENABLE_INPUT_SHIFT
;
498 if (cfg
->params
[PROP_ID_LOCK
] != -1) {
499 reg
&= ~(1 << TEGRA_MUX_LOCK_SHIFT
);
500 reg
|= (cfg
->params
[PROP_ID_LOCK
] & 1) <<
501 TEGRA_MUX_LOCK_SHIFT
;
503 if (cfg
->params
[PROP_ID_IORESET
] != -1) {
504 reg
&= ~(1 << TEGRA_MUX_IORESET_SHIFT
);
505 reg
|= (cfg
->params
[PROP_ID_IORESET
] & 1) <<
506 TEGRA_MUX_IORESET_SHIFT
;
508 if (cfg
->params
[PROP_ID_RCV_SEL
] != -1) {
509 reg
&= ~(1 << TEGRA_MUX_RCV_SEL_SHIFT
);
510 reg
|= (cfg
->params
[PROP_ID_RCV_SEL
] & 1) <<
511 TEGRA_MUX_RCV_SEL_SHIFT
;
513 bus_write_4(sc
->mux_mem_res
, mux
->reg
, reg
);
518 pinmux_config_grp(struct pinmux_softc
*sc
, char *grp_name
,
519 const struct tegra_grp
*grp
, struct pincfg
*cfg
)
523 reg
= bus_read_4(sc
->pad_mem_res
, grp
->reg
);
525 if (cfg
->params
[PROP_ID_HIGH_SPEED_MODE
] != -1) {
526 reg
&= ~(1 << TEGRA_GRP_HSM_SHIFT
);
527 reg
|= (cfg
->params
[PROP_ID_HIGH_SPEED_MODE
] & 1) <<
530 if (cfg
->params
[PROP_ID_SCHMITT
] != -1) {
531 reg
&= ~(1 << TEGRA_GRP_SCHMT_SHIFT
);
532 reg
|= (cfg
->params
[PROP_ID_SCHMITT
] & 1) <<
533 TEGRA_GRP_SCHMT_SHIFT
;
535 if (cfg
->params
[PROP_ID_DRIVE_TYPE
] != -1) {
536 reg
&= ~(TEGRA_GRP_DRV_TYPE_MASK
<< TEGRA_GRP_DRV_TYPE_SHIFT
);
537 reg
|= (cfg
->params
[PROP_ID_DRIVE_TYPE
] &
538 TEGRA_GRP_DRV_TYPE_MASK
) << TEGRA_GRP_DRV_TYPE_SHIFT
;
540 if (cfg
->params
[PROP_ID_SLEW_RATE_RISING
] != -1) {
541 reg
&= ~(TEGRA_GRP_DRV_DRVDN_SLWR_MASK
<<
542 TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT
);
543 reg
|= (cfg
->params
[PROP_ID_SLEW_RATE_RISING
] &
544 TEGRA_GRP_DRV_DRVDN_SLWR_MASK
) <<
545 TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT
;
547 if (cfg
->params
[PROP_ID_SLEW_RATE_FALLING
] != -1) {
548 reg
&= ~(TEGRA_GRP_DRV_DRVUP_SLWF_MASK
<<
549 TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT
);
550 reg
|= (cfg
->params
[PROP_ID_SLEW_RATE_FALLING
] &
551 TEGRA_GRP_DRV_DRVUP_SLWF_MASK
) <<
552 TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT
;
554 if ((cfg
->params
[PROP_ID_DRIVE_DOWN_STRENGTH
] != -1) &&
555 (grp
->drvdn_mask
!= 0)) {
556 reg
&= ~(grp
->drvdn_shift
<< grp
->drvdn_mask
);
557 reg
|= (cfg
->params
[PROP_ID_DRIVE_DOWN_STRENGTH
] &
558 grp
->drvdn_mask
) << grp
->drvdn_shift
;
560 if ((cfg
->params
[PROP_ID_DRIVE_UP_STRENGTH
] != -1) &&
561 (grp
->drvup_mask
!= 0)) {
562 reg
&= ~(grp
->drvup_shift
<< grp
->drvup_mask
);
563 reg
|= (cfg
->params
[PROP_ID_DRIVE_UP_STRENGTH
] &
564 grp
->drvup_mask
) << grp
->drvup_shift
;
566 bus_write_4(sc
->pad_mem_res
, grp
->reg
, reg
);
571 pinmux_config_node(struct pinmux_softc
*sc
, char *pin_name
, struct pincfg
*cfg
)
573 const struct tegra_mux
*mux
;
574 const struct tegra_grp
*grp
;
578 /* Handle pin muxes */
579 mux
= pinmux_search_mux(pin_name
);
582 if (mux
->gpio_num
!= -1) {
583 /* XXXX TODO: Reserve gpio here */
585 rv
= pinmux_config_mux(sc
, pin_name
, mux
, cfg
);
588 if (mux
->grp
.reg
<= 0) {
589 rv
= pinmux_config_grp(sc
, pin_name
, &mux
->grp
, cfg
);
595 /* And/or handle pin groups */
596 grp
= pinmux_search_grp(pin_name
);
598 rv
= pinmux_config_grp(sc
, pin_name
, grp
, cfg
);
605 device_printf(sc
->dev
, "Unknown pin: %s\n", pin_name
);
612 pinmux_read_node(struct pinmux_softc
*sc
, phandle_t node
, struct pincfg
*cfg
,
613 char **pins
, int *lpins
)
617 *lpins
= OF_getprop_alloc(node
, "nvidia,pins", (void **)pins
);
621 /* Read function (mux) settings. */
622 rv
= OF_getprop_alloc(node
, "nvidia,function", (void **)&cfg
->function
);
624 cfg
->function
= NULL
;
626 /* Read numeric properties. */
627 for (i
= 0; i
< PROP_ID_MAX_ID
; i
++) {
628 rv
= OF_getencprop(node
, prop_names
[i
].name
, &cfg
->params
[i
],
629 sizeof(cfg
->params
[i
]));
637 pinmux_process_node(struct pinmux_softc
*sc
, phandle_t node
)
641 int i
, len
, lpins
, rv
;
643 rv
= pinmux_read_node(sc
, node
, &cfg
, &pins
, &lpins
);
650 i
= strlen(pname
) + 1;
651 rv
= pinmux_config_node(sc
, pname
, &cfg
);
653 device_printf(sc
->dev
, "Cannot configure pin: %s: %d\n",
657 } while (len
< lpins
);
661 if (cfg
.function
!= NULL
)
662 OF_prop_free(cfg
.function
);
666 static int pinmux_configure(device_t dev
, phandle_t cfgxref
)
668 struct pinmux_softc
*sc
;
669 phandle_t node
, cfgnode
;
671 sc
= device_get_softc(dev
);
672 cfgnode
= OF_node_from_xref(cfgxref
);
675 for (node
= OF_child(cfgnode
); node
!= 0; node
= OF_peer(node
)) {
676 if (!ofw_bus_node_status_okay(node
))
678 pinmux_process_node(sc
, node
);
684 pinmux_probe(device_t dev
)
687 if (!ofw_bus_status_okay(dev
))
690 if (!ofw_bus_search_compatible(dev
, compat_data
)->ocd_data
)
693 device_set_desc(dev
, "Tegra pin configuration");
694 return (BUS_PROBE_DEFAULT
);
698 pinmux_detach(device_t dev
)
701 /* This device is always present. */
706 pinmux_attach(device_t dev
)
708 struct pinmux_softc
* sc
;
711 sc
= device_get_softc(dev
);
715 sc
->pad_mem_res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
, &rid
,
717 if (sc
->pad_mem_res
== NULL
) {
718 device_printf(dev
, "Cannot allocate memory resources\n");
723 sc
->mux_mem_res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
, &rid
,
725 if (sc
->mux_mem_res
== NULL
) {
726 device_printf(dev
, "Cannot allocate memory resources\n");
731 /* Register as a pinctrl device and process default configuration */
732 fdt_pinctrl_register(dev
, NULL
);
733 fdt_pinctrl_configure_by_name(dev
, "boot");
739 static device_method_t tegra210_pinmux_methods
[] = {
740 /* Device interface */
741 DEVMETHOD(device_probe
, pinmux_probe
),
742 DEVMETHOD(device_attach
, pinmux_attach
),
743 DEVMETHOD(device_detach
, pinmux_detach
),
745 /* fdt_pinctrl interface */
746 DEVMETHOD(fdt_pinctrl_configure
,pinmux_configure
),
751 static DEFINE_CLASS_0(pinmux
, tegra210_pinmux_driver
, tegra210_pinmux_methods
,
752 sizeof(struct pinmux_softc
));
753 EARLY_DRIVER_MODULE(tegra210_pinmux
, simplebus
, tegra210_pinmux_driver
,