1 /*-
2 * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 /*
29 * Pin multiplexer driver for Tegra SoCs.
30 */
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/malloc.h>
37 #include <sys/rman.h>
38
39 #include <machine/bus.h>
40 #include <machine/fdt.h>
41
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>
47
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
59
60 /* Pin goup register. */
61 #define TEGRA_GRP_HSM_SHIFT 2
62 #define TEGRA_GRP_SCHMT_SHIFT 3
63 #define TEGRA_GRP_DRV_TYPE_SHIFT 6
64 #define TEGRA_GRP_DRV_TYPE_MASK 0x03
65 #define TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT 28
66 #define TEGRA_GRP_DRV_DRVDN_SLWR_MASK 0x03
67 #define TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT 30
68 #define TEGRA_GRP_DRV_DRVUP_SLWF_MASK 0x03
69
70 struct pinmux_softc {
71 device_t dev;
72 struct resource *pad_mem_res;
73 struct resource *mux_mem_res;
74 struct resource *mipi_mem_res;
75 };
76
77 static struct ofw_compat_data compat_data[] = {
78 {"nvidia,tegra124-pinmux", 1},
79 {NULL, 0},
80 };
81
82 enum prop_id {
83 PROP_ID_PULL,
84 PROP_ID_TRISTATE,
85 PROP_ID_ENABLE_INPUT,
86 PROP_ID_OPEN_DRAIN,
87 PROP_ID_LOCK,
88 PROP_ID_IORESET,
89 PROP_ID_RCV_SEL,
90 PROP_ID_HIGH_SPEED_MODE,
91 PROP_ID_SCHMITT,
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,
97 PROP_ID_DRIVE_TYPE,
98
99 PROP_ID_MAX_ID
100 };
101
102 /* Numeric based parameters. */
103 static const struct prop_name {
104 const char *name;
105 enum prop_id id;
106 } prop_names[] = {
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,high-speed-mode", PROP_ID_HIGH_SPEED_MODE},
115 {"nvidia,schmitt", PROP_ID_SCHMITT},
116 {"nvidia,low-power-mode", PROP_ID_LOW_POWER_MODE},
117 {"nvidia,pull-down-strength", PROP_ID_DRIVE_DOWN_STRENGTH},
118 {"nvidia,pull-up-strength", PROP_ID_DRIVE_UP_STRENGTH},
119 {"nvidia,slew-rate-falling", PROP_ID_SLEW_RATE_FALLING},
120 {"nvidia,slew-rate-rising", PROP_ID_SLEW_RATE_RISING},
121 {"nvidia,drive-type", PROP_ID_DRIVE_TYPE},
122 };
123
124 /*
125 * configuration for one pin group.
126 */
127 struct pincfg {
128 char *function;
129 int params[PROP_ID_MAX_ID];
130 };
131 #define GPIO_BANK_A 0
132 #define GPIO_BANK_B 1
133 #define GPIO_BANK_C 2
134 #define GPIO_BANK_D 3
135 #define GPIO_BANK_E 4
136 #define GPIO_BANK_F 5
137 #define GPIO_BANK_G 6
138 #define GPIO_BANK_H 7
139 #define GPIO_BANK_I 8
140 #define GPIO_BANK_J 9
141 #define GPIO_BANK_K 10
142 #define GPIO_BANK_L 11
143 #define GPIO_BANK_M 12
144 #define GPIO_BANK_N 13
145 #define GPIO_BANK_O 14
146 #define GPIO_BANK_P 15
147 #define GPIO_BANK_Q 16
148 #define GPIO_BANK_R 17
149 #define GPIO_BANK_S 18
150 #define GPIO_BANK_T 19
151 #define GPIO_BANK_U 20
152 #define GPIO_BANK_V 21
153 #define GPIO_BANK_W 22
154 #define GPIO_BANK_X 23
155 #define GPIO_BANK_Y 24
156 #define GPIO_BANK_Z 25
157 #define GPIO_BANK_AA 26
158 #define GPIO_BANK_BB 27
159 #define GPIO_BANK_CC 28
160 #define GPIO_BANK_DD 29
161 #define GPIO_BANK_EE 30
162 #define GPIO_BANK_FF 31
163 #define GPIO_NUM(b, p) (8 * (b) + (p))
164
165 struct tegra_mux {
166 char *name;
167 bus_size_t reg;
168 char *functions[4];
169 int gpio_num;
170 };
171
172 #define GMUX(r, gb, gi, nm, f1, f2, f3, f4) \
173 { \
174 .name = #nm, \
175 .reg = r, \
176 .gpio_num = GPIO_NUM(GPIO_BANK_##gb, gi), \
177 .functions = {#f1, #f2, #f3, #f4}, \
178 }
179
180 #define FMUX(r, nm, f1, f2, f3, f4) \
181 { \
182 .name = #nm, \
183 .reg = r, \
184 .gpio_num = -1, \
185 .functions = {#f1, #f2, #f3, #f4}, \
186 }
187
188 static const struct tegra_mux pin_mux_tbl[] = {
189 GMUX(0x000, O, 1, ulpi_data0_po1, spi3, hsi, uarta, ulpi),
190 GMUX(0x004, O, 2, ulpi_data1_po2, spi3, hsi, uarta, ulpi),
191 GMUX(0x008, O, 3, ulpi_data2_po3, spi3, hsi, uarta, ulpi),
192 GMUX(0x00C, O, 4, ulpi_data3_po4, spi3, hsi, uarta, ulpi),
193 GMUX(0x010, O, 5, ulpi_data4_po5, spi2, hsi, uarta, ulpi),
194 GMUX(0x014, O, 6, ulpi_data5_po6, spi2, hsi, uarta, ulpi),
195 GMUX(0x018, O, 7, ulpi_data6_po7, spi2, hsi, uarta, ulpi),
196 GMUX(0x01C, O, 0, ulpi_data7_po0, spi2, hsi, uarta, ulpi),
197 GMUX(0x020, P, 9, ulpi_clk_py0, spi1, spi5, uartd, ulpi),
198 GMUX(0x024, P, 1, ulpi_dir_py1, spi1, spi5, uartd, ulpi),
199 GMUX(0x028, P, 2, ulpi_nxt_py2, spi1, spi5, uartd, ulpi),
200 GMUX(0x02C, P, 3, ulpi_stp_py3, spi1, spi5, uartd, ulpi),
201 GMUX(0x030, P, 0, dap3_fs_pp0, i2s2, spi5, displaya, displayb),
202 GMUX(0x034, P, 1, dap3_din_pp1, i2s2, spi5, displaya, displayb),
203 GMUX(0x038, P, 2, dap3_dout_pp2, i2s2, spi5, displaya, rsvd4),
204 GMUX(0x03C, P, 3, dap3_sclk_pp3, i2s2, spi5, rsvd3, displayb),
205 GMUX(0x040, V, 0, pv0, rsvd1, rsvd2, rsvd3, rsvd4),
206 GMUX(0x044, V, 1, pv1, rsvd1, rsvd2, rsvd3, rsvd4),
207 GMUX(0x048, Z, 0, sdmmc1_clk_pz0, sdmmc1, clk12, rsvd3, rsvd4),
208 GMUX(0x04C, Z, 1, sdmmc1_cmd_pz1, sdmmc1, spdif, spi4, uarta),
209 GMUX(0x050, Y, 4, sdmmc1_dat3_py4, sdmmc1, spdif, spi4, uarta),
210 GMUX(0x054, Y, 5, sdmmc1_dat2_py5, sdmmc1, pwm0, spi4, uarta),
211 GMUX(0x058, Y, 6, sdmmc1_dat1_py6, sdmmc1, pwm1, spi4, uarta),
212 GMUX(0x05C, Y, 7, sdmmc1_dat0_py7, sdmmc1, rsvd2, spi4, uarta),
213 GMUX(0x068, W, 5, clk2_out_pw5, extperiph2, rsvd2, rsvd3, rsvd4),
214 GMUX(0x06C, CC, 5, clk2_req_pcc5, dap, rsvd2, rsvd3, rsvd4),
215 GMUX(0x110, N, 7, hdmi_int_pn7, rsvd1, rsvd2, rsvd3, rsvd4),
216 GMUX(0x114, V, 4, ddc_scl_pv4, i2c4, rsvd2, rsvd3, rsvd4),
217 GMUX(0x118, V, 5, ddc_sda_pv5, i2c4, rsvd2, rsvd3, rsvd4),
218 GMUX(0x164, V, 3, uart2_rxd_pc3, irda, spdif, uarta, spi4),
219 GMUX(0x168, C, 2, uart2_txd_pc2, irda, spdif, uarta, spi4),
220 GMUX(0x16C, J, 6, uart2_rts_n_pj6, uarta, uartb, gmi, spi4),
221 GMUX(0x170, J, 5, uart2_cts_n_pj5, uarta, uartb, gmi, spi4),
222 GMUX(0x174, W, 6, uart3_txd_pw6, uartc, rsvd2, gmi, spi4),
223 GMUX(0x178, W, 7, uart3_rxd_pw7, uartc, rsvd2, gmi, spi4),
224 GMUX(0x17C, S, 1, uart3_cts_n_pa1, uartc, sdmmc1, dtv, gmi),
225 GMUX(0x180, C, 0, uart3_rts_n_pc0, uartc, pwm0, dtv, gmi),
226 GMUX(0x184, U, 0, pu0, owr, uarta, gmi, rsvd4),
227 GMUX(0x188, U, 1, pu1, rsvd1, uarta, gmi, rsvd4),
228 GMUX(0x18C, U, 2, pu2, rsvd1, uarta, gmi, rsvd4),
229 GMUX(0x190, U, 3, pu3, pwm0, uarta, gmi, displayb),
230 GMUX(0x194, U, 4, pu4, pwm1, uarta, gmi, displayb),
231 GMUX(0x198, U, 5, pu5, pwm2, uarta, gmi, displayb),
232 GMUX(0x19C, U, 6, pu6, pwm3, uarta, rsvd3, gmi),
233 GMUX(0x1A0, C, 5, gen1_i2c_sda_pc5, i2c1, rsvd2, rsvd3, rsvd4),
234 GMUX(0x1A4, C, 4, gen1_i2c_scl_pc4, i2c1, rsvd2, rsvd3, rsvd4),
235 GMUX(0x1A8, P, 3, dap4_fs_pp4, i2s3, gmi, dtv, rsvd4),
236 GMUX(0x1AC, P, 4, dap4_din_pp5, i2s3, gmi, rsvd3, rsvd4),
237 GMUX(0x1B0, P, 5, dap4_dout_pp6, i2s3, gmi, dtv, rsvd4),
238 GMUX(0x1B4, P, 7, dap4_sclk_pp7, i2s3, gmi, rsvd3, rsvd4),
239 GMUX(0x1B8, P, 0, clk3_out_pee0, extperiph3, rsvd2, rsvd3, rsvd4),
240 GMUX(0x1BC, EE, 1, clk3_req_pee1, dev3, rsvd2, rsvd3, rsvd4),
241 GMUX(0x1C0, C, 7, pc7, rsvd1, rsvd2, gmi, gmi_alt),
242 GMUX(0x1C4, I, 5, pi5, sdmmc2, rsvd2, gmi, rsvd4),
243 GMUX(0x1C8, I, 7, pi7, rsvd1, trace, gmi, dtv),
244 GMUX(0x1CC, K, 0, pk0, rsvd1, sdmmc3, gmi, soc),
245 GMUX(0x1D0, K, 1, pk1, sdmmc2, trace, gmi, rsvd4),
246 GMUX(0x1D4, J, 0, pj0, rsvd1, rsvd2, gmi, usb),
247 GMUX(0x1D8, J, 2, pj2, rsvd1, rsvd2, gmi, soc),
248 GMUX(0x1DC, K, 3, pk3, sdmmc2, trace, gmi, ccla),
249 GMUX(0x1E0, K, 4, pk4, sdmmc2, rsvd2, gmi, gmi_alt),
250 GMUX(0x1E4, K, 2, pk2, rsvd1, rsvd2, gmi, rsvd4),
251 GMUX(0x1E8, I, 3, pi3, rsvd1, rsvd2, gmi, spi4),
252 GMUX(0x1EC, I, 6, pi6, rsvd1, rsvd2, gmi, sdmmc2),
253 GMUX(0x1F0, G, 0, pg0, rsvd1, rsvd2, gmi, rsvd4),
254 GMUX(0x1F4, G, 1, pg1, rsvd1, rsvd2, gmi, rsvd4),
255 GMUX(0x1F8, G, 2, pg2, rsvd1, trace, gmi, rsvd4),
256 GMUX(0x1FC, G, 3, pg3, rsvd1, trace, gmi, rsvd4),
257 GMUX(0x200, G, 4, pg4, rsvd1, tmds, gmi, spi4),
258 GMUX(0x204, G, 5, pg5, rsvd1, rsvd2, gmi, spi4),
259 GMUX(0x208, G, 6, pg6, rsvd1, rsvd2, gmi, spi4),
260 GMUX(0x20C, G, 7, pg7, rsvd1, rsvd2, gmi, spi4),
261 GMUX(0x210, H, 0, ph0, pwm0, trace, gmi, dtv),
262 GMUX(0x214, H, 1, ph1, pwm1, tmds, gmi, displaya),
263 GMUX(0x218, H, 2, ph2, pwm2, tmds, gmi, cldvfs),
264 GMUX(0x21C, H, 3, ph3, pwm3, spi4, gmi, cldvfs),
265 GMUX(0x220, H, 4, ph4, sdmmc2, rsvd2, gmi, rsvd4),
266 GMUX(0x224, H, 5, ph5, sdmmc2, rsvd2, gmi, rsvd4),
267 GMUX(0x228, H, 6, ph6, sdmmc2, trace, gmi, dtv),
268 GMUX(0x22C, H, 7, ph7, sdmmc2, trace, gmi, dtv),
269 GMUX(0x230, J, 7, pj7, uartd, rsvd2, gmi, gmi_alt),
270 GMUX(0x234, B, 0, pb0, uartd, rsvd2, gmi, rsvd4),
271 GMUX(0x238, B, 1, pb1, uartd, rsvd2, gmi, rsvd4),
272 GMUX(0x23C, K, 7, pk7, uartd, rsvd2, gmi, rsvd4),
273 GMUX(0x240, I, 0, pi0, rsvd1, rsvd2, gmi, rsvd4),
274 GMUX(0x244, I, 1, pi1, rsvd1, rsvd2, gmi, rsvd4),
275 GMUX(0x248, I, 2, pi2, sdmmc2, trace, gmi, rsvd4),
276 GMUX(0x24C, I, 4, pi4, spi4, trace, gmi, displaya),
277 GMUX(0x250, T, 5, gen2_i2c_scl_pt5, i2c2, rsvd2, gmi, rsvd4),
278 GMUX(0x254, T, 6, gen2_i2c_sda_pt6, i2c2, rsvd2, gmi, rsvd4),
279 GMUX(0x258, CC, 4, sdmmc4_clk_pcc4, sdmmc4, rsvd2, gmi, rsvd4),
280 GMUX(0x25C, T, 7, sdmmc4_cmd_pt7, sdmmc4, rsvd2, gmi, rsvd4),
281 GMUX(0x260, AA, 0, sdmmc4_dat0_paa0, sdmmc4, spi3, gmi, rsvd4),
282 GMUX(0x264, AA, 1, sdmmc4_dat1_paa1, sdmmc4, spi3, gmi, rsvd4),
283 GMUX(0x268, AA, 2, sdmmc4_dat2_paa2, sdmmc4, spi3, gmi, rsvd4),
284 GMUX(0x26C, AA, 3, sdmmc4_dat3_paa3, sdmmc4, spi3, gmi, rsvd4),
285 GMUX(0x270, AA, 4, sdmmc4_dat4_paa4, sdmmc4, spi3, gmi, rsvd4),
286 GMUX(0x274, AA, 5, sdmmc4_dat5_paa5, sdmmc4, spi3, rsvd3, rsvd4),
287 GMUX(0x278, AA, 6, sdmmc4_dat6_paa6, sdmmc4, spi3, gmi, rsvd4),
288 GMUX(0x27C, AA, 7, sdmmc4_dat7_paa7, sdmmc4, rsvd2, gmi, rsvd4),
289 GMUX(0x284, CC, 0, cam_mclk_pcc0, vi, vi_alt1, vi_alt3, sdmmc2),
290 GMUX(0x288, CC, 1, pcc1, i2s4, rsvd2, rsvd3, sdmmc2),
291 GMUX(0x28C, BB, 0, pbb0, vgp6, vimclk2, sdmmc2, vimclk2_alt),
292 GMUX(0x290, BB, 1, cam_i2c_scl_pbb1, vgp1, i2c3, rsvd3, sdmmc2),
293 GMUX(0x294, BB, 2, cam_i2c_sda_pbb2, vgp2, i2c3, rsvd3, sdmmc2),
294 GMUX(0x298, BB, 3, pbb3, vgp3, displaya, displayb, sdmmc2),
295 GMUX(0x29C, BB, 4, pbb4, vgp4, displaya, displayb, sdmmc2),
296 GMUX(0x2A0, BB, 5, pbb5, vgp5, displaya, rsvd3, sdmmc2),
297 GMUX(0x2A4, BB, 6, pbb6, i2s4, rsvd2, displayb, sdmmc2),
298 GMUX(0x2A8, BB, 7, pbb7, i2s4, rsvd2, rsvd3, sdmmc2),
299 GMUX(0x2AC, CC, 2, pcc2, i2s4, rsvd2, sdmmc3, sdmmc2),
300 FMUX(0x2B0, jtag_rtck, rtck, rsvd2, rsvd3, rsvd4),
301 GMUX(0x2B4, Z, 6, pwr_i2c_scl_pz6, i2cpwr, rsvd2, rsvd3, rsvd4),
302 GMUX(0x2B8, Z, 7, pwr_i2c_sda_pz7, i2cpwr, rsvd2, rsvd3, rsvd4),
303 GMUX(0x2BC, R, 0, kb_row0_pr0, kbc, rsvd2, rsvd3, rsvd4),
304 GMUX(0x2C0, R, 1, kb_row1_pr1, kbc, rsvd2, rsvd3, rsvd4),
305 GMUX(0x2C4, R, 2, kb_row2_pr2, kbc, rsvd2, rsvd3, rsvd4),
306 GMUX(0x2C8, R, 3, kb_row3_pr3, kbc, displaya, sys, displayb),
307 GMUX(0x2CC, R, 4, kb_row4_pr4, kbc, displaya, rsvd3, displayb),
308 GMUX(0x2D0, R, 5, kb_row5_pr5, kbc, displaya, rsvd3, displayb),
309 GMUX(0x2D4, R, 6, kb_row6_pr6, kbc, displaya, displaya_alt, displayb),
310 GMUX(0x2D8, R, 7, kb_row7_pr7, kbc, rsvd2, cldvfs, uarta),
311 GMUX(0x2DC, S, 0, kb_row8_ps0, kbc, rsvd2, cldvfs, uarta),
312 GMUX(0x2E0, S, 1, kb_row9_ps1, kbc, rsvd2, rsvd3, uarta),
313 GMUX(0x2E4, S, 2, kb_row10_ps2, kbc, rsvd2, rsvd3, uarta),
314 GMUX(0x2E8, S, 3, kb_row11_ps3, kbc, rsvd2, rsvd3, irda),
315 GMUX(0x2EC, S, 4, kb_row12_ps4, kbc, rsvd2, rsvd3, irda),
316 GMUX(0x2F0, S, 5, kb_row13_ps5, kbc, rsvd2, spi2, rsvd4),
317 GMUX(0x2F4, S, 6, kb_row14_ps6, kbc, rsvd2, spi2, rsvd4),
318 GMUX(0x2F8, S, 7, kb_row15_ps7, kbc, soc, rsvd3, rsvd4),
319 GMUX(0x2FC, Q, 0, kb_col0_pq0, kbc, rsvd2, spi2, rsvd4),
320 GMUX(0x300, Q, 1, kb_col1_pq1, kbc, rsvd2, spi2, rsvd4),
321 GMUX(0x304, Q, 2, kb_col2_pq2, kbc, rsvd2, spi2, rsvd4),
322 GMUX(0x308, Q, 3, kb_col3_pq3, kbc, displaya, pwm2, uarta),
323 GMUX(0x30C, Q, 4, kb_col4_pq4, kbc, owr, sdmmc3, uarta),
324 GMUX(0x310, Q, 5, kb_col5_pq5, kbc, rsvd2, sdmmc3, rsvd4),
325 GMUX(0x314, Q, 6, kb_col6_pq6, kbc, rsvd2, spi2, uartd),
326 GMUX(0x318, Q, 7, kb_col7_pq7, kbc, rsvd2, spi2, uartd),
327 GMUX(0x31C, A, 0, clk_32k_out_pa0, blink, soc, rsvd3, rsvd4),
328 FMUX(0x324, core_pwr_req, pwron, rsvd2, rsvd3, rsvd4),
329 FMUX(0x328, cpu_pwr_req, cpu, rsvd2, rsvd3, rsvd4),
330 FMUX(0x32C, pwr_int_n, pmi, rsvd2, rsvd3, rsvd4),
331 FMUX(0x330, clk_32k_in, clk, rsvd2, rsvd3, rsvd4),
332 FMUX(0x334, owr, owr, rsvd2, rsvd3, rsvd4),
333 GMUX(0x338, N, 0, dap1_fs_pn0, i2s0, hda, gmi, rsvd4),
334 GMUX(0x33C, N, 1, dap1_din_pn1, i2s0, hda, gmi, rsvd4),
335 GMUX(0x340, N, 2, dap1_dout_pn2, i2s0, hda, gmi, sata),
336 GMUX(0x344, N, 3, dap1_sclk_pn3, i2s0, hda, gmi, rsvd4),
337 GMUX(0x348, EE, 2, dap_mclk1_req_pee2, dap, dap1, sata, rsvd4),
338 GMUX(0x34C, W, 4, dap_mclk1_pw4, extperiph1, dap2, rsvd3, rsvd4),
339 GMUX(0x350, K, 6, spdif_in_pk6, spdif, rsvd2, rsvd3, i2c3),
340 GMUX(0x354, K, 5, spdif_out_pk5, spdif, rsvd2, rsvd3, i2c3),
341 GMUX(0x358, A, 2, dap2_fs_pa2, i2s1, hda, gmi, rsvd4),
342 GMUX(0x35C, A, 4, dap2_din_pa4, i2s1, hda, gmi, rsvd4),
343 GMUX(0x360, A, 5, dap2_dout_pa5, i2s1, hda, gmi, rsvd4),
344 GMUX(0x364, A, 3, dap2_sclk_pa3, i2s1, hda, gmi, rsvd4),
345 GMUX(0x368, X, 0, dvfs_pwm_px0, spi6, cldvfs, gmi, rsvd4),
346 GMUX(0x36C, X, 1, gpio_x1_aud_px1, spi6, rsvd2, gmi, rsvd4),
347 GMUX(0x370, X, 3, gpio_x3_aud_px3, spi6, spi1, gmi, rsvd4),
348 GMUX(0x374, X, 2, dvfs_clk_px2, spi6, cldvfs, gmi, rsvd4),
349 GMUX(0x378, X, 4, gpio_x4_aud_px4, gmi, spi1, spi2, dap2),
350 GMUX(0x37C, X, 5, gpio_x5_aud_px5, gmi, spi1, spi2, rsvd4),
351 GMUX(0x380, X, 6, gpio_x6_aud_px6, spi6, spi1, spi2, gmi),
352 GMUX(0x384, X, 7, gpio_x7_aud_px7, rsvd1, spi1, spi2, rsvd4),
353 GMUX(0x390, A, 6, sdmmc3_clk_pa6, sdmmc3, rsvd2, rsvd3, spi3),
354 GMUX(0x394, A, 7, sdmmc3_cmd_pa7, sdmmc3, pwm3, uarta, spi3),
355 GMUX(0x398, B, 7, sdmmc3_dat0_pb7, sdmmc3, rsvd2, rsvd3, spi3),
356 GMUX(0x39C, B, 6, sdmmc3_dat1_pb6, sdmmc3, pwm2, uarta, spi3),
357 GMUX(0x3A0, B, 5, sdmmc3_dat2_pb5, sdmmc3, pwm1, displaya, spi3),
358 GMUX(0x3A4, B, 4, sdmmc3_dat3_pb4, sdmmc3, pwm0, displayb, spi3),
359 GMUX(0x3BC, DD, 1, pex_l0_rst_n_pdd1, pe0, rsvd2, rsvd3, rsvd4),
360 GMUX(0x3C0, DD, 2, pex_l0_clkreq_n_pdd2, pe0, rsvd2, rsvd3, rsvd4),
361 GMUX(0x3C4, DD, 3, pex_wake_n_pdd3, pe, rsvd2, rsvd3, rsvd4),
362 GMUX(0x3CC, DD, 5, pex_l1_rst_n_pdd5, pe1, rsvd2, rsvd3, rsvd4),
363 GMUX(0x3D0, DD, 6, pex_l1_clkreq_n_pdd6, pe1, rsvd2, rsvd3, rsvd4),
364 GMUX(0x3E0, EE, 3, hdmi_cec_pee3, cec, rsvd2, rsvd3, rsvd4),
365 GMUX(0x3E4, V, 3, sdmmc1_wp_n_pv3, sdmmc1, clk12, spi4, uarta),
366 GMUX(0x3E8, V, 2, sdmmc3_cd_n_pv2, sdmmc3, owr, rsvd3, rsvd4),
367 GMUX(0x3EC, W, 2, gpio_w2_aud_pw2, spi6, rsvd2, spi2, i2c1),
368 GMUX(0x3F0, W, 3, gpio_w3_aud_pw3, spi6, spi1, spi2, i2c1),
369 GMUX(0x3F4, N, 4, usb_vbus_en0_pn4, usb, rsvd2, rsvd3, rsvd4),
370 GMUX(0x3F8, N, 5, usb_vbus_en1_pn5, usb, rsvd2, rsvd3, rsvd4),
371 GMUX(0x3FC, EE, 5, sdmmc3_clk_lb_in_pee5, sdmmc3, rsvd2, rsvd3, rsvd4),
372 GMUX(0x400, EE, 4, sdmmc3_clk_lb_out_pee4, sdmmc3, rsvd2, rsvd3, rsvd4),
373 FMUX(0x404, gmi_clk_lb, sdmmc2, rsvd2, gmi, rsvd4),
374 FMUX(0x408, reset_out_n, rsvd1, rsvd2, rsvd3, reset_out_n),
375 GMUX(0x40C, T, 0, kb_row16_pt0, kbc, rsvd2, rsvd3, uartc),
376 GMUX(0x410, T, 1, kb_row17_pt1, kbc, rsvd2, rsvd3, uartc),
377 GMUX(0x414, FF, 1, usb_vbus_en2_pff1, usb, rsvd2, rsvd3, rsvd4),
378 GMUX(0x418, FF, 2, pff2, sata, rsvd2, rsvd3, rsvd4),
379 GMUX(0x430, FF, 0, dp_hpd_pff0, dp, rsvd2, rsvd3, rsvd4),
380 };
381
382 struct tegra_grp {
383 char *name;
384 bus_size_t reg;
385 int drvdn_shift;
386 int drvdn_mask;
387 int drvup_shift;
388 int drvup_mask;
389 };
390
391 #define GRP(r, nm, dn_s, dn_w, up_s, up_w) \
392 { \
393 .name = #nm, \
394 .reg = r - 0x868, \
395 .drvdn_shift = dn_s, \
396 .drvdn_mask = (1 << dn_w) - 1, \
397 .drvup_shift = up_s, \
398 .drvup_mask = (1 << dn_w) - 1, \
399 }
400
401 /* Use register offsets from TRM */
402 static const struct tegra_grp pin_grp_tbl[] = {
403 GRP(0x868, ao1, 12, 5, 20, 5),
404 GRP(0x86C, ao2, 12, 5, 20, 5),
405 GRP(0x870, at1, 12, 7, 20, 7),
406 GRP(0x874, at2, 12, 7, 20, 7),
407 GRP(0x878, at3, 12, 7, 20, 7),
408 GRP(0x87C, at4, 12, 7, 20, 7),
409 GRP(0x880, at5, 14, 5, 19, 5),
410 GRP(0x884, cdev1, 12, 5, 20, 5),
411 GRP(0x888, cdev2, 12, 5, 20, 5),
412 GRP(0x890, dap1, 12, 5, 20, 5),
413 GRP(0x894, dap2, 12, 5, 20, 5),
414 GRP(0x898, dap3, 12, 5, 20, 5),
415 GRP(0x89C, dap4, 12, 5, 20, 5),
416 GRP(0x8A0, dbg, 12, 5, 20, 5),
417 GRP(0x8B0, sdio3, 12, 7, 20, 7),
418 GRP(0x8B4, spi, 12, 5, 20, 5),
419 GRP(0x8B8, uaa, 12, 5, 20, 5),
420 GRP(0x8BC, uab, 12, 5, 20, 5),
421 GRP(0x8C0, uart2, 12, 5, 20, 5),
422 GRP(0x8C4, uart3, 12, 5, 20, 5),
423 GRP(0x8EC, sdio1, 12, 7, 20, 7),
424 GRP(0x8FC, ddc, 12, 5, 20, 5),
425 GRP(0x900, gma, 14, 5, 20, 5),
426 GRP(0x910, gme, 14, 5, 19, 5),
427 GRP(0x914, gmf, 14, 5, 19, 5),
428 GRP(0x918, gmg, 14, 5, 19, 5),
429 GRP(0x91C, gmh, 14, 5, 19, 5),
430 GRP(0x920, owr, 12, 5, 20, 5),
431 GRP(0x924, uda, 12, 5, 20, 5),
432 GRP(0x928, gpv, 12, 5, 20, 5),
433 GRP(0x92C, dev3, 12, 5, 20, 5),
434 GRP(0x938, cec, 12, 5, 20, 5),
435 GRP(0x994, at6, 12, 7, 20, 7),
436 GRP(0x998, dap5, 12, 5, 20, 5),
437 GRP(0x99C, usb_vbus_en, 12, 5, 20, 5),
438 GRP(0x9A8, ao3, 12, 5, -1, 0),
439 GRP(0x9B0, ao0, 12, 5, 20, 5),
440 GRP(0x9B4, hv0, 12, 5, -1, 0),
441 GRP(0x9C4, sdio4, 12, 5, 20, 5),
442 GRP(0x9C8, ao4, 12, 7, 20, 7),
443 };
444
445 static const struct tegra_grp *
pinmux_search_grp(char * grp_name)446 pinmux_search_grp(char *grp_name)
447 {
448 int i;
449
450 for (i = 0; i < nitems(pin_grp_tbl); i++) {
451 if (strcmp(grp_name, pin_grp_tbl[i].name) == 0)
452 return (&pin_grp_tbl[i]);
453 }
454 return (NULL);
455 }
456
457 static const struct tegra_mux *
pinmux_search_mux(char * pin_name)458 pinmux_search_mux(char *pin_name)
459 {
460 int i;
461
462 for (i = 0; i < nitems(pin_mux_tbl); i++) {
463 if (strcmp(pin_name, pin_mux_tbl[i].name) == 0)
464 return (&pin_mux_tbl[i]);
465 }
466 return (NULL);
467 }
468
469 static int
pinmux_mux_function(const struct tegra_mux * mux,char * fnc_name)470 pinmux_mux_function(const struct tegra_mux *mux, char *fnc_name)
471 {
472 int i;
473
474 for (i = 0; i < 4; i++) {
475 if (strcmp(fnc_name, mux->functions[i]) == 0)
476 return (i);
477 }
478 return (-1);
479 }
480
481 static int
pinmux_config_mux(struct pinmux_softc * sc,char * pin_name,const struct tegra_mux * mux,struct pincfg * cfg)482 pinmux_config_mux(struct pinmux_softc *sc, char *pin_name,
483 const struct tegra_mux *mux, struct pincfg *cfg)
484 {
485 int tmp;
486 uint32_t reg;
487
488 reg = bus_read_4(sc->mux_mem_res, mux->reg);
489
490 if (cfg->function != NULL) {
491 tmp = pinmux_mux_function(mux, cfg->function);
492 if (tmp == -1) {
493 device_printf(sc->dev,
494 "Unknown function %s for pin %s\n", cfg->function,
495 pin_name);
496 return (ENXIO);
497 }
498 reg &= ~(TEGRA_MUX_FUNCTION_MASK << TEGRA_MUX_FUNCTION_SHIFT);
499 reg |= (tmp & TEGRA_MUX_FUNCTION_MASK) <<
500 TEGRA_MUX_FUNCTION_SHIFT;
501 }
502 if (cfg->params[PROP_ID_PULL] != -1) {
503 reg &= ~(TEGRA_MUX_PUPD_MASK << TEGRA_MUX_PUPD_SHIFT);
504 reg |= (cfg->params[PROP_ID_PULL] & TEGRA_MUX_PUPD_MASK) <<
505 TEGRA_MUX_PUPD_SHIFT;
506 }
507 if (cfg->params[PROP_ID_TRISTATE] != -1) {
508 reg &= ~(1 << TEGRA_MUX_TRISTATE_SHIFT);
509 reg |= (cfg->params[PROP_ID_TRISTATE] & 1) <<
510 TEGRA_MUX_TRISTATE_SHIFT;
511 }
512 if (cfg->params[TEGRA_MUX_ENABLE_INPUT_SHIFT] != -1) {
513 reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
514 reg |= (cfg->params[TEGRA_MUX_ENABLE_INPUT_SHIFT] & 1) <<
515 TEGRA_MUX_ENABLE_INPUT_SHIFT;
516 }
517 if (cfg->params[PROP_ID_ENABLE_INPUT] != -1) {
518 reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
519 reg |= (cfg->params[PROP_ID_ENABLE_INPUT] & 1) <<
520 TEGRA_MUX_ENABLE_INPUT_SHIFT;
521 }
522 if (cfg->params[PROP_ID_ENABLE_INPUT] != -1) {
523 reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
524 reg |= (cfg->params[PROP_ID_OPEN_DRAIN] & 1) <<
525 TEGRA_MUX_ENABLE_INPUT_SHIFT;
526 }
527 if (cfg->params[PROP_ID_LOCK] != -1) {
528 reg &= ~(1 << TEGRA_MUX_LOCK_SHIFT);
529 reg |= (cfg->params[PROP_ID_LOCK] & 1) <<
530 TEGRA_MUX_LOCK_SHIFT;
531 }
532 if (cfg->params[PROP_ID_IORESET] != -1) {
533 reg &= ~(1 << TEGRA_MUX_IORESET_SHIFT);
534 reg |= (cfg->params[PROP_ID_IORESET] & 1) <<
535 TEGRA_MUX_IORESET_SHIFT;
536 }
537 if (cfg->params[PROP_ID_RCV_SEL] != -1) {
538 reg &= ~(1 << TEGRA_MUX_RCV_SEL_SHIFT);
539 reg |= (cfg->params[PROP_ID_RCV_SEL] & 1) <<
540 TEGRA_MUX_RCV_SEL_SHIFT;
541 }
542 bus_write_4(sc->mux_mem_res, mux->reg, reg);
543 return (0);
544 }
545
546 static int
pinmux_config_grp(struct pinmux_softc * sc,char * grp_name,const struct tegra_grp * grp,struct pincfg * cfg)547 pinmux_config_grp(struct pinmux_softc *sc, char *grp_name,
548 const struct tegra_grp *grp, struct pincfg *cfg)
549 {
550 uint32_t reg;
551
552 reg = bus_read_4(sc->pad_mem_res, grp->reg);
553
554 if (cfg->params[PROP_ID_HIGH_SPEED_MODE] != -1) {
555 reg &= ~(1 << TEGRA_GRP_HSM_SHIFT);
556 reg |= (cfg->params[PROP_ID_HIGH_SPEED_MODE] & 1) <<
557 TEGRA_GRP_HSM_SHIFT;
558 }
559 if (cfg->params[PROP_ID_SCHMITT] != -1) {
560 reg &= ~(1 << TEGRA_GRP_SCHMT_SHIFT);
561 reg |= (cfg->params[PROP_ID_SCHMITT] & 1) <<
562 TEGRA_GRP_SCHMT_SHIFT;
563 }
564 if (cfg->params[PROP_ID_DRIVE_TYPE] != -1) {
565 reg &= ~(TEGRA_GRP_DRV_TYPE_MASK << TEGRA_GRP_DRV_TYPE_SHIFT);
566 reg |= (cfg->params[PROP_ID_DRIVE_TYPE] &
567 TEGRA_GRP_DRV_TYPE_MASK) << TEGRA_GRP_DRV_TYPE_SHIFT;
568 }
569 if (cfg->params[PROP_ID_SLEW_RATE_RISING] != -1) {
570 reg &= ~(TEGRA_GRP_DRV_DRVDN_SLWR_MASK <<
571 TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT);
572 reg |= (cfg->params[PROP_ID_SLEW_RATE_RISING] &
573 TEGRA_GRP_DRV_DRVDN_SLWR_MASK) <<
574 TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT;
575 }
576 if (cfg->params[PROP_ID_SLEW_RATE_FALLING] != -1) {
577 reg &= ~(TEGRA_GRP_DRV_DRVUP_SLWF_MASK <<
578 TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT);
579 reg |= (cfg->params[PROP_ID_SLEW_RATE_FALLING] &
580 TEGRA_GRP_DRV_DRVUP_SLWF_MASK) <<
581 TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT;
582 }
583 if ((cfg->params[PROP_ID_DRIVE_DOWN_STRENGTH] != -1) &&
584 (grp->drvdn_mask != -1)) {
585 reg &= ~(grp->drvdn_shift << grp->drvdn_mask);
586 reg |= (cfg->params[PROP_ID_DRIVE_DOWN_STRENGTH] &
587 grp->drvdn_mask) << grp->drvdn_shift;
588 }
589 if ((cfg->params[PROP_ID_DRIVE_UP_STRENGTH] != -1) &&
590 (grp->drvup_mask != -1)) {
591 reg &= ~(grp->drvup_shift << grp->drvup_mask);
592 reg |= (cfg->params[PROP_ID_DRIVE_UP_STRENGTH] &
593 grp->drvup_mask) << grp->drvup_shift;
594 }
595 bus_write_4(sc->pad_mem_res, grp->reg, reg);
596 return (0);
597 }
598
599 static int
pinmux_config_node(struct pinmux_softc * sc,char * pin_name,struct pincfg * cfg)600 pinmux_config_node(struct pinmux_softc *sc, char *pin_name, struct pincfg *cfg)
601 {
602 const struct tegra_mux *mux;
603 const struct tegra_grp *grp;
604 uint32_t reg;
605 int rv;
606
607 /* Handle MIPI special case first */
608 if (strcmp(pin_name, "dsi_b") == 0) {
609 if (cfg->function == NULL) {
610 /* nothing to set */
611 return (0);
612 }
613 reg = bus_read_4(sc->mipi_mem_res, 0); /* register 0x820 */
614 if (strcmp(cfg->function, "csi") == 0)
615 reg &= ~(1 << 1);
616 else if (strcmp(cfg->function, "dsi_b") == 0)
617 reg |= (1 << 1);
618 bus_write_4(sc->mipi_mem_res, 0, reg); /* register 0x820 */
619 }
620
621 /* Handle pin muxes */
622 mux = pinmux_search_mux(pin_name);
623 if (mux != NULL) {
624 if (mux->gpio_num != -1) {
625 /* XXXX TODO: Reserve gpio here */
626 }
627 rv = pinmux_config_mux(sc, pin_name, mux, cfg);
628 return (rv);
629 }
630
631 /* Handle pin groups */
632 grp = pinmux_search_grp(pin_name);
633 if (grp != NULL) {
634 rv = pinmux_config_grp(sc, pin_name, grp, cfg);
635 return (rv);
636 }
637
638 device_printf(sc->dev, "Unknown pin: %s\n", pin_name);
639 return (ENXIO);
640 }
641
642 static int
pinmux_read_node(struct pinmux_softc * sc,phandle_t node,struct pincfg * cfg,char ** pins,int * lpins)643 pinmux_read_node(struct pinmux_softc *sc, phandle_t node, struct pincfg *cfg,
644 char **pins, int *lpins)
645 {
646 int rv, i;
647
648 *lpins = OF_getprop_alloc(node, "nvidia,pins", (void **)pins);
649 if (*lpins <= 0)
650 return (ENOENT);
651
652 /* Read function (mux) settings. */
653 rv = OF_getprop_alloc(node, "nvidia,function",
654 (void **)&cfg->function);
655 if (rv <= 0)
656 cfg->function = NULL;
657
658 /* Read numeric properties. */
659 for (i = 0; i < PROP_ID_MAX_ID; i++) {
660 rv = OF_getencprop(node, prop_names[i].name, &cfg->params[i],
661 sizeof(cfg->params[i]));
662 if (rv <= 0)
663 cfg->params[i] = -1;
664 }
665 return (0);
666 }
667
668 static int
pinmux_process_node(struct pinmux_softc * sc,phandle_t node)669 pinmux_process_node(struct pinmux_softc *sc, phandle_t node)
670 {
671 struct pincfg cfg;
672 char *pins, *pname;
673 int i, len, lpins, rv;
674
675 rv = pinmux_read_node(sc, node, &cfg, &pins, &lpins);
676 if (rv != 0)
677 return (rv);
678
679 len = 0;
680 pname = pins;
681 do {
682 i = strlen(pname) + 1;
683 rv = pinmux_config_node(sc, pname, &cfg);
684 if (rv != 0)
685 device_printf(sc->dev,
686 "Cannot configure pin: %s: %d\n", pname, rv);
687
688 len += i;
689 pname += i;
690 } while (len < lpins);
691
692 if (pins != NULL)
693 OF_prop_free(pins);
694 if (cfg.function != NULL)
695 OF_prop_free(cfg.function);
696 return (rv);
697 }
698
pinmux_configure(device_t dev,phandle_t cfgxref)699 static int pinmux_configure(device_t dev, phandle_t cfgxref)
700 {
701 struct pinmux_softc *sc;
702 phandle_t node, cfgnode;
703
704 sc = device_get_softc(dev);
705 cfgnode = OF_node_from_xref(cfgxref);
706
707 for (node = OF_child(cfgnode); node != 0; node = OF_peer(node)) {
708 if (!ofw_bus_node_status_okay(node))
709 continue;
710 pinmux_process_node(sc, node);
711 }
712 return (0);
713 }
714
715 static int
pinmux_probe(device_t dev)716 pinmux_probe(device_t dev)
717 {
718
719 if (!ofw_bus_status_okay(dev))
720 return (ENXIO);
721
722 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
723 return (ENXIO);
724
725 device_set_desc(dev, "Tegra pin configuration");
726 return (BUS_PROBE_DEFAULT);
727 }
728
729 static int
pinmux_detach(device_t dev)730 pinmux_detach(device_t dev)
731 {
732
733 /* This device is always present. */
734 return (EBUSY);
735 }
736
737 static int
pinmux_attach(device_t dev)738 pinmux_attach(device_t dev)
739 {
740 struct pinmux_softc * sc;
741 int rid;
742
743 sc = device_get_softc(dev);
744 sc->dev = dev;
745
746 rid = 0;
747 sc->pad_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
748 RF_ACTIVE);
749 if (sc->pad_mem_res == NULL) {
750 device_printf(dev, "Cannot allocate memory resources\n");
751 return (ENXIO);
752 }
753
754 rid = 1;
755 sc->mux_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
756 RF_ACTIVE);
757 if (sc->mux_mem_res == NULL) {
758 device_printf(dev, "Cannot allocate memory resources\n");
759 return (ENXIO);
760 }
761
762 rid = 2;
763 sc->mipi_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
764 RF_ACTIVE);
765 if (sc->mipi_mem_res == NULL) {
766 device_printf(dev, "Cannot allocate memory resources\n");
767 return (ENXIO);
768 }
769
770 /* Register as a pinctrl device and process default configuration */
771 fdt_pinctrl_register(dev, NULL);
772 fdt_pinctrl_configure_by_name(dev, "boot");
773
774 return (0);
775 }
776
777 static device_method_t tegra_pinmux_methods[] = {
778 /* Device interface */
779 DEVMETHOD(device_probe, pinmux_probe),
780 DEVMETHOD(device_attach, pinmux_attach),
781 DEVMETHOD(device_detach, pinmux_detach),
782
783 /* fdt_pinctrl interface */
784 DEVMETHOD(fdt_pinctrl_configure,pinmux_configure),
785
786 DEVMETHOD_END
787 };
788
789 static DEFINE_CLASS_0(pinmux, tegra_pinmux_driver, tegra_pinmux_methods,
790 sizeof(struct pinmux_softc));
791 EARLY_DRIVER_MODULE(tegra_pinmux, simplebus, tegra_pinmux_driver, NULL, NULL,
792 71);
793