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.c153
1 files changed, 107 insertions, 46 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index 1d201650d7a4..ac35d2b76850 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -21,6 +21,7 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/of_device.h>
24 25
25#include <mach/iomap.h> 26#include <mach/iomap.h>
26#include <mach/pinmux.h> 27#include <mach/pinmux.h>
@@ -33,8 +34,10 @@
33#define SLWR(reg) (((reg) >> 28) & 0x3) 34#define SLWR(reg) (((reg) >> 28) & 0x3)
34#define SLWF(reg) (((reg) >> 30) & 0x3) 35#define SLWF(reg) (((reg) >> 30) & 0x3)
35 36
36static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups; 37static const struct tegra_pingroup_desc *pingroups;
37static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups; 38static const struct tegra_drive_pingroup_desc *drive_pingroups;
39static int pingroup_max;
40static int drive_max;
38 41
39static char *tegra_mux_names[TEGRA_MAX_MUX] = { 42static char *tegra_mux_names[TEGRA_MAX_MUX] = {
40 [TEGRA_MUX_AHB_CLK] = "AHB_CLK", 43 [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
@@ -97,6 +100,49 @@ static char *tegra_mux_names[TEGRA_MAX_MUX] = {
97 [TEGRA_MUX_VI] = "VI", 100 [TEGRA_MUX_VI] = "VI",
98 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK", 101 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
99 [TEGRA_MUX_XIO] = "XIO", 102 [TEGRA_MUX_XIO] = "XIO",
103 [TEGRA_MUX_BLINK] = "BLINK",
104 [TEGRA_MUX_CEC] = "CEC",
105 [TEGRA_MUX_CLK12] = "CLK12",
106 [TEGRA_MUX_DAP] = "DAP",
107 [TEGRA_MUX_DAPSDMMC2] = "DAPSDMMC2",
108 [TEGRA_MUX_DDR] = "DDR",
109 [TEGRA_MUX_DEV3] = "DEV3",
110 [TEGRA_MUX_DTV] = "DTV",
111 [TEGRA_MUX_VI_ALT1] = "VI_ALT1",
112 [TEGRA_MUX_VI_ALT2] = "VI_ALT2",
113 [TEGRA_MUX_VI_ALT3] = "VI_ALT3",
114 [TEGRA_MUX_EMC_DLL] = "EMC_DLL",
115 [TEGRA_MUX_EXTPERIPH1] = "EXTPERIPH1",
116 [TEGRA_MUX_EXTPERIPH2] = "EXTPERIPH2",
117 [TEGRA_MUX_EXTPERIPH3] = "EXTPERIPH3",
118 [TEGRA_MUX_GMI_ALT] = "GMI_ALT",
119 [TEGRA_MUX_HDA] = "HDA",
120 [TEGRA_MUX_HSI] = "HSI",
121 [TEGRA_MUX_I2C4] = "I2C4",
122 [TEGRA_MUX_I2C5] = "I2C5",
123 [TEGRA_MUX_I2CPWR] = "I2CPWR",
124 [TEGRA_MUX_I2S0] = "I2S0",
125 [TEGRA_MUX_I2S1] = "I2S1",
126 [TEGRA_MUX_I2S2] = "I2S2",
127 [TEGRA_MUX_I2S3] = "I2S3",
128 [TEGRA_MUX_I2S4] = "I2S4",
129 [TEGRA_MUX_NAND_ALT] = "NAND_ALT",
130 [TEGRA_MUX_POPSDIO4] = "POPSDIO4",
131 [TEGRA_MUX_POPSDMMC4] = "POPSDMMC4",
132 [TEGRA_MUX_PWM0] = "PWM0",
133 [TEGRA_MUX_PWM1] = "PWM2",
134 [TEGRA_MUX_PWM2] = "PWM2",
135 [TEGRA_MUX_PWM3] = "PWM3",
136 [TEGRA_MUX_SATA] = "SATA",
137 [TEGRA_MUX_SPI5] = "SPI5",
138 [TEGRA_MUX_SPI6] = "SPI6",
139 [TEGRA_MUX_SYSCLK] = "SYSCLK",
140 [TEGRA_MUX_VGP1] = "VGP1",
141 [TEGRA_MUX_VGP2] = "VGP2",
142 [TEGRA_MUX_VGP3] = "VGP3",
143 [TEGRA_MUX_VGP4] = "VGP4",
144 [TEGRA_MUX_VGP5] = "VGP5",
145 [TEGRA_MUX_VGP6] = "VGP6",
100 [TEGRA_MUX_SAFE] = "<safe>", 146 [TEGRA_MUX_SAFE] = "<safe>",
101}; 147};
102 148
@@ -116,9 +162,9 @@ static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
116 162
117static DEFINE_SPINLOCK(mux_lock); 163static DEFINE_SPINLOCK(mux_lock);
118 164
119static const char *pingroup_name(enum tegra_pingroup pg) 165static const char *pingroup_name(int pg)
120{ 166{
121 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 167 if (pg < 0 || pg >= pingroup_max)
122 return "<UNKNOWN>"; 168 return "<UNKNOWN>";
123 169
124 return pingroups[pg].name; 170 return pingroups[pg].name;
@@ -189,10 +235,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
189 int i; 235 int i;
190 unsigned long reg; 236 unsigned long reg;
191 unsigned long flags; 237 unsigned long flags;
192 enum tegra_pingroup pg = config->pingroup; 238 int pg = config->pingroup;
193 enum tegra_mux_func func = config->func; 239 enum tegra_mux_func func = config->func;
194 240
195 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 241 if (pg < 0 || pg >= pingroup_max)
196 return -ERANGE; 242 return -ERANGE;
197 243
198 if (pingroups[pg].mux_reg < 0) 244 if (pingroups[pg].mux_reg < 0)
@@ -230,13 +276,12 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
230 return 0; 276 return 0;
231} 277}
232 278
233int tegra_pinmux_set_tristate(enum tegra_pingroup pg, 279int tegra_pinmux_set_tristate(int pg, enum tegra_tristate tristate)
234 enum tegra_tristate tristate)
235{ 280{
236 unsigned long reg; 281 unsigned long reg;
237 unsigned long flags; 282 unsigned long flags;
238 283
239 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 284 if (pg < 0 || pg >= pingroup_max)
240 return -ERANGE; 285 return -ERANGE;
241 286
242 if (pingroups[pg].tri_reg < 0) 287 if (pingroups[pg].tri_reg < 0)
@@ -255,13 +300,12 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
255 return 0; 300 return 0;
256} 301}
257 302
258int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, 303int tegra_pinmux_set_pullupdown(int pg, enum tegra_pullupdown pupd)
259 enum tegra_pullupdown pupd)
260{ 304{
261 unsigned long reg; 305 unsigned long reg;
262 unsigned long flags; 306 unsigned long flags;
263 307
264 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 308 if (pg < 0 || pg >= pingroup_max)
265 return -ERANGE; 309 return -ERANGE;
266 310
267 if (pingroups[pg].pupd_reg < 0) 311 if (pingroups[pg].pupd_reg < 0)
@@ -287,7 +331,7 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
287 331
288static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config) 332static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
289{ 333{
290 enum tegra_pingroup pingroup = config->pingroup; 334 int pingroup = config->pingroup;
291 enum tegra_mux_func func = config->func; 335 enum tegra_mux_func func = config->func;
292 enum tegra_pullupdown pupd = config->pupd; 336 enum tegra_pullupdown pupd = config->pupd;
293 enum tegra_tristate tristate = config->tristate; 337 enum tegra_tristate tristate = config->tristate;
@@ -323,9 +367,9 @@ void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int l
323 tegra_pinmux_config_pingroup(&config[i]); 367 tegra_pinmux_config_pingroup(&config[i]);
324} 368}
325 369
326static const char *drive_pinmux_name(enum tegra_drive_pingroup pg) 370static const char *drive_pinmux_name(int pg)
327{ 371{
328 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 372 if (pg < 0 || pg >= drive_max)
329 return "<UNKNOWN>"; 373 return "<UNKNOWN>";
330 374
331 return drive_pingroups[pg].name; 375 return drive_pingroups[pg].name;
@@ -352,12 +396,11 @@ static const char *slew_name(unsigned long val)
352 return tegra_slew_names[val]; 396 return tegra_slew_names[val];
353} 397}
354 398
355static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg, 399static int tegra_drive_pinmux_set_hsm(int pg, enum tegra_hsm hsm)
356 enum tegra_hsm hsm)
357{ 400{
358 unsigned long flags; 401 unsigned long flags;
359 u32 reg; 402 u32 reg;
360 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 403 if (pg < 0 || pg >= drive_max)
361 return -ERANGE; 404 return -ERANGE;
362 405
363 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE) 406 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
@@ -377,12 +420,11 @@ static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
377 return 0; 420 return 0;
378} 421}
379 422
380static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg, 423static int tegra_drive_pinmux_set_schmitt(int pg, enum tegra_schmitt schmitt)
381 enum tegra_schmitt schmitt)
382{ 424{
383 unsigned long flags; 425 unsigned long flags;
384 u32 reg; 426 u32 reg;
385 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 427 if (pg < 0 || pg >= drive_max)
386 return -ERANGE; 428 return -ERANGE;
387 429
388 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE) 430 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
@@ -402,12 +444,11 @@ static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
402 return 0; 444 return 0;
403} 445}
404 446
405static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg, 447static int tegra_drive_pinmux_set_drive(int pg, enum tegra_drive drive)
406 enum tegra_drive drive)
407{ 448{
408 unsigned long flags; 449 unsigned long flags;
409 u32 reg; 450 u32 reg;
410 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 451 if (pg < 0 || pg >= drive_max)
411 return -ERANGE; 452 return -ERANGE;
412 453
413 if (drive < 0 || drive >= TEGRA_MAX_DRIVE) 454 if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
@@ -425,12 +466,12 @@ static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
425 return 0; 466 return 0;
426} 467}
427 468
428static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg, 469static int tegra_drive_pinmux_set_pull_down(int pg,
429 enum tegra_pull_strength pull_down) 470 enum tegra_pull_strength pull_down)
430{ 471{
431 unsigned long flags; 472 unsigned long flags;
432 u32 reg; 473 u32 reg;
433 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 474 if (pg < 0 || pg >= drive_max)
434 return -ERANGE; 475 return -ERANGE;
435 476
436 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL) 477 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
@@ -448,12 +489,12 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
448 return 0; 489 return 0;
449} 490}
450 491
451static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg, 492static int tegra_drive_pinmux_set_pull_up(int pg,
452 enum tegra_pull_strength pull_up) 493 enum tegra_pull_strength pull_up)
453{ 494{
454 unsigned long flags; 495 unsigned long flags;
455 u32 reg; 496 u32 reg;
456 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 497 if (pg < 0 || pg >= drive_max)
457 return -ERANGE; 498 return -ERANGE;
458 499
459 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL) 500 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
@@ -471,12 +512,12 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
471 return 0; 512 return 0;
472} 513}
473 514
474static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg, 515static int tegra_drive_pinmux_set_slew_rising(int pg,
475 enum tegra_slew slew_rising) 516 enum tegra_slew slew_rising)
476{ 517{
477 unsigned long flags; 518 unsigned long flags;
478 u32 reg; 519 u32 reg;
479 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 520 if (pg < 0 || pg >= drive_max)
480 return -ERANGE; 521 return -ERANGE;
481 522
482 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW) 523 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
@@ -494,12 +535,12 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
494 return 0; 535 return 0;
495} 536}
496 537
497static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg, 538static int tegra_drive_pinmux_set_slew_falling(int pg,
498 enum tegra_slew slew_falling) 539 enum tegra_slew slew_falling)
499{ 540{
500 unsigned long flags; 541 unsigned long flags;
501 u32 reg; 542 u32 reg;
502 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 543 if (pg < 0 || pg >= drive_max)
503 return -ERANGE; 544 return -ERANGE;
504 545
505 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW) 546 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
@@ -517,7 +558,7 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
517 return 0; 558 return 0;
518} 559}
519 560
520static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup, 561static void tegra_drive_pinmux_config_pingroup(int pingroup,
521 enum tegra_hsm hsm, 562 enum tegra_hsm hsm,
522 enum tegra_schmitt schmitt, 563 enum tegra_schmitt schmitt,
523 enum tegra_drive drive, 564 enum tegra_drive drive,
@@ -596,7 +637,7 @@ void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *conf
596 for (i = 0; i < len; i++) { 637 for (i = 0; i < len; i++) {
597 int err; 638 int err;
598 c = config[i]; 639 c = config[i];
599 if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) { 640 if (c.pingroup < 0 || c.pingroup >= pingroup_max) {
600 WARN_ON(1); 641 WARN_ON(1);
601 continue; 642 continue;
602 } 643 }
@@ -617,7 +658,7 @@ void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config
617 for (i = 0; i < len; i++) { 658 for (i = 0; i < len; i++) {
618 int err; 659 int err;
619 if (config[i].pingroup < 0 || 660 if (config[i].pingroup < 0 ||
620 config[i].pingroup >= TEGRA_MAX_PINGROUP) { 661 config[i].pingroup >= pingroup_max) {
621 WARN_ON(1); 662 WARN_ON(1);
622 continue; 663 continue;
623 } 664 }
@@ -635,7 +676,7 @@ void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *conf
635{ 676{
636 int i; 677 int i;
637 int err; 678 int err;
638 enum tegra_pingroup pingroup; 679 int pingroup;
639 680
640 for (i = 0; i < len; i++) { 681 for (i = 0; i < len; i++) {
641 pingroup = config[i].pingroup; 682 pingroup = config[i].pingroup;
@@ -654,7 +695,7 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
654{ 695{
655 int i; 696 int i;
656 int err; 697 int err;
657 enum tegra_pingroup pingroup; 698 int pingroup;
658 699
659 for (i = 0; i < len; i++) { 700 for (i = 0; i < len; i++) {
660 pingroup = config[i].pingroup; 701 pingroup = config[i].pingroup;
@@ -668,11 +709,36 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
668 } 709 }
669} 710}
670 711
712static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
713#ifdef CONFIG_ARCH_TEGRA_2x_SOC
714 { .compatible = "nvidia,tegra20-pinmux", tegra20_pinmux_init },
715#endif
716#ifdef CONFIG_ARCH_TEGRA_3x_SOC
717 { .compatible = "nvidia,tegra30-pinmux", tegra30_pinmux_init },
718#endif
719 { },
720};
721
671static int __devinit tegra_pinmux_probe(struct platform_device *pdev) 722static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
672{ 723{
673 struct resource *res; 724 struct resource *res;
674 int i; 725 int i;
675 int config_bad = 0; 726 int config_bad = 0;
727 const struct of_device_id *match;
728
729 match = of_match_device(tegra_pinmux_of_match, &pdev->dev);
730
731 if (match)
732 ((pinmux_init)(match->data))(&pingroups, &pingroup_max,
733 &drive_pingroups, &drive_max);
734#ifdef CONFIG_ARCH_TEGRA_2x_SOC
735 else
736 /* no device tree available, so we must be on tegra20 */
737 tegra20_pinmux_init(&pingroups, &pingroup_max,
738 &drive_pingroups, &drive_max);
739#else
740 pr_warn("non Tegra20 platform requires pinmux devicetree node\n");
741#endif
676 742
677 for (i = 0; ; i++) { 743 for (i = 0; ; i++) {
678 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 744 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
@@ -681,7 +747,7 @@ static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
681 } 747 }
682 nbanks = i; 748 nbanks = i;
683 749
684 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { 750 for (i = 0; i < pingroup_max; i++) {
685 if (pingroups[i].tri_bank >= nbanks) { 751 if (pingroups[i].tri_bank >= nbanks) {
686 dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i); 752 dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i);
687 config_bad = 1; 753 config_bad = 1;
@@ -698,7 +764,7 @@ static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
698 } 764 }
699 } 765 }
700 766
701 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) { 767 for (i = 0; i < drive_max; i++) {
702 if (drive_pingroups[i].reg_bank >= nbanks) { 768 if (drive_pingroups[i].reg_bank >= nbanks) {
703 dev_err(&pdev->dev, 769 dev_err(&pdev->dev,
704 "drive pingroup %d: bad reg_bank\n", i); 770 "drive pingroup %d: bad reg_bank\n", i);
@@ -741,11 +807,6 @@ static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
741 return 0; 807 return 0;
742} 808}
743 809
744static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
745 { .compatible = "nvidia,tegra20-pinmux", },
746 { },
747};
748
749static struct platform_driver tegra_pinmux_driver = { 810static struct platform_driver tegra_pinmux_driver = {
750 .driver = { 811 .driver = {
751 .name = "tegra-pinmux", 812 .name = "tegra-pinmux",
@@ -779,7 +840,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
779 int i; 840 int i;
780 int len; 841 int len;
781 842
782 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { 843 for (i = 0; i < pingroup_max; i++) {
783 unsigned long reg; 844 unsigned long reg;
784 unsigned long tri; 845 unsigned long tri;
785 unsigned long mux; 846 unsigned long mux;
@@ -850,7 +911,7 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
850 int i; 911 int i;
851 int len; 912 int len;
852 913
853 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) { 914 for (i = 0; i < drive_max; i++) {
854 u32 reg; 915 u32 reg;
855 916
856 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s", 917 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",