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.c1056
1 files changed, 1056 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644
index 00000000000..245aa627fdf
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -0,0 +1,1056 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA Corporation.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/spinlock.h>
23#include <linux/io.h>
24
25#include <mach/iomap.h>
26#include <mach/pinmux.h>
27
28#define HSM_EN(reg) (((reg) >> 2) & 0x1)
29#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
30#define LPMD(reg) (((reg) >> 4) & 0x3)
31#define DRVDN(reg, offset) (((reg) >> offset) & 0x1f)
32#define DRVUP(reg, offset) (((reg) >> offset) & 0x1f)
33#define SLWR(reg, offset) (((reg) >> offset) & 0x3)
34#define SLWF(reg, offset) (((reg) >> offset) & 0x3)
35
36static const struct tegra_pingroup_desc *const pingroups = tegra_soc_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;
39
40static char *tegra_mux_names[TEGRA_MAX_MUX] = {
41#define TEGRA_MUX(mux) [TEGRA_MUX_##mux] = #mux,
42 TEGRA_MUX_LIST
43#undef TEGRA_MUX
44 [TEGRA_MUX_SAFE] = "<safe>",
45};
46
47static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
48 [TEGRA_DRIVE_DIV_8] = "DIV_8",
49 [TEGRA_DRIVE_DIV_4] = "DIV_4",
50 [TEGRA_DRIVE_DIV_2] = "DIV_2",
51 [TEGRA_DRIVE_DIV_1] = "DIV_1",
52};
53
54static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
55 [TEGRA_SLEW_FASTEST] = "FASTEST",
56 [TEGRA_SLEW_FAST] = "FAST",
57 [TEGRA_SLEW_SLOW] = "SLOW",
58 [TEGRA_SLEW_SLOWEST] = "SLOWEST",
59};
60
61static DEFINE_SPINLOCK(mux_lock);
62
63static const char *pingroup_name(enum tegra_pingroup pg)
64{
65 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
66 return "<UNKNOWN>";
67
68 return pingroups[pg].name;
69}
70
71static const char *func_name(enum tegra_mux_func func)
72{
73 if (func == TEGRA_MUX_RSVD1)
74 return "RSVD1";
75
76 if (func == TEGRA_MUX_RSVD2)
77 return "RSVD2";
78
79 if (func == TEGRA_MUX_RSVD3)
80 return "RSVD3";
81
82 if (func == TEGRA_MUX_RSVD4)
83 return "RSVD4";
84
85 if (func == TEGRA_MUX_INVALID)
86 return "INVALID";
87
88 if (func < 0 || func >= TEGRA_MAX_MUX)
89 return "<UNKNOWN>";
90
91 return tegra_mux_names[func];
92}
93
94
95static const char *tri_name(unsigned long val)
96{
97 return val ? "TRISTATE" : "NORMAL";
98}
99
100static const char *pupd_name(unsigned long val)
101{
102 switch (val) {
103 case 0:
104 return "NORMAL";
105
106 case 1:
107 return "PULL_DOWN";
108
109 case 2:
110 return "PULL_UP";
111
112 default:
113 return "RSVD";
114 }
115}
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
182
183static inline unsigned long pg_readl(unsigned long offset)
184{
185 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
186}
187
188static inline void pg_writel(unsigned long value, unsigned long offset)
189{
190 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
191}
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
199static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
200{
201 int mux = -1;
202 int i;
203 int find = 0;
204 unsigned long reg;
205 unsigned long flags;
206 enum tegra_pingroup pg = config->pingroup;
207 enum tegra_mux_func func = config->func;
208
209 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
210 return -ERANGE;
211
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);
219 return -EINVAL;
220 }
221
222 if (func < 0)
223 return -ERANGE;
224
225 if (func == TEGRA_MUX_SAFE)
226 func = pingroups[pg].func_safe;
227
228 if (func & TEGRA_MUX_RSVD) {
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 }
239 } else {
240 for (i = 0; i < 4; i++) {
241 if (pingroups[pg].funcs[i] == func) {
242 mux = i;
243 find = 1;
244 break;
245 }
246 }
247 }
248
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);
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));
260
261 spin_lock_irqsave(&mux_lock, flags);
262
263 reg = pg_readl(pingroups[pg].mux_reg);
264 reg &= ~(0x3 << 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
270 pg_writel(reg, pingroups[pg].mux_reg);
271
272 spin_unlock_irqrestore(&mux_lock, flags);
273
274 return 0;
275}
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
299int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
300 enum tegra_tristate tristate)
301{
302 unsigned long reg;
303 unsigned long flags;
304
305 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
306 return -ERANGE;
307
308 if (pingroups[pg].tri_reg <= 0)
309 return -EINVAL;
310
311 spin_lock_irqsave(&mux_lock, flags);
312
313 reg = pg_readl(pingroups[pg].tri_reg);
314 reg &= ~(0x1 << pingroups[pg].tri_bit);
315 if (tristate)
316 reg |= 1 << pingroups[pg].tri_bit;
317 pg_writel(reg, pingroups[pg].tri_reg);
318
319 spin_unlock_irqrestore(&mux_lock, flags);
320
321 return 0;
322}
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
432int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
433 enum tegra_pullupdown pupd)
434{
435 unsigned long reg;
436 unsigned long flags;
437
438 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
439 return -ERANGE;
440
441 if (pingroups[pg].pupd_reg <= 0)
442 return -EINVAL;
443
444 if (pupd != TEGRA_PUPD_NORMAL &&
445 pupd != TEGRA_PUPD_PULL_DOWN &&
446 pupd != TEGRA_PUPD_PULL_UP)
447 return -EINVAL;
448
449
450 spin_lock_irqsave(&mux_lock, flags);
451
452 reg = pg_readl(pingroups[pg].pupd_reg);
453 reg &= ~(0x3 << pingroups[pg].pupd_bit);
454 reg |= pupd << pingroups[pg].pupd_bit;
455 pg_writel(reg, pingroups[pg].pupd_reg);
456
457 spin_unlock_irqrestore(&mux_lock, flags);
458
459 return 0;
460}
461
462static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
463{
464 enum tegra_pingroup pingroup = config->pingroup;
465 enum tegra_mux_func func = config->func;
466 enum tegra_pullupdown pupd = config->pupd;
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
473 int err;
474
475 if (pingroups[pingroup].mux_reg > 0) {
476 err = tegra_pinmux_set_func(config);
477 if (err < 0)
478 pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
479 pingroup_name(pingroup), func_name(func), err);
480 }
481
482 if (pingroups[pingroup].pupd_reg > 0) {
483 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
484 if (err < 0)
485 pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
486 pingroup_name(pingroup), pupd_name(pupd), err);
487 }
488
489 if (pingroups[pingroup].tri_reg > 0) {
490 err = tegra_pinmux_set_tristate(pingroup, tristate);
491 if (err < 0)
492 pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
493 pingroup_name(pingroup), tri_name(func), err);
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
518}
519
520void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
521{
522 int i;
523
524 for (i = 0; i < len; i++)
525 tegra_pinmux_config_pingroup(&config[i]);
526}
527EXPORT_SYMBOL(tegra_pinmux_config_table);
528
529static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
530{
531 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
532 return "<UNKNOWN>";
533
534 return drive_pingroups[pg].name;
535}
536
537static const char *enable_name(unsigned long val)
538{
539 return val ? "ENABLE" : "DISABLE";
540}
541
542static const char *drive_name(unsigned long val)
543{
544 if (val >= TEGRA_MAX_DRIVE)
545 return "<UNKNOWN>";
546
547 return tegra_drive_names[val];
548}
549
550static const char *slew_name(unsigned long val)
551{
552 if (val >= TEGRA_MAX_SLEW)
553 return "<UNKNOWN>";
554
555 return tegra_slew_names[val];
556}
557
558static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
559 enum tegra_hsm hsm)
560{
561 unsigned long flags;
562 u32 reg;
563 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
564 return -ERANGE;
565
566 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
567 return -EINVAL;
568
569 spin_lock_irqsave(&mux_lock, flags);
570
571 reg = pg_readl(drive_pingroups[pg].reg);
572 if (hsm == TEGRA_HSM_ENABLE)
573 reg |= (1 << 2);
574 else
575 reg &= ~(1 << 2);
576 pg_writel(reg, drive_pingroups[pg].reg);
577
578 spin_unlock_irqrestore(&mux_lock, flags);
579
580 return 0;
581}
582
583static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
584 enum tegra_schmitt schmitt)
585{
586 unsigned long flags;
587 u32 reg;
588 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
589 return -ERANGE;
590
591 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
592 return -EINVAL;
593
594 spin_lock_irqsave(&mux_lock, flags);
595
596 reg = pg_readl(drive_pingroups[pg].reg);
597 if (schmitt == TEGRA_SCHMITT_ENABLE)
598 reg |= (1 << 3);
599 else
600 reg &= ~(1 << 3);
601 pg_writel(reg, drive_pingroups[pg].reg);
602
603 spin_unlock_irqrestore(&mux_lock, flags);
604
605 return 0;
606}
607
608static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
609 enum tegra_drive drive)
610{
611 unsigned long flags;
612 u32 reg;
613 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
614 return -ERANGE;
615
616 if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
617 return -EINVAL;
618
619 spin_lock_irqsave(&mux_lock, flags);
620
621 reg = pg_readl(drive_pingroups[pg].reg);
622 reg &= ~(0x3 << 4);
623 reg |= drive << 4;
624 pg_writel(reg, drive_pingroups[pg].reg);
625
626 spin_unlock_irqrestore(&mux_lock, flags);
627
628 return 0;
629}
630
631static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
632 enum tegra_pull_strength pull_down)
633{
634 unsigned long flags;
635 u32 reg;
636
637 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
638 return -ERANGE;
639
640 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
641 return -EINVAL;
642
643 spin_lock_irqsave(&mux_lock, flags);
644
645 reg = pg_readl(drive_pingroups[pg].reg);
646 reg &= ~(drive_pingroups[pg].drvdown_mask <<
647 drive_pingroups[pg].drvdown_offset);
648 reg |= pull_down << drive_pingroups[pg].drvdown_offset;
649 pg_writel(reg, drive_pingroups[pg].reg);
650
651 spin_unlock_irqrestore(&mux_lock, flags);
652
653 return 0;
654}
655
656static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
657 enum tegra_pull_strength pull_up)
658{
659 unsigned long flags;
660 u32 reg;
661
662 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
663 return -ERANGE;
664
665 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
666 return -EINVAL;
667
668 spin_lock_irqsave(&mux_lock, flags);
669
670 reg = pg_readl(drive_pingroups[pg].reg);
671 reg &= ~(drive_pingroups[pg].drvup_mask <<
672 drive_pingroups[pg].drvup_offset);
673 reg |= pull_up << drive_pingroups[pg].drvup_offset;
674 pg_writel(reg, drive_pingroups[pg].reg);
675
676 spin_unlock_irqrestore(&mux_lock, flags);
677
678 return 0;
679}
680
681static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
682 enum tegra_slew slew_rising)
683{
684 unsigned long flags;
685 u32 reg;
686 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
687 return -ERANGE;
688
689 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
690 return -EINVAL;
691
692 spin_lock_irqsave(&mux_lock, flags);
693
694 reg = pg_readl(drive_pingroups[pg].reg);
695 reg &= ~(drive_pingroups[pg].slewrise_mask <<
696 drive_pingroups[pg].slewrise_offset);
697 reg |= slew_rising << drive_pingroups[pg].slewrise_offset;
698 pg_writel(reg, drive_pingroups[pg].reg);
699
700 spin_unlock_irqrestore(&mux_lock, flags);
701
702 return 0;
703}
704
705static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
706 enum tegra_slew slew_falling)
707{
708 unsigned long flags;
709 u32 reg;
710 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
711 return -ERANGE;
712
713 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
714 return -EINVAL;
715
716 spin_lock_irqsave(&mux_lock, flags);
717
718 reg = pg_readl(drive_pingroups[pg].reg);
719 reg &= ~(drive_pingroups[pg].slewfall_mask <<
720 drive_pingroups[pg].slewfall_offset);
721 reg |= slew_falling << drive_pingroups[pg].slewfall_offset;
722 pg_writel(reg, drive_pingroups[pg].reg);
723
724 spin_unlock_irqrestore(&mux_lock, flags);
725
726 return 0;
727}
728
729static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
730 enum tegra_hsm hsm,
731 enum tegra_schmitt schmitt,
732 enum tegra_drive drive,
733 enum tegra_pull_strength pull_down,
734 enum tegra_pull_strength pull_up,
735 enum tegra_slew slew_rising,
736 enum tegra_slew slew_falling)
737{
738 int err;
739
740 err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
741 if (err < 0)
742 pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
743 drive_pinmux_name(pingroup),
744 enable_name(hsm), err);
745
746 err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
747 if (err < 0)
748 pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
749 drive_pinmux_name(pingroup),
750 enable_name(schmitt), err);
751
752 err = tegra_drive_pinmux_set_drive(pingroup, drive);
753 if (err < 0)
754 pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
755 drive_pinmux_name(pingroup),
756 drive_name(drive), err);
757
758 err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
759 if (err < 0)
760 pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
761 drive_pinmux_name(pingroup),
762 pull_down, err);
763
764 err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
765 if (err < 0)
766 pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
767 drive_pinmux_name(pingroup),
768 pull_up, err);
769
770 err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
771 if (err < 0)
772 pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
773 drive_pinmux_name(pingroup),
774 slew_name(slew_rising), err);
775
776 err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
777 if (err < 0)
778 pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
779 drive_pinmux_name(pingroup),
780 slew_name(slew_falling), err);
781}
782
783void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
784 int len)
785{
786 int i;
787
788 for (i = 0; i < len; i++)
789 tegra_drive_pinmux_config_pingroup(config[i].pingroup,
790 config[i].hsm,
791 config[i].schmitt,
792 config[i].drive,
793 config[i].pull_down,
794 config[i].pull_up,
795 config[i].slew_rising,
796 config[i].slew_falling);
797}
798
799void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
800 int len)
801{
802 int i;
803 struct tegra_pingroup_config c;
804
805 for (i = 0; i < len; i++) {
806 int err;
807 c = config[i];
808 if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) {
809 WARN_ON(1);
810 continue;
811 }
812 c.func = pingroups[c.pingroup].func_safe;
813 err = tegra_pinmux_set_func(&c);
814 if (err < 0)
815 pr_err("%s: tegra_pinmux_set_func returned %d setting "
816 "%s to %s\n", __func__, err,
817 pingroup_name(c.pingroup), func_name(c.func));
818 }
819}
820
821void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
822 int len)
823{
824 int i;
825
826 for (i = 0; i < len; i++) {
827 int err;
828 if (config[i].pingroup < 0 ||
829 config[i].pingroup >= TEGRA_MAX_PINGROUP) {
830 WARN_ON(1);
831 continue;
832 }
833 err = tegra_pinmux_set_func(&config[i]);
834 if (err < 0)
835 pr_err("%s: tegra_pinmux_set_func returned %d setting "
836 "%s to %s\n", __func__, err,
837 pingroup_name(config[i].pingroup),
838 func_name(config[i].func));
839 }
840}
841
842void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
843 int len, enum tegra_tristate tristate)
844{
845 int i;
846 int err;
847 enum tegra_pingroup pingroup;
848
849 for (i = 0; i < len; i++) {
850 pingroup = config[i].pingroup;
851 if (pingroups[pingroup].tri_reg > 0) {
852 err = tegra_pinmux_set_tristate(pingroup, tristate);
853 if (err < 0)
854 pr_err("pinmux: can't set pingroup %s tristate"
855 " to %s: %d\n", pingroup_name(pingroup),
856 tri_name(tristate), err);
857 }
858 }
859}
860
861void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
862 int len, enum tegra_pullupdown pupd)
863{
864 int i;
865 int err;
866 enum tegra_pingroup pingroup;
867
868 for (i = 0; i < len; i++) {
869 pingroup = config[i].pingroup;
870 if (pingroups[pingroup].pupd_reg > 0) {
871 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
872 if (err < 0)
873 pr_err("pinmux: can't set pingroup %s pullupdown"
874 " to %s: %d\n", pingroup_name(pingroup),
875 pupd_name(pupd), err);
876 }
877 }
878}
879
880#ifdef CONFIG_DEBUG_FS
881
882#include <linux/debugfs.h>
883#include <linux/seq_file.h>
884
885static void dbg_pad_field(struct seq_file *s, int len)
886{
887 seq_putc(s, ',');
888
889 while (len-- > -1)
890 seq_putc(s, ' ');
891}
892
893static int dbg_pinmux_show(struct seq_file *s, void *unused)
894{
895 int i;
896 int len;
897
898 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
899 unsigned long tri;
900 unsigned long mux;
901 unsigned long pupd;
902
903 seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
904 len = strlen(pingroups[i].name);
905 dbg_pad_field(s, 15 - len);
906
907 if (pingroups[i].mux_reg <= 0) {
908 seq_printf(s, "TEGRA_MUX_NONE");
909 len = strlen("NONE");
910 } else {
911 mux = (pg_readl(pingroups[i].mux_reg) >>
912 pingroups[i].mux_bit) & 0x3;
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) {
918 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
919 len = 5;
920 } else {
921 BUG_ON(!tegra_mux_names[pingroups[i].funcs[mux]]);
922 seq_printf(s, "TEGRA_MUX_%s",
923 tegra_mux_names[pingroups[i].funcs[mux]]);
924 len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
925 }
926 }
927 dbg_pad_field(s, 13-len);
928
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) {
939 seq_printf(s, "TEGRA_PUPD_NORMAL");
940 len = strlen("NORMAL");
941 } else {
942 pupd = (pg_readl(pingroups[i].pupd_reg) >>
943 pingroups[i].pupd_bit) & 0x3;
944 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
945 len = strlen(pupd_name(pupd));
946 }
947 dbg_pad_field(s, 9 - len);
948
949 if (pingroups[i].tri_reg <= 0) {
950 seq_printf(s, "TEGRA_TRI_NORMAL");
951 } else {
952 tri = (pg_readl(pingroups[i].tri_reg) >>
953 pingroups[i].tri_bit) & 0x1;
954
955 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
956 }
957 seq_printf(s, "},\n");
958 }
959 return 0;
960}
961
962static int dbg_pinmux_open(struct inode *inode, struct file *file)
963{
964 return single_open(file, dbg_pinmux_show, &inode->i_private);
965}
966
967static const struct file_operations debug_fops = {
968 .open = dbg_pinmux_open,
969 .read = seq_read,
970 .llseek = seq_lseek,
971 .release = single_release,
972};
973
974static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
975{
976 int i;
977 int len;
978 u8 offset;
979
980 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
981 u32 reg;
982
983 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
984 drive_pingroups[i].name);
985 len = strlen(drive_pingroups[i].name);
986 dbg_pad_field(s, 7 - len);
987
988
989 reg = pg_readl(drive_pingroups[i].reg);
990 if (HSM_EN(reg)) {
991 seq_printf(s, "TEGRA_HSM_ENABLE");
992 len = 16;
993 } else {
994 seq_printf(s, "TEGRA_HSM_DISABLE");
995 len = 17;
996 }
997 dbg_pad_field(s, 17 - len);
998
999 if (SCHMT_EN(reg)) {
1000 seq_printf(s, "TEGRA_SCHMITT_ENABLE");
1001 len = 21;
1002 } else {
1003 seq_printf(s, "TEGRA_SCHMITT_DISABLE");
1004 len = 22;
1005 }
1006 dbg_pad_field(s, 22 - len);
1007
1008 seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
1009 len = strlen(drive_name(LPMD(reg)));
1010 dbg_pad_field(s, 5 - len);
1011
1012 offset = drive_pingroups[i].drvdown_offset;
1013 seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg, offset));
1014 len = DRVDN(reg, offset) < 10 ? 1 : 2;
1015 dbg_pad_field(s, 2 - len);
1016
1017 offset = drive_pingroups[i].drvup_offset;
1018 seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg, offset));
1019 len = DRVUP(reg, offset) < 10 ? 1 : 2;
1020 dbg_pad_field(s, 2 - len);
1021
1022 offset = drive_pingroups[i].slewrise_offset;
1023 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg, offset)));
1024 len = strlen(slew_name(SLWR(reg, offset)));
1025 dbg_pad_field(s, 7 - len);
1026
1027 offset= drive_pingroups[i].slewfall_offset;
1028 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg, offset)));
1029
1030 seq_printf(s, "},\n");
1031 }
1032 return 0;
1033}
1034
1035static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
1036{
1037 return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
1038}
1039
1040static const struct file_operations debug_drive_fops = {
1041 .open = dbg_drive_pinmux_open,
1042 .read = seq_read,
1043 .llseek = seq_lseek,
1044 .release = single_release,
1045};
1046
1047static int __init tegra_pinmux_debuginit(void)
1048{
1049 (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
1050 NULL, NULL, &debug_fops);
1051 (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
1052 NULL, NULL, &debug_drive_fops);
1053 return 0;
1054}
1055late_initcall(tegra_pinmux_debuginit);
1056#endif