aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/pinmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/pinmux.c')
-rw-r--r--arch/arm/mach-tegra/pinmux.c427
1 files changed, 329 insertions, 98 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index f80d507671b..245aa627fdf 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -2,6 +2,7 @@
2 * linux/arch/arm/mach-tegra/pinmux.c 2 * linux/arch/arm/mach-tegra/pinmux.c
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
5 * 6 *
6 * This software is licensed under the terms of the GNU General Public 7 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 8 * License version 2, as published by the Free Software Foundation, and
@@ -27,75 +28,19 @@
27#define HSM_EN(reg) (((reg) >> 2) & 0x1) 28#define HSM_EN(reg) (((reg) >> 2) & 0x1)
28#define SCHMT_EN(reg) (((reg) >> 3) & 0x1) 29#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
29#define LPMD(reg) (((reg) >> 4) & 0x3) 30#define LPMD(reg) (((reg) >> 4) & 0x3)
30#define DRVDN(reg) (((reg) >> 12) & 0x1f) 31#define DRVDN(reg, offset) (((reg) >> offset) & 0x1f)
31#define DRVUP(reg) (((reg) >> 20) & 0x1f) 32#define DRVUP(reg, offset) (((reg) >> offset) & 0x1f)
32#define SLWR(reg) (((reg) >> 28) & 0x3) 33#define SLWR(reg, offset) (((reg) >> offset) & 0x3)
33#define SLWF(reg) (((reg) >> 30) & 0x3) 34#define SLWF(reg, offset) (((reg) >> offset) & 0x3)
34 35
35static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups; 36static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups;
36static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups; 37static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups;
38static const int *gpio_to_pingroups_map = gpio_to_pingroup;
37 39
38static char *tegra_mux_names[TEGRA_MAX_MUX] = { 40static char *tegra_mux_names[TEGRA_MAX_MUX] = {
39 [TEGRA_MUX_AHB_CLK] = "AHB_CLK", 41#define TEGRA_MUX(mux) [TEGRA_MUX_##mux] = #mux,
40 [TEGRA_MUX_APB_CLK] = "APB_CLK", 42 TEGRA_MUX_LIST
41 [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC", 43#undef TEGRA_MUX
42 [TEGRA_MUX_CRT] = "CRT",
43 [TEGRA_MUX_DAP1] = "DAP1",
44 [TEGRA_MUX_DAP2] = "DAP2",
45 [TEGRA_MUX_DAP3] = "DAP3",
46 [TEGRA_MUX_DAP4] = "DAP4",
47 [TEGRA_MUX_DAP5] = "DAP5",
48 [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
49 [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
50 [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
51 [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
52 [TEGRA_MUX_GMI] = "GMI",
53 [TEGRA_MUX_GMI_INT] = "GMI_INT",
54 [TEGRA_MUX_HDMI] = "HDMI",
55 [TEGRA_MUX_I2C] = "I2C",
56 [TEGRA_MUX_I2C2] = "I2C2",
57 [TEGRA_MUX_I2C3] = "I2C3",
58 [TEGRA_MUX_IDE] = "IDE",
59 [TEGRA_MUX_IRDA] = "IRDA",
60 [TEGRA_MUX_KBC] = "KBC",
61 [TEGRA_MUX_MIO] = "MIO",
62 [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
63 [TEGRA_MUX_NAND] = "NAND",
64 [TEGRA_MUX_OSC] = "OSC",
65 [TEGRA_MUX_OWR] = "OWR",
66 [TEGRA_MUX_PCIE] = "PCIE",
67 [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
68 [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
69 [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
70 [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
71 [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
72 [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
73 [TEGRA_MUX_PWM] = "PWM",
74 [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
75 [TEGRA_MUX_PWR_ON] = "PWR_ON",
76 [TEGRA_MUX_RTCK] = "RTCK",
77 [TEGRA_MUX_SDIO1] = "SDIO1",
78 [TEGRA_MUX_SDIO2] = "SDIO2",
79 [TEGRA_MUX_SDIO3] = "SDIO3",
80 [TEGRA_MUX_SDIO4] = "SDIO4",
81 [TEGRA_MUX_SFLASH] = "SFLASH",
82 [TEGRA_MUX_SPDIF] = "SPDIF",
83 [TEGRA_MUX_SPI1] = "SPI1",
84 [TEGRA_MUX_SPI2] = "SPI2",
85 [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
86 [TEGRA_MUX_SPI3] = "SPI3",
87 [TEGRA_MUX_SPI4] = "SPI4",
88 [TEGRA_MUX_TRACE] = "TRACE",
89 [TEGRA_MUX_TWC] = "TWC",
90 [TEGRA_MUX_UARTA] = "UARTA",
91 [TEGRA_MUX_UARTB] = "UARTB",
92 [TEGRA_MUX_UARTC] = "UARTC",
93 [TEGRA_MUX_UARTD] = "UARTD",
94 [TEGRA_MUX_UARTE] = "UARTE",
95 [TEGRA_MUX_ULPI] = "ULPI",
96 [TEGRA_MUX_VI] = "VI",
97 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
98 [TEGRA_MUX_XIO] = "XIO",
99 [TEGRA_MUX_SAFE] = "<safe>", 44 [TEGRA_MUX_SAFE] = "<safe>",
100}; 45};
101 46
@@ -137,8 +82,8 @@ static const char *func_name(enum tegra_mux_func func)
137 if (func == TEGRA_MUX_RSVD4) 82 if (func == TEGRA_MUX_RSVD4)
138 return "RSVD4"; 83 return "RSVD4";
139 84
140 if (func == TEGRA_MUX_NONE) 85 if (func == TEGRA_MUX_INVALID)
141 return "NONE"; 86 return "INVALID";
142 87
143 if (func < 0 || func >= TEGRA_MAX_MUX) 88 if (func < 0 || func >= TEGRA_MAX_MUX)
144 return "<UNKNOWN>"; 89 return "<UNKNOWN>";
@@ -169,21 +114,93 @@ static const char *pupd_name(unsigned long val)
169 } 114 }
170} 115}
171 116
117#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
118static const char *lock_name(unsigned long val)
119{
120 switch (val) {
121 case TEGRA_PIN_LOCK_DEFAULT:
122 return "LOCK_DEFUALT";
123
124 case TEGRA_PIN_LOCK_DISABLE:
125 return "LOCK_DISABLE";
126
127 case TEGRA_PIN_LOCK_ENABLE:
128 return "LOCK_ENABLE";
129 default:
130 return "LOCK_DEFAULT";
131 }
132}
133
134static const char *od_name(unsigned long val)
135{
136 switch (val) {
137 case TEGRA_PIN_OD_DEFAULT:
138 return "OD_DEFAULT";
139
140 case TEGRA_PIN_OD_DISABLE:
141 return "OD_DISABLE";
142
143 case TEGRA_PIN_OD_ENABLE:
144 return "OD_ENABLE";
145 default:
146 return "OD_DEFAULT";
147 }
148}
149
150static const char *ioreset_name(unsigned long val)
151{
152 switch (val) {
153 case TEGRA_PIN_IO_RESET_DEFAULT:
154 return "IO_RESET_DEFAULT";
155
156 case TEGRA_PIN_IO_RESET_DISABLE:
157 return "IO_RESET_DISABLE";
158
159 case TEGRA_PIN_IO_RESET_ENABLE:
160 return "IO_RESET_ENABLE";
161 default:
162 return "IO_RESET_DEFAULT";
163 }
164}
165#endif
166
167#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
168static const char *io_name(unsigned long val)
169{
170 switch (val) {
171 case 0:
172 return "OUTPUT";
173
174 case 1:
175 return "INPUT";
176
177 default:
178 return "RSVD";
179 }
180}
181#endif
172 182
173static inline unsigned long pg_readl(unsigned long offset) 183static inline unsigned long pg_readl(unsigned long offset)
174{ 184{
175 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); 185 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
176} 186}
177 187
178static inline void pg_writel(unsigned long value, unsigned long offset) 188static inline void pg_writel(unsigned long value, unsigned long offset)
179{ 189{
180 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); 190 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
181} 191}
182 192
193int tegra_pinmux_get_pingroup(int gpio_nr)
194{
195 return gpio_to_pingroups_map[gpio_nr];
196}
197EXPORT_SYMBOL_GPL(tegra_pinmux_get_pingroup);
198
183static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) 199static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
184{ 200{
185 int mux = -1; 201 int mux = -1;
186 int i; 202 int i;
203 int find = 0;
187 unsigned long reg; 204 unsigned long reg;
188 unsigned long flags; 205 unsigned long flags;
189 enum tegra_pingroup pg = config->pingroup; 206 enum tegra_pingroup pg = config->pingroup;
@@ -192,8 +209,15 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
192 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 209 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
193 return -ERANGE; 210 return -ERANGE;
194 211
195 if (pingroups[pg].mux_reg < 0) 212 if (pingroups[pg].mux_reg <= 0)
213 return -EINVAL;
214
215 if (func == TEGRA_MUX_INVALID) {
216 pr_err("The pingroup %s is not recommended for option %s\n",
217 pingroup_name(pg), func_name(func));
218 WARN_ON(1);
196 return -EINVAL; 219 return -EINVAL;
220 }
197 221
198 if (func < 0) 222 if (func < 0)
199 return -ERANGE; 223 return -ERANGE;
@@ -202,24 +226,47 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
202 func = pingroups[pg].func_safe; 226 func = pingroups[pg].func_safe;
203 227
204 if (func & TEGRA_MUX_RSVD) { 228 if (func & TEGRA_MUX_RSVD) {
205 mux = func & 0x3; 229 for (i = 0; i < 4; i++) {
230 if (pingroups[pg].funcs[i] & TEGRA_MUX_RSVD)
231 mux = i;
232
233 if (pingroups[pg].funcs[i] == func) {
234 mux = i;
235 find = 1;
236 break;
237 }
238 }
206 } else { 239 } else {
207 for (i = 0; i < 4; i++) { 240 for (i = 0; i < 4; i++) {
208 if (pingroups[pg].funcs[i] == func) { 241 if (pingroups[pg].funcs[i] == func) {
209 mux = i; 242 mux = i;
243 find = 1;
210 break; 244 break;
211 } 245 }
212 } 246 }
213 } 247 }
214 248
215 if (mux < 0) 249 if (mux < 0) {
250 pr_err("The pingroup %s is not supported option %s\n",
251 pingroup_name(pg), func_name(func));
252 WARN_ON(1);
216 return -EINVAL; 253 return -EINVAL;
254 }
255
256 if (!find)
257 pr_warn("The pingroup %s was configured to %s instead of %s\n",
258 pingroup_name(pg), func_name(pingroups[pg].funcs[mux]),
259 func_name(func));
217 260
218 spin_lock_irqsave(&mux_lock, flags); 261 spin_lock_irqsave(&mux_lock, flags);
219 262
220 reg = pg_readl(pingroups[pg].mux_reg); 263 reg = pg_readl(pingroups[pg].mux_reg);
221 reg &= ~(0x3 << pingroups[pg].mux_bit); 264 reg &= ~(0x3 << pingroups[pg].mux_bit);
222 reg |= mux << pingroups[pg].mux_bit; 265 reg |= mux << pingroups[pg].mux_bit;
266#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
267 reg &= ~(0x1 << 5);
268 reg |= ((config->io & 0x1) << 5);
269#endif
223 pg_writel(reg, pingroups[pg].mux_reg); 270 pg_writel(reg, pingroups[pg].mux_reg);
224 271
225 spin_unlock_irqrestore(&mux_lock, flags); 272 spin_unlock_irqrestore(&mux_lock, flags);
@@ -227,6 +274,28 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
227 return 0; 274 return 0;
228} 275}
229 276
277int tegra_pinmux_get_func(enum tegra_pingroup pg)
278{
279 int mux = -1;
280 unsigned long reg;
281 unsigned long flags;
282
283 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
284 return -ERANGE;
285
286 if (pingroups[pg].mux_reg <= 0)
287 return -EINVAL;
288
289 spin_lock_irqsave(&mux_lock, flags);
290
291 reg = pg_readl(pingroups[pg].mux_reg);
292 mux = (reg >> pingroups[pg].mux_bit) & 0x3;
293
294 spin_unlock_irqrestore(&mux_lock, flags);
295
296 return mux;
297}
298
230int tegra_pinmux_set_tristate(enum tegra_pingroup pg, 299int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
231 enum tegra_tristate tristate) 300 enum tegra_tristate tristate)
232{ 301{
@@ -236,7 +305,7 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
236 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 305 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
237 return -ERANGE; 306 return -ERANGE;
238 307
239 if (pingroups[pg].tri_reg < 0) 308 if (pingroups[pg].tri_reg <= 0)
240 return -EINVAL; 309 return -EINVAL;
241 310
242 spin_lock_irqsave(&mux_lock, flags); 311 spin_lock_irqsave(&mux_lock, flags);
@@ -252,6 +321,114 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
252 return 0; 321 return 0;
253} 322}
254 323
324int tegra_pinmux_set_io(enum tegra_pingroup pg,
325 enum tegra_pin_io input)
326{
327#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
328 unsigned long io;
329
330 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
331 return -ERANGE;
332
333 io = pg_readl(pingroups[pg].mux_reg);
334 if (input)
335 io |= 0x20;
336 else
337 io &= ~(1 << 5);
338 pg_writel(io, pingroups[pg].mux_reg);
339#endif
340 return 0;
341}
342EXPORT_SYMBOL_GPL(tegra_pinmux_set_io);
343
344#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
345static int tegra_pinmux_set_lock(enum tegra_pingroup pg,
346 enum tegra_pin_lock lock)
347{
348 unsigned long reg;
349 unsigned long flags;
350
351 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
352 return -ERANGE;
353
354 if (pingroups[pg].mux_reg <= 0)
355 return -EINVAL;
356
357 if ((lock == TEGRA_PIN_LOCK_DEFAULT) || (pingroups[pg].lock_bit < 0))
358 return 0;
359
360 spin_lock_irqsave(&mux_lock, flags);
361
362 reg = pg_readl(pingroups[pg].mux_reg);
363 reg &= ~(0x1 << pingroups[pg].lock_bit);
364 if (lock == TEGRA_PIN_LOCK_ENABLE)
365 reg |= (0x1 << pingroups[pg].lock_bit);
366
367 pg_writel(reg, pingroups[pg].mux_reg);
368
369 spin_unlock_irqrestore(&mux_lock, flags);
370 return 0;
371}
372
373static int tegra_pinmux_set_od(enum tegra_pingroup pg,
374 enum tegra_pin_od od)
375{
376 unsigned long reg;
377 unsigned long flags;
378
379 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
380 return -ERANGE;
381
382 if (pingroups[pg].mux_reg <= 0)
383 return -EINVAL;
384
385 if ((od == TEGRA_PIN_OD_DEFAULT) || (pingroups[pg].od_bit < 0))
386 return 0;
387
388 spin_lock_irqsave(&mux_lock, flags);
389
390 reg = pg_readl(pingroups[pg].mux_reg);
391 reg &= ~(0x1 << pingroups[pg].od_bit);
392 if (od == TEGRA_PIN_OD_ENABLE)
393 reg |= 1 << pingroups[pg].od_bit;
394
395 pg_writel(reg, pingroups[pg].mux_reg);
396
397 spin_unlock_irqrestore(&mux_lock, flags);
398
399 return 0;
400}
401
402static int tegra_pinmux_set_ioreset(enum tegra_pingroup pg,
403 enum tegra_pin_ioreset ioreset)
404{
405 unsigned long reg;
406 unsigned long flags;
407
408 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
409 return -ERANGE;
410
411 if (pingroups[pg].mux_reg <= 0)
412 return -EINVAL;
413
414 if ((ioreset == TEGRA_PIN_IO_RESET_DEFAULT) || (pingroups[pg].ioreset_bit < 0))
415 return 0;
416
417 spin_lock_irqsave(&mux_lock, flags);
418
419 reg = pg_readl(pingroups[pg].mux_reg);
420 reg &= ~(0x1 << pingroups[pg].ioreset_bit);
421 if (ioreset == TEGRA_PIN_IO_RESET_ENABLE)
422 reg |= 1 << pingroups[pg].ioreset_bit;
423
424 pg_writel(reg, pingroups[pg].mux_reg);
425
426 spin_unlock_irqrestore(&mux_lock, flags);
427
428 return 0;
429}
430#endif
431
255int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, 432int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
256 enum tegra_pullupdown pupd) 433 enum tegra_pullupdown pupd)
257{ 434{
@@ -261,7 +438,7 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
261 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 438 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
262 return -ERANGE; 439 return -ERANGE;
263 440
264 if (pingroups[pg].pupd_reg < 0) 441 if (pingroups[pg].pupd_reg <= 0)
265 return -EINVAL; 442 return -EINVAL;
266 443
267 if (pupd != TEGRA_PUPD_NORMAL && 444 if (pupd != TEGRA_PUPD_NORMAL &&
@@ -288,28 +465,56 @@ static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *con
288 enum tegra_mux_func func = config->func; 465 enum tegra_mux_func func = config->func;
289 enum tegra_pullupdown pupd = config->pupd; 466 enum tegra_pullupdown pupd = config->pupd;
290 enum tegra_tristate tristate = config->tristate; 467 enum tegra_tristate tristate = config->tristate;
468#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
469 enum tegra_pin_lock lock = config->lock;
470 enum tegra_pin_od od = config->od;
471 enum tegra_pin_ioreset ioreset = config->ioreset;
472#endif
291 int err; 473 int err;
292 474
293 if (pingroups[pingroup].mux_reg >= 0) { 475 if (pingroups[pingroup].mux_reg > 0) {
294 err = tegra_pinmux_set_func(config); 476 err = tegra_pinmux_set_func(config);
295 if (err < 0) 477 if (err < 0)
296 pr_err("pinmux: can't set pingroup %s func to %s: %d\n", 478 pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
297 pingroup_name(pingroup), func_name(func), err); 479 pingroup_name(pingroup), func_name(func), err);
298 } 480 }
299 481
300 if (pingroups[pingroup].pupd_reg >= 0) { 482 if (pingroups[pingroup].pupd_reg > 0) {
301 err = tegra_pinmux_set_pullupdown(pingroup, pupd); 483 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
302 if (err < 0) 484 if (err < 0)
303 pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n", 485 pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
304 pingroup_name(pingroup), pupd_name(pupd), err); 486 pingroup_name(pingroup), pupd_name(pupd), err);
305 } 487 }
306 488
307 if (pingroups[pingroup].tri_reg >= 0) { 489 if (pingroups[pingroup].tri_reg > 0) {
308 err = tegra_pinmux_set_tristate(pingroup, tristate); 490 err = tegra_pinmux_set_tristate(pingroup, tristate);
309 if (err < 0) 491 if (err < 0)
310 pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n", 492 pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
311 pingroup_name(pingroup), tri_name(func), err); 493 pingroup_name(pingroup), tri_name(func), err);
312 } 494 }
495
496#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
497 if (pingroups[pingroup].mux_reg > 0) {
498 err = tegra_pinmux_set_lock(pingroup, lock);
499 if (err < 0)
500 pr_err("pinmux: can't set pingroup %s lock to %s: %d\n",
501 pingroup_name(pingroup), lock_name(func), err);
502 }
503
504 if (pingroups[pingroup].mux_reg > 0) {
505 err = tegra_pinmux_set_od(pingroup, od);
506 if (err < 0)
507 pr_err("pinmux: can't set pingroup %s od to %s: %d\n",
508 pingroup_name(pingroup), od_name(func), err);
509 }
510
511 if (pingroups[pingroup].mux_reg > 0) {
512 err = tegra_pinmux_set_ioreset(pingroup, ioreset);
513 if (err < 0)
514 pr_err("pinmux: can't set pingroup %s ioreset to %s: %d\n",
515 pingroup_name(pingroup), ioreset_name(func), err);
516 }
517#endif
313} 518}
314 519
315void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len) 520void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
@@ -319,6 +524,7 @@ void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int l
319 for (i = 0; i < len; i++) 524 for (i = 0; i < len; i++)
320 tegra_pinmux_config_pingroup(&config[i]); 525 tegra_pinmux_config_pingroup(&config[i]);
321} 526}
527EXPORT_SYMBOL(tegra_pinmux_config_table);
322 528
323static const char *drive_pinmux_name(enum tegra_drive_pingroup pg) 529static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
324{ 530{
@@ -427,6 +633,7 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
427{ 633{
428 unsigned long flags; 634 unsigned long flags;
429 u32 reg; 635 u32 reg;
636
430 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 637 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
431 return -ERANGE; 638 return -ERANGE;
432 639
@@ -436,8 +643,9 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
436 spin_lock_irqsave(&mux_lock, flags); 643 spin_lock_irqsave(&mux_lock, flags);
437 644
438 reg = pg_readl(drive_pingroups[pg].reg); 645 reg = pg_readl(drive_pingroups[pg].reg);
439 reg &= ~(0x1f << 12); 646 reg &= ~(drive_pingroups[pg].drvdown_mask <<
440 reg |= pull_down << 12; 647 drive_pingroups[pg].drvdown_offset);
648 reg |= pull_down << drive_pingroups[pg].drvdown_offset;
441 pg_writel(reg, drive_pingroups[pg].reg); 649 pg_writel(reg, drive_pingroups[pg].reg);
442 650
443 spin_unlock_irqrestore(&mux_lock, flags); 651 spin_unlock_irqrestore(&mux_lock, flags);
@@ -450,6 +658,7 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
450{ 658{
451 unsigned long flags; 659 unsigned long flags;
452 u32 reg; 660 u32 reg;
661
453 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 662 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
454 return -ERANGE; 663 return -ERANGE;
455 664
@@ -459,8 +668,9 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
459 spin_lock_irqsave(&mux_lock, flags); 668 spin_lock_irqsave(&mux_lock, flags);
460 669
461 reg = pg_readl(drive_pingroups[pg].reg); 670 reg = pg_readl(drive_pingroups[pg].reg);
462 reg &= ~(0x1f << 12); 671 reg &= ~(drive_pingroups[pg].drvup_mask <<
463 reg |= pull_up << 12; 672 drive_pingroups[pg].drvup_offset);
673 reg |= pull_up << drive_pingroups[pg].drvup_offset;
464 pg_writel(reg, drive_pingroups[pg].reg); 674 pg_writel(reg, drive_pingroups[pg].reg);
465 675
466 spin_unlock_irqrestore(&mux_lock, flags); 676 spin_unlock_irqrestore(&mux_lock, flags);
@@ -482,8 +692,9 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
482 spin_lock_irqsave(&mux_lock, flags); 692 spin_lock_irqsave(&mux_lock, flags);
483 693
484 reg = pg_readl(drive_pingroups[pg].reg); 694 reg = pg_readl(drive_pingroups[pg].reg);
485 reg &= ~(0x3 << 28); 695 reg &= ~(drive_pingroups[pg].slewrise_mask <<
486 reg |= slew_rising << 28; 696 drive_pingroups[pg].slewrise_offset);
697 reg |= slew_rising << drive_pingroups[pg].slewrise_offset;
487 pg_writel(reg, drive_pingroups[pg].reg); 698 pg_writel(reg, drive_pingroups[pg].reg);
488 699
489 spin_unlock_irqrestore(&mux_lock, flags); 700 spin_unlock_irqrestore(&mux_lock, flags);
@@ -505,8 +716,9 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
505 spin_lock_irqsave(&mux_lock, flags); 716 spin_lock_irqsave(&mux_lock, flags);
506 717
507 reg = pg_readl(drive_pingroups[pg].reg); 718 reg = pg_readl(drive_pingroups[pg].reg);
508 reg &= ~(0x3 << 30); 719 reg &= ~(drive_pingroups[pg].slewfall_mask <<
509 reg |= slew_falling << 30; 720 drive_pingroups[pg].slewfall_offset);
721 reg |= slew_falling << drive_pingroups[pg].slewfall_offset;
510 pg_writel(reg, drive_pingroups[pg].reg); 722 pg_writel(reg, drive_pingroups[pg].reg);
511 723
512 spin_unlock_irqrestore(&mux_lock, flags); 724 spin_unlock_irqrestore(&mux_lock, flags);
@@ -636,7 +848,7 @@ void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *conf
636 848
637 for (i = 0; i < len; i++) { 849 for (i = 0; i < len; i++) {
638 pingroup = config[i].pingroup; 850 pingroup = config[i].pingroup;
639 if (pingroups[pingroup].tri_reg >= 0) { 851 if (pingroups[pingroup].tri_reg > 0) {
640 err = tegra_pinmux_set_tristate(pingroup, tristate); 852 err = tegra_pinmux_set_tristate(pingroup, tristate);
641 if (err < 0) 853 if (err < 0)
642 pr_err("pinmux: can't set pingroup %s tristate" 854 pr_err("pinmux: can't set pingroup %s tristate"
@@ -655,7 +867,7 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
655 867
656 for (i = 0; i < len; i++) { 868 for (i = 0; i < len; i++) {
657 pingroup = config[i].pingroup; 869 pingroup = config[i].pingroup;
658 if (pingroups[pingroup].pupd_reg >= 0) { 870 if (pingroups[pingroup].pupd_reg > 0) {
659 err = tegra_pinmux_set_pullupdown(pingroup, pupd); 871 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
660 if (err < 0) 872 if (err < 0)
661 pr_err("pinmux: can't set pingroup %s pullupdown" 873 pr_err("pinmux: can't set pingroup %s pullupdown"
@@ -690,18 +902,23 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
690 902
691 seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name); 903 seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
692 len = strlen(pingroups[i].name); 904 len = strlen(pingroups[i].name);
693 dbg_pad_field(s, 5 - len); 905 dbg_pad_field(s, 15 - len);
694 906
695 if (pingroups[i].mux_reg < 0) { 907 if (pingroups[i].mux_reg <= 0) {
696 seq_printf(s, "TEGRA_MUX_NONE"); 908 seq_printf(s, "TEGRA_MUX_NONE");
697 len = strlen("NONE"); 909 len = strlen("NONE");
698 } else { 910 } else {
699 mux = (pg_readl(pingroups[i].mux_reg) >> 911 mux = (pg_readl(pingroups[i].mux_reg) >>
700 pingroups[i].mux_bit) & 0x3; 912 pingroups[i].mux_bit) & 0x3;
701 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { 913 BUG_ON(pingroups[i].funcs[mux] == 0);
914 if (pingroups[i].funcs[mux] == TEGRA_MUX_INVALID) {
915 seq_printf(s, "TEGRA_MUX_INVALID");
916 len = 7;
917 } else if (pingroups[i].funcs[mux] & TEGRA_MUX_RSVD) {
702 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); 918 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
703 len = 5; 919 len = 5;
704 } else { 920 } else {
921 BUG_ON(!tegra_mux_names[pingroups[i].funcs[mux]]);
705 seq_printf(s, "TEGRA_MUX_%s", 922 seq_printf(s, "TEGRA_MUX_%s",
706 tegra_mux_names[pingroups[i].funcs[mux]]); 923 tegra_mux_names[pingroups[i].funcs[mux]]);
707 len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]); 924 len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
@@ -709,7 +926,16 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
709 } 926 }
710 dbg_pad_field(s, 13-len); 927 dbg_pad_field(s, 13-len);
711 928
712 if (pingroups[i].pupd_reg < 0) { 929#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
930 {
931 unsigned long io;
932 io = (pg_readl(pingroups[i].mux_reg) >> 5) & 0x1;
933 seq_printf(s, "TEGRA_PIN_%s", io_name(io));
934 len = strlen(io_name(io));
935 dbg_pad_field(s, 6 - len);
936 }
937#endif
938 if (pingroups[i].pupd_reg <= 0) {
713 seq_printf(s, "TEGRA_PUPD_NORMAL"); 939 seq_printf(s, "TEGRA_PUPD_NORMAL");
714 len = strlen("NORMAL"); 940 len = strlen("NORMAL");
715 } else { 941 } else {
@@ -720,7 +946,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
720 } 946 }
721 dbg_pad_field(s, 9 - len); 947 dbg_pad_field(s, 9 - len);
722 948
723 if (pingroups[i].tri_reg < 0) { 949 if (pingroups[i].tri_reg <= 0) {
724 seq_printf(s, "TEGRA_TRI_NORMAL"); 950 seq_printf(s, "TEGRA_TRI_NORMAL");
725 } else { 951 } else {
726 tri = (pg_readl(pingroups[i].tri_reg) >> 952 tri = (pg_readl(pingroups[i].tri_reg) >>
@@ -749,6 +975,7 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
749{ 975{
750 int i; 976 int i;
751 int len; 977 int len;
978 u8 offset;
752 979
753 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) { 980 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
754 u32 reg; 981 u32 reg;
@@ -782,19 +1009,23 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
782 len = strlen(drive_name(LPMD(reg))); 1009 len = strlen(drive_name(LPMD(reg)));
783 dbg_pad_field(s, 5 - len); 1010 dbg_pad_field(s, 5 - len);
784 1011
785 seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg)); 1012 offset = drive_pingroups[i].drvdown_offset;
786 len = DRVDN(reg) < 10 ? 1 : 2; 1013 seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg, offset));
1014 len = DRVDN(reg, offset) < 10 ? 1 : 2;
787 dbg_pad_field(s, 2 - len); 1015 dbg_pad_field(s, 2 - len);
788 1016
789 seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg)); 1017 offset = drive_pingroups[i].drvup_offset;
790 len = DRVUP(reg) < 10 ? 1 : 2; 1018 seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg, offset));
1019 len = DRVUP(reg, offset) < 10 ? 1 : 2;
791 dbg_pad_field(s, 2 - len); 1020 dbg_pad_field(s, 2 - len);
792 1021
793 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg))); 1022 offset = drive_pingroups[i].slewrise_offset;
794 len = strlen(slew_name(SLWR(reg))); 1023 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg, offset)));
1024 len = strlen(slew_name(SLWR(reg, offset)));
795 dbg_pad_field(s, 7 - len); 1025 dbg_pad_field(s, 7 - len);
796 1026
797 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg))); 1027 offset= drive_pingroups[i].slewfall_offset;
1028 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg, offset)));
798 1029
799 seq_printf(s, "},\n"); 1030 seq_printf(s, "},\n");
800 } 1031 }