diff options
Diffstat (limited to 'arch/arm/mach-imx')
38 files changed, 9784 insertions, 7 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 11235ef10436..59c97a331136 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -1,5 +1,15 @@ | |||
1 | config IMX_HAVE_DMA_V1 | 1 | config IMX_HAVE_DMA_V1 |
2 | bool | 2 | bool |
3 | # | ||
4 | # ARCH_MX31 and ARCH_MX35 are left for compatibility | ||
5 | # Some usages assume that having one of them implies not having (e.g.) ARCH_MX2. | ||
6 | # To easily distinguish good and reviewed from unreviewed usages new (and IMHO | ||
7 | # more sensible) names are used: SOC_IMX31 and SOC_IMX35 | ||
8 | config ARCH_MX31 | ||
9 | bool | ||
10 | |||
11 | config ARCH_MX35 | ||
12 | bool | ||
3 | 13 | ||
4 | config SOC_IMX1 | 14 | config SOC_IMX1 |
5 | bool | 15 | bool |
@@ -31,6 +41,24 @@ config SOC_IMX27 | |||
31 | select IMX_HAVE_IOMUX_V1 | 41 | select IMX_HAVE_IOMUX_V1 |
32 | select MXC_AVIC | 42 | select MXC_AVIC |
33 | 43 | ||
44 | config SOC_IMX31 | ||
45 | bool | ||
46 | select CPU_V6 | ||
47 | select IMX_HAVE_PLATFORM_MXC_RNGA | ||
48 | select ARCH_MXC_AUDMUX_V2 | ||
49 | select ARCH_MX31 | ||
50 | select MXC_AVIC | ||
51 | |||
52 | config SOC_IMX35 | ||
53 | bool | ||
54 | select CPU_V6 | ||
55 | select ARCH_MXC_IOMUX_V3 | ||
56 | select ARCH_MXC_AUDMUX_V2 | ||
57 | select HAVE_EPIT | ||
58 | select ARCH_MX35 | ||
59 | select MXC_AVIC | ||
60 | |||
61 | |||
34 | if ARCH_MX1 | 62 | if ARCH_MX1 |
35 | 63 | ||
36 | comment "MX1 platforms:" | 64 | comment "MX1 platforms:" |
@@ -324,3 +352,251 @@ config MACH_IMX27IPCAM | |||
324 | configurations for the board and its peripherals. | 352 | configurations for the board and its peripherals. |
325 | 353 | ||
326 | endif | 354 | endif |
355 | |||
356 | if ARCH_MX3 | ||
357 | |||
358 | comment "MX31 platforms:" | ||
359 | |||
360 | config MACH_MX31ADS | ||
361 | bool "Support MX31ADS platforms" | ||
362 | select SOC_IMX31 | ||
363 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
364 | select IMX_HAVE_PLATFORM_IMX_SSI | ||
365 | select IMX_HAVE_PLATFORM_IMX_UART | ||
366 | default y | ||
367 | help | ||
368 | Include support for MX31ADS platform. This includes specific | ||
369 | configurations for the board and its peripherals. | ||
370 | |||
371 | config MACH_MX31ADS_WM1133_EV1 | ||
372 | bool "Support Wolfson Microelectronics 1133-EV1 module" | ||
373 | depends on MACH_MX31ADS | ||
374 | depends on MFD_WM8350_I2C | ||
375 | depends on REGULATOR_WM8350 | ||
376 | select MFD_WM8350_CONFIG_MODE_0 | ||
377 | select MFD_WM8352_CONFIG_MODE_0 | ||
378 | help | ||
379 | Include support for the Wolfson Microelectronics 1133-EV1 PMU | ||
380 | and audio module for the MX31ADS platform. | ||
381 | |||
382 | config MACH_MX31LILLY | ||
383 | bool "Support MX31 LILLY-1131 platforms (INCO startec)" | ||
384 | select SOC_IMX31 | ||
385 | select IMX_HAVE_PLATFORM_IMX_UART | ||
386 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
387 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
388 | select IMX_HAVE_PLATFORM_MXC_MMC | ||
389 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
390 | select MXC_ULPI if USB_ULPI | ||
391 | help | ||
392 | Include support for mx31 based LILLY1131 modules. This includes | ||
393 | specific configurations for the board and its peripherals. | ||
394 | |||
395 | config MACH_MX31LITE | ||
396 | bool "Support MX31 LITEKIT (LogicPD)" | ||
397 | select SOC_IMX31 | ||
398 | select MXC_ULPI if USB_ULPI | ||
399 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
400 | select IMX_HAVE_PLATFORM_IMX_UART | ||
401 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
402 | select IMX_HAVE_PLATFORM_MXC_MMC | ||
403 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
404 | select IMX_HAVE_PLATFORM_MXC_RTC | ||
405 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
406 | help | ||
407 | Include support for MX31 LITEKIT platform. This includes specific | ||
408 | configurations for the board and its peripherals. | ||
409 | |||
410 | config MACH_PCM037 | ||
411 | bool "Support Phytec pcm037 (i.MX31) platforms" | ||
412 | select SOC_IMX31 | ||
413 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
414 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
415 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
416 | select IMX_HAVE_PLATFORM_IMX_UART | ||
417 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
418 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
419 | select IMX_HAVE_PLATFORM_MXC_MMC | ||
420 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
421 | select IMX_HAVE_PLATFORM_MXC_W1 | ||
422 | select MXC_ULPI if USB_ULPI | ||
423 | help | ||
424 | Include support for Phytec pcm037 platform. This includes | ||
425 | specific configurations for the board and its peripherals. | ||
426 | |||
427 | config MACH_PCM037_EET | ||
428 | bool "Support pcm037 EET board extensions" | ||
429 | depends on MACH_PCM037 | ||
430 | select IMX_HAVE_PLATFORM_GPIO_KEYS | ||
431 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
432 | help | ||
433 | Add support for PCM037 EET baseboard extensions. If you are using the | ||
434 | OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel | ||
435 | command-line parameter. | ||
436 | |||
437 | config MACH_MX31_3DS | ||
438 | bool "Support MX31PDK (3DS)" | ||
439 | select SOC_IMX31 | ||
440 | select MXC_DEBUG_BOARD | ||
441 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
442 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
443 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
444 | select IMX_HAVE_PLATFORM_IMX_KEYPAD | ||
445 | select IMX_HAVE_PLATFORM_IMX_UART | ||
446 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
447 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
448 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
449 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
450 | select MXC_ULPI if USB_ULPI | ||
451 | help | ||
452 | Include support for MX31PDK (3DS) platform. This includes specific | ||
453 | configurations for the board and its peripherals. | ||
454 | |||
455 | config MACH_MX31_3DS_MXC_NAND_USE_BBT | ||
456 | bool "Make the MXC NAND driver use the in flash Bad Block Table" | ||
457 | depends on MACH_MX31_3DS | ||
458 | depends on MTD_NAND_MXC | ||
459 | help | ||
460 | Enable this if you want that the MXC NAND driver uses the in flash | ||
461 | Bad Block Table to know what blocks are bad instead of scanning the | ||
462 | entire flash looking for bad block markers. | ||
463 | |||
464 | config MACH_MX31MOBOARD | ||
465 | bool "Support mx31moboard platforms (EPFL Mobots group)" | ||
466 | select SOC_IMX31 | ||
467 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
468 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
469 | select IMX_HAVE_PLATFORM_IMX_UART | ||
470 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
471 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
472 | select IMX_HAVE_PLATFORM_MXC_MMC | ||
473 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
474 | select MXC_ULPI if USB_ULPI | ||
475 | help | ||
476 | Include support for mx31moboard platform. This includes specific | ||
477 | configurations for the board and its peripherals. | ||
478 | |||
479 | config MACH_QONG | ||
480 | bool "Support Dave/DENX QongEVB-LITE platform" | ||
481 | select SOC_IMX31 | ||
482 | select IMX_HAVE_PLATFORM_IMX_UART | ||
483 | help | ||
484 | Include support for Dave/DENX QongEVB-LITE platform. This includes | ||
485 | specific configurations for the board and its peripherals. | ||
486 | |||
487 | config MACH_ARMADILLO5X0 | ||
488 | bool "Support Atmark Armadillo-500 Development Base Board" | ||
489 | select SOC_IMX31 | ||
490 | select IMX_HAVE_PLATFORM_GPIO_KEYS | ||
491 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
492 | select IMX_HAVE_PLATFORM_IMX_UART | ||
493 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
494 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
495 | select IMX_HAVE_PLATFORM_MXC_MMC | ||
496 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
497 | select MXC_ULPI if USB_ULPI | ||
498 | help | ||
499 | Include support for Atmark Armadillo-500 platform. This includes | ||
500 | specific configurations for the board and its peripherals. | ||
501 | |||
502 | config MACH_KZM_ARM11_01 | ||
503 | bool "Support KZM-ARM11-01(Kyoto Microcomputer)" | ||
504 | select SOC_IMX31 | ||
505 | select IMX_HAVE_PLATFORM_IMX_UART | ||
506 | help | ||
507 | Include support for KZM-ARM11-01. This includes specific | ||
508 | configurations for the board and its peripherals. | ||
509 | |||
510 | config MACH_BUG | ||
511 | bool "Support Buglabs BUGBase platform" | ||
512 | select SOC_IMX31 | ||
513 | select IMX_HAVE_PLATFORM_IMX_UART | ||
514 | default y | ||
515 | help | ||
516 | Include support for BUGBase 1.3 platform. This includes specific | ||
517 | configurations for the board and its peripherals. | ||
518 | |||
519 | comment "MX35 platforms:" | ||
520 | |||
521 | config MACH_PCM043 | ||
522 | bool "Support Phytec pcm043 (i.MX35) platforms" | ||
523 | select SOC_IMX35 | ||
524 | select IMX_HAVE_PLATFORM_FLEXCAN | ||
525 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
526 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
527 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
528 | select IMX_HAVE_PLATFORM_IMX_SSI | ||
529 | select IMX_HAVE_PLATFORM_IMX_UART | ||
530 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
531 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
532 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
533 | select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | ||
534 | select MXC_ULPI if USB_ULPI | ||
535 | help | ||
536 | Include support for Phytec pcm043 platform. This includes | ||
537 | specific configurations for the board and its peripherals. | ||
538 | |||
539 | config MACH_MX35_3DS | ||
540 | bool "Support MX35PDK platform" | ||
541 | select SOC_IMX35 | ||
542 | select MXC_DEBUG_BOARD | ||
543 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
544 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
545 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
546 | select IMX_HAVE_PLATFORM_IMX_UART | ||
547 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
548 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
549 | select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | ||
550 | help | ||
551 | Include support for MX35PDK platform. This includes specific | ||
552 | configurations for the board and its peripherals. | ||
553 | |||
554 | config MACH_EUKREA_CPUIMX35 | ||
555 | bool "Support Eukrea CPUIMX35 Platform" | ||
556 | select SOC_IMX35 | ||
557 | select IMX_HAVE_PLATFORM_FLEXCAN | ||
558 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
559 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
560 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
561 | select IMX_HAVE_PLATFORM_IMX_UART | ||
562 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
563 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
564 | select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | ||
565 | select MXC_ULPI if USB_ULPI | ||
566 | help | ||
567 | Include support for Eukrea CPUIMX35 platform. This includes | ||
568 | specific configurations for the board and its peripherals. | ||
569 | |||
570 | choice | ||
571 | prompt "Baseboard" | ||
572 | depends on MACH_EUKREA_CPUIMX35 | ||
573 | default MACH_EUKREA_MBIMXSD35_BASEBOARD | ||
574 | |||
575 | config MACH_EUKREA_MBIMXSD35_BASEBOARD | ||
576 | bool "Eukrea MBIMXSD development board" | ||
577 | select IMX_HAVE_PLATFORM_GPIO_KEYS | ||
578 | select IMX_HAVE_PLATFORM_IMX_SSI | ||
579 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
580 | help | ||
581 | This adds board specific devices that can be found on Eukrea's | ||
582 | MBIMXSD evaluation board. | ||
583 | |||
584 | endchoice | ||
585 | |||
586 | config MACH_VPR200 | ||
587 | bool "Support VPR200 platform" | ||
588 | select SOC_IMX35 | ||
589 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | ||
590 | select IMX_HAVE_PLATFORM_GPIO_KEYS | ||
591 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
592 | select IMX_HAVE_PLATFORM_IMX_UART | ||
593 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
594 | select IMX_HAVE_PLATFORM_IPU_CORE | ||
595 | select IMX_HAVE_PLATFORM_MXC_EHCI | ||
596 | select IMX_HAVE_PLATFORM_MXC_NAND | ||
597 | select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | ||
598 | help | ||
599 | Include support for VPR200 platform. This includes specific | ||
600 | configurations for the board and its peripherals. | ||
601 | |||
602 | endif | ||
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 270f5f9db92e..e9eb36dad888 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
@@ -1,9 +1,3 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | |||
5 | # Object file lists. | ||
6 | |||
7 | obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o | 1 | obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o |
8 | 2 | ||
9 | obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o | 3 | obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o |
@@ -14,19 +8,27 @@ obj-$(CONFIG_ARCH_MX25) += clock-imx25.o mm-imx25.o ehci-imx25.o | |||
14 | obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o | 8 | obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o |
15 | obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o ehci-imx27.o | 9 | obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o ehci-imx27.o |
16 | 10 | ||
11 | obj-$(CONFIG_SOC_IMX31) += mm-imx31.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o | ||
12 | obj-$(CONFIG_SOC_IMX35) += mm-imx35.o cpu-imx35.o clock-imx35.o ehci-imx35.o | ||
13 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o | ||
14 | |||
17 | # Support for CMOS sensor interface | 15 | # Support for CMOS sensor interface |
18 | obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o | 16 | obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o |
19 | 17 | ||
18 | # i.MX1 based machines | ||
20 | obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o | 19 | obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o |
21 | obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o | 20 | obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o |
22 | obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o | 21 | obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o |
23 | 22 | ||
23 | # i.MX21 based machines | ||
24 | obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o | 24 | obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o |
25 | 25 | ||
26 | # i.MX25 based machines | ||
26 | obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o | 27 | obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o |
27 | obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-eukrea_cpuimx25.o | 28 | obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-eukrea_cpuimx25.o |
28 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o | 29 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o |
29 | 30 | ||
31 | # i.MX27 based machines | ||
30 | obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o | 32 | obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o |
31 | obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o | 33 | obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o |
32 | obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o | 34 | obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o |
@@ -38,3 +40,24 @@ obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o | |||
38 | obj-$(CONFIG_MACH_PCA100) += mach-pca100.o | 40 | obj-$(CONFIG_MACH_PCA100) += mach-pca100.o |
39 | obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o | 41 | obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o |
40 | obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o | 42 | obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o |
43 | |||
44 | # i.MX31 based machines | ||
45 | obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o | ||
46 | obj-$(CONFIG_MACH_MX31LILLY) += mach-mx31lilly.o mx31lilly-db.o | ||
47 | obj-$(CONFIG_MACH_MX31LITE) += mach-mx31lite.o mx31lite-db.o | ||
48 | obj-$(CONFIG_MACH_PCM037) += mach-pcm037.o | ||
49 | obj-$(CONFIG_MACH_PCM037_EET) += mach-pcm037_eet.o | ||
50 | obj-$(CONFIG_MACH_MX31_3DS) += mach-mx31_3ds.o | ||
51 | obj-$(CONFIG_MACH_MX31MOBOARD) += mach-mx31moboard.o mx31moboard-devboard.o \ | ||
52 | mx31moboard-marxbot.o mx31moboard-smartbot.o | ||
53 | obj-$(CONFIG_MACH_QONG) += mach-qong.o | ||
54 | obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o | ||
55 | obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o | ||
56 | obj-$(CONFIG_MACH_BUG) += mach-bug.o | ||
57 | |||
58 | # i.MX35 based machines | ||
59 | obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o | ||
60 | obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o | ||
61 | obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o | ||
62 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o | ||
63 | obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o | ||
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot index 3953d60bff0b..ebee18b3884c 100644 --- a/arch/arm/mach-imx/Makefile.boot +++ b/arch/arm/mach-imx/Makefile.boot | |||
@@ -13,3 +13,7 @@ initrd_phys-$(CONFIG_ARCH_MX25) := 0x80800000 | |||
13 | zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000 | 13 | zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000 |
14 | params_phys-$(CONFIG_MACH_MX27) := 0xA0000100 | 14 | params_phys-$(CONFIG_MACH_MX27) := 0xA0000100 |
15 | initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000 | 15 | initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000 |
16 | |||
17 | zreladdr-$(CONFIG_ARCH_MX3) := 0x80008000 | ||
18 | params_phys-$(CONFIG_ARCH_MX3) := 0x80000100 | ||
19 | initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000 | ||
diff --git a/arch/arm/mach-imx/cache-l2x0.c b/arch/arm/mach-imx/cache-l2x0.c new file mode 100644 index 000000000000..69d1322add3c --- /dev/null +++ b/arch/arm/mach-imx/cache-l2x0.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009-2010 Pengutronix | ||
3 | * Sascha Hauer <s.hauer@pengutronix.de> | ||
4 | * Juergen Beisert <j.beisert@pengutronix.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it under | ||
7 | * the terms of the GNU General Public License version 2 as published by the | ||
8 | * Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/kernel.h> | ||
14 | |||
15 | #include <asm/hardware/cache-l2x0.h> | ||
16 | |||
17 | #include <mach/hardware.h> | ||
18 | |||
19 | static int mxc_init_l2x0(void) | ||
20 | { | ||
21 | void __iomem *l2x0_base; | ||
22 | void __iomem *clkctl_base; | ||
23 | |||
24 | if (!cpu_is_mx31() && !cpu_is_mx35()) | ||
25 | return 0; | ||
26 | |||
27 | /* | ||
28 | * First of all, we must repair broken chip settings. There are some | ||
29 | * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These | ||
30 | * misconfigured CPUs will run amok immediately when the L2 cache gets enabled. | ||
31 | * Workaraound is to setup the correct register setting prior enabling the | ||
32 | * L2 cache. This should not hurt already working CPUs, as they are using the | ||
33 | * same value. | ||
34 | */ | ||
35 | #define L2_MEM_VAL 0x10 | ||
36 | |||
37 | clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096); | ||
38 | if (clkctl_base != NULL) { | ||
39 | writel(0x00000515, clkctl_base + L2_MEM_VAL); | ||
40 | iounmap(clkctl_base); | ||
41 | } else { | ||
42 | pr_err("L2 cache: Cannot fix timing. Trying to continue without\n"); | ||
43 | } | ||
44 | |||
45 | l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096); | ||
46 | if (IS_ERR(l2x0_base)) { | ||
47 | printk(KERN_ERR "remapping L2 cache area failed with %ld\n", | ||
48 | PTR_ERR(l2x0_base)); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | l2x0_init(l2x0_base, 0x00030024, 0x00000000); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | arch_initcall(mxc_init_l2x0); | ||
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c new file mode 100644 index 000000000000..25f343fca2b9 --- /dev/null +++ b/arch/arm/mach-imx/clock-imx31.c | |||
@@ -0,0 +1,629 @@ | |||
1 | /* | ||
2 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | * MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/clkdev.h> | ||
27 | |||
28 | #include <asm/div64.h> | ||
29 | |||
30 | #include <mach/clock.h> | ||
31 | #include <mach/hardware.h> | ||
32 | #include <mach/mx31.h> | ||
33 | #include <mach/common.h> | ||
34 | |||
35 | #include "crmregs-imx31.h" | ||
36 | |||
37 | #define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ | ||
38 | |||
39 | static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) | ||
40 | { | ||
41 | u32 min_pre, temp_pre, old_err, err; | ||
42 | |||
43 | if (div >= 512) { | ||
44 | *pre = 8; | ||
45 | *post = 64; | ||
46 | } else if (div >= 64) { | ||
47 | min_pre = (div - 1) / 64 + 1; | ||
48 | old_err = 8; | ||
49 | for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { | ||
50 | err = div % temp_pre; | ||
51 | if (err == 0) { | ||
52 | *pre = temp_pre; | ||
53 | break; | ||
54 | } | ||
55 | err = temp_pre - err; | ||
56 | if (err < old_err) { | ||
57 | old_err = err; | ||
58 | *pre = temp_pre; | ||
59 | } | ||
60 | } | ||
61 | *post = (div + *pre - 1) / *pre; | ||
62 | } else if (div <= 8) { | ||
63 | *pre = div; | ||
64 | *post = 1; | ||
65 | } else { | ||
66 | *pre = 1; | ||
67 | *post = div; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static struct clk mcu_pll_clk; | ||
72 | static struct clk serial_pll_clk; | ||
73 | static struct clk ipg_clk; | ||
74 | static struct clk ckih_clk; | ||
75 | |||
76 | static int cgr_enable(struct clk *clk) | ||
77 | { | ||
78 | u32 reg; | ||
79 | |||
80 | if (!clk->enable_reg) | ||
81 | return 0; | ||
82 | |||
83 | reg = __raw_readl(clk->enable_reg); | ||
84 | reg |= 3 << clk->enable_shift; | ||
85 | __raw_writel(reg, clk->enable_reg); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static void cgr_disable(struct clk *clk) | ||
91 | { | ||
92 | u32 reg; | ||
93 | |||
94 | if (!clk->enable_reg) | ||
95 | return; | ||
96 | |||
97 | reg = __raw_readl(clk->enable_reg); | ||
98 | reg &= ~(3 << clk->enable_shift); | ||
99 | |||
100 | /* special case for EMI clock */ | ||
101 | if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8) | ||
102 | reg |= (1 << clk->enable_shift); | ||
103 | |||
104 | __raw_writel(reg, clk->enable_reg); | ||
105 | } | ||
106 | |||
107 | static unsigned long pll_ref_get_rate(void) | ||
108 | { | ||
109 | unsigned long ccmr; | ||
110 | unsigned int prcs; | ||
111 | |||
112 | ccmr = __raw_readl(MXC_CCM_CCMR); | ||
113 | prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; | ||
114 | if (prcs == 0x1) | ||
115 | return CKIL_CLK_FREQ * 1024; | ||
116 | else | ||
117 | return clk_get_rate(&ckih_clk); | ||
118 | } | ||
119 | |||
120 | static unsigned long usb_pll_get_rate(struct clk *clk) | ||
121 | { | ||
122 | unsigned long reg; | ||
123 | |||
124 | reg = __raw_readl(MXC_CCM_UPCTL); | ||
125 | |||
126 | return mxc_decode_pll(reg, pll_ref_get_rate()); | ||
127 | } | ||
128 | |||
129 | static unsigned long serial_pll_get_rate(struct clk *clk) | ||
130 | { | ||
131 | unsigned long reg; | ||
132 | |||
133 | reg = __raw_readl(MXC_CCM_SRPCTL); | ||
134 | |||
135 | return mxc_decode_pll(reg, pll_ref_get_rate()); | ||
136 | } | ||
137 | |||
138 | static unsigned long mcu_pll_get_rate(struct clk *clk) | ||
139 | { | ||
140 | unsigned long reg, ccmr; | ||
141 | |||
142 | ccmr = __raw_readl(MXC_CCM_CCMR); | ||
143 | |||
144 | if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS)) | ||
145 | return clk_get_rate(&ckih_clk); | ||
146 | |||
147 | reg = __raw_readl(MXC_CCM_MPCTL); | ||
148 | |||
149 | return mxc_decode_pll(reg, pll_ref_get_rate()); | ||
150 | } | ||
151 | |||
152 | static int usb_pll_enable(struct clk *clk) | ||
153 | { | ||
154 | u32 reg; | ||
155 | |||
156 | reg = __raw_readl(MXC_CCM_CCMR); | ||
157 | reg |= MXC_CCM_CCMR_UPE; | ||
158 | __raw_writel(reg, MXC_CCM_CCMR); | ||
159 | |||
160 | /* No lock bit on MX31, so using max time from spec */ | ||
161 | udelay(80); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static void usb_pll_disable(struct clk *clk) | ||
167 | { | ||
168 | u32 reg; | ||
169 | |||
170 | reg = __raw_readl(MXC_CCM_CCMR); | ||
171 | reg &= ~MXC_CCM_CCMR_UPE; | ||
172 | __raw_writel(reg, MXC_CCM_CCMR); | ||
173 | } | ||
174 | |||
175 | static int serial_pll_enable(struct clk *clk) | ||
176 | { | ||
177 | u32 reg; | ||
178 | |||
179 | reg = __raw_readl(MXC_CCM_CCMR); | ||
180 | reg |= MXC_CCM_CCMR_SPE; | ||
181 | __raw_writel(reg, MXC_CCM_CCMR); | ||
182 | |||
183 | /* No lock bit on MX31, so using max time from spec */ | ||
184 | udelay(80); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void serial_pll_disable(struct clk *clk) | ||
190 | { | ||
191 | u32 reg; | ||
192 | |||
193 | reg = __raw_readl(MXC_CCM_CCMR); | ||
194 | reg &= ~MXC_CCM_CCMR_SPE; | ||
195 | __raw_writel(reg, MXC_CCM_CCMR); | ||
196 | } | ||
197 | |||
198 | #define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off) | ||
199 | #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) | ||
200 | #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) | ||
201 | |||
202 | static unsigned long mcu_main_get_rate(struct clk *clk) | ||
203 | { | ||
204 | u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); | ||
205 | |||
206 | if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) | ||
207 | return clk_get_rate(&serial_pll_clk); | ||
208 | else | ||
209 | return clk_get_rate(&mcu_pll_clk); | ||
210 | } | ||
211 | |||
212 | static unsigned long ahb_get_rate(struct clk *clk) | ||
213 | { | ||
214 | unsigned long max_pdf; | ||
215 | |||
216 | max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK, | ||
217 | MXC_CCM_PDR0_MAX_PODF_OFFSET); | ||
218 | return clk_get_rate(clk->parent) / (max_pdf + 1); | ||
219 | } | ||
220 | |||
221 | static unsigned long ipg_get_rate(struct clk *clk) | ||
222 | { | ||
223 | unsigned long ipg_pdf; | ||
224 | |||
225 | ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK, | ||
226 | MXC_CCM_PDR0_IPG_PODF_OFFSET); | ||
227 | return clk_get_rate(clk->parent) / (ipg_pdf + 1); | ||
228 | } | ||
229 | |||
230 | static unsigned long nfc_get_rate(struct clk *clk) | ||
231 | { | ||
232 | unsigned long nfc_pdf; | ||
233 | |||
234 | nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK, | ||
235 | MXC_CCM_PDR0_NFC_PODF_OFFSET); | ||
236 | return clk_get_rate(clk->parent) / (nfc_pdf + 1); | ||
237 | } | ||
238 | |||
239 | static unsigned long hsp_get_rate(struct clk *clk) | ||
240 | { | ||
241 | unsigned long hsp_pdf; | ||
242 | |||
243 | hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK, | ||
244 | MXC_CCM_PDR0_HSP_PODF_OFFSET); | ||
245 | return clk_get_rate(clk->parent) / (hsp_pdf + 1); | ||
246 | } | ||
247 | |||
248 | static unsigned long usb_get_rate(struct clk *clk) | ||
249 | { | ||
250 | unsigned long usb_pdf, usb_prepdf; | ||
251 | |||
252 | usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK, | ||
253 | MXC_CCM_PDR1_USB_PODF_OFFSET); | ||
254 | usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK, | ||
255 | MXC_CCM_PDR1_USB_PRDF_OFFSET); | ||
256 | return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); | ||
257 | } | ||
258 | |||
259 | static unsigned long csi_get_rate(struct clk *clk) | ||
260 | { | ||
261 | u32 reg, pre, post; | ||
262 | |||
263 | reg = __raw_readl(MXC_CCM_PDR0); | ||
264 | pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >> | ||
265 | MXC_CCM_PDR0_CSI_PRDF_OFFSET; | ||
266 | pre++; | ||
267 | post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >> | ||
268 | MXC_CCM_PDR0_CSI_PODF_OFFSET; | ||
269 | post++; | ||
270 | return clk_get_rate(clk->parent) / (pre * post); | ||
271 | } | ||
272 | |||
273 | static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) | ||
274 | { | ||
275 | u32 pre, post, parent = clk_get_rate(clk->parent); | ||
276 | u32 div = parent / rate; | ||
277 | |||
278 | if (parent % rate) | ||
279 | div++; | ||
280 | |||
281 | __calc_pre_post_dividers(div, &pre, &post); | ||
282 | |||
283 | return parent / (pre * post); | ||
284 | } | ||
285 | |||
286 | static int csi_set_rate(struct clk *clk, unsigned long rate) | ||
287 | { | ||
288 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); | ||
289 | |||
290 | div = parent / rate; | ||
291 | |||
292 | if ((parent / div) != rate) | ||
293 | return -EINVAL; | ||
294 | |||
295 | __calc_pre_post_dividers(div, &pre, &post); | ||
296 | |||
297 | /* Set CSI clock divider */ | ||
298 | reg = __raw_readl(MXC_CCM_PDR0) & | ||
299 | ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK); | ||
300 | reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET; | ||
301 | reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET; | ||
302 | __raw_writel(reg, MXC_CCM_PDR0); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static unsigned long ssi1_get_rate(struct clk *clk) | ||
308 | { | ||
309 | unsigned long ssi1_pdf, ssi1_prepdf; | ||
310 | |||
311 | ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK, | ||
312 | MXC_CCM_PDR1_SSI1_PODF_OFFSET); | ||
313 | ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK, | ||
314 | MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET); | ||
315 | return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); | ||
316 | } | ||
317 | |||
318 | static unsigned long ssi2_get_rate(struct clk *clk) | ||
319 | { | ||
320 | unsigned long ssi2_pdf, ssi2_prepdf; | ||
321 | |||
322 | ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK, | ||
323 | MXC_CCM_PDR1_SSI2_PODF_OFFSET); | ||
324 | ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK, | ||
325 | MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET); | ||
326 | return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); | ||
327 | } | ||
328 | |||
329 | static unsigned long firi_get_rate(struct clk *clk) | ||
330 | { | ||
331 | unsigned long firi_pdf, firi_prepdf; | ||
332 | |||
333 | firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK, | ||
334 | MXC_CCM_PDR1_FIRI_PODF_OFFSET); | ||
335 | firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK, | ||
336 | MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET); | ||
337 | return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); | ||
338 | } | ||
339 | |||
340 | static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) | ||
341 | { | ||
342 | u32 pre, post; | ||
343 | u32 parent = clk_get_rate(clk->parent); | ||
344 | u32 div = parent / rate; | ||
345 | |||
346 | if (parent % rate) | ||
347 | div++; | ||
348 | |||
349 | __calc_pre_post_dividers(div, &pre, &post); | ||
350 | |||
351 | return parent / (pre * post); | ||
352 | |||
353 | } | ||
354 | |||
355 | static int firi_set_rate(struct clk *clk, unsigned long rate) | ||
356 | { | ||
357 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); | ||
358 | |||
359 | div = parent / rate; | ||
360 | |||
361 | if ((parent / div) != rate) | ||
362 | return -EINVAL; | ||
363 | |||
364 | __calc_pre_post_dividers(div, &pre, &post); | ||
365 | |||
366 | /* Set FIRI clock divider */ | ||
367 | reg = __raw_readl(MXC_CCM_PDR1) & | ||
368 | ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK); | ||
369 | reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET; | ||
370 | reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET; | ||
371 | __raw_writel(reg, MXC_CCM_PDR1); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static unsigned long mbx_get_rate(struct clk *clk) | ||
377 | { | ||
378 | return clk_get_rate(clk->parent) / 2; | ||
379 | } | ||
380 | |||
381 | static unsigned long mstick1_get_rate(struct clk *clk) | ||
382 | { | ||
383 | unsigned long msti_pdf; | ||
384 | |||
385 | msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK, | ||
386 | MXC_CCM_PDR2_MST1_PDF_OFFSET); | ||
387 | return clk_get_rate(clk->parent) / (msti_pdf + 1); | ||
388 | } | ||
389 | |||
390 | static unsigned long mstick2_get_rate(struct clk *clk) | ||
391 | { | ||
392 | unsigned long msti_pdf; | ||
393 | |||
394 | msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK, | ||
395 | MXC_CCM_PDR2_MST2_PDF_OFFSET); | ||
396 | return clk_get_rate(clk->parent) / (msti_pdf + 1); | ||
397 | } | ||
398 | |||
399 | static unsigned long ckih_rate; | ||
400 | |||
401 | static unsigned long clk_ckih_get_rate(struct clk *clk) | ||
402 | { | ||
403 | return ckih_rate; | ||
404 | } | ||
405 | |||
406 | static unsigned long clk_ckil_get_rate(struct clk *clk) | ||
407 | { | ||
408 | return CKIL_CLK_FREQ; | ||
409 | } | ||
410 | |||
411 | static struct clk ckih_clk = { | ||
412 | .get_rate = clk_ckih_get_rate, | ||
413 | }; | ||
414 | |||
415 | static struct clk mcu_pll_clk = { | ||
416 | .parent = &ckih_clk, | ||
417 | .get_rate = mcu_pll_get_rate, | ||
418 | }; | ||
419 | |||
420 | static struct clk mcu_main_clk = { | ||
421 | .parent = &mcu_pll_clk, | ||
422 | .get_rate = mcu_main_get_rate, | ||
423 | }; | ||
424 | |||
425 | static struct clk serial_pll_clk = { | ||
426 | .parent = &ckih_clk, | ||
427 | .get_rate = serial_pll_get_rate, | ||
428 | .enable = serial_pll_enable, | ||
429 | .disable = serial_pll_disable, | ||
430 | }; | ||
431 | |||
432 | static struct clk usb_pll_clk = { | ||
433 | .parent = &ckih_clk, | ||
434 | .get_rate = usb_pll_get_rate, | ||
435 | .enable = usb_pll_enable, | ||
436 | .disable = usb_pll_disable, | ||
437 | }; | ||
438 | |||
439 | static struct clk ahb_clk = { | ||
440 | .parent = &mcu_main_clk, | ||
441 | .get_rate = ahb_get_rate, | ||
442 | }; | ||
443 | |||
444 | #define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ | ||
445 | static struct clk name = { \ | ||
446 | .id = i, \ | ||
447 | .enable_reg = er, \ | ||
448 | .enable_shift = es, \ | ||
449 | .get_rate = gr, \ | ||
450 | .enable = cgr_enable, \ | ||
451 | .disable = cgr_disable, \ | ||
452 | .secondary = s, \ | ||
453 | .parent = p, \ | ||
454 | } | ||
455 | |||
456 | #define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ | ||
457 | static struct clk name = { \ | ||
458 | .id = i, \ | ||
459 | .enable_reg = er, \ | ||
460 | .enable_shift = es, \ | ||
461 | .get_rate = getsetround##_get_rate, \ | ||
462 | .set_rate = getsetround##_set_rate, \ | ||
463 | .round_rate = getsetround##_round_rate, \ | ||
464 | .enable = cgr_enable, \ | ||
465 | .disable = cgr_disable, \ | ||
466 | .secondary = s, \ | ||
467 | .parent = p, \ | ||
468 | } | ||
469 | |||
470 | DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
471 | DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); | ||
472 | |||
473 | DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); | ||
474 | DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); | ||
475 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk); | ||
476 | DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); | ||
477 | DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); | ||
478 | DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); | ||
479 | DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); | ||
480 | DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk); | ||
481 | DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); | ||
482 | DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); | ||
483 | DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); | ||
484 | DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk); | ||
485 | DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk); | ||
486 | DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk); | ||
487 | DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk); | ||
488 | DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk); | ||
489 | |||
490 | DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); | ||
491 | DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); | ||
492 | DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); | ||
493 | DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); | ||
494 | DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk); | ||
495 | DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); | ||
496 | DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); | ||
497 | DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); | ||
498 | DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk); | ||
499 | DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk); | ||
500 | DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk); | ||
501 | DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk); | ||
502 | DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk); | ||
503 | DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk); | ||
504 | |||
505 | DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk); | ||
506 | DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk); | ||
507 | DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk); | ||
508 | DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk); | ||
509 | DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk); | ||
510 | DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk); | ||
511 | DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk); | ||
512 | |||
513 | DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
514 | DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk); | ||
515 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); | ||
516 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
517 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); | ||
518 | |||
519 | #define _REGISTER_CLOCK(d, n, c) \ | ||
520 | { \ | ||
521 | .dev_id = d, \ | ||
522 | .con_id = n, \ | ||
523 | .clk = &c, \ | ||
524 | }, | ||
525 | |||
526 | static struct clk_lookup lookups[] = { | ||
527 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
528 | _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk) | ||
529 | _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk) | ||
530 | _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk) | ||
531 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
532 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | ||
533 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) | ||
534 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
535 | _REGISTER_CLOCK(NULL, "epit", epit1_clk) | ||
536 | _REGISTER_CLOCK(NULL, "epit", epit2_clk) | ||
537 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
538 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) | ||
539 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) | ||
540 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
541 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1) | ||
542 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2) | ||
543 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1) | ||
544 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2) | ||
545 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1) | ||
546 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2) | ||
547 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) | ||
548 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) | ||
549 | _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) | ||
550 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | ||
551 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | ||
552 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | ||
553 | _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) | ||
554 | _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) | ||
555 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
556 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
557 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) | ||
558 | _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) | ||
559 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) | ||
560 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) | ||
561 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
562 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
563 | _REGISTER_CLOCK(NULL, "firi", firi_clk) | ||
564 | _REGISTER_CLOCK(NULL, "ata", ata_clk) | ||
565 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
566 | _REGISTER_CLOCK(NULL, "rng", rng_clk) | ||
567 | _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1) | ||
568 | _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) | ||
569 | _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) | ||
570 | _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) | ||
571 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
572 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
573 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) | ||
574 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) | ||
575 | }; | ||
576 | |||
577 | int __init mx31_clocks_init(unsigned long fref) | ||
578 | { | ||
579 | u32 reg; | ||
580 | |||
581 | ckih_rate = fref; | ||
582 | |||
583 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
584 | |||
585 | /* change the csi_clk parent if necessary */ | ||
586 | reg = __raw_readl(MXC_CCM_CCMR); | ||
587 | if (!(reg & MXC_CCM_CCMR_CSCS)) | ||
588 | if (clk_set_parent(&csi_clk, &usb_pll_clk)) | ||
589 | pr_err("%s: error changing csi_clk parent\n", __func__); | ||
590 | |||
591 | |||
592 | /* Turn off all possible clocks */ | ||
593 | __raw_writel((3 << 4), MXC_CCM_CGR0); | ||
594 | __raw_writel(0, MXC_CCM_CGR1); | ||
595 | __raw_writel((3 << 8) | (3 << 14) | (3 << 16)| | ||
596 | 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for | ||
597 | MX32, but still required to be set */ | ||
598 | MXC_CCM_CGR2); | ||
599 | |||
600 | /* | ||
601 | * Before turning off usb_pll make sure ipg_per_clk is generated | ||
602 | * by ipg_clk and not usb_pll. | ||
603 | */ | ||
604 | __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR); | ||
605 | |||
606 | usb_pll_disable(&usb_pll_clk); | ||
607 | |||
608 | pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); | ||
609 | |||
610 | clk_enable(&gpt_clk); | ||
611 | clk_enable(&emi_clk); | ||
612 | clk_enable(&iim_clk); | ||
613 | |||
614 | clk_enable(&serial_pll_clk); | ||
615 | |||
616 | mx31_read_cpu_rev(); | ||
617 | |||
618 | if (mx31_revision() >= IMX_CHIP_REVISION_2_0) { | ||
619 | reg = __raw_readl(MXC_CCM_PMCR1); | ||
620 | /* No PLL restart on DVFS switch; enable auto EMI handshake */ | ||
621 | reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN; | ||
622 | __raw_writel(reg, MXC_CCM_PMCR1); | ||
623 | } | ||
624 | |||
625 | mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), | ||
626 | MX31_INT_GPT); | ||
627 | |||
628 | return 0; | ||
629 | } | ||
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c new file mode 100644 index 000000000000..5a4cc1ea405b --- /dev/null +++ b/arch/arm/mach-imx/clock-imx35.c | |||
@@ -0,0 +1,549 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 by Sascha Hauer, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
16 | * MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | |||
26 | #include <mach/clock.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/common.h> | ||
29 | |||
30 | #define CCM_BASE MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR) | ||
31 | |||
32 | #define CCM_CCMR 0x00 | ||
33 | #define CCM_PDR0 0x04 | ||
34 | #define CCM_PDR1 0x08 | ||
35 | #define CCM_PDR2 0x0C | ||
36 | #define CCM_PDR3 0x10 | ||
37 | #define CCM_PDR4 0x14 | ||
38 | #define CCM_RCSR 0x18 | ||
39 | #define CCM_MPCTL 0x1C | ||
40 | #define CCM_PPCTL 0x20 | ||
41 | #define CCM_ACMR 0x24 | ||
42 | #define CCM_COSR 0x28 | ||
43 | #define CCM_CGR0 0x2C | ||
44 | #define CCM_CGR1 0x30 | ||
45 | #define CCM_CGR2 0x34 | ||
46 | #define CCM_CGR3 0x38 | ||
47 | |||
48 | #ifdef HAVE_SET_RATE_SUPPORT | ||
49 | static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost) | ||
50 | { | ||
51 | u32 min_pre, temp_pre, old_err, err; | ||
52 | |||
53 | min_pre = (div - 1) / maxpost + 1; | ||
54 | old_err = 8; | ||
55 | |||
56 | for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { | ||
57 | if (div > (temp_pre * maxpost)) | ||
58 | break; | ||
59 | |||
60 | if (div < (temp_pre * temp_pre)) | ||
61 | continue; | ||
62 | |||
63 | err = div % temp_pre; | ||
64 | |||
65 | if (err == 0) { | ||
66 | *pre = temp_pre; | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | err = temp_pre - err; | ||
71 | |||
72 | if (err < old_err) { | ||
73 | old_err = err; | ||
74 | *pre = temp_pre; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | *post = (div + *pre - 1) / *pre; | ||
79 | } | ||
80 | |||
81 | /* get the best values for a 3-bit divider combined with a 6-bit divider */ | ||
82 | static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post) | ||
83 | { | ||
84 | if (div >= 512) { | ||
85 | *pre = 8; | ||
86 | *post = 64; | ||
87 | } else if (div >= 64) { | ||
88 | calc_dividers(div, pre, post, 64); | ||
89 | } else if (div <= 8) { | ||
90 | *pre = div; | ||
91 | *post = 1; | ||
92 | } else { | ||
93 | *pre = 1; | ||
94 | *post = div; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* get the best values for two cascaded 3-bit dividers */ | ||
99 | static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post) | ||
100 | { | ||
101 | if (div >= 64) { | ||
102 | *pre = *post = 8; | ||
103 | } else if (div > 8) { | ||
104 | calc_dividers(div, pre, post, 8); | ||
105 | } else { | ||
106 | *pre = 1; | ||
107 | *post = div; | ||
108 | } | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | static unsigned long get_rate_mpll(void) | ||
113 | { | ||
114 | ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL); | ||
115 | |||
116 | return mxc_decode_pll(mpctl, 24000000); | ||
117 | } | ||
118 | |||
119 | static unsigned long get_rate_ppll(void) | ||
120 | { | ||
121 | ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL); | ||
122 | |||
123 | return mxc_decode_pll(ppctl, 24000000); | ||
124 | } | ||
125 | |||
126 | struct arm_ahb_div { | ||
127 | unsigned char arm, ahb, sel; | ||
128 | }; | ||
129 | |||
130 | static struct arm_ahb_div clk_consumer[] = { | ||
131 | { .arm = 1, .ahb = 4, .sel = 0}, | ||
132 | { .arm = 1, .ahb = 3, .sel = 1}, | ||
133 | { .arm = 2, .ahb = 2, .sel = 0}, | ||
134 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
135 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
136 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
137 | { .arm = 4, .ahb = 1, .sel = 0}, | ||
138 | { .arm = 1, .ahb = 5, .sel = 0}, | ||
139 | { .arm = 1, .ahb = 8, .sel = 0}, | ||
140 | { .arm = 1, .ahb = 6, .sel = 1}, | ||
141 | { .arm = 2, .ahb = 4, .sel = 0}, | ||
142 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
143 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
144 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
145 | { .arm = 4, .ahb = 2, .sel = 0}, | ||
146 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
147 | }; | ||
148 | |||
149 | static unsigned long get_rate_arm(void) | ||
150 | { | ||
151 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | ||
152 | struct arm_ahb_div *aad; | ||
153 | unsigned long fref = get_rate_mpll(); | ||
154 | |||
155 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | ||
156 | if (aad->sel) | ||
157 | fref = fref * 3 / 4; | ||
158 | |||
159 | return fref / aad->arm; | ||
160 | } | ||
161 | |||
162 | static unsigned long get_rate_ahb(struct clk *clk) | ||
163 | { | ||
164 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | ||
165 | struct arm_ahb_div *aad; | ||
166 | unsigned long fref = get_rate_arm(); | ||
167 | |||
168 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | ||
169 | |||
170 | return fref / aad->ahb; | ||
171 | } | ||
172 | |||
173 | static unsigned long get_rate_ipg(struct clk *clk) | ||
174 | { | ||
175 | return get_rate_ahb(NULL) >> 1; | ||
176 | } | ||
177 | |||
178 | static unsigned long get_rate_uart(struct clk *clk) | ||
179 | { | ||
180 | unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); | ||
181 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | ||
182 | unsigned long div = ((pdr4 >> 10) & 0x3f) + 1; | ||
183 | |||
184 | if (pdr3 & (1 << 14)) | ||
185 | return get_rate_arm() / div; | ||
186 | else | ||
187 | return get_rate_ppll() / div; | ||
188 | } | ||
189 | |||
190 | static unsigned long get_rate_sdhc(struct clk *clk) | ||
191 | { | ||
192 | unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); | ||
193 | unsigned long div, rate; | ||
194 | |||
195 | if (pdr3 & (1 << 6)) | ||
196 | rate = get_rate_arm(); | ||
197 | else | ||
198 | rate = get_rate_ppll(); | ||
199 | |||
200 | switch (clk->id) { | ||
201 | default: | ||
202 | case 0: | ||
203 | div = pdr3 & 0x3f; | ||
204 | break; | ||
205 | case 1: | ||
206 | div = (pdr3 >> 8) & 0x3f; | ||
207 | break; | ||
208 | case 2: | ||
209 | div = (pdr3 >> 16) & 0x3f; | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | return rate / (div + 1); | ||
214 | } | ||
215 | |||
216 | static unsigned long get_rate_mshc(struct clk *clk) | ||
217 | { | ||
218 | unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1); | ||
219 | unsigned long div1, div2, rate; | ||
220 | |||
221 | if (pdr1 & (1 << 7)) | ||
222 | rate = get_rate_arm(); | ||
223 | else | ||
224 | rate = get_rate_ppll(); | ||
225 | |||
226 | div1 = (pdr1 >> 29) & 0x7; | ||
227 | div2 = (pdr1 >> 22) & 0x3f; | ||
228 | |||
229 | return rate / ((div1 + 1) * (div2 + 1)); | ||
230 | } | ||
231 | |||
232 | static unsigned long get_rate_ssi(struct clk *clk) | ||
233 | { | ||
234 | unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); | ||
235 | unsigned long div1, div2, rate; | ||
236 | |||
237 | if (pdr2 & (1 << 6)) | ||
238 | rate = get_rate_arm(); | ||
239 | else | ||
240 | rate = get_rate_ppll(); | ||
241 | |||
242 | switch (clk->id) { | ||
243 | default: | ||
244 | case 0: | ||
245 | div1 = pdr2 & 0x3f; | ||
246 | div2 = (pdr2 >> 24) & 0x7; | ||
247 | break; | ||
248 | case 1: | ||
249 | div1 = (pdr2 >> 8) & 0x3f; | ||
250 | div2 = (pdr2 >> 27) & 0x7; | ||
251 | break; | ||
252 | } | ||
253 | |||
254 | return rate / ((div1 + 1) * (div2 + 1)); | ||
255 | } | ||
256 | |||
257 | static unsigned long get_rate_csi(struct clk *clk) | ||
258 | { | ||
259 | unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); | ||
260 | unsigned long rate; | ||
261 | |||
262 | if (pdr2 & (1 << 7)) | ||
263 | rate = get_rate_arm(); | ||
264 | else | ||
265 | rate = get_rate_ppll(); | ||
266 | |||
267 | return rate / (((pdr2 >> 16) & 0x3f) + 1); | ||
268 | } | ||
269 | |||
270 | static unsigned long get_rate_otg(struct clk *clk) | ||
271 | { | ||
272 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | ||
273 | unsigned long rate; | ||
274 | |||
275 | if (pdr4 & (1 << 9)) | ||
276 | rate = get_rate_arm(); | ||
277 | else | ||
278 | rate = get_rate_ppll(); | ||
279 | |||
280 | return rate / (((pdr4 >> 22) & 0x3f) + 1); | ||
281 | } | ||
282 | |||
283 | static unsigned long get_rate_ipg_per(struct clk *clk) | ||
284 | { | ||
285 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | ||
286 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | ||
287 | unsigned long div; | ||
288 | |||
289 | if (pdr0 & (1 << 26)) { | ||
290 | div = (pdr4 >> 16) & 0x3f; | ||
291 | return get_rate_arm() / (div + 1); | ||
292 | } else { | ||
293 | div = (pdr0 >> 12) & 0x7; | ||
294 | return get_rate_ahb(NULL) / (div + 1); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | static unsigned long get_rate_hsp(struct clk *clk) | ||
299 | { | ||
300 | unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03; | ||
301 | unsigned long fref = get_rate_mpll(); | ||
302 | |||
303 | if (fref > 400 * 1000 * 1000) { | ||
304 | switch (hsp_podf) { | ||
305 | case 0: | ||
306 | return fref >> 2; | ||
307 | case 1: | ||
308 | return fref >> 3; | ||
309 | case 2: | ||
310 | return fref / 3; | ||
311 | } | ||
312 | } else { | ||
313 | switch (hsp_podf) { | ||
314 | case 0: | ||
315 | case 2: | ||
316 | return fref / 3; | ||
317 | case 1: | ||
318 | return fref / 6; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int clk_cgr_enable(struct clk *clk) | ||
326 | { | ||
327 | u32 reg; | ||
328 | |||
329 | reg = __raw_readl(clk->enable_reg); | ||
330 | reg |= 3 << clk->enable_shift; | ||
331 | __raw_writel(reg, clk->enable_reg); | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static void clk_cgr_disable(struct clk *clk) | ||
337 | { | ||
338 | u32 reg; | ||
339 | |||
340 | reg = __raw_readl(clk->enable_reg); | ||
341 | reg &= ~(3 << clk->enable_shift); | ||
342 | __raw_writel(reg, clk->enable_reg); | ||
343 | } | ||
344 | |||
345 | #define DEFINE_CLOCK(name, i, er, es, gr, sr) \ | ||
346 | static struct clk name = { \ | ||
347 | .id = i, \ | ||
348 | .enable_reg = CCM_BASE + er, \ | ||
349 | .enable_shift = es, \ | ||
350 | .get_rate = gr, \ | ||
351 | .set_rate = sr, \ | ||
352 | .enable = clk_cgr_enable, \ | ||
353 | .disable = clk_cgr_disable, \ | ||
354 | } | ||
355 | |||
356 | DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL); | ||
357 | DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL); | ||
358 | /* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); */ | ||
359 | DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL); | ||
360 | DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL); | ||
361 | DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL); | ||
362 | DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL); | ||
363 | DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL); | ||
364 | DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL); | ||
365 | DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL); | ||
366 | DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL); | ||
367 | DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL); | ||
368 | DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL); | ||
369 | DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL); | ||
370 | DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL); | ||
371 | DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL); | ||
372 | |||
373 | DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL); | ||
374 | DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL); | ||
375 | DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL); | ||
376 | DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL); | ||
377 | DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL); | ||
378 | DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL); | ||
379 | DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); | ||
380 | DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); | ||
381 | DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); | ||
382 | DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_hsp, NULL); | ||
383 | DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); | ||
384 | DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); | ||
385 | DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); | ||
386 | DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL); | ||
387 | DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL); | ||
388 | DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL); | ||
389 | |||
390 | DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL); | ||
391 | DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL); | ||
392 | DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL); | ||
393 | DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL); | ||
394 | DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL); | ||
395 | DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL); | ||
396 | DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL); | ||
397 | DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL); | ||
398 | DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); | ||
399 | DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); | ||
400 | DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); | ||
401 | DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL); | ||
402 | DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); | ||
403 | DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); | ||
404 | DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL); | ||
405 | |||
406 | DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL); | ||
407 | DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL); | ||
408 | DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); | ||
409 | |||
410 | DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL); | ||
411 | |||
412 | static int clk_dummy_enable(struct clk *clk) | ||
413 | { | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static void clk_dummy_disable(struct clk *clk) | ||
418 | { | ||
419 | } | ||
420 | |||
421 | static unsigned long get_rate_nfc(struct clk *clk) | ||
422 | { | ||
423 | unsigned long div1; | ||
424 | |||
425 | div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1; | ||
426 | |||
427 | return get_rate_ahb(NULL) / div1; | ||
428 | } | ||
429 | |||
430 | /* NAND Controller: It seems it can't be disabled */ | ||
431 | static struct clk nfc_clk = { | ||
432 | .id = 0, | ||
433 | .enable_reg = 0, | ||
434 | .enable_shift = 0, | ||
435 | .get_rate = get_rate_nfc, | ||
436 | .set_rate = NULL, /* set_rate_nfc, */ | ||
437 | .enable = clk_dummy_enable, | ||
438 | .disable = clk_dummy_disable | ||
439 | }; | ||
440 | |||
441 | #define _REGISTER_CLOCK(d, n, c) \ | ||
442 | { \ | ||
443 | .dev_id = d, \ | ||
444 | .con_id = n, \ | ||
445 | .clk = &c, \ | ||
446 | }, | ||
447 | |||
448 | static struct clk_lookup lookups[] = { | ||
449 | _REGISTER_CLOCK(NULL, "asrc", asrc_clk) | ||
450 | _REGISTER_CLOCK(NULL, "ata", ata_clk) | ||
451 | _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) | ||
452 | _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) | ||
453 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) | ||
454 | _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) | ||
455 | _REGISTER_CLOCK(NULL, "ect", ect_clk) | ||
456 | _REGISTER_CLOCK(NULL, "edio", edio_clk) | ||
457 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
458 | _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk) | ||
459 | _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk) | ||
460 | _REGISTER_CLOCK(NULL, "esai", esai_clk) | ||
461 | _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) | ||
462 | _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) | ||
463 | _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk) | ||
464 | _REGISTER_CLOCK("fec.0", NULL, fec_clk) | ||
465 | _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) | ||
466 | _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) | ||
467 | _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) | ||
468 | _REGISTER_CLOCK("gpt.0", NULL, gpt_clk) | ||
469 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
470 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
471 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) | ||
472 | _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) | ||
473 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) | ||
474 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) | ||
475 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
476 | _REGISTER_CLOCK(NULL, "mlb", mlb_clk) | ||
477 | _REGISTER_CLOCK(NULL, "mshc", mshc_clk) | ||
478 | _REGISTER_CLOCK("mxc_w1", NULL, owire_clk) | ||
479 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | ||
480 | _REGISTER_CLOCK(NULL, "rngc", rngc_clk) | ||
481 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
482 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
483 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
484 | _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) | ||
485 | _REGISTER_CLOCK(NULL, "spba", spba_clk) | ||
486 | _REGISTER_CLOCK(NULL, "spdif", spdif_clk) | ||
487 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
488 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
489 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | ||
490 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | ||
491 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | ||
492 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) | ||
493 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) | ||
494 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) | ||
495 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) | ||
496 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk) | ||
497 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) | ||
498 | _REGISTER_CLOCK(NULL, "max", max_clk) | ||
499 | _REGISTER_CLOCK(NULL, "audmux", audmux_clk) | ||
500 | _REGISTER_CLOCK(NULL, "csi", csi_clk) | ||
501 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
502 | _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) | ||
503 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
504 | }; | ||
505 | |||
506 | int __init mx35_clocks_init() | ||
507 | { | ||
508 | unsigned int cgr2 = 3 << 26, cgr3 = 0; | ||
509 | |||
510 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) | ||
511 | cgr2 |= 3 << 16; | ||
512 | #endif | ||
513 | |||
514 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
515 | |||
516 | /* Turn off all clocks except the ones we need to survive, namely: | ||
517 | * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart | ||
518 | */ | ||
519 | __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); | ||
520 | __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), | ||
521 | CCM_BASE + CCM_CGR1); | ||
522 | |||
523 | /* | ||
524 | * Check if we came up in internal boot mode. If yes, we need some | ||
525 | * extra clocks turned on, otherwise the MX35 boot ROM code will | ||
526 | * hang after a watchdog reset. | ||
527 | */ | ||
528 | if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) { | ||
529 | /* Additionally turn on UART1, SCC, and IIM clocks */ | ||
530 | cgr2 |= 3 << 16 | 3 << 4; | ||
531 | cgr3 |= 3 << 2; | ||
532 | } | ||
533 | |||
534 | __raw_writel(cgr2, CCM_BASE + CCM_CGR2); | ||
535 | __raw_writel(cgr3, CCM_BASE + CCM_CGR3); | ||
536 | |||
537 | clk_enable(&iim_clk); | ||
538 | mx35_read_cpu_rev(); | ||
539 | |||
540 | #ifdef CONFIG_MXC_USE_EPIT | ||
541 | epit_timer_init(&epit1_clk, | ||
542 | MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); | ||
543 | #else | ||
544 | mxc_timer_init(&gpt_clk, | ||
545 | MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); | ||
546 | #endif | ||
547 | |||
548 | return 0; | ||
549 | } | ||
diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c new file mode 100644 index 000000000000..a3780700a882 --- /dev/null +++ b/arch/arm/mach-imx/cpu-imx31.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * MX31 CPU type detection | ||
3 | * | ||
4 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <mach/hardware.h> | ||
15 | #include <mach/iim.h> | ||
16 | |||
17 | unsigned int mx31_cpu_rev; | ||
18 | EXPORT_SYMBOL(mx31_cpu_rev); | ||
19 | |||
20 | static struct { | ||
21 | u8 srev; | ||
22 | const char *name; | ||
23 | const char *v; | ||
24 | unsigned int rev; | ||
25 | } mx31_cpu_type[] __initdata = { | ||
26 | { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = IMX_CHIP_REVISION_1_0 }, | ||
27 | { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = IMX_CHIP_REVISION_1_1 }, | ||
28 | { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = IMX_CHIP_REVISION_1_1 }, | ||
29 | { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = IMX_CHIP_REVISION_1_1 }, | ||
30 | { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = IMX_CHIP_REVISION_1_1 }, | ||
31 | { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = IMX_CHIP_REVISION_1_2 }, | ||
32 | { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = IMX_CHIP_REVISION_1_2 }, | ||
33 | { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = IMX_CHIP_REVISION_2_0 }, | ||
34 | { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = IMX_CHIP_REVISION_2_0 }, | ||
35 | }; | ||
36 | |||
37 | void __init mx31_read_cpu_rev(void) | ||
38 | { | ||
39 | u32 i, srev; | ||
40 | |||
41 | /* read SREV register from IIM module */ | ||
42 | srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); | ||
43 | |||
44 | for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) | ||
45 | if (srev == mx31_cpu_type[i].srev) { | ||
46 | printk(KERN_INFO | ||
47 | "CPU identified as %s, silicon rev %s\n", | ||
48 | mx31_cpu_type[i].name, mx31_cpu_type[i].v); | ||
49 | |||
50 | mx31_cpu_rev = mx31_cpu_type[i].rev; | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | mx31_cpu_rev = IMX_CHIP_REVISION_UNKNOWN; | ||
55 | |||
56 | printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev); | ||
57 | } | ||
diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c new file mode 100644 index 000000000000..6637cd819ecb --- /dev/null +++ b/arch/arm/mach-imx/cpu-imx35.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * MX35 CPU type detection | ||
3 | * | ||
4 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <mach/hardware.h> | ||
14 | #include <mach/iim.h> | ||
15 | |||
16 | unsigned int mx35_cpu_rev; | ||
17 | EXPORT_SYMBOL(mx35_cpu_rev); | ||
18 | |||
19 | void __init mx35_read_cpu_rev(void) | ||
20 | { | ||
21 | u32 rev; | ||
22 | char *srev; | ||
23 | |||
24 | rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); | ||
25 | switch (rev) { | ||
26 | case 0x00: | ||
27 | mx35_cpu_rev = IMX_CHIP_REVISION_1_0; | ||
28 | srev = "1.0"; | ||
29 | break; | ||
30 | case 0x10: | ||
31 | mx35_cpu_rev = IMX_CHIP_REVISION_2_0; | ||
32 | srev = "2.0"; | ||
33 | break; | ||
34 | case 0x11: | ||
35 | mx35_cpu_rev = IMX_CHIP_REVISION_2_1; | ||
36 | srev = "2.1"; | ||
37 | break; | ||
38 | default: | ||
39 | mx35_cpu_rev = IMX_CHIP_REVISION_UNKNOWN; | ||
40 | srev = "unknown"; | ||
41 | } | ||
42 | |||
43 | printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev); | ||
44 | } | ||
diff --git a/arch/arm/mach-imx/crmregs-imx31.h b/arch/arm/mach-imx/crmregs-imx31.h new file mode 100644 index 000000000000..37a8a07beda3 --- /dev/null +++ b/arch/arm/mach-imx/crmregs-imx31.h | |||
@@ -0,0 +1,248 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | * MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__ | ||
21 | #define __ARCH_ARM_MACH_MX3_CRM_REGS_H__ | ||
22 | |||
23 | #define CKIH_CLK_FREQ 26000000 | ||
24 | #define CKIH_CLK_FREQ_27MHZ 27000000 | ||
25 | #define CKIL_CLK_FREQ 32768 | ||
26 | |||
27 | #define MXC_CCM_BASE MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) | ||
28 | |||
29 | /* Register addresses */ | ||
30 | #define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) | ||
31 | #define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04) | ||
32 | #define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08) | ||
33 | #define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C) | ||
34 | #define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10) | ||
35 | #define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14) | ||
36 | #define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18) | ||
37 | #define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C) | ||
38 | #define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20) | ||
39 | #define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24) | ||
40 | #define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28) | ||
41 | #define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C) | ||
42 | #define MXC_CCM_LDC (MXC_CCM_BASE + 0x30) | ||
43 | #define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34) | ||
44 | #define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38) | ||
45 | #define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C) | ||
46 | #define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40) | ||
47 | #define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44) | ||
48 | #define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48) | ||
49 | #define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C) | ||
50 | #define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50) | ||
51 | #define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54) | ||
52 | #define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58) | ||
53 | #define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C) | ||
54 | #define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60) | ||
55 | #define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64) | ||
56 | |||
57 | /* Register bit definitions */ | ||
58 | #define MXC_CCM_CCMR_WBEN (1 << 27) | ||
59 | #define MXC_CCM_CCMR_CSCS (1 << 25) | ||
60 | #define MXC_CCM_CCMR_PERCS (1 << 24) | ||
61 | #define MXC_CCM_CCMR_SSI1S_OFFSET 18 | ||
62 | #define MXC_CCM_CCMR_SSI1S_MASK (0x3 << 18) | ||
63 | #define MXC_CCM_CCMR_SSI2S_OFFSET 21 | ||
64 | #define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21) | ||
65 | #define MXC_CCM_CCMR_LPM_OFFSET 14 | ||
66 | #define MXC_CCM_CCMR_LPM_MASK (0x3 << 14) | ||
67 | #define MXC_CCM_CCMR_FIRS_OFFSET 11 | ||
68 | #define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11) | ||
69 | #define MXC_CCM_CCMR_UPE (1 << 9) | ||
70 | #define MXC_CCM_CCMR_SPE (1 << 8) | ||
71 | #define MXC_CCM_CCMR_MDS (1 << 7) | ||
72 | #define MXC_CCM_CCMR_SBYCS (1 << 4) | ||
73 | #define MXC_CCM_CCMR_MPE (1 << 3) | ||
74 | #define MXC_CCM_CCMR_PRCS_OFFSET 1 | ||
75 | #define MXC_CCM_CCMR_PRCS_MASK (0x3 << 1) | ||
76 | |||
77 | #define MXC_CCM_PDR0_CSI_PODF_OFFSET 26 | ||
78 | #define MXC_CCM_PDR0_CSI_PODF_MASK (0x3F << 26) | ||
79 | #define MXC_CCM_PDR0_CSI_PRDF_OFFSET 23 | ||
80 | #define MXC_CCM_PDR0_CSI_PRDF_MASK (0x7 << 23) | ||
81 | #define MXC_CCM_PDR0_PER_PODF_OFFSET 16 | ||
82 | #define MXC_CCM_PDR0_PER_PODF_MASK (0x1F << 16) | ||
83 | #define MXC_CCM_PDR0_HSP_PODF_OFFSET 11 | ||
84 | #define MXC_CCM_PDR0_HSP_PODF_MASK (0x7 << 11) | ||
85 | #define MXC_CCM_PDR0_NFC_PODF_OFFSET 8 | ||
86 | #define MXC_CCM_PDR0_NFC_PODF_MASK (0x7 << 8) | ||
87 | #define MXC_CCM_PDR0_IPG_PODF_OFFSET 6 | ||
88 | #define MXC_CCM_PDR0_IPG_PODF_MASK (0x3 << 6) | ||
89 | #define MXC_CCM_PDR0_MAX_PODF_OFFSET 3 | ||
90 | #define MXC_CCM_PDR0_MAX_PODF_MASK (0x7 << 3) | ||
91 | #define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 | ||
92 | #define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 | ||
93 | |||
94 | #define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 | ||
95 | #define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) | ||
96 | #define MXC_CCM_PDR1_USB_PODF_OFFSET 27 | ||
97 | #define MXC_CCM_PDR1_USB_PODF_MASK (0x7 << 27) | ||
98 | #define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET 24 | ||
99 | #define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK (0x7 << 24) | ||
100 | #define MXC_CCM_PDR1_FIRI_PODF_OFFSET 18 | ||
101 | #define MXC_CCM_PDR1_FIRI_PODF_MASK (0x3F << 18) | ||
102 | #define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET 15 | ||
103 | #define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK (0x7 << 15) | ||
104 | #define MXC_CCM_PDR1_SSI2_PODF_OFFSET 9 | ||
105 | #define MXC_CCM_PDR1_SSI2_PODF_MASK (0x3F << 9) | ||
106 | #define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET 6 | ||
107 | #define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK (0x7 << 6) | ||
108 | #define MXC_CCM_PDR1_SSI1_PODF_OFFSET 0 | ||
109 | #define MXC_CCM_PDR1_SSI1_PODF_MASK 0x3F | ||
110 | |||
111 | /* Bit definitions for RCSR */ | ||
112 | #define MXC_CCM_RCSR_NF16B 0x80000000 | ||
113 | |||
114 | /* | ||
115 | * LTR0 register offsets | ||
116 | */ | ||
117 | #define MXC_CCM_LTR0_DIV3CK_OFFSET 1 | ||
118 | #define MXC_CCM_LTR0_DIV3CK_MASK (0x3 << 1) | ||
119 | #define MXC_CCM_LTR0_DNTHR_OFFSET 16 | ||
120 | #define MXC_CCM_LTR0_DNTHR_MASK (0x3F << 16) | ||
121 | #define MXC_CCM_LTR0_UPTHR_OFFSET 22 | ||
122 | #define MXC_CCM_LTR0_UPTHR_MASK (0x3F << 22) | ||
123 | |||
124 | /* | ||
125 | * LTR1 register offsets | ||
126 | */ | ||
127 | #define MXC_CCM_LTR1_PNCTHR_OFFSET 0 | ||
128 | #define MXC_CCM_LTR1_PNCTHR_MASK 0x3F | ||
129 | #define MXC_CCM_LTR1_UPCNT_OFFSET 6 | ||
130 | #define MXC_CCM_LTR1_UPCNT_MASK (0xFF << 6) | ||
131 | #define MXC_CCM_LTR1_DNCNT_OFFSET 14 | ||
132 | #define MXC_CCM_LTR1_DNCNT_MASK (0xFF << 14) | ||
133 | #define MXC_CCM_LTR1_LTBRSR_MASK 0x400000 | ||
134 | #define MXC_CCM_LTR1_LTBRSR_OFFSET 22 | ||
135 | #define MXC_CCM_LTR1_LTBRSR 0x400000 | ||
136 | #define MXC_CCM_LTR1_LTBRSH 0x800000 | ||
137 | |||
138 | /* | ||
139 | * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15 | ||
140 | */ | ||
141 | #define MXC_CCM_LTR2_WSW_OFFSET(x) (11 + (x) * 3) | ||
142 | #define MXC_CCM_LTR2_WSW_MASK(x) (0x7 << \ | ||
143 | MXC_CCM_LTR2_WSW_OFFSET((x))) | ||
144 | #define MXC_CCM_LTR2_EMAC_OFFSET 0 | ||
145 | #define MXC_CCM_LTR2_EMAC_MASK 0x1FF | ||
146 | |||
147 | /* | ||
148 | * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8 | ||
149 | */ | ||
150 | #define MXC_CCM_LTR3_WSW_OFFSET(x) (5 + (x) * 3) | ||
151 | #define MXC_CCM_LTR3_WSW_MASK(x) (0x7 << \ | ||
152 | MXC_CCM_LTR3_WSW_OFFSET((x))) | ||
153 | |||
154 | #define MXC_CCM_PMCR0_DFSUP1 0x80000000 | ||
155 | #define MXC_CCM_PMCR0_DFSUP1_SPLL (0 << 31) | ||
156 | #define MXC_CCM_PMCR0_DFSUP1_MPLL (1 << 31) | ||
157 | #define MXC_CCM_PMCR0_DFSUP0 0x40000000 | ||
158 | #define MXC_CCM_PMCR0_DFSUP0_PLL (0 << 30) | ||
159 | #define MXC_CCM_PMCR0_DFSUP0_PDR (1 << 30) | ||
160 | #define MXC_CCM_PMCR0_DFSUP_MASK (0x3 << 30) | ||
161 | |||
162 | #define DVSUP_TURBO 0 | ||
163 | #define DVSUP_HIGH 1 | ||
164 | #define DVSUP_MEDIUM 2 | ||
165 | #define DVSUP_LOW 3 | ||
166 | #define MXC_CCM_PMCR0_DVSUP_TURBO (DVSUP_TURBO << 28) | ||
167 | #define MXC_CCM_PMCR0_DVSUP_HIGH (DVSUP_HIGH << 28) | ||
168 | #define MXC_CCM_PMCR0_DVSUP_MEDIUM (DVSUP_MEDIUM << 28) | ||
169 | #define MXC_CCM_PMCR0_DVSUP_LOW (DVSUP_LOW << 28) | ||
170 | #define MXC_CCM_PMCR0_DVSUP_OFFSET 28 | ||
171 | #define MXC_CCM_PMCR0_DVSUP_MASK (0x3 << 28) | ||
172 | #define MXC_CCM_PMCR0_UDSC 0x08000000 | ||
173 | #define MXC_CCM_PMCR0_UDSC_MASK (1 << 27) | ||
174 | #define MXC_CCM_PMCR0_UDSC_UP (1 << 27) | ||
175 | #define MXC_CCM_PMCR0_UDSC_DOWN (0 << 27) | ||
176 | |||
177 | #define MXC_CCM_PMCR0_VSCNT_1 (0x0 << 24) | ||
178 | #define MXC_CCM_PMCR0_VSCNT_2 (0x1 << 24) | ||
179 | #define MXC_CCM_PMCR0_VSCNT_3 (0x2 << 24) | ||
180 | #define MXC_CCM_PMCR0_VSCNT_4 (0x3 << 24) | ||
181 | #define MXC_CCM_PMCR0_VSCNT_5 (0x4 << 24) | ||
182 | #define MXC_CCM_PMCR0_VSCNT_6 (0x5 << 24) | ||
183 | #define MXC_CCM_PMCR0_VSCNT_7 (0x6 << 24) | ||
184 | #define MXC_CCM_PMCR0_VSCNT_8 (0x7 << 24) | ||
185 | #define MXC_CCM_PMCR0_VSCNT_OFFSET 24 | ||
186 | #define MXC_CCM_PMCR0_VSCNT_MASK (0x7 << 24) | ||
187 | #define MXC_CCM_PMCR0_DVFEV 0x00800000 | ||
188 | #define MXC_CCM_PMCR0_DVFIS 0x00400000 | ||
189 | #define MXC_CCM_PMCR0_LBMI 0x00200000 | ||
190 | #define MXC_CCM_PMCR0_LBFL 0x00100000 | ||
191 | #define MXC_CCM_PMCR0_LBCF_4 (0x0 << 18) | ||
192 | #define MXC_CCM_PMCR0_LBCF_8 (0x1 << 18) | ||
193 | #define MXC_CCM_PMCR0_LBCF_12 (0x2 << 18) | ||
194 | #define MXC_CCM_PMCR0_LBCF_16 (0x3 << 18) | ||
195 | #define MXC_CCM_PMCR0_LBCF_OFFSET 18 | ||
196 | #define MXC_CCM_PMCR0_LBCF_MASK (0x3 << 18) | ||
197 | #define MXC_CCM_PMCR0_PTVIS 0x00020000 | ||
198 | #define MXC_CCM_PMCR0_UPDTEN 0x00010000 | ||
199 | #define MXC_CCM_PMCR0_UPDTEN_MASK (0x1 << 16) | ||
200 | #define MXC_CCM_PMCR0_FSVAIM 0x00008000 | ||
201 | #define MXC_CCM_PMCR0_FSVAI_OFFSET 13 | ||
202 | #define MXC_CCM_PMCR0_FSVAI_MASK (0x3 << 13) | ||
203 | #define MXC_CCM_PMCR0_DPVCR 0x00001000 | ||
204 | #define MXC_CCM_PMCR0_DPVV 0x00000800 | ||
205 | #define MXC_CCM_PMCR0_WFIM 0x00000400 | ||
206 | #define MXC_CCM_PMCR0_DRCE3 0x00000200 | ||
207 | #define MXC_CCM_PMCR0_DRCE2 0x00000100 | ||
208 | #define MXC_CCM_PMCR0_DRCE1 0x00000080 | ||
209 | #define MXC_CCM_PMCR0_DRCE0 0x00000040 | ||
210 | #define MXC_CCM_PMCR0_DCR 0x00000020 | ||
211 | #define MXC_CCM_PMCR0_DVFEN 0x00000010 | ||
212 | #define MXC_CCM_PMCR0_PTVAIM 0x00000008 | ||
213 | #define MXC_CCM_PMCR0_PTVAI_OFFSET 1 | ||
214 | #define MXC_CCM_PMCR0_PTVAI_MASK (0x3 << 1) | ||
215 | #define MXC_CCM_PMCR0_DPTEN 0x00000001 | ||
216 | |||
217 | #define MXC_CCM_PMCR1_DVGP_OFFSET 0 | ||
218 | #define MXC_CCM_PMCR1_DVGP_MASK (0xF) | ||
219 | |||
220 | #define MXC_CCM_PMCR1_PLLRDIS (0x1 << 7) | ||
221 | #define MXC_CCM_PMCR1_EMIRQ_EN (0x1 << 8) | ||
222 | |||
223 | #define MXC_CCM_DCVR_ULV_MASK (0x3FF << 22) | ||
224 | #define MXC_CCM_DCVR_ULV_OFFSET 22 | ||
225 | #define MXC_CCM_DCVR_LLV_MASK (0x3FF << 12) | ||
226 | #define MXC_CCM_DCVR_LLV_OFFSET 12 | ||
227 | #define MXC_CCM_DCVR_ELV_MASK (0x3FF << 2) | ||
228 | #define MXC_CCM_DCVR_ELV_OFFSET 2 | ||
229 | |||
230 | #define MXC_CCM_PDR2_MST2_PDF_MASK (0x3F << 7) | ||
231 | #define MXC_CCM_PDR2_MST2_PDF_OFFSET 7 | ||
232 | #define MXC_CCM_PDR2_MST1_PDF_MASK 0x3F | ||
233 | #define MXC_CCM_PDR2_MST1_PDF_OFFSET 0 | ||
234 | |||
235 | #define MXC_CCM_COSR_CLKOSEL_MASK 0x0F | ||
236 | #define MXC_CCM_COSR_CLKOSEL_OFFSET 0 | ||
237 | #define MXC_CCM_COSR_CLKOUTDIV_MASK (0x07 << 6) | ||
238 | #define MXC_CCM_COSR_CLKOUTDIV_OFFSET 6 | ||
239 | #define MXC_CCM_COSR_CLKOEN (1 << 9) | ||
240 | |||
241 | /* | ||
242 | * PMCR0 register offsets | ||
243 | */ | ||
244 | #define MXC_CCM_PMCR0_LBFL_OFFSET 20 | ||
245 | #define MXC_CCM_PMCR0_DFSUP0_OFFSET 30 | ||
246 | #define MXC_CCM_PMCR0_DFSUP1_OFFSET 31 | ||
247 | |||
248 | #endif /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */ | ||
diff --git a/arch/arm/mach-imx/devices-imx31.h b/arch/arm/mach-imx/devices-imx31.h new file mode 100644 index 000000000000..dbe940d9c53a --- /dev/null +++ b/arch/arm/mach-imx/devices-imx31.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Pengutronix | ||
3 | * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | ||
6 | * the terms of the GNU General Public License version 2 as published by the | ||
7 | * Free Software Foundation. | ||
8 | */ | ||
9 | #include <mach/mx31.h> | ||
10 | #include <mach/devices-common.h> | ||
11 | |||
12 | extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data; | ||
13 | #define imx31_add_fsl_usb2_udc(pdata) \ | ||
14 | imx_add_fsl_usb2_udc(&imx31_fsl_usb2_udc_data, pdata) | ||
15 | |||
16 | extern const struct imx_imx2_wdt_data imx31_imx2_wdt_data; | ||
17 | #define imx31_add_imx2_wdt(pdata) \ | ||
18 | imx_add_imx2_wdt(&imx31_imx2_wdt_data) | ||
19 | |||
20 | extern const struct imx_imx_i2c_data imx31_imx_i2c_data[]; | ||
21 | #define imx31_add_imx_i2c(id, pdata) \ | ||
22 | imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata) | ||
23 | #define imx31_add_imx_i2c0(pdata) imx31_add_imx_i2c(0, pdata) | ||
24 | #define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata) | ||
25 | #define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata) | ||
26 | |||
27 | extern const struct imx_imx_keypad_data imx31_imx_keypad_data; | ||
28 | #define imx31_add_imx_keypad(pdata) \ | ||
29 | imx_add_imx_keypad(&imx31_imx_keypad_data, pdata) | ||
30 | |||
31 | extern const struct imx_imx_ssi_data imx31_imx_ssi_data[]; | ||
32 | #define imx31_add_imx_ssi(id, pdata) \ | ||
33 | imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata) | ||
34 | |||
35 | extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[]; | ||
36 | #define imx31_add_imx_uart(id, pdata) \ | ||
37 | imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata) | ||
38 | #define imx31_add_imx_uart0(pdata) imx31_add_imx_uart(0, pdata) | ||
39 | #define imx31_add_imx_uart1(pdata) imx31_add_imx_uart(1, pdata) | ||
40 | #define imx31_add_imx_uart2(pdata) imx31_add_imx_uart(2, pdata) | ||
41 | #define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata) | ||
42 | #define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata) | ||
43 | |||
44 | extern const struct imx_ipu_core_data imx31_ipu_core_data; | ||
45 | #define imx31_add_ipu_core(pdata) \ | ||
46 | imx_add_ipu_core(&imx31_ipu_core_data, pdata) | ||
47 | #define imx31_alloc_mx3_camera(pdata) \ | ||
48 | imx_alloc_mx3_camera(&imx31_ipu_core_data, pdata) | ||
49 | #define imx31_add_mx3_sdc_fb(pdata) \ | ||
50 | imx_add_mx3_sdc_fb(&imx31_ipu_core_data, pdata) | ||
51 | |||
52 | extern const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data; | ||
53 | #define imx31_add_mxc_ehci_otg(pdata) \ | ||
54 | imx_add_mxc_ehci(&imx31_mxc_ehci_otg_data, pdata) | ||
55 | extern const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[]; | ||
56 | #define imx31_add_mxc_ehci_hs(id, pdata) \ | ||
57 | imx_add_mxc_ehci(&imx31_mxc_ehci_hs_data[id - 1], pdata) | ||
58 | |||
59 | extern const struct imx_mxc_mmc_data imx31_mxc_mmc_data[]; | ||
60 | #define imx31_add_mxc_mmc(id, pdata) \ | ||
61 | imx_add_mxc_mmc(&imx31_mxc_mmc_data[id], pdata) | ||
62 | |||
63 | extern const struct imx_mxc_nand_data imx31_mxc_nand_data; | ||
64 | #define imx31_add_mxc_nand(pdata) \ | ||
65 | imx_add_mxc_nand(&imx31_mxc_nand_data, pdata) | ||
66 | |||
67 | extern const struct imx_mxc_rtc_data imx31_mxc_rtc_data; | ||
68 | #define imx31_add_mxc_rtc(pdata) \ | ||
69 | imx_add_mxc_rtc(&imx31_mxc_rtc_data) | ||
70 | |||
71 | extern const struct imx_mxc_w1_data imx31_mxc_w1_data; | ||
72 | #define imx31_add_mxc_w1(pdata) \ | ||
73 | imx_add_mxc_w1(&imx31_mxc_w1_data) | ||
74 | |||
75 | extern const struct imx_spi_imx_data imx31_cspi_data[]; | ||
76 | #define imx31_add_cspi(id, pdata) \ | ||
77 | imx_add_spi_imx(&imx31_cspi_data[id], pdata) | ||
78 | #define imx31_add_spi_imx0(pdata) imx31_add_cspi(0, pdata) | ||
79 | #define imx31_add_spi_imx1(pdata) imx31_add_cspi(1, pdata) | ||
80 | #define imx31_add_spi_imx2(pdata) imx31_add_cspi(2, pdata) | ||
diff --git a/arch/arm/mach-imx/devices-imx35.h b/arch/arm/mach-imx/devices-imx35.h new file mode 100644 index 000000000000..234cbd3c18af --- /dev/null +++ b/arch/arm/mach-imx/devices-imx35.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Pengutronix | ||
3 | * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | ||
6 | * the terms of the GNU General Public License version 2 as published by the | ||
7 | * Free Software Foundation. | ||
8 | */ | ||
9 | #include <mach/mx35.h> | ||
10 | #include <mach/devices-common.h> | ||
11 | |||
12 | extern const struct imx_fec_data imx35_fec_data; | ||
13 | #define imx35_add_fec(pdata) \ | ||
14 | imx_add_fec(&imx35_fec_data, pdata) | ||
15 | |||
16 | extern const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data; | ||
17 | #define imx35_add_fsl_usb2_udc(pdata) \ | ||
18 | imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata) | ||
19 | |||
20 | extern const struct imx_flexcan_data imx35_flexcan_data[]; | ||
21 | #define imx35_add_flexcan(id, pdata) \ | ||
22 | imx_add_flexcan(&imx35_flexcan_data[id], pdata) | ||
23 | #define imx35_add_flexcan0(pdata) imx35_add_flexcan(0, pdata) | ||
24 | #define imx35_add_flexcan1(pdata) imx35_add_flexcan(1, pdata) | ||
25 | |||
26 | extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data; | ||
27 | #define imx35_add_imx2_wdt(pdata) \ | ||
28 | imx_add_imx2_wdt(&imx35_imx2_wdt_data) | ||
29 | |||
30 | extern const struct imx_imx_i2c_data imx35_imx_i2c_data[]; | ||
31 | #define imx35_add_imx_i2c(id, pdata) \ | ||
32 | imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata) | ||
33 | #define imx35_add_imx_i2c0(pdata) imx35_add_imx_i2c(0, pdata) | ||
34 | #define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata) | ||
35 | #define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata) | ||
36 | |||
37 | extern const struct imx_imx_keypad_data imx35_imx_keypad_data; | ||
38 | #define imx35_add_imx_keypad(pdata) \ | ||
39 | imx_add_imx_keypad(&imx35_imx_keypad_data, pdata) | ||
40 | |||
41 | extern const struct imx_imx_ssi_data imx35_imx_ssi_data[]; | ||
42 | #define imx35_add_imx_ssi(id, pdata) \ | ||
43 | imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata) | ||
44 | |||
45 | extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[]; | ||
46 | #define imx35_add_imx_uart(id, pdata) \ | ||
47 | imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata) | ||
48 | #define imx35_add_imx_uart0(pdata) imx35_add_imx_uart(0, pdata) | ||
49 | #define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata) | ||
50 | #define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata) | ||
51 | |||
52 | extern const struct imx_ipu_core_data imx35_ipu_core_data; | ||
53 | #define imx35_add_ipu_core(pdata) \ | ||
54 | imx_add_ipu_core(&imx35_ipu_core_data, pdata) | ||
55 | #define imx35_alloc_mx3_camera(pdata) \ | ||
56 | imx_alloc_mx3_camera(&imx35_ipu_core_data, pdata) | ||
57 | #define imx35_add_mx3_sdc_fb(pdata) \ | ||
58 | imx_add_mx3_sdc_fb(&imx35_ipu_core_data, pdata) | ||
59 | |||
60 | extern const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data; | ||
61 | #define imx35_add_mxc_ehci_otg(pdata) \ | ||
62 | imx_add_mxc_ehci(&imx35_mxc_ehci_otg_data, pdata) | ||
63 | extern const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data; | ||
64 | #define imx35_add_mxc_ehci_hs(pdata) \ | ||
65 | imx_add_mxc_ehci(&imx35_mxc_ehci_hs_data, pdata) | ||
66 | |||
67 | extern const struct imx_mxc_nand_data imx35_mxc_nand_data; | ||
68 | #define imx35_add_mxc_nand(pdata) \ | ||
69 | imx_add_mxc_nand(&imx35_mxc_nand_data, pdata) | ||
70 | |||
71 | extern const struct imx_mxc_w1_data imx35_mxc_w1_data; | ||
72 | #define imx35_add_mxc_w1(pdata) \ | ||
73 | imx_add_mxc_w1(&imx35_mxc_w1_data) | ||
74 | |||
75 | extern const struct imx_sdhci_esdhc_imx_data imx35_sdhci_esdhc_imx_data[]; | ||
76 | #define imx35_add_sdhci_esdhc_imx(id, pdata) \ | ||
77 | imx_add_sdhci_esdhc_imx(&imx35_sdhci_esdhc_imx_data[id], pdata) | ||
78 | |||
79 | extern const struct imx_spi_imx_data imx35_cspi_data[]; | ||
80 | #define imx35_add_cspi(id, pdata) \ | ||
81 | imx_add_spi_imx(&imx35_cspi_data[id], pdata) | ||
82 | #define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata) | ||
83 | #define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata) | ||
diff --git a/arch/arm/mach-imx/ehci-imx31.c b/arch/arm/mach-imx/ehci-imx31.c new file mode 100644 index 000000000000..faad0f15ac7f --- /dev/null +++ b/arch/arm/mach-imx/ehci-imx31.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright (C) 2010 Freescale Semiconductor, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
13 | * for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <mach/hardware.h> | ||
20 | #include <mach/mxc_ehci.h> | ||
21 | |||
22 | #define USBCTRL_OTGBASE_OFFSET 0x600 | ||
23 | |||
24 | #define MX31_OTG_SIC_SHIFT 29 | ||
25 | #define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) | ||
26 | #define MX31_OTG_PM_BIT (1 << 24) | ||
27 | |||
28 | #define MX31_H2_SIC_SHIFT 21 | ||
29 | #define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT) | ||
30 | #define MX31_H2_PM_BIT (1 << 16) | ||
31 | #define MX31_H2_DT_BIT (1 << 5) | ||
32 | |||
33 | #define MX31_H1_SIC_SHIFT 13 | ||
34 | #define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT) | ||
35 | #define MX31_H1_PM_BIT (1 << 8) | ||
36 | #define MX31_H1_DT_BIT (1 << 4) | ||
37 | |||
38 | int mx31_initialize_usb_hw(int port, unsigned int flags) | ||
39 | { | ||
40 | unsigned int v; | ||
41 | |||
42 | v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); | ||
43 | |||
44 | switch (port) { | ||
45 | case 0: /* OTG port */ | ||
46 | v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); | ||
47 | v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; | ||
48 | |||
49 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
50 | v |= MX31_OTG_PM_BIT; | ||
51 | |||
52 | break; | ||
53 | case 1: /* H1 port */ | ||
54 | v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); | ||
55 | v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; | ||
56 | |||
57 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
58 | v |= MX31_H1_PM_BIT; | ||
59 | |||
60 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
61 | v |= MX31_H1_DT_BIT; | ||
62 | |||
63 | break; | ||
64 | case 2: /* H2 port */ | ||
65 | v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); | ||
66 | v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; | ||
67 | |||
68 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
69 | v |= MX31_H2_PM_BIT; | ||
70 | |||
71 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
72 | v |= MX31_H2_DT_BIT; | ||
73 | |||
74 | break; | ||
75 | default: | ||
76 | return -EINVAL; | ||
77 | } | ||
78 | |||
79 | writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c new file mode 100644 index 000000000000..001ec3971f5d --- /dev/null +++ b/arch/arm/mach-imx/ehci-imx35.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright (C) 2010 Freescale Semiconductor, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
13 | * for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <mach/hardware.h> | ||
20 | #include <mach/mxc_ehci.h> | ||
21 | |||
22 | #define USBCTRL_OTGBASE_OFFSET 0x600 | ||
23 | |||
24 | #define MX35_OTG_SIC_SHIFT 29 | ||
25 | #define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT) | ||
26 | #define MX35_OTG_PM_BIT (1 << 24) | ||
27 | |||
28 | #define MX35_H1_SIC_SHIFT 21 | ||
29 | #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) | ||
30 | #define MX35_H1_PM_BIT (1 << 8) | ||
31 | #define MX35_H1_IPPUE_UP_BIT (1 << 7) | ||
32 | #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) | ||
33 | #define MX35_H1_TLL_BIT (1 << 5) | ||
34 | #define MX35_H1_USBTE_BIT (1 << 4) | ||
35 | |||
36 | int mx35_initialize_usb_hw(int port, unsigned int flags) | ||
37 | { | ||
38 | unsigned int v; | ||
39 | |||
40 | v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); | ||
41 | |||
42 | switch (port) { | ||
43 | case 0: /* OTG port */ | ||
44 | v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); | ||
45 | v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT; | ||
46 | |||
47 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
48 | v |= MX35_OTG_PM_BIT; | ||
49 | |||
50 | break; | ||
51 | case 1: /* H1 port */ | ||
52 | v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | | ||
53 | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); | ||
54 | v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT; | ||
55 | |||
56 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
57 | v |= MX35_H1_PM_BIT; | ||
58 | |||
59 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
60 | v |= MX35_H1_TLL_BIT; | ||
61 | |||
62 | if (flags & MXC_EHCI_INTERNAL_PHY) | ||
63 | v |= MX35_H1_USBTE_BIT; | ||
64 | |||
65 | if (flags & MXC_EHCI_IPPUE_DOWN) | ||
66 | v |= MX35_H1_IPPUE_DOWN_BIT; | ||
67 | |||
68 | if (flags & MXC_EHCI_IPPUE_UP) | ||
69 | v |= MX35_H1_IPPUE_UP_BIT; | ||
70 | |||
71 | break; | ||
72 | default: | ||
73 | return -EINVAL; | ||
74 | } | ||
75 | |||
76 | writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c new file mode 100644 index 000000000000..4909ea05855a --- /dev/null +++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c | |||
@@ -0,0 +1,303 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Eric Benard - eric@eukrea.com | ||
3 | * | ||
4 | * Based on pcm970-baseboard.c which is : | ||
5 | * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
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 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
19 | * MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | |||
25 | #include <linux/gpio.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/leds.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/input.h> | ||
30 | #include <video/platform_lcd.h> | ||
31 | #include <linux/i2c.h> | ||
32 | |||
33 | #include <asm/mach-types.h> | ||
34 | #include <asm/mach/arch.h> | ||
35 | #include <asm/mach/time.h> | ||
36 | #include <asm/mach/map.h> | ||
37 | |||
38 | #include <mach/hardware.h> | ||
39 | #include <mach/common.h> | ||
40 | #include <mach/iomux-mx35.h> | ||
41 | #include <mach/audmux.h> | ||
42 | |||
43 | #include "devices-imx35.h" | ||
44 | |||
45 | static const struct fb_videomode fb_modedb[] = { | ||
46 | { | ||
47 | .name = "CMO-QVGA", | ||
48 | .refresh = 60, | ||
49 | .xres = 320, | ||
50 | .yres = 240, | ||
51 | .pixclock = KHZ2PICOS(6500), | ||
52 | .left_margin = 68, | ||
53 | .right_margin = 20, | ||
54 | .upper_margin = 15, | ||
55 | .lower_margin = 4, | ||
56 | .hsync_len = 30, | ||
57 | .vsync_len = 3, | ||
58 | .sync = 0, | ||
59 | .vmode = FB_VMODE_NONINTERLACED, | ||
60 | .flag = 0, | ||
61 | }, | ||
62 | { | ||
63 | .name = "DVI-VGA", | ||
64 | .refresh = 60, | ||
65 | .xres = 640, | ||
66 | .yres = 480, | ||
67 | .pixclock = 32000, | ||
68 | .left_margin = 100, | ||
69 | .right_margin = 100, | ||
70 | .upper_margin = 7, | ||
71 | .lower_margin = 100, | ||
72 | .hsync_len = 7, | ||
73 | .vsync_len = 7, | ||
74 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT | | ||
75 | FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, | ||
76 | .vmode = FB_VMODE_NONINTERLACED, | ||
77 | .flag = 0, | ||
78 | }, | ||
79 | { | ||
80 | .name = "DVI-SVGA", | ||
81 | .refresh = 60, | ||
82 | .xres = 800, | ||
83 | .yres = 600, | ||
84 | .pixclock = 25000, | ||
85 | .left_margin = 75, | ||
86 | .right_margin = 75, | ||
87 | .upper_margin = 7, | ||
88 | .lower_margin = 75, | ||
89 | .hsync_len = 7, | ||
90 | .vsync_len = 7, | ||
91 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT | | ||
92 | FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, | ||
93 | .vmode = FB_VMODE_NONINTERLACED, | ||
94 | .flag = 0, | ||
95 | }, | ||
96 | }; | ||
97 | |||
98 | static const struct ipu_platform_data mx3_ipu_data __initconst = { | ||
99 | .irq_base = MXC_IPU_IRQ_START, | ||
100 | }; | ||
101 | |||
102 | static struct mx3fb_platform_data mx3fb_pdata __initdata = { | ||
103 | .name = "CMO-QVGA", | ||
104 | .mode = fb_modedb, | ||
105 | .num_modes = ARRAY_SIZE(fb_modedb), | ||
106 | }; | ||
107 | |||
108 | static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = { | ||
109 | /* LCD */ | ||
110 | MX35_PAD_LD0__IPU_DISPB_DAT_0, | ||
111 | MX35_PAD_LD1__IPU_DISPB_DAT_1, | ||
112 | MX35_PAD_LD2__IPU_DISPB_DAT_2, | ||
113 | MX35_PAD_LD3__IPU_DISPB_DAT_3, | ||
114 | MX35_PAD_LD4__IPU_DISPB_DAT_4, | ||
115 | MX35_PAD_LD5__IPU_DISPB_DAT_5, | ||
116 | MX35_PAD_LD6__IPU_DISPB_DAT_6, | ||
117 | MX35_PAD_LD7__IPU_DISPB_DAT_7, | ||
118 | MX35_PAD_LD8__IPU_DISPB_DAT_8, | ||
119 | MX35_PAD_LD9__IPU_DISPB_DAT_9, | ||
120 | MX35_PAD_LD10__IPU_DISPB_DAT_10, | ||
121 | MX35_PAD_LD11__IPU_DISPB_DAT_11, | ||
122 | MX35_PAD_LD12__IPU_DISPB_DAT_12, | ||
123 | MX35_PAD_LD13__IPU_DISPB_DAT_13, | ||
124 | MX35_PAD_LD14__IPU_DISPB_DAT_14, | ||
125 | MX35_PAD_LD15__IPU_DISPB_DAT_15, | ||
126 | MX35_PAD_LD16__IPU_DISPB_DAT_16, | ||
127 | MX35_PAD_LD17__IPU_DISPB_DAT_17, | ||
128 | MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC, | ||
129 | MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, | ||
130 | MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, | ||
131 | MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, | ||
132 | /* Backlight */ | ||
133 | MX35_PAD_CONTRAST__IPU_DISPB_CONTR, | ||
134 | /* LCD_PWR */ | ||
135 | MX35_PAD_D3_CLS__GPIO1_4, | ||
136 | /* LED */ | ||
137 | MX35_PAD_LD23__GPIO3_29, | ||
138 | /* SWITCH */ | ||
139 | MX35_PAD_LD19__GPIO3_25, | ||
140 | /* UART2 */ | ||
141 | MX35_PAD_CTS2__UART2_CTS, | ||
142 | MX35_PAD_RTS2__UART2_RTS, | ||
143 | MX35_PAD_TXD2__UART2_TXD_MUX, | ||
144 | MX35_PAD_RXD2__UART2_RXD_MUX, | ||
145 | /* I2S */ | ||
146 | MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS, | ||
147 | MX35_PAD_STXD4__AUDMUX_AUD4_TXD, | ||
148 | MX35_PAD_SRXD4__AUDMUX_AUD4_RXD, | ||
149 | MX35_PAD_SCK4__AUDMUX_AUD4_TXC, | ||
150 | /* CAN2 */ | ||
151 | MX35_PAD_TX5_RX0__CAN2_TXCAN, | ||
152 | MX35_PAD_TX4_RX1__CAN2_RXCAN, | ||
153 | /* SDCARD */ | ||
154 | MX35_PAD_SD1_CMD__ESDHC1_CMD, | ||
155 | MX35_PAD_SD1_CLK__ESDHC1_CLK, | ||
156 | MX35_PAD_SD1_DATA0__ESDHC1_DAT0, | ||
157 | MX35_PAD_SD1_DATA1__ESDHC1_DAT1, | ||
158 | MX35_PAD_SD1_DATA2__ESDHC1_DAT2, | ||
159 | MX35_PAD_SD1_DATA3__ESDHC1_DAT3, | ||
160 | /* SD1 CD */ | ||
161 | MX35_PAD_LD18__GPIO3_24, | ||
162 | }; | ||
163 | |||
164 | #define GPIO_LED1 IMX_GPIO_NR(3, 29) | ||
165 | #define GPIO_SWITCH1 IMX_GPIO_NR(3, 25) | ||
166 | #define GPIO_LCDPWR IMX_GPIO_NR(1, 4) | ||
167 | #define GPIO_SD1CD IMX_GPIO_NR(3, 24) | ||
168 | |||
169 | static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd, | ||
170 | unsigned int power) | ||
171 | { | ||
172 | if (power) | ||
173 | gpio_direction_output(GPIO_LCDPWR, 1); | ||
174 | else | ||
175 | gpio_direction_output(GPIO_LCDPWR, 0); | ||
176 | } | ||
177 | |||
178 | static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = { | ||
179 | .set_power = eukrea_mbimxsd_lcd_power_set, | ||
180 | }; | ||
181 | |||
182 | static struct platform_device eukrea_mbimxsd_lcd_powerdev = { | ||
183 | .name = "platform-lcd", | ||
184 | .dev.platform_data = &eukrea_mbimxsd_lcd_power_data, | ||
185 | }; | ||
186 | |||
187 | static struct gpio_led eukrea_mbimxsd_leds[] = { | ||
188 | { | ||
189 | .name = "led1", | ||
190 | .default_trigger = "heartbeat", | ||
191 | .active_low = 1, | ||
192 | .gpio = GPIO_LED1, | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static struct gpio_led_platform_data eukrea_mbimxsd_led_info = { | ||
197 | .leds = eukrea_mbimxsd_leds, | ||
198 | .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds), | ||
199 | }; | ||
200 | |||
201 | static struct platform_device eukrea_mbimxsd_leds_gpio = { | ||
202 | .name = "leds-gpio", | ||
203 | .id = -1, | ||
204 | .dev = { | ||
205 | .platform_data = &eukrea_mbimxsd_led_info, | ||
206 | }, | ||
207 | }; | ||
208 | |||
209 | static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = { | ||
210 | { | ||
211 | .gpio = GPIO_SWITCH1, | ||
212 | .code = BTN_0, | ||
213 | .desc = "BP1", | ||
214 | .active_low = 1, | ||
215 | .wakeup = 1, | ||
216 | }, | ||
217 | }; | ||
218 | |||
219 | static const struct gpio_keys_platform_data | ||
220 | eukrea_mbimxsd_button_data __initconst = { | ||
221 | .buttons = eukrea_mbimxsd_gpio_buttons, | ||
222 | .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons), | ||
223 | }; | ||
224 | |||
225 | static struct platform_device *platform_devices[] __initdata = { | ||
226 | &eukrea_mbimxsd_leds_gpio, | ||
227 | &eukrea_mbimxsd_lcd_powerdev, | ||
228 | }; | ||
229 | |||
230 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
231 | .flags = IMXUART_HAVE_RTSCTS, | ||
232 | }; | ||
233 | |||
234 | static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = { | ||
235 | { | ||
236 | I2C_BOARD_INFO("tlv320aic23", 0x1a), | ||
237 | }, | ||
238 | }; | ||
239 | |||
240 | static const | ||
241 | struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { | ||
242 | .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE, | ||
243 | }; | ||
244 | |||
245 | static struct esdhc_platform_data sd1_pdata = { | ||
246 | .cd_gpio = GPIO_SD1CD, | ||
247 | .wp_gpio = -EINVAL, | ||
248 | }; | ||
249 | |||
250 | /* | ||
251 | * system init for baseboard usage. Will be called by cpuimx35 init. | ||
252 | * | ||
253 | * Add platform devices present on this baseboard and init | ||
254 | * them from CPU side as far as required to use them later on | ||
255 | */ | ||
256 | void __init eukrea_mbimxsd35_baseboard_init(void) | ||
257 | { | ||
258 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, | ||
259 | ARRAY_SIZE(eukrea_mbimxsd_pads))) | ||
260 | printk(KERN_ERR "error setting mbimxsd pads !\n"); | ||
261 | |||
262 | #if defined(CONFIG_SND_SOC_EUKREA_TLV320) | ||
263 | /* SSI unit master I2S codec connected to SSI_AUD4 */ | ||
264 | mxc_audmux_v2_configure_port(0, | ||
265 | MXC_AUDMUX_V2_PTCR_SYN | | ||
266 | MXC_AUDMUX_V2_PTCR_TFSDIR | | ||
267 | MXC_AUDMUX_V2_PTCR_TFSEL(3) | | ||
268 | MXC_AUDMUX_V2_PTCR_TCLKDIR | | ||
269 | MXC_AUDMUX_V2_PTCR_TCSEL(3), | ||
270 | MXC_AUDMUX_V2_PDCR_RXDSEL(3) | ||
271 | ); | ||
272 | mxc_audmux_v2_configure_port(3, | ||
273 | MXC_AUDMUX_V2_PTCR_SYN, | ||
274 | MXC_AUDMUX_V2_PDCR_RXDSEL(0) | ||
275 | ); | ||
276 | #endif | ||
277 | |||
278 | imx35_add_imx_uart1(&uart_pdata); | ||
279 | imx35_add_ipu_core(&mx3_ipu_data); | ||
280 | imx35_add_mx3_sdc_fb(&mx3fb_pdata); | ||
281 | |||
282 | imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); | ||
283 | |||
284 | imx35_add_flexcan1(NULL); | ||
285 | imx35_add_sdhci_esdhc_imx(0, &sd1_pdata); | ||
286 | |||
287 | gpio_request(GPIO_LED1, "LED1"); | ||
288 | gpio_direction_output(GPIO_LED1, 1); | ||
289 | gpio_free(GPIO_LED1); | ||
290 | |||
291 | gpio_request(GPIO_SWITCH1, "SWITCH1"); | ||
292 | gpio_direction_input(GPIO_SWITCH1); | ||
293 | gpio_free(GPIO_SWITCH1); | ||
294 | |||
295 | gpio_request(GPIO_LCDPWR, "LCDPWR"); | ||
296 | gpio_direction_output(GPIO_LCDPWR, 1); | ||
297 | |||
298 | i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices, | ||
299 | ARRAY_SIZE(eukrea_mbimxsd_i2c_devices)); | ||
300 | |||
301 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
302 | imx_add_gpio_keys(&eukrea_mbimxsd_button_data); | ||
303 | } | ||
diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c new file mode 100644 index 000000000000..cf8f8099ebd7 --- /dev/null +++ b/arch/arm/mach-imx/iomux-imx31.c | |||
@@ -0,0 +1,181 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | ||
4 | * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | * MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <mach/hardware.h> | ||
26 | #include <mach/gpio.h> | ||
27 | #include <mach/iomux-mx3.h> | ||
28 | |||
29 | /* | ||
30 | * IOMUX register (base) addresses | ||
31 | */ | ||
32 | #define IOMUX_BASE MX31_IO_ADDRESS(MX31_IOMUXC_BASE_ADDR) | ||
33 | #define IOMUXINT_OBS1 (IOMUX_BASE + 0x000) | ||
34 | #define IOMUXINT_OBS2 (IOMUX_BASE + 0x004) | ||
35 | #define IOMUXGPR (IOMUX_BASE + 0x008) | ||
36 | #define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C) | ||
37 | #define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154) | ||
38 | |||
39 | static DEFINE_SPINLOCK(gpio_mux_lock); | ||
40 | |||
41 | #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) | ||
42 | |||
43 | unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; | ||
44 | /* | ||
45 | * set the mode for a IOMUX pin. | ||
46 | */ | ||
47 | int mxc_iomux_mode(unsigned int pin_mode) | ||
48 | { | ||
49 | u32 field, l, mode, ret = 0; | ||
50 | void __iomem *reg; | ||
51 | |||
52 | reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK); | ||
53 | field = pin_mode & 0x3; | ||
54 | mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; | ||
55 | |||
56 | spin_lock(&gpio_mux_lock); | ||
57 | |||
58 | l = __raw_readl(reg); | ||
59 | l &= ~(0xff << (field * 8)); | ||
60 | l |= mode << (field * 8); | ||
61 | __raw_writel(l, reg); | ||
62 | |||
63 | spin_unlock(&gpio_mux_lock); | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | EXPORT_SYMBOL(mxc_iomux_mode); | ||
68 | |||
69 | /* | ||
70 | * This function configures the pad value for a IOMUX pin. | ||
71 | */ | ||
72 | void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) | ||
73 | { | ||
74 | u32 field, l; | ||
75 | void __iomem *reg; | ||
76 | |||
77 | pin &= IOMUX_PADNUM_MASK; | ||
78 | reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4; | ||
79 | field = (pin + 2) % 3; | ||
80 | |||
81 | pr_debug("%s: reg offset = 0x%x, field = %d\n", | ||
82 | __func__, (pin + 2) / 3, field); | ||
83 | |||
84 | spin_lock(&gpio_mux_lock); | ||
85 | |||
86 | l = __raw_readl(reg); | ||
87 | l &= ~(0x1ff << (field * 10)); | ||
88 | l |= config << (field * 10); | ||
89 | __raw_writel(l, reg); | ||
90 | |||
91 | spin_unlock(&gpio_mux_lock); | ||
92 | } | ||
93 | EXPORT_SYMBOL(mxc_iomux_set_pad); | ||
94 | |||
95 | /* | ||
96 | * allocs a single pin: | ||
97 | * - reserves the pin so that it is not claimed by another driver | ||
98 | * - setups the iomux according to the configuration | ||
99 | */ | ||
100 | int mxc_iomux_alloc_pin(unsigned int pin, const char *label) | ||
101 | { | ||
102 | unsigned pad = pin & IOMUX_PADNUM_MASK; | ||
103 | |||
104 | if (pad >= (PIN_MAX + 1)) { | ||
105 | printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n", | ||
106 | pad, label ? label : "?"); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | |||
110 | if (test_and_set_bit(pad, mxc_pin_alloc_map)) { | ||
111 | printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n", | ||
112 | pad, label ? label : "?"); | ||
113 | return -EBUSY; | ||
114 | } | ||
115 | mxc_iomux_mode(pin); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | EXPORT_SYMBOL(mxc_iomux_alloc_pin); | ||
120 | |||
121 | int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count, | ||
122 | const char *label) | ||
123 | { | ||
124 | const unsigned int *p = pin_list; | ||
125 | int i; | ||
126 | int ret = -EINVAL; | ||
127 | |||
128 | for (i = 0; i < count; i++) { | ||
129 | ret = mxc_iomux_alloc_pin(*p, label); | ||
130 | if (ret) | ||
131 | goto setup_error; | ||
132 | p++; | ||
133 | } | ||
134 | return 0; | ||
135 | |||
136 | setup_error: | ||
137 | mxc_iomux_release_multiple_pins(pin_list, i); | ||
138 | return ret; | ||
139 | } | ||
140 | EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins); | ||
141 | |||
142 | void mxc_iomux_release_pin(unsigned int pin) | ||
143 | { | ||
144 | unsigned pad = pin & IOMUX_PADNUM_MASK; | ||
145 | |||
146 | if (pad < (PIN_MAX + 1)) | ||
147 | clear_bit(pad, mxc_pin_alloc_map); | ||
148 | } | ||
149 | EXPORT_SYMBOL(mxc_iomux_release_pin); | ||
150 | |||
151 | void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count) | ||
152 | { | ||
153 | const unsigned int *p = pin_list; | ||
154 | int i; | ||
155 | |||
156 | for (i = 0; i < count; i++) { | ||
157 | mxc_iomux_release_pin(*p); | ||
158 | p++; | ||
159 | } | ||
160 | } | ||
161 | EXPORT_SYMBOL(mxc_iomux_release_multiple_pins); | ||
162 | |||
163 | /* | ||
164 | * This function enables/disables the general purpose function for a particular | ||
165 | * signal. | ||
166 | */ | ||
167 | void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) | ||
168 | { | ||
169 | u32 l; | ||
170 | |||
171 | spin_lock(&gpio_mux_lock); | ||
172 | l = __raw_readl(IOMUXGPR); | ||
173 | if (en) | ||
174 | l |= gp; | ||
175 | else | ||
176 | l &= ~gp; | ||
177 | |||
178 | __raw_writel(l, IOMUXGPR); | ||
179 | spin_unlock(&gpio_mux_lock); | ||
180 | } | ||
181 | EXPORT_SYMBOL(mxc_iomux_set_gpr); | ||
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c new file mode 100644 index 000000000000..ffb40ff619b1 --- /dev/null +++ b/arch/arm/mach-imx/mach-armadillo5x0.c | |||
@@ -0,0 +1,565 @@ | |||
1 | /* | ||
2 | * armadillo5x0.c | ||
3 | * | ||
4 | * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
5 | * updates in http://alberdroid.blogspot.com/ | ||
6 | * | ||
7 | * Based on Atmark Techno, Inc. armadillo 500 BSP 2008 | ||
8 | * Based on mx31ads.c and pcm037.c Great Work! | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
23 | * MA 02110-1301, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/types.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/gpio.h> | ||
31 | #include <linux/smsc911x.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/irq.h> | ||
34 | #include <linux/mtd/physmap.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <linux/input.h> | ||
37 | #include <linux/i2c.h> | ||
38 | #include <linux/usb/otg.h> | ||
39 | #include <linux/usb/ulpi.h> | ||
40 | #include <linux/delay.h> | ||
41 | |||
42 | #include <mach/hardware.h> | ||
43 | #include <asm/mach-types.h> | ||
44 | #include <asm/mach/arch.h> | ||
45 | #include <asm/mach/time.h> | ||
46 | #include <asm/memory.h> | ||
47 | #include <asm/mach/map.h> | ||
48 | |||
49 | #include <mach/common.h> | ||
50 | #include <mach/iomux-mx3.h> | ||
51 | #include <mach/ulpi.h> | ||
52 | |||
53 | #include "devices-imx31.h" | ||
54 | #include "crmregs-imx31.h" | ||
55 | |||
56 | static int armadillo5x0_pins[] = { | ||
57 | /* UART1 */ | ||
58 | MX31_PIN_CTS1__CTS1, | ||
59 | MX31_PIN_RTS1__RTS1, | ||
60 | MX31_PIN_TXD1__TXD1, | ||
61 | MX31_PIN_RXD1__RXD1, | ||
62 | /* UART2 */ | ||
63 | MX31_PIN_CTS2__CTS2, | ||
64 | MX31_PIN_RTS2__RTS2, | ||
65 | MX31_PIN_TXD2__TXD2, | ||
66 | MX31_PIN_RXD2__RXD2, | ||
67 | /* LAN9118_IRQ */ | ||
68 | IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), | ||
69 | /* SDHC1 */ | ||
70 | MX31_PIN_SD1_DATA3__SD1_DATA3, | ||
71 | MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
72 | MX31_PIN_SD1_DATA1__SD1_DATA1, | ||
73 | MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
74 | MX31_PIN_SD1_CLK__SD1_CLK, | ||
75 | MX31_PIN_SD1_CMD__SD1_CMD, | ||
76 | /* Framebuffer */ | ||
77 | MX31_PIN_LD0__LD0, | ||
78 | MX31_PIN_LD1__LD1, | ||
79 | MX31_PIN_LD2__LD2, | ||
80 | MX31_PIN_LD3__LD3, | ||
81 | MX31_PIN_LD4__LD4, | ||
82 | MX31_PIN_LD5__LD5, | ||
83 | MX31_PIN_LD6__LD6, | ||
84 | MX31_PIN_LD7__LD7, | ||
85 | MX31_PIN_LD8__LD8, | ||
86 | MX31_PIN_LD9__LD9, | ||
87 | MX31_PIN_LD10__LD10, | ||
88 | MX31_PIN_LD11__LD11, | ||
89 | MX31_PIN_LD12__LD12, | ||
90 | MX31_PIN_LD13__LD13, | ||
91 | MX31_PIN_LD14__LD14, | ||
92 | MX31_PIN_LD15__LD15, | ||
93 | MX31_PIN_LD16__LD16, | ||
94 | MX31_PIN_LD17__LD17, | ||
95 | MX31_PIN_VSYNC3__VSYNC3, | ||
96 | MX31_PIN_HSYNC__HSYNC, | ||
97 | MX31_PIN_FPSHIFT__FPSHIFT, | ||
98 | MX31_PIN_DRDY0__DRDY0, | ||
99 | IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/ | ||
100 | /* I2C2 */ | ||
101 | MX31_PIN_CSPI2_MOSI__SCL, | ||
102 | MX31_PIN_CSPI2_MISO__SDA, | ||
103 | /* OTG */ | ||
104 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
105 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
106 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
107 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
108 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
109 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
110 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
111 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
112 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, | ||
113 | MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
114 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, | ||
115 | MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
116 | /* USB host 2 */ | ||
117 | IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), | ||
118 | IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), | ||
119 | IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), | ||
120 | IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), | ||
121 | IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), | ||
122 | IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), | ||
123 | IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), | ||
124 | IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), | ||
125 | IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), | ||
126 | IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), | ||
127 | IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), | ||
128 | IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), | ||
129 | }; | ||
130 | |||
131 | /* USB */ | ||
132 | |||
133 | #define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4) | ||
134 | #define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6) | ||
135 | #define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3) | ||
136 | |||
137 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
138 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
139 | |||
140 | static int usbotg_init(struct platform_device *pdev) | ||
141 | { | ||
142 | int err; | ||
143 | |||
144 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); | ||
145 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); | ||
146 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); | ||
147 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); | ||
148 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); | ||
149 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); | ||
150 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); | ||
151 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); | ||
152 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); | ||
153 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); | ||
154 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); | ||
155 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); | ||
156 | |||
157 | /* Chip already enabled by hardware */ | ||
158 | /* OTG phy reset*/ | ||
159 | err = gpio_request(OTG_RESET, "USB-OTG-RESET"); | ||
160 | if (err) { | ||
161 | pr_err("Failed to request the usb otg reset gpio\n"); | ||
162 | return err; | ||
163 | } | ||
164 | |||
165 | err = gpio_direction_output(OTG_RESET, 1/*HIGH*/); | ||
166 | if (err) { | ||
167 | pr_err("Failed to reset the usb otg phy\n"); | ||
168 | goto otg_free_reset; | ||
169 | } | ||
170 | |||
171 | gpio_set_value(OTG_RESET, 0/*LOW*/); | ||
172 | mdelay(5); | ||
173 | gpio_set_value(OTG_RESET, 1/*HIGH*/); | ||
174 | mdelay(10); | ||
175 | |||
176 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | | ||
177 | MXC_EHCI_INTERFACE_DIFF_UNI); | ||
178 | |||
179 | otg_free_reset: | ||
180 | gpio_free(OTG_RESET); | ||
181 | return err; | ||
182 | } | ||
183 | |||
184 | static int usbh2_init(struct platform_device *pdev) | ||
185 | { | ||
186 | int err; | ||
187 | |||
188 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); | ||
189 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); | ||
190 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); | ||
191 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); | ||
192 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); | ||
193 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); | ||
194 | mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); | ||
195 | mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); | ||
196 | mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); | ||
197 | mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); | ||
198 | mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); | ||
199 | mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); | ||
200 | |||
201 | mxc_iomux_set_gpr(MUX_PGP_UH2, true); | ||
202 | |||
203 | |||
204 | /* Enable the chip */ | ||
205 | err = gpio_request(USBH2_CS, "USB-H2-CS"); | ||
206 | if (err) { | ||
207 | pr_err("Failed to request the usb host 2 CS gpio\n"); | ||
208 | return err; | ||
209 | } | ||
210 | |||
211 | err = gpio_direction_output(USBH2_CS, 0/*Enabled*/); | ||
212 | if (err) { | ||
213 | pr_err("Failed to drive the usb host 2 CS gpio\n"); | ||
214 | goto h2_free_cs; | ||
215 | } | ||
216 | |||
217 | /* H2 phy reset*/ | ||
218 | err = gpio_request(USBH2_RESET, "USB-H2-RESET"); | ||
219 | if (err) { | ||
220 | pr_err("Failed to request the usb host 2 reset gpio\n"); | ||
221 | goto h2_free_cs; | ||
222 | } | ||
223 | |||
224 | err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/); | ||
225 | if (err) { | ||
226 | pr_err("Failed to reset the usb host 2 phy\n"); | ||
227 | goto h2_free_reset; | ||
228 | } | ||
229 | |||
230 | gpio_set_value(USBH2_RESET, 0/*LOW*/); | ||
231 | mdelay(5); | ||
232 | gpio_set_value(USBH2_RESET, 1/*HIGH*/); | ||
233 | mdelay(10); | ||
234 | |||
235 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | | ||
236 | MXC_EHCI_INTERFACE_DIFF_UNI); | ||
237 | |||
238 | h2_free_reset: | ||
239 | gpio_free(USBH2_RESET); | ||
240 | h2_free_cs: | ||
241 | gpio_free(USBH2_CS); | ||
242 | return err; | ||
243 | } | ||
244 | |||
245 | static struct mxc_usbh_platform_data usbotg_pdata __initdata = { | ||
246 | .init = usbotg_init, | ||
247 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
248 | }; | ||
249 | |||
250 | static struct mxc_usbh_platform_data usbh2_pdata __initdata = { | ||
251 | .init = usbh2_init, | ||
252 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
253 | }; | ||
254 | |||
255 | /* RTC over I2C*/ | ||
256 | #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) | ||
257 | |||
258 | static struct i2c_board_info armadillo5x0_i2c_rtc = { | ||
259 | I2C_BOARD_INFO("s35390a", 0x30), | ||
260 | }; | ||
261 | |||
262 | /* GPIO BUTTONS */ | ||
263 | static struct gpio_keys_button armadillo5x0_buttons[] = { | ||
264 | { | ||
265 | .code = KEY_ENTER, /*28*/ | ||
266 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SCLK0), | ||
267 | .active_low = 1, | ||
268 | .desc = "menu", | ||
269 | .wakeup = 1, | ||
270 | }, { | ||
271 | .code = KEY_BACK, /*158*/ | ||
272 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SRST0), | ||
273 | .active_low = 1, | ||
274 | .desc = "back", | ||
275 | .wakeup = 1, | ||
276 | } | ||
277 | }; | ||
278 | |||
279 | static const struct gpio_keys_platform_data | ||
280 | armadillo5x0_button_data __initconst = { | ||
281 | .buttons = armadillo5x0_buttons, | ||
282 | .nbuttons = ARRAY_SIZE(armadillo5x0_buttons), | ||
283 | }; | ||
284 | |||
285 | /* | ||
286 | * NAND Flash | ||
287 | */ | ||
288 | static const struct mxc_nand_platform_data | ||
289 | armadillo5x0_nand_board_info __initconst = { | ||
290 | .width = 1, | ||
291 | .hw_ecc = 1, | ||
292 | }; | ||
293 | |||
294 | /* | ||
295 | * MTD NOR Flash | ||
296 | */ | ||
297 | static struct mtd_partition armadillo5x0_nor_flash_partitions[] = { | ||
298 | { | ||
299 | .name = "nor.bootloader", | ||
300 | .offset = 0x00000000, | ||
301 | .size = 4*32*1024, | ||
302 | }, { | ||
303 | .name = "nor.kernel", | ||
304 | .offset = MTDPART_OFS_APPEND, | ||
305 | .size = 16*128*1024, | ||
306 | }, { | ||
307 | .name = "nor.userland", | ||
308 | .offset = MTDPART_OFS_APPEND, | ||
309 | .size = 110*128*1024, | ||
310 | }, { | ||
311 | .name = "nor.config", | ||
312 | .offset = MTDPART_OFS_APPEND, | ||
313 | .size = 1*128*1024, | ||
314 | }, | ||
315 | }; | ||
316 | |||
317 | static struct physmap_flash_data armadillo5x0_nor_flash_pdata = { | ||
318 | .width = 2, | ||
319 | .parts = armadillo5x0_nor_flash_partitions, | ||
320 | .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions), | ||
321 | }; | ||
322 | |||
323 | static struct resource armadillo5x0_nor_flash_resource = { | ||
324 | .flags = IORESOURCE_MEM, | ||
325 | .start = MX31_CS0_BASE_ADDR, | ||
326 | .end = MX31_CS0_BASE_ADDR + SZ_64M - 1, | ||
327 | }; | ||
328 | |||
329 | static struct platform_device armadillo5x0_nor_flash = { | ||
330 | .name = "physmap-flash", | ||
331 | .id = -1, | ||
332 | .num_resources = 1, | ||
333 | .resource = &armadillo5x0_nor_flash_resource, | ||
334 | }; | ||
335 | |||
336 | /* | ||
337 | * FB support | ||
338 | */ | ||
339 | static const struct fb_videomode fb_modedb[] = { | ||
340 | { /* 640x480 @ 60 Hz */ | ||
341 | .name = "CRT-VGA", | ||
342 | .refresh = 60, | ||
343 | .xres = 640, | ||
344 | .yres = 480, | ||
345 | .pixclock = 39721, | ||
346 | .left_margin = 35, | ||
347 | .right_margin = 115, | ||
348 | .upper_margin = 43, | ||
349 | .lower_margin = 1, | ||
350 | .hsync_len = 10, | ||
351 | .vsync_len = 1, | ||
352 | .sync = FB_SYNC_OE_ACT_HIGH, | ||
353 | .vmode = FB_VMODE_NONINTERLACED, | ||
354 | .flag = 0, | ||
355 | }, {/* 800x600 @ 56 Hz */ | ||
356 | .name = "CRT-SVGA", | ||
357 | .refresh = 56, | ||
358 | .xres = 800, | ||
359 | .yres = 600, | ||
360 | .pixclock = 30000, | ||
361 | .left_margin = 30, | ||
362 | .right_margin = 108, | ||
363 | .upper_margin = 13, | ||
364 | .lower_margin = 10, | ||
365 | .hsync_len = 10, | ||
366 | .vsync_len = 1, | ||
367 | .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT | | ||
368 | FB_SYNC_VERT_HIGH_ACT, | ||
369 | .vmode = FB_VMODE_NONINTERLACED, | ||
370 | .flag = 0, | ||
371 | }, | ||
372 | }; | ||
373 | |||
374 | static const struct ipu_platform_data mx3_ipu_data __initconst = { | ||
375 | .irq_base = MXC_IPU_IRQ_START, | ||
376 | }; | ||
377 | |||
378 | static struct mx3fb_platform_data mx3fb_pdata __initdata = { | ||
379 | .name = "CRT-VGA", | ||
380 | .mode = fb_modedb, | ||
381 | .num_modes = ARRAY_SIZE(fb_modedb), | ||
382 | }; | ||
383 | |||
384 | /* | ||
385 | * SDHC 1 | ||
386 | * MMC support | ||
387 | */ | ||
388 | static int armadillo5x0_sdhc1_get_ro(struct device *dev) | ||
389 | { | ||
390 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B)); | ||
391 | } | ||
392 | |||
393 | static int armadillo5x0_sdhc1_init(struct device *dev, | ||
394 | irq_handler_t detect_irq, void *data) | ||
395 | { | ||
396 | int ret; | ||
397 | int gpio_det, gpio_wp; | ||
398 | |||
399 | gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK); | ||
400 | gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B); | ||
401 | |||
402 | ret = gpio_request(gpio_det, "sdhc-card-detect"); | ||
403 | if (ret) | ||
404 | return ret; | ||
405 | |||
406 | gpio_direction_input(gpio_det); | ||
407 | |||
408 | ret = gpio_request(gpio_wp, "sdhc-write-protect"); | ||
409 | if (ret) | ||
410 | goto err_gpio_free; | ||
411 | |||
412 | gpio_direction_input(gpio_wp); | ||
413 | |||
414 | /* When supported the trigger type have to be BOTH */ | ||
415 | ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq, | ||
416 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
417 | "sdhc-detect", data); | ||
418 | |||
419 | if (ret) | ||
420 | goto err_gpio_free_2; | ||
421 | |||
422 | return 0; | ||
423 | |||
424 | err_gpio_free_2: | ||
425 | gpio_free(gpio_wp); | ||
426 | |||
427 | err_gpio_free: | ||
428 | gpio_free(gpio_det); | ||
429 | |||
430 | return ret; | ||
431 | |||
432 | } | ||
433 | |||
434 | static void armadillo5x0_sdhc1_exit(struct device *dev, void *data) | ||
435 | { | ||
436 | free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data); | ||
437 | gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)); | ||
438 | gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B)); | ||
439 | } | ||
440 | |||
441 | static const struct imxmmc_platform_data sdhc_pdata __initconst = { | ||
442 | .get_ro = armadillo5x0_sdhc1_get_ro, | ||
443 | .init = armadillo5x0_sdhc1_init, | ||
444 | .exit = armadillo5x0_sdhc1_exit, | ||
445 | }; | ||
446 | |||
447 | /* | ||
448 | * SMSC 9118 | ||
449 | * Network support | ||
450 | */ | ||
451 | static struct resource armadillo5x0_smc911x_resources[] = { | ||
452 | { | ||
453 | .start = MX31_CS3_BASE_ADDR, | ||
454 | .end = MX31_CS3_BASE_ADDR + SZ_32M - 1, | ||
455 | .flags = IORESOURCE_MEM, | ||
456 | }, { | ||
457 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), | ||
458 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), | ||
459 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | ||
460 | }, | ||
461 | }; | ||
462 | |||
463 | static struct smsc911x_platform_config smsc911x_info = { | ||
464 | .flags = SMSC911X_USE_16BIT, | ||
465 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
466 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | ||
467 | }; | ||
468 | |||
469 | static struct platform_device armadillo5x0_smc911x_device = { | ||
470 | .name = "smsc911x", | ||
471 | .id = -1, | ||
472 | .num_resources = ARRAY_SIZE(armadillo5x0_smc911x_resources), | ||
473 | .resource = armadillo5x0_smc911x_resources, | ||
474 | .dev = { | ||
475 | .platform_data = &smsc911x_info, | ||
476 | }, | ||
477 | }; | ||
478 | |||
479 | /* UART device data */ | ||
480 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
481 | .flags = IMXUART_HAVE_RTSCTS, | ||
482 | }; | ||
483 | |||
484 | static struct platform_device *devices[] __initdata = { | ||
485 | &armadillo5x0_smc911x_device, | ||
486 | }; | ||
487 | |||
488 | /* | ||
489 | * Perform board specific initializations | ||
490 | */ | ||
491 | static void __init armadillo5x0_init(void) | ||
492 | { | ||
493 | mxc_iomux_setup_multiple_pins(armadillo5x0_pins, | ||
494 | ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); | ||
495 | |||
496 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
497 | imx_add_gpio_keys(&armadillo5x0_button_data); | ||
498 | imx31_add_imx_i2c1(NULL); | ||
499 | |||
500 | /* Register UART */ | ||
501 | imx31_add_imx_uart0(&uart_pdata); | ||
502 | imx31_add_imx_uart1(&uart_pdata); | ||
503 | |||
504 | /* SMSC9118 IRQ pin */ | ||
505 | gpio_direction_input(MX31_PIN_GPIO1_0); | ||
506 | |||
507 | /* Register SDHC */ | ||
508 | imx31_add_mxc_mmc(0, &sdhc_pdata); | ||
509 | |||
510 | /* Register FB */ | ||
511 | imx31_add_ipu_core(&mx3_ipu_data); | ||
512 | imx31_add_mx3_sdc_fb(&mx3fb_pdata); | ||
513 | |||
514 | /* Register NOR Flash */ | ||
515 | mxc_register_device(&armadillo5x0_nor_flash, | ||
516 | &armadillo5x0_nor_flash_pdata); | ||
517 | |||
518 | /* Register NAND Flash */ | ||
519 | imx31_add_mxc_nand(&armadillo5x0_nand_board_info); | ||
520 | |||
521 | /* set NAND page size to 2k if not configured via boot mode pins */ | ||
522 | __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR); | ||
523 | |||
524 | /* RTC */ | ||
525 | /* Get RTC IRQ and register the chip */ | ||
526 | if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) { | ||
527 | if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0) | ||
528 | armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO); | ||
529 | else | ||
530 | gpio_free(ARMADILLO5X0_RTC_GPIO); | ||
531 | } | ||
532 | if (armadillo5x0_i2c_rtc.irq == 0) | ||
533 | pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); | ||
534 | i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); | ||
535 | |||
536 | /* USB */ | ||
537 | |||
538 | usbotg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
539 | ULPI_OTG_DRVVBUS_EXT); | ||
540 | if (usbotg_pdata.otg) | ||
541 | imx31_add_mxc_ehci_otg(&usbotg_pdata); | ||
542 | usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
543 | ULPI_OTG_DRVVBUS_EXT); | ||
544 | if (usbh2_pdata.otg) | ||
545 | imx31_add_mxc_ehci_hs(2, &usbh2_pdata); | ||
546 | } | ||
547 | |||
548 | static void __init armadillo5x0_timer_init(void) | ||
549 | { | ||
550 | mx31_clocks_init(26000000); | ||
551 | } | ||
552 | |||
553 | static struct sys_timer armadillo5x0_timer = { | ||
554 | .init = armadillo5x0_timer_init, | ||
555 | }; | ||
556 | |||
557 | MACHINE_START(ARMADILLO5X0, "Armadillo-500") | ||
558 | /* Maintainer: Alberto Panizzo */ | ||
559 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
560 | .map_io = mx31_map_io, | ||
561 | .init_early = imx31_init_early, | ||
562 | .init_irq = mx31_init_irq, | ||
563 | .timer = &armadillo5x0_timer, | ||
564 | .init_machine = armadillo5x0_init, | ||
565 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-bug.c b/arch/arm/mach-imx/mach-bug.c new file mode 100644 index 000000000000..42e4f078a19c --- /dev/null +++ b/arch/arm/mach-imx/mach-bug.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
3 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
4 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
5 | * Copyright 2011 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #include <mach/iomux-mx3.h> | ||
23 | #include <mach/hardware.h> | ||
24 | #include <mach/common.h> | ||
25 | |||
26 | #include <asm/mach/time.h> | ||
27 | #include <asm/mach/arch.h> | ||
28 | #include <asm/mach-types.h> | ||
29 | |||
30 | #include "devices-imx31.h" | ||
31 | |||
32 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
33 | .flags = IMXUART_HAVE_RTSCTS, | ||
34 | }; | ||
35 | |||
36 | static const unsigned int bug_pins[] __initconst = { | ||
37 | MX31_PIN_PC_RST__CTS5, | ||
38 | MX31_PIN_PC_VS2__RTS5, | ||
39 | MX31_PIN_PC_BVD2__TXD5, | ||
40 | MX31_PIN_PC_BVD1__RXD5, | ||
41 | }; | ||
42 | |||
43 | static void __init bug_board_init(void) | ||
44 | { | ||
45 | mxc_iomux_setup_multiple_pins(bug_pins, | ||
46 | ARRAY_SIZE(bug_pins), "uart-4"); | ||
47 | imx31_add_imx_uart4(&uart_pdata); | ||
48 | } | ||
49 | |||
50 | static void __init bug_timer_init(void) | ||
51 | { | ||
52 | mx31_clocks_init(26000000); | ||
53 | } | ||
54 | |||
55 | static struct sys_timer bug_timer = { | ||
56 | .init = bug_timer_init, | ||
57 | }; | ||
58 | |||
59 | MACHINE_START(BUG, "BugLabs BUGBase") | ||
60 | .map_io = mx31_map_io, | ||
61 | .init_early = imx31_init_early, | ||
62 | .init_irq = mx31_init_irq, | ||
63 | .timer = &bug_timer, | ||
64 | .init_machine = bug_board_init, | ||
65 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c new file mode 100644 index 000000000000..3f8ef825fa6f --- /dev/null +++ b/arch/arm/mach-imx/mach-cpuimx35.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Eric Benard - eric@eukrea.com | ||
3 | * Copyright (C) 2009 Sascha Hauer, Pengutronix | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include <linux/init.h> | ||
22 | |||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/mtd/physmap.h> | ||
25 | #include <linux/memory.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/i2c/tsc2007.h> | ||
31 | #include <linux/usb/otg.h> | ||
32 | #include <linux/usb/ulpi.h> | ||
33 | #include <linux/i2c-gpio.h> | ||
34 | |||
35 | #include <asm/mach-types.h> | ||
36 | #include <asm/mach/arch.h> | ||
37 | #include <asm/mach/time.h> | ||
38 | #include <asm/mach/map.h> | ||
39 | |||
40 | #include <mach/eukrea-baseboards.h> | ||
41 | #include <mach/hardware.h> | ||
42 | #include <mach/common.h> | ||
43 | #include <mach/iomux-mx35.h> | ||
44 | |||
45 | #include "devices-imx35.h" | ||
46 | |||
47 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
48 | .flags = IMXUART_HAVE_RTSCTS, | ||
49 | }; | ||
50 | |||
51 | static const struct imxi2c_platform_data | ||
52 | eukrea_cpuimx35_i2c0_data __initconst = { | ||
53 | .bitrate = 100000, | ||
54 | }; | ||
55 | |||
56 | static struct tsc2007_platform_data tsc2007_info = { | ||
57 | .model = 2007, | ||
58 | .x_plate_ohms = 180, | ||
59 | }; | ||
60 | |||
61 | #define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2) | ||
62 | static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { | ||
63 | { | ||
64 | I2C_BOARD_INFO("pcf8563", 0x51), | ||
65 | }, { | ||
66 | I2C_BOARD_INFO("tsc2007", 0x48), | ||
67 | .type = "tsc2007", | ||
68 | .platform_data = &tsc2007_info, | ||
69 | .irq = gpio_to_irq(TSC2007_IRQGPIO), | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static iomux_v3_cfg_t eukrea_cpuimx35_pads[] = { | ||
74 | /* UART1 */ | ||
75 | MX35_PAD_CTS1__UART1_CTS, | ||
76 | MX35_PAD_RTS1__UART1_RTS, | ||
77 | MX35_PAD_TXD1__UART1_TXD_MUX, | ||
78 | MX35_PAD_RXD1__UART1_RXD_MUX, | ||
79 | /* FEC */ | ||
80 | MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, | ||
81 | MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, | ||
82 | MX35_PAD_FEC_RX_DV__FEC_RX_DV, | ||
83 | MX35_PAD_FEC_COL__FEC_COL, | ||
84 | MX35_PAD_FEC_RDATA0__FEC_RDATA_0, | ||
85 | MX35_PAD_FEC_TDATA0__FEC_TDATA_0, | ||
86 | MX35_PAD_FEC_TX_EN__FEC_TX_EN, | ||
87 | MX35_PAD_FEC_MDC__FEC_MDC, | ||
88 | MX35_PAD_FEC_MDIO__FEC_MDIO, | ||
89 | MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, | ||
90 | MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, | ||
91 | MX35_PAD_FEC_CRS__FEC_CRS, | ||
92 | MX35_PAD_FEC_RDATA1__FEC_RDATA_1, | ||
93 | MX35_PAD_FEC_TDATA1__FEC_TDATA_1, | ||
94 | MX35_PAD_FEC_RDATA2__FEC_RDATA_2, | ||
95 | MX35_PAD_FEC_TDATA2__FEC_TDATA_2, | ||
96 | MX35_PAD_FEC_RDATA3__FEC_RDATA_3, | ||
97 | MX35_PAD_FEC_TDATA3__FEC_TDATA_3, | ||
98 | /* I2C1 */ | ||
99 | MX35_PAD_I2C1_CLK__I2C1_SCL, | ||
100 | MX35_PAD_I2C1_DAT__I2C1_SDA, | ||
101 | /* TSC2007 IRQ */ | ||
102 | MX35_PAD_ATA_DA2__GPIO3_2, | ||
103 | }; | ||
104 | |||
105 | static const struct mxc_nand_platform_data | ||
106 | eukrea_cpuimx35_nand_board_info __initconst = { | ||
107 | .width = 1, | ||
108 | .hw_ecc = 1, | ||
109 | .flash_bbt = 1, | ||
110 | }; | ||
111 | |||
112 | static int eukrea_cpuimx35_otg_init(struct platform_device *pdev) | ||
113 | { | ||
114 | return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); | ||
115 | } | ||
116 | |||
117 | static const struct mxc_usbh_platform_data otg_pdata __initconst = { | ||
118 | .init = eukrea_cpuimx35_otg_init, | ||
119 | .portsc = MXC_EHCI_MODE_UTMI, | ||
120 | }; | ||
121 | |||
122 | static int eukrea_cpuimx35_usbh1_init(struct platform_device *pdev) | ||
123 | { | ||
124 | return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI | | ||
125 | MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN); | ||
126 | } | ||
127 | |||
128 | static const struct mxc_usbh_platform_data usbh1_pdata __initconst = { | ||
129 | .init = eukrea_cpuimx35_usbh1_init, | ||
130 | .portsc = MXC_EHCI_MODE_SERIAL, | ||
131 | }; | ||
132 | |||
133 | static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { | ||
134 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
135 | .phy_mode = FSL_USB2_PHY_UTMI, | ||
136 | .workaround = FLS_USB2_WORKAROUND_ENGCM09152, | ||
137 | }; | ||
138 | |||
139 | static int otg_mode_host; | ||
140 | |||
141 | static int __init eukrea_cpuimx35_otg_mode(char *options) | ||
142 | { | ||
143 | if (!strcmp(options, "host")) | ||
144 | otg_mode_host = 1; | ||
145 | else if (!strcmp(options, "device")) | ||
146 | otg_mode_host = 0; | ||
147 | else | ||
148 | pr_info("otg_mode neither \"host\" nor \"device\". " | ||
149 | "Defaulting to device\n"); | ||
150 | return 0; | ||
151 | } | ||
152 | __setup("otg_mode=", eukrea_cpuimx35_otg_mode); | ||
153 | |||
154 | /* | ||
155 | * Board specific initialization. | ||
156 | */ | ||
157 | static void __init eukrea_cpuimx35_init(void) | ||
158 | { | ||
159 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads, | ||
160 | ARRAY_SIZE(eukrea_cpuimx35_pads)); | ||
161 | |||
162 | imx35_add_fec(NULL); | ||
163 | imx35_add_imx2_wdt(NULL); | ||
164 | |||
165 | imx35_add_imx_uart0(&uart_pdata); | ||
166 | imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info); | ||
167 | |||
168 | i2c_register_board_info(0, eukrea_cpuimx35_i2c_devices, | ||
169 | ARRAY_SIZE(eukrea_cpuimx35_i2c_devices)); | ||
170 | imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data); | ||
171 | |||
172 | if (otg_mode_host) | ||
173 | imx35_add_mxc_ehci_otg(&otg_pdata); | ||
174 | else | ||
175 | imx35_add_fsl_usb2_udc(&otg_device_pdata); | ||
176 | |||
177 | imx35_add_mxc_ehci_hs(&usbh1_pdata); | ||
178 | |||
179 | #ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD | ||
180 | eukrea_mbimxsd35_baseboard_init(); | ||
181 | #endif | ||
182 | } | ||
183 | |||
184 | static void __init eukrea_cpuimx35_timer_init(void) | ||
185 | { | ||
186 | mx35_clocks_init(); | ||
187 | } | ||
188 | |||
189 | struct sys_timer eukrea_cpuimx35_timer = { | ||
190 | .init = eukrea_cpuimx35_timer_init, | ||
191 | }; | ||
192 | |||
193 | MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35") | ||
194 | /* Maintainer: Eukrea Electromatique */ | ||
195 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
196 | .map_io = mx35_map_io, | ||
197 | .init_early = imx35_init_early, | ||
198 | .init_irq = mx35_init_irq, | ||
199 | .timer = &eukrea_cpuimx35_timer, | ||
200 | .init_machine = eukrea_cpuimx35_init, | ||
201 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c new file mode 100644 index 000000000000..1ecae20cf4e3 --- /dev/null +++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | * KZM-ARM11-01 support | ||
3 | * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.org> | ||
4 | * | ||
5 | * based on code for MX31ADS, | ||
6 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
7 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
8 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/serial_8250.h> | ||
25 | #include <linux/smsc911x.h> | ||
26 | #include <linux/types.h> | ||
27 | |||
28 | #include <asm/irq.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/memory.h> | ||
31 | #include <asm/setup.h> | ||
32 | #include <asm/mach/arch.h> | ||
33 | #include <asm/mach/irq.h> | ||
34 | #include <asm/mach/map.h> | ||
35 | #include <asm/mach/time.h> | ||
36 | |||
37 | #include <mach/clock.h> | ||
38 | #include <mach/common.h> | ||
39 | #include <mach/iomux-mx3.h> | ||
40 | |||
41 | #include "devices-imx31.h" | ||
42 | |||
43 | #define KZM_ARM11_IO_ADDRESS(x) (IOMEM( \ | ||
44 | IMX_IO_P2V_MODULE(x, MX31_CS4) ?: \ | ||
45 | IMX_IO_P2V_MODULE(x, MX31_CS5)) ?: \ | ||
46 | MX31_IO_ADDRESS(x)) | ||
47 | |||
48 | /* | ||
49 | * KZM-ARM11-01 Board Control Registers on FPGA | ||
50 | */ | ||
51 | #define KZM_ARM11_CTL1 (MX31_CS4_BASE_ADDR + 0x1000) | ||
52 | #define KZM_ARM11_CTL2 (MX31_CS4_BASE_ADDR + 0x1001) | ||
53 | #define KZM_ARM11_RSW1 (MX31_CS4_BASE_ADDR + 0x1002) | ||
54 | #define KZM_ARM11_BACK_LIGHT (MX31_CS4_BASE_ADDR + 0x1004) | ||
55 | #define KZM_ARM11_FPGA_REV (MX31_CS4_BASE_ADDR + 0x1008) | ||
56 | #define KZM_ARM11_7SEG_LED (MX31_CS4_BASE_ADDR + 0x1010) | ||
57 | #define KZM_ARM11_LEDS (MX31_CS4_BASE_ADDR + 0x1020) | ||
58 | #define KZM_ARM11_DIPSW2 (MX31_CS4_BASE_ADDR + 0x1003) | ||
59 | |||
60 | /* | ||
61 | * External UART for touch panel on FPGA | ||
62 | */ | ||
63 | #define KZM_ARM11_16550 (MX31_CS4_BASE_ADDR + 0x1050) | ||
64 | |||
65 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
66 | /* | ||
67 | * KZM-ARM11-01 has an external UART on FPGA | ||
68 | */ | ||
69 | static struct plat_serial8250_port serial_platform_data[] = { | ||
70 | { | ||
71 | .membase = KZM_ARM11_IO_ADDRESS(KZM_ARM11_16550), | ||
72 | .mapbase = KZM_ARM11_16550, | ||
73 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), | ||
74 | .irqflags = IRQ_TYPE_EDGE_RISING, | ||
75 | .uartclk = 14745600, | ||
76 | .regshift = 0, | ||
77 | .iotype = UPIO_MEM, | ||
78 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
79 | UPF_BUGGY_UART, | ||
80 | }, | ||
81 | {}, | ||
82 | }; | ||
83 | |||
84 | static struct resource serial8250_resources[] = { | ||
85 | { | ||
86 | .start = KZM_ARM11_16550, | ||
87 | .end = KZM_ARM11_16550 + 0x10, | ||
88 | .flags = IORESOURCE_MEM, | ||
89 | }, | ||
90 | { | ||
91 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), | ||
92 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), | ||
93 | .flags = IORESOURCE_IRQ, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct platform_device serial_device = { | ||
98 | .name = "serial8250", | ||
99 | .id = PLAT8250_DEV_PLATFORM, | ||
100 | .dev = { | ||
101 | .platform_data = serial_platform_data, | ||
102 | }, | ||
103 | .num_resources = ARRAY_SIZE(serial8250_resources), | ||
104 | .resource = serial8250_resources, | ||
105 | }; | ||
106 | |||
107 | static int __init kzm_init_ext_uart(void) | ||
108 | { | ||
109 | u8 tmp; | ||
110 | |||
111 | /* | ||
112 | * GPIO 1-1: external UART interrupt line | ||
113 | */ | ||
114 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO)); | ||
115 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int"); | ||
116 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); | ||
117 | |||
118 | /* | ||
119 | * Unmask UART interrupt | ||
120 | */ | ||
121 | tmp = __raw_readb(KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1)); | ||
122 | tmp |= 0x2; | ||
123 | __raw_writeb(tmp, KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1)); | ||
124 | |||
125 | return platform_device_register(&serial_device); | ||
126 | } | ||
127 | #else | ||
128 | static inline int kzm_init_ext_uart(void) | ||
129 | { | ||
130 | return 0; | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | /* | ||
135 | * SMSC LAN9118 | ||
136 | */ | ||
137 | #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) | ||
138 | static struct smsc911x_platform_config kzm_smsc9118_config = { | ||
139 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
140 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, | ||
141 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | ||
142 | .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, | ||
143 | }; | ||
144 | |||
145 | static struct resource kzm_smsc9118_resources[] = { | ||
146 | { | ||
147 | .start = MX31_CS5_BASE_ADDR, | ||
148 | .end = MX31_CS5_BASE_ADDR + SZ_128K - 1, | ||
149 | .flags = IORESOURCE_MEM, | ||
150 | }, | ||
151 | { | ||
152 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), | ||
153 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), | ||
154 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
155 | }, | ||
156 | }; | ||
157 | |||
158 | static struct platform_device kzm_smsc9118_device = { | ||
159 | .name = "smsc911x", | ||
160 | .id = -1, | ||
161 | .num_resources = ARRAY_SIZE(kzm_smsc9118_resources), | ||
162 | .resource = kzm_smsc9118_resources, | ||
163 | .dev = { | ||
164 | .platform_data = &kzm_smsc9118_config, | ||
165 | }, | ||
166 | }; | ||
167 | |||
168 | static int __init kzm_init_smsc9118(void) | ||
169 | { | ||
170 | /* | ||
171 | * GPIO 1-2: SMSC9118 interrupt line | ||
172 | */ | ||
173 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO)); | ||
174 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int"); | ||
175 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); | ||
176 | |||
177 | return platform_device_register(&kzm_smsc9118_device); | ||
178 | } | ||
179 | #else | ||
180 | static inline int kzm_init_smsc9118(void) | ||
181 | { | ||
182 | return 0; | ||
183 | } | ||
184 | #endif | ||
185 | |||
186 | #if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) | ||
187 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
188 | .flags = IMXUART_HAVE_RTSCTS, | ||
189 | }; | ||
190 | |||
191 | static void __init kzm_init_imx_uart(void) | ||
192 | { | ||
193 | imx31_add_imx_uart0(&uart_pdata); | ||
194 | imx31_add_imx_uart1(&uart_pdata); | ||
195 | } | ||
196 | #else | ||
197 | static inline void kzm_init_imx_uart(void) | ||
198 | { | ||
199 | } | ||
200 | #endif | ||
201 | |||
202 | static int kzm_pins[] __initdata = { | ||
203 | MX31_PIN_CTS1__CTS1, | ||
204 | MX31_PIN_RTS1__RTS1, | ||
205 | MX31_PIN_TXD1__TXD1, | ||
206 | MX31_PIN_RXD1__RXD1, | ||
207 | MX31_PIN_DCD_DCE1__DCD_DCE1, | ||
208 | MX31_PIN_RI_DCE1__RI_DCE1, | ||
209 | MX31_PIN_DSR_DCE1__DSR_DCE1, | ||
210 | MX31_PIN_DTR_DCE1__DTR_DCE1, | ||
211 | MX31_PIN_CTS2__CTS2, | ||
212 | MX31_PIN_RTS2__RTS2, | ||
213 | MX31_PIN_TXD2__TXD2, | ||
214 | MX31_PIN_RXD2__RXD2, | ||
215 | MX31_PIN_DCD_DTE1__DCD_DTE2, | ||
216 | MX31_PIN_RI_DTE1__RI_DTE2, | ||
217 | MX31_PIN_DSR_DTE1__DSR_DTE2, | ||
218 | MX31_PIN_DTR_DTE1__DTR_DTE2, | ||
219 | }; | ||
220 | |||
221 | /* | ||
222 | * Board specific initialization. | ||
223 | */ | ||
224 | static void __init kzm_board_init(void) | ||
225 | { | ||
226 | mxc_iomux_setup_multiple_pins(kzm_pins, | ||
227 | ARRAY_SIZE(kzm_pins), "kzm"); | ||
228 | kzm_init_ext_uart(); | ||
229 | kzm_init_smsc9118(); | ||
230 | kzm_init_imx_uart(); | ||
231 | |||
232 | pr_info("Clock input source is 26MHz\n"); | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * This structure defines static mappings for the kzm-arm11-01 board. | ||
237 | */ | ||
238 | static struct map_desc kzm_io_desc[] __initdata = { | ||
239 | { | ||
240 | .virtual = MX31_CS4_BASE_ADDR_VIRT, | ||
241 | .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), | ||
242 | .length = MX31_CS4_SIZE, | ||
243 | .type = MT_DEVICE | ||
244 | }, | ||
245 | { | ||
246 | .virtual = MX31_CS5_BASE_ADDR_VIRT, | ||
247 | .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR), | ||
248 | .length = MX31_CS5_SIZE, | ||
249 | .type = MT_DEVICE | ||
250 | }, | ||
251 | }; | ||
252 | |||
253 | /* | ||
254 | * Set up static virtual mappings. | ||
255 | */ | ||
256 | static void __init kzm_map_io(void) | ||
257 | { | ||
258 | mx31_map_io(); | ||
259 | iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc)); | ||
260 | } | ||
261 | |||
262 | static void __init kzm_timer_init(void) | ||
263 | { | ||
264 | mx31_clocks_init(26000000); | ||
265 | } | ||
266 | |||
267 | static struct sys_timer kzm_timer = { | ||
268 | .init = kzm_timer_init, | ||
269 | }; | ||
270 | |||
271 | MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01") | ||
272 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
273 | .map_io = kzm_map_io, | ||
274 | .init_early = imx31_init_early, | ||
275 | .init_irq = mx31_init_irq, | ||
276 | .timer = &kzm_timer, | ||
277 | .init_machine = kzm_board_init, | ||
278 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c new file mode 100644 index 000000000000..9b982449cb52 --- /dev/null +++ b/arch/arm/mach-imx/mach-mx31_3ds.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/delay.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/mfd/mc13783.h> | ||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/spi/l4f00242t03.h> | ||
25 | #include <linux/regulator/machine.h> | ||
26 | #include <linux/usb/otg.h> | ||
27 | #include <linux/usb/ulpi.h> | ||
28 | #include <linux/memblock.h> | ||
29 | |||
30 | #include <media/soc_camera.h> | ||
31 | |||
32 | #include <mach/hardware.h> | ||
33 | #include <asm/mach-types.h> | ||
34 | #include <asm/mach/arch.h> | ||
35 | #include <asm/mach/time.h> | ||
36 | #include <asm/memory.h> | ||
37 | #include <asm/mach/map.h> | ||
38 | #include <mach/common.h> | ||
39 | #include <mach/iomux-mx3.h> | ||
40 | #include <mach/3ds_debugboard.h> | ||
41 | #include <mach/ulpi.h> | ||
42 | |||
43 | #include "devices-imx31.h" | ||
44 | |||
45 | /* CPLD IRQ line for external uart, external ethernet etc */ | ||
46 | #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) | ||
47 | |||
48 | static int mx31_3ds_pins[] = { | ||
49 | /* UART1 */ | ||
50 | MX31_PIN_CTS1__CTS1, | ||
51 | MX31_PIN_RTS1__RTS1, | ||
52 | MX31_PIN_TXD1__TXD1, | ||
53 | MX31_PIN_RXD1__RXD1, | ||
54 | IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), | ||
55 | /*SPI0*/ | ||
56 | MX31_PIN_CSPI1_SCLK__SCLK, | ||
57 | MX31_PIN_CSPI1_MOSI__MOSI, | ||
58 | MX31_PIN_CSPI1_MISO__MISO, | ||
59 | MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, | ||
60 | MX31_PIN_CSPI1_SS2__SS2, /* CS for LCD */ | ||
61 | /* SPI 1 */ | ||
62 | MX31_PIN_CSPI2_SCLK__SCLK, | ||
63 | MX31_PIN_CSPI2_MOSI__MOSI, | ||
64 | MX31_PIN_CSPI2_MISO__MISO, | ||
65 | MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, | ||
66 | MX31_PIN_CSPI2_SS0__SS0, | ||
67 | MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ | ||
68 | /* MC13783 IRQ */ | ||
69 | IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), | ||
70 | /* USB OTG reset */ | ||
71 | IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO), | ||
72 | /* USB OTG */ | ||
73 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
74 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
75 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
76 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
77 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
78 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
79 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
80 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
81 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, | ||
82 | MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
83 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, | ||
84 | MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
85 | /*Keyboard*/ | ||
86 | MX31_PIN_KEY_ROW0_KEY_ROW0, | ||
87 | MX31_PIN_KEY_ROW1_KEY_ROW1, | ||
88 | MX31_PIN_KEY_ROW2_KEY_ROW2, | ||
89 | MX31_PIN_KEY_COL0_KEY_COL0, | ||
90 | MX31_PIN_KEY_COL1_KEY_COL1, | ||
91 | MX31_PIN_KEY_COL2_KEY_COL2, | ||
92 | MX31_PIN_KEY_COL3_KEY_COL3, | ||
93 | /* USB Host 2 */ | ||
94 | IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), | ||
95 | IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), | ||
96 | IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), | ||
97 | IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), | ||
98 | IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), | ||
99 | IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), | ||
100 | IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT1), | ||
101 | IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1), | ||
102 | IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1), | ||
103 | IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1), | ||
104 | IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1), | ||
105 | IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1), | ||
106 | /* USB Host2 reset */ | ||
107 | IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO), | ||
108 | /* I2C1 */ | ||
109 | MX31_PIN_I2C_CLK__I2C1_SCL, | ||
110 | MX31_PIN_I2C_DAT__I2C1_SDA, | ||
111 | /* SDHC1 */ | ||
112 | MX31_PIN_SD1_DATA3__SD1_DATA3, | ||
113 | MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
114 | MX31_PIN_SD1_DATA1__SD1_DATA1, | ||
115 | MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
116 | MX31_PIN_SD1_CLK__SD1_CLK, | ||
117 | MX31_PIN_SD1_CMD__SD1_CMD, | ||
118 | MX31_PIN_GPIO3_1__GPIO3_1, /* Card detect */ | ||
119 | MX31_PIN_GPIO3_0__GPIO3_0, /* OE */ | ||
120 | /* Framebuffer */ | ||
121 | MX31_PIN_LD0__LD0, | ||
122 | MX31_PIN_LD1__LD1, | ||
123 | MX31_PIN_LD2__LD2, | ||
124 | MX31_PIN_LD3__LD3, | ||
125 | MX31_PIN_LD4__LD4, | ||
126 | MX31_PIN_LD5__LD5, | ||
127 | MX31_PIN_LD6__LD6, | ||
128 | MX31_PIN_LD7__LD7, | ||
129 | MX31_PIN_LD8__LD8, | ||
130 | MX31_PIN_LD9__LD9, | ||
131 | MX31_PIN_LD10__LD10, | ||
132 | MX31_PIN_LD11__LD11, | ||
133 | MX31_PIN_LD12__LD12, | ||
134 | MX31_PIN_LD13__LD13, | ||
135 | MX31_PIN_LD14__LD14, | ||
136 | MX31_PIN_LD15__LD15, | ||
137 | MX31_PIN_LD16__LD16, | ||
138 | MX31_PIN_LD17__LD17, | ||
139 | MX31_PIN_VSYNC3__VSYNC3, | ||
140 | MX31_PIN_HSYNC__HSYNC, | ||
141 | MX31_PIN_FPSHIFT__FPSHIFT, | ||
142 | MX31_PIN_CONTRAST__CONTRAST, | ||
143 | /* CSI */ | ||
144 | MX31_PIN_CSI_D6__CSI_D6, | ||
145 | MX31_PIN_CSI_D7__CSI_D7, | ||
146 | MX31_PIN_CSI_D8__CSI_D8, | ||
147 | MX31_PIN_CSI_D9__CSI_D9, | ||
148 | MX31_PIN_CSI_D10__CSI_D10, | ||
149 | MX31_PIN_CSI_D11__CSI_D11, | ||
150 | MX31_PIN_CSI_D12__CSI_D12, | ||
151 | MX31_PIN_CSI_D13__CSI_D13, | ||
152 | MX31_PIN_CSI_D14__CSI_D14, | ||
153 | MX31_PIN_CSI_D15__CSI_D15, | ||
154 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, | ||
155 | MX31_PIN_CSI_MCLK__CSI_MCLK, | ||
156 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, | ||
157 | MX31_PIN_CSI_VSYNC__CSI_VSYNC, | ||
158 | MX31_PIN_CSI_D5__GPIO3_5, /* CMOS PWDN */ | ||
159 | IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_GPIO), /* CMOS reset */ | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * Camera support | ||
164 | */ | ||
165 | static phys_addr_t mx3_camera_base __initdata; | ||
166 | #define MX31_3DS_CAMERA_BUF_SIZE SZ_8M | ||
167 | |||
168 | #define MX31_3DS_GPIO_CAMERA_PW IOMUX_TO_GPIO(MX31_PIN_CSI_D5) | ||
169 | #define MX31_3DS_GPIO_CAMERA_RST IOMUX_TO_GPIO(MX31_PIN_RI_DTE1) | ||
170 | |||
171 | static struct gpio mx31_3ds_camera_gpios[] = { | ||
172 | { MX31_3DS_GPIO_CAMERA_PW, GPIOF_OUT_INIT_HIGH, "camera-power" }, | ||
173 | { MX31_3DS_GPIO_CAMERA_RST, GPIOF_OUT_INIT_HIGH, "camera-reset" }, | ||
174 | }; | ||
175 | |||
176 | static const struct mx3_camera_pdata mx31_3ds_camera_pdata __initconst = { | ||
177 | .flags = MX3_CAMERA_DATAWIDTH_10, | ||
178 | .mclk_10khz = 2600, | ||
179 | }; | ||
180 | |||
181 | static int __init mx31_3ds_init_camera(void) | ||
182 | { | ||
183 | int dma, ret = -ENOMEM; | ||
184 | struct platform_device *pdev = | ||
185 | imx31_alloc_mx3_camera(&mx31_3ds_camera_pdata); | ||
186 | |||
187 | if (IS_ERR(pdev)) | ||
188 | return PTR_ERR(pdev); | ||
189 | |||
190 | if (!mx3_camera_base) | ||
191 | goto err; | ||
192 | |||
193 | dma = dma_declare_coherent_memory(&pdev->dev, | ||
194 | mx3_camera_base, mx3_camera_base, | ||
195 | MX31_3DS_CAMERA_BUF_SIZE, | ||
196 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); | ||
197 | |||
198 | if (!(dma & DMA_MEMORY_MAP)) | ||
199 | goto err; | ||
200 | |||
201 | ret = platform_device_add(pdev); | ||
202 | if (ret) | ||
203 | err: | ||
204 | platform_device_put(pdev); | ||
205 | |||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static int mx31_3ds_camera_power(struct device *dev, int on) | ||
210 | { | ||
211 | /* enable or disable the camera */ | ||
212 | pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE"); | ||
213 | gpio_set_value(MX31_3DS_GPIO_CAMERA_PW, on ? 0 : 1); | ||
214 | |||
215 | if (!on) | ||
216 | goto out; | ||
217 | |||
218 | /* If enabled, give a reset impulse */ | ||
219 | gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 0); | ||
220 | msleep(20); | ||
221 | gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 1); | ||
222 | msleep(100); | ||
223 | |||
224 | out: | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static struct i2c_board_info mx31_3ds_i2c_camera = { | ||
229 | I2C_BOARD_INFO("ov2640", 0x30), | ||
230 | }; | ||
231 | |||
232 | static struct regulator_bulk_data mx31_3ds_camera_regs[] = { | ||
233 | { .supply = "cmos_vcore" }, | ||
234 | { .supply = "cmos_2v8" }, | ||
235 | }; | ||
236 | |||
237 | static struct soc_camera_link iclink_ov2640 = { | ||
238 | .bus_id = 0, | ||
239 | .board_info = &mx31_3ds_i2c_camera, | ||
240 | .i2c_adapter_id = 0, | ||
241 | .power = mx31_3ds_camera_power, | ||
242 | .regulators = mx31_3ds_camera_regs, | ||
243 | .num_regulators = ARRAY_SIZE(mx31_3ds_camera_regs), | ||
244 | }; | ||
245 | |||
246 | static struct platform_device mx31_3ds_ov2640 = { | ||
247 | .name = "soc-camera-pdrv", | ||
248 | .id = 0, | ||
249 | .dev = { | ||
250 | .platform_data = &iclink_ov2640, | ||
251 | }, | ||
252 | }; | ||
253 | |||
254 | /* | ||
255 | * FB support | ||
256 | */ | ||
257 | static const struct fb_videomode fb_modedb[] = { | ||
258 | { /* 480x640 @ 60 Hz */ | ||
259 | .name = "Epson-VGA", | ||
260 | .refresh = 60, | ||
261 | .xres = 480, | ||
262 | .yres = 640, | ||
263 | .pixclock = 41701, | ||
264 | .left_margin = 20, | ||
265 | .right_margin = 41, | ||
266 | .upper_margin = 10, | ||
267 | .lower_margin = 5, | ||
268 | .hsync_len = 20, | ||
269 | .vsync_len = 10, | ||
270 | .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, | ||
271 | .vmode = FB_VMODE_NONINTERLACED, | ||
272 | .flag = 0, | ||
273 | }, | ||
274 | }; | ||
275 | |||
276 | static struct ipu_platform_data mx3_ipu_data = { | ||
277 | .irq_base = MXC_IPU_IRQ_START, | ||
278 | }; | ||
279 | |||
280 | static struct mx3fb_platform_data mx3fb_pdata __initdata = { | ||
281 | .name = "Epson-VGA", | ||
282 | .mode = fb_modedb, | ||
283 | .num_modes = ARRAY_SIZE(fb_modedb), | ||
284 | }; | ||
285 | |||
286 | /* LCD */ | ||
287 | static struct l4f00242t03_pdata mx31_3ds_l4f00242t03_pdata = { | ||
288 | .reset_gpio = IOMUX_TO_GPIO(MX31_PIN_LCS1), | ||
289 | .data_enable_gpio = IOMUX_TO_GPIO(MX31_PIN_SER_RS), | ||
290 | .core_supply = "lcd_2v8", | ||
291 | .io_supply = "vdd_lcdio", | ||
292 | }; | ||
293 | |||
294 | /* | ||
295 | * Support for SD card slot in personality board | ||
296 | */ | ||
297 | #define MX31_3DS_GPIO_SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_GPIO3_1) | ||
298 | #define MX31_3DS_GPIO_SDHC1_BE IOMUX_TO_GPIO(MX31_PIN_GPIO3_0) | ||
299 | |||
300 | static struct gpio mx31_3ds_sdhc1_gpios[] = { | ||
301 | { MX31_3DS_GPIO_SDHC1_CD, GPIOF_IN, "sdhc1-card-detect" }, | ||
302 | { MX31_3DS_GPIO_SDHC1_BE, GPIOF_OUT_INIT_LOW, "sdhc1-bus-en" }, | ||
303 | }; | ||
304 | |||
305 | static int mx31_3ds_sdhc1_init(struct device *dev, | ||
306 | irq_handler_t detect_irq, | ||
307 | void *data) | ||
308 | { | ||
309 | int ret; | ||
310 | |||
311 | ret = gpio_request_array(mx31_3ds_sdhc1_gpios, | ||
312 | ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); | ||
313 | if (ret) { | ||
314 | pr_warning("Unable to request the SD/MMC GPIOs.\n"); | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), | ||
319 | detect_irq, IRQF_DISABLED | | ||
320 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
321 | "sdhc1-detect", data); | ||
322 | if (ret) { | ||
323 | pr_warning("Unable to request the SD/MMC card-detect IRQ.\n"); | ||
324 | goto gpio_free; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | |||
329 | gpio_free: | ||
330 | gpio_free_array(mx31_3ds_sdhc1_gpios, | ||
331 | ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static void mx31_3ds_sdhc1_exit(struct device *dev, void *data) | ||
336 | { | ||
337 | free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), data); | ||
338 | gpio_free_array(mx31_3ds_sdhc1_gpios, | ||
339 | ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); | ||
340 | } | ||
341 | |||
342 | static void mx31_3ds_sdhc1_setpower(struct device *dev, unsigned int vdd) | ||
343 | { | ||
344 | /* | ||
345 | * While the voltage stuff is done by the driver, activate the | ||
346 | * Buffer Enable Pin only if there is a card in slot to fix the card | ||
347 | * voltage issue caused by bi-directional chip TXB0108 on 3Stack. | ||
348 | * Done here because at this stage we have for sure a debounced value | ||
349 | * of the presence of the card, showed by the value of vdd. | ||
350 | * 7 == ilog2(MMC_VDD_165_195) | ||
351 | */ | ||
352 | if (vdd > 7) | ||
353 | gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 1); | ||
354 | else | ||
355 | gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 0); | ||
356 | } | ||
357 | |||
358 | static struct imxmmc_platform_data sdhc1_pdata = { | ||
359 | .init = mx31_3ds_sdhc1_init, | ||
360 | .exit = mx31_3ds_sdhc1_exit, | ||
361 | .setpower = mx31_3ds_sdhc1_setpower, | ||
362 | }; | ||
363 | |||
364 | /* | ||
365 | * Matrix keyboard | ||
366 | */ | ||
367 | |||
368 | static const uint32_t mx31_3ds_keymap[] = { | ||
369 | KEY(0, 0, KEY_UP), | ||
370 | KEY(0, 1, KEY_DOWN), | ||
371 | KEY(1, 0, KEY_RIGHT), | ||
372 | KEY(1, 1, KEY_LEFT), | ||
373 | KEY(1, 2, KEY_ENTER), | ||
374 | KEY(2, 0, KEY_F6), | ||
375 | KEY(2, 1, KEY_F8), | ||
376 | KEY(2, 2, KEY_F9), | ||
377 | KEY(2, 3, KEY_F10), | ||
378 | }; | ||
379 | |||
380 | static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = { | ||
381 | .keymap = mx31_3ds_keymap, | ||
382 | .keymap_size = ARRAY_SIZE(mx31_3ds_keymap), | ||
383 | }; | ||
384 | |||
385 | /* Regulators */ | ||
386 | static struct regulator_init_data pwgtx_init = { | ||
387 | .constraints = { | ||
388 | .boot_on = 1, | ||
389 | .always_on = 1, | ||
390 | }, | ||
391 | }; | ||
392 | |||
393 | static struct regulator_init_data gpo_init = { | ||
394 | .constraints = { | ||
395 | .boot_on = 1, | ||
396 | .always_on = 1, | ||
397 | } | ||
398 | }; | ||
399 | |||
400 | static struct regulator_consumer_supply vmmc2_consumers[] = { | ||
401 | REGULATOR_SUPPLY("vmmc", "mxc-mmc.0"), | ||
402 | }; | ||
403 | |||
404 | static struct regulator_init_data vmmc2_init = { | ||
405 | .constraints = { | ||
406 | .min_uV = 3000000, | ||
407 | .max_uV = 3000000, | ||
408 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
409 | REGULATOR_CHANGE_STATUS, | ||
410 | }, | ||
411 | .num_consumer_supplies = ARRAY_SIZE(vmmc2_consumers), | ||
412 | .consumer_supplies = vmmc2_consumers, | ||
413 | }; | ||
414 | |||
415 | static struct regulator_consumer_supply vmmc1_consumers[] = { | ||
416 | REGULATOR_SUPPLY("lcd_2v8", NULL), | ||
417 | REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"), | ||
418 | }; | ||
419 | |||
420 | static struct regulator_init_data vmmc1_init = { | ||
421 | .constraints = { | ||
422 | .min_uV = 2800000, | ||
423 | .max_uV = 2800000, | ||
424 | .apply_uV = 1, | ||
425 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
426 | REGULATOR_CHANGE_STATUS, | ||
427 | }, | ||
428 | .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers), | ||
429 | .consumer_supplies = vmmc1_consumers, | ||
430 | }; | ||
431 | |||
432 | static struct regulator_consumer_supply vgen_consumers[] = { | ||
433 | REGULATOR_SUPPLY("vdd_lcdio", NULL), | ||
434 | }; | ||
435 | |||
436 | static struct regulator_init_data vgen_init = { | ||
437 | .constraints = { | ||
438 | .min_uV = 1800000, | ||
439 | .max_uV = 1800000, | ||
440 | .apply_uV = 1, | ||
441 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
442 | REGULATOR_CHANGE_STATUS, | ||
443 | }, | ||
444 | .num_consumer_supplies = ARRAY_SIZE(vgen_consumers), | ||
445 | .consumer_supplies = vgen_consumers, | ||
446 | }; | ||
447 | |||
448 | static struct regulator_consumer_supply vvib_consumers[] = { | ||
449 | REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"), | ||
450 | }; | ||
451 | |||
452 | static struct regulator_init_data vvib_init = { | ||
453 | .constraints = { | ||
454 | .min_uV = 1300000, | ||
455 | .max_uV = 1300000, | ||
456 | .apply_uV = 1, | ||
457 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
458 | REGULATOR_CHANGE_STATUS, | ||
459 | }, | ||
460 | .num_consumer_supplies = ARRAY_SIZE(vvib_consumers), | ||
461 | .consumer_supplies = vvib_consumers, | ||
462 | }; | ||
463 | |||
464 | static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = { | ||
465 | { | ||
466 | .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */ | ||
467 | .init_data = &pwgtx_init, | ||
468 | }, { | ||
469 | .id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */ | ||
470 | .init_data = &pwgtx_init, | ||
471 | }, { | ||
472 | |||
473 | .id = MC13783_REG_GPO1, /* Turn on 1.8V */ | ||
474 | .init_data = &gpo_init, | ||
475 | }, { | ||
476 | .id = MC13783_REG_GPO3, /* Turn on 3.3V */ | ||
477 | .init_data = &gpo_init, | ||
478 | }, { | ||
479 | .id = MC13783_REG_VMMC2, /* Power MMC/SD, WiFi/Bluetooth. */ | ||
480 | .init_data = &vmmc2_init, | ||
481 | }, { | ||
482 | .id = MC13783_REG_VMMC1, /* Power LCD, CMOS, FM, GPS, Accel. */ | ||
483 | .init_data = &vmmc1_init, | ||
484 | }, { | ||
485 | .id = MC13783_REG_VGEN, /* Power LCD */ | ||
486 | .init_data = &vgen_init, | ||
487 | }, { | ||
488 | .id = MC13783_REG_VVIB, /* Power CMOS */ | ||
489 | .init_data = &vvib_init, | ||
490 | }, | ||
491 | }; | ||
492 | |||
493 | /* MC13783 */ | ||
494 | static struct mc13xxx_platform_data mc13783_pdata = { | ||
495 | .regulators = { | ||
496 | .regulators = mx31_3ds_regulators, | ||
497 | .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), | ||
498 | }, | ||
499 | .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN, | ||
500 | }; | ||
501 | |||
502 | /* SPI */ | ||
503 | static int spi0_internal_chipselect[] = { | ||
504 | MXC_SPI_CS(2), | ||
505 | }; | ||
506 | |||
507 | static const struct spi_imx_master spi0_pdata __initconst = { | ||
508 | .chipselect = spi0_internal_chipselect, | ||
509 | .num_chipselect = ARRAY_SIZE(spi0_internal_chipselect), | ||
510 | }; | ||
511 | |||
512 | static int spi1_internal_chipselect[] = { | ||
513 | MXC_SPI_CS(0), | ||
514 | MXC_SPI_CS(2), | ||
515 | }; | ||
516 | |||
517 | static const struct spi_imx_master spi1_pdata __initconst = { | ||
518 | .chipselect = spi1_internal_chipselect, | ||
519 | .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), | ||
520 | }; | ||
521 | |||
522 | static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { | ||
523 | { | ||
524 | .modalias = "mc13783", | ||
525 | .max_speed_hz = 1000000, | ||
526 | .bus_num = 1, | ||
527 | .chip_select = 1, /* SS2 */ | ||
528 | .platform_data = &mc13783_pdata, | ||
529 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
530 | .mode = SPI_CS_HIGH, | ||
531 | }, { | ||
532 | .modalias = "l4f00242t03", | ||
533 | .max_speed_hz = 5000000, | ||
534 | .bus_num = 0, | ||
535 | .chip_select = 0, /* SS2 */ | ||
536 | .platform_data = &mx31_3ds_l4f00242t03_pdata, | ||
537 | }, | ||
538 | }; | ||
539 | |||
540 | /* | ||
541 | * NAND Flash | ||
542 | */ | ||
543 | static const struct mxc_nand_platform_data | ||
544 | mx31_3ds_nand_board_info __initconst = { | ||
545 | .width = 1, | ||
546 | .hw_ecc = 1, | ||
547 | #ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT | ||
548 | .flash_bbt = 1, | ||
549 | #endif | ||
550 | }; | ||
551 | |||
552 | /* | ||
553 | * USB OTG | ||
554 | */ | ||
555 | |||
556 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
557 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
558 | |||
559 | #define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR) | ||
560 | #define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP) | ||
561 | |||
562 | static int mx31_3ds_usbotg_init(void) | ||
563 | { | ||
564 | int err; | ||
565 | |||
566 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); | ||
567 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); | ||
568 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); | ||
569 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); | ||
570 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); | ||
571 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); | ||
572 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); | ||
573 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); | ||
574 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); | ||
575 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); | ||
576 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); | ||
577 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); | ||
578 | |||
579 | err = gpio_request(USBOTG_RST_B, "otgusb-reset"); | ||
580 | if (err) { | ||
581 | pr_err("Failed to request the USB OTG reset gpio\n"); | ||
582 | return err; | ||
583 | } | ||
584 | |||
585 | err = gpio_direction_output(USBOTG_RST_B, 0); | ||
586 | if (err) { | ||
587 | pr_err("Failed to drive the USB OTG reset gpio\n"); | ||
588 | goto usbotg_free_reset; | ||
589 | } | ||
590 | |||
591 | mdelay(1); | ||
592 | gpio_set_value(USBOTG_RST_B, 1); | ||
593 | return 0; | ||
594 | |||
595 | usbotg_free_reset: | ||
596 | gpio_free(USBOTG_RST_B); | ||
597 | return err; | ||
598 | } | ||
599 | |||
600 | static int mx31_3ds_otg_init(struct platform_device *pdev) | ||
601 | { | ||
602 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); | ||
603 | } | ||
604 | |||
605 | static int mx31_3ds_host2_init(struct platform_device *pdev) | ||
606 | { | ||
607 | int err; | ||
608 | |||
609 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); | ||
610 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); | ||
611 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); | ||
612 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); | ||
613 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); | ||
614 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); | ||
615 | mxc_iomux_set_pad(MX31_PIN_PC_VS2, USB_PAD_CFG); | ||
616 | mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG); | ||
617 | mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG); | ||
618 | mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG); | ||
619 | mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG); | ||
620 | mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG); | ||
621 | |||
622 | err = gpio_request(USBH2_RST_B, "usbh2-reset"); | ||
623 | if (err) { | ||
624 | pr_err("Failed to request the USB Host 2 reset gpio\n"); | ||
625 | return err; | ||
626 | } | ||
627 | |||
628 | err = gpio_direction_output(USBH2_RST_B, 0); | ||
629 | if (err) { | ||
630 | pr_err("Failed to drive the USB Host 2 reset gpio\n"); | ||
631 | goto usbotg_free_reset; | ||
632 | } | ||
633 | |||
634 | mdelay(1); | ||
635 | gpio_set_value(USBH2_RST_B, 1); | ||
636 | |||
637 | mdelay(10); | ||
638 | |||
639 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); | ||
640 | |||
641 | usbotg_free_reset: | ||
642 | gpio_free(USBH2_RST_B); | ||
643 | return err; | ||
644 | } | ||
645 | |||
646 | static struct mxc_usbh_platform_data otg_pdata __initdata = { | ||
647 | .init = mx31_3ds_otg_init, | ||
648 | .portsc = MXC_EHCI_MODE_ULPI, | ||
649 | }; | ||
650 | |||
651 | static struct mxc_usbh_platform_data usbh2_pdata __initdata = { | ||
652 | .init = mx31_3ds_host2_init, | ||
653 | .portsc = MXC_EHCI_MODE_ULPI, | ||
654 | }; | ||
655 | |||
656 | static const struct fsl_usb2_platform_data usbotg_pdata __initconst = { | ||
657 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
658 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
659 | }; | ||
660 | |||
661 | static int otg_mode_host; | ||
662 | |||
663 | static int __init mx31_3ds_otg_mode(char *options) | ||
664 | { | ||
665 | if (!strcmp(options, "host")) | ||
666 | otg_mode_host = 1; | ||
667 | else if (!strcmp(options, "device")) | ||
668 | otg_mode_host = 0; | ||
669 | else | ||
670 | pr_info("otg_mode neither \"host\" nor \"device\". " | ||
671 | "Defaulting to device\n"); | ||
672 | return 0; | ||
673 | } | ||
674 | __setup("otg_mode=", mx31_3ds_otg_mode); | ||
675 | |||
676 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
677 | .flags = IMXUART_HAVE_RTSCTS, | ||
678 | }; | ||
679 | |||
680 | static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = { | ||
681 | .bitrate = 100000, | ||
682 | }; | ||
683 | |||
684 | static struct platform_device *devices[] __initdata = { | ||
685 | &mx31_3ds_ov2640, | ||
686 | }; | ||
687 | |||
688 | static void __init mx31_3ds_init(void) | ||
689 | { | ||
690 | int ret; | ||
691 | |||
692 | mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), | ||
693 | "mx31_3ds"); | ||
694 | |||
695 | imx31_add_imx_uart0(&uart_pdata); | ||
696 | imx31_add_mxc_nand(&mx31_3ds_nand_board_info); | ||
697 | |||
698 | imx31_add_spi_imx1(&spi1_pdata); | ||
699 | spi_register_board_info(mx31_3ds_spi_devs, | ||
700 | ARRAY_SIZE(mx31_3ds_spi_devs)); | ||
701 | |||
702 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
703 | |||
704 | imx31_add_imx_keypad(&mx31_3ds_keymap_data); | ||
705 | |||
706 | mx31_3ds_usbotg_init(); | ||
707 | if (otg_mode_host) { | ||
708 | otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
709 | ULPI_OTG_DRVVBUS_EXT); | ||
710 | if (otg_pdata.otg) | ||
711 | imx31_add_mxc_ehci_otg(&otg_pdata); | ||
712 | } | ||
713 | usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
714 | ULPI_OTG_DRVVBUS_EXT); | ||
715 | if (usbh2_pdata.otg) | ||
716 | imx31_add_mxc_ehci_hs(2, &usbh2_pdata); | ||
717 | |||
718 | if (!otg_mode_host) | ||
719 | imx31_add_fsl_usb2_udc(&usbotg_pdata); | ||
720 | |||
721 | if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT)) | ||
722 | printk(KERN_WARNING "Init of the debug board failed, all " | ||
723 | "devices on the debug board are unusable.\n"); | ||
724 | imx31_add_imx2_wdt(NULL); | ||
725 | imx31_add_imx_i2c0(&mx31_3ds_i2c0_data); | ||
726 | imx31_add_mxc_mmc(0, &sdhc1_pdata); | ||
727 | |||
728 | imx31_add_spi_imx0(&spi0_pdata); | ||
729 | imx31_add_ipu_core(&mx3_ipu_data); | ||
730 | imx31_add_mx3_sdc_fb(&mx3fb_pdata); | ||
731 | |||
732 | /* CSI */ | ||
733 | /* Camera power: default - off */ | ||
734 | ret = gpio_request_array(mx31_3ds_camera_gpios, | ||
735 | ARRAY_SIZE(mx31_3ds_camera_gpios)); | ||
736 | if (ret) { | ||
737 | pr_err("Failed to request camera gpios"); | ||
738 | iclink_ov2640.power = NULL; | ||
739 | } | ||
740 | |||
741 | mx31_3ds_init_camera(); | ||
742 | } | ||
743 | |||
744 | static void __init mx31_3ds_timer_init(void) | ||
745 | { | ||
746 | mx31_clocks_init(26000000); | ||
747 | } | ||
748 | |||
749 | static struct sys_timer mx31_3ds_timer = { | ||
750 | .init = mx31_3ds_timer_init, | ||
751 | }; | ||
752 | |||
753 | static void __init mx31_3ds_reserve(void) | ||
754 | { | ||
755 | /* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */ | ||
756 | mx3_camera_base = memblock_alloc(MX31_3DS_CAMERA_BUF_SIZE, | ||
757 | MX31_3DS_CAMERA_BUF_SIZE); | ||
758 | memblock_free(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE); | ||
759 | memblock_remove(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE); | ||
760 | } | ||
761 | |||
762 | MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") | ||
763 | /* Maintainer: Freescale Semiconductor, Inc. */ | ||
764 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
765 | .map_io = mx31_map_io, | ||
766 | .init_early = imx31_init_early, | ||
767 | .init_irq = mx31_init_irq, | ||
768 | .timer = &mx31_3ds_timer, | ||
769 | .init_machine = mx31_3ds_init, | ||
770 | .reserve = mx31_3ds_reserve, | ||
771 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c new file mode 100644 index 000000000000..f4dee0254634 --- /dev/null +++ b/arch/arm/mach-imx/mach-mx31ads.c | |||
@@ -0,0 +1,542 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
3 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
4 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
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 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/serial_8250.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/irq.h> | ||
24 | |||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | #include <asm/mach/time.h> | ||
28 | #include <asm/memory.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | #include <mach/common.h> | ||
31 | #include <mach/board-mx31ads.h> | ||
32 | #include <mach/iomux-mx3.h> | ||
33 | |||
34 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | ||
35 | #include <linux/mfd/wm8350/audio.h> | ||
36 | #include <linux/mfd/wm8350/core.h> | ||
37 | #include <linux/mfd/wm8350/pmic.h> | ||
38 | #endif | ||
39 | |||
40 | #include "devices-imx31.h" | ||
41 | |||
42 | /* PBC Board interrupt status register */ | ||
43 | #define PBC_INTSTATUS 0x000016 | ||
44 | |||
45 | /* PBC Board interrupt current status register */ | ||
46 | #define PBC_INTCURR_STATUS 0x000018 | ||
47 | |||
48 | /* PBC Interrupt mask register set address */ | ||
49 | #define PBC_INTMASK_SET 0x00001A | ||
50 | |||
51 | /* PBC Interrupt mask register clear address */ | ||
52 | #define PBC_INTMASK_CLEAR 0x00001C | ||
53 | |||
54 | /* External UART A */ | ||
55 | #define PBC_SC16C652_UARTA 0x010000 | ||
56 | |||
57 | /* External UART B */ | ||
58 | #define PBC_SC16C652_UARTB 0x010010 | ||
59 | |||
60 | #define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS) | ||
61 | #define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) | ||
62 | #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) | ||
63 | #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) | ||
64 | |||
65 | #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) | ||
66 | |||
67 | #define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) | ||
68 | #define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11) | ||
69 | |||
70 | #define MXC_MAX_EXP_IO_LINES 16 | ||
71 | |||
72 | /* | ||
73 | * The serial port definition structure. | ||
74 | */ | ||
75 | static struct plat_serial8250_port serial_platform_data[] = { | ||
76 | { | ||
77 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA), | ||
78 | .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA), | ||
79 | .irq = EXPIO_INT_XUART_INTA, | ||
80 | .uartclk = 14745600, | ||
81 | .regshift = 0, | ||
82 | .iotype = UPIO_MEM, | ||
83 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, | ||
84 | }, { | ||
85 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB), | ||
86 | .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB), | ||
87 | .irq = EXPIO_INT_XUART_INTB, | ||
88 | .uartclk = 14745600, | ||
89 | .regshift = 0, | ||
90 | .iotype = UPIO_MEM, | ||
91 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, | ||
92 | }, | ||
93 | {}, | ||
94 | }; | ||
95 | |||
96 | static struct platform_device serial_device = { | ||
97 | .name = "serial8250", | ||
98 | .id = 0, | ||
99 | .dev = { | ||
100 | .platform_data = serial_platform_data, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static int __init mxc_init_extuart(void) | ||
105 | { | ||
106 | return platform_device_register(&serial_device); | ||
107 | } | ||
108 | |||
109 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
110 | .flags = IMXUART_HAVE_RTSCTS, | ||
111 | }; | ||
112 | |||
113 | static unsigned int uart_pins[] = { | ||
114 | MX31_PIN_CTS1__CTS1, | ||
115 | MX31_PIN_RTS1__RTS1, | ||
116 | MX31_PIN_TXD1__TXD1, | ||
117 | MX31_PIN_RXD1__RXD1 | ||
118 | }; | ||
119 | |||
120 | static inline void mxc_init_imx_uart(void) | ||
121 | { | ||
122 | mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0"); | ||
123 | imx31_add_imx_uart0(&uart_pdata); | ||
124 | } | ||
125 | |||
126 | static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) | ||
127 | { | ||
128 | u32 imr_val; | ||
129 | u32 int_valid; | ||
130 | u32 expio_irq; | ||
131 | |||
132 | imr_val = __raw_readw(PBC_INTMASK_SET_REG); | ||
133 | int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; | ||
134 | |||
135 | expio_irq = MXC_EXP_IO_BASE; | ||
136 | for (; int_valid != 0; int_valid >>= 1, expio_irq++) { | ||
137 | if ((int_valid & 1) == 0) | ||
138 | continue; | ||
139 | |||
140 | generic_handle_irq(expio_irq); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Disable an expio pin's interrupt by setting the bit in the imr. | ||
146 | * @param d an expio virtual irq description | ||
147 | */ | ||
148 | static void expio_mask_irq(struct irq_data *d) | ||
149 | { | ||
150 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | ||
151 | /* mask the interrupt */ | ||
152 | __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); | ||
153 | __raw_readw(PBC_INTMASK_CLEAR_REG); | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr. | ||
158 | * @param d an expio virtual irq description | ||
159 | */ | ||
160 | static void expio_ack_irq(struct irq_data *d) | ||
161 | { | ||
162 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | ||
163 | /* clear the interrupt status */ | ||
164 | __raw_writew(1 << expio, PBC_INTSTATUS_REG); | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Enable a expio pin's interrupt by clearing the bit in the imr. | ||
169 | * @param d an expio virtual irq description | ||
170 | */ | ||
171 | static void expio_unmask_irq(struct irq_data *d) | ||
172 | { | ||
173 | u32 expio = MXC_IRQ_TO_EXPIO(d->irq); | ||
174 | /* unmask the interrupt */ | ||
175 | __raw_writew(1 << expio, PBC_INTMASK_SET_REG); | ||
176 | } | ||
177 | |||
178 | static struct irq_chip expio_irq_chip = { | ||
179 | .name = "EXPIO(CPLD)", | ||
180 | .irq_ack = expio_ack_irq, | ||
181 | .irq_mask = expio_mask_irq, | ||
182 | .irq_unmask = expio_unmask_irq, | ||
183 | }; | ||
184 | |||
185 | static void __init mx31ads_init_expio(void) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); | ||
190 | |||
191 | /* | ||
192 | * Configure INT line as GPIO input | ||
193 | */ | ||
194 | mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); | ||
195 | |||
196 | /* disable the interrupt and clear the status */ | ||
197 | __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); | ||
198 | __raw_writew(0xFFFF, PBC_INTSTATUS_REG); | ||
199 | for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); | ||
200 | i++) { | ||
201 | irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); | ||
202 | set_irq_flags(i, IRQF_VALID); | ||
203 | } | ||
204 | irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH); | ||
205 | irq_set_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); | ||
206 | } | ||
207 | |||
208 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | ||
209 | /* This section defines setup for the Wolfson Microelectronics | ||
210 | * 1133-EV1 PMU/audio board. When other PMU boards are supported the | ||
211 | * regulator definitions may be shared with them, but for now they can | ||
212 | * only be used with this board so would generate warnings about | ||
213 | * unused statics and some of the configuration is specific to this | ||
214 | * module. | ||
215 | */ | ||
216 | |||
217 | /* CPU */ | ||
218 | static struct regulator_consumer_supply sw1a_consumers[] = { | ||
219 | { | ||
220 | .supply = "cpu_vcc", | ||
221 | } | ||
222 | }; | ||
223 | |||
224 | static struct regulator_init_data sw1a_data = { | ||
225 | .constraints = { | ||
226 | .name = "SW1A", | ||
227 | .min_uV = 1275000, | ||
228 | .max_uV = 1600000, | ||
229 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
230 | REGULATOR_CHANGE_MODE, | ||
231 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
232 | REGULATOR_MODE_FAST, | ||
233 | .state_mem = { | ||
234 | .uV = 1400000, | ||
235 | .mode = REGULATOR_MODE_NORMAL, | ||
236 | .enabled = 1, | ||
237 | }, | ||
238 | .initial_state = PM_SUSPEND_MEM, | ||
239 | .always_on = 1, | ||
240 | .boot_on = 1, | ||
241 | }, | ||
242 | .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers), | ||
243 | .consumer_supplies = sw1a_consumers, | ||
244 | }; | ||
245 | |||
246 | /* System IO - High */ | ||
247 | static struct regulator_init_data viohi_data = { | ||
248 | .constraints = { | ||
249 | .name = "VIOHO", | ||
250 | .min_uV = 2800000, | ||
251 | .max_uV = 2800000, | ||
252 | .state_mem = { | ||
253 | .uV = 2800000, | ||
254 | .mode = REGULATOR_MODE_NORMAL, | ||
255 | .enabled = 1, | ||
256 | }, | ||
257 | .initial_state = PM_SUSPEND_MEM, | ||
258 | .always_on = 1, | ||
259 | .boot_on = 1, | ||
260 | }, | ||
261 | }; | ||
262 | |||
263 | /* System IO - Low */ | ||
264 | static struct regulator_init_data violo_data = { | ||
265 | .constraints = { | ||
266 | .name = "VIOLO", | ||
267 | .min_uV = 1800000, | ||
268 | .max_uV = 1800000, | ||
269 | .state_mem = { | ||
270 | .uV = 1800000, | ||
271 | .mode = REGULATOR_MODE_NORMAL, | ||
272 | .enabled = 1, | ||
273 | }, | ||
274 | .initial_state = PM_SUSPEND_MEM, | ||
275 | .always_on = 1, | ||
276 | .boot_on = 1, | ||
277 | }, | ||
278 | }; | ||
279 | |||
280 | /* DDR RAM */ | ||
281 | static struct regulator_init_data sw2a_data = { | ||
282 | .constraints = { | ||
283 | .name = "SW2A", | ||
284 | .min_uV = 1800000, | ||
285 | .max_uV = 1800000, | ||
286 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
287 | .state_mem = { | ||
288 | .uV = 1800000, | ||
289 | .mode = REGULATOR_MODE_NORMAL, | ||
290 | .enabled = 1, | ||
291 | }, | ||
292 | .state_disk = { | ||
293 | .mode = REGULATOR_MODE_NORMAL, | ||
294 | .enabled = 0, | ||
295 | }, | ||
296 | .always_on = 1, | ||
297 | .boot_on = 1, | ||
298 | .initial_state = PM_SUSPEND_MEM, | ||
299 | }, | ||
300 | }; | ||
301 | |||
302 | static struct regulator_init_data ldo1_data = { | ||
303 | .constraints = { | ||
304 | .name = "VCAM/VMMC1/VMMC2", | ||
305 | .min_uV = 2800000, | ||
306 | .max_uV = 2800000, | ||
307 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
308 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
309 | .apply_uV = 1, | ||
310 | }, | ||
311 | }; | ||
312 | |||
313 | static struct regulator_consumer_supply ldo2_consumers[] = { | ||
314 | { .supply = "AVDD", .dev_name = "1-001a" }, | ||
315 | { .supply = "HPVDD", .dev_name = "1-001a" }, | ||
316 | }; | ||
317 | |||
318 | /* CODEC and SIM */ | ||
319 | static struct regulator_init_data ldo2_data = { | ||
320 | .constraints = { | ||
321 | .name = "VESIM/VSIM/AVDD", | ||
322 | .min_uV = 3300000, | ||
323 | .max_uV = 3300000, | ||
324 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
325 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
326 | .apply_uV = 1, | ||
327 | }, | ||
328 | .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers), | ||
329 | .consumer_supplies = ldo2_consumers, | ||
330 | }; | ||
331 | |||
332 | /* General */ | ||
333 | static struct regulator_init_data vdig_data = { | ||
334 | .constraints = { | ||
335 | .name = "VDIG", | ||
336 | .min_uV = 1500000, | ||
337 | .max_uV = 1500000, | ||
338 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
339 | .apply_uV = 1, | ||
340 | .always_on = 1, | ||
341 | .boot_on = 1, | ||
342 | }, | ||
343 | }; | ||
344 | |||
345 | /* Tranceivers */ | ||
346 | static struct regulator_init_data ldo4_data = { | ||
347 | .constraints = { | ||
348 | .name = "VRF1/CVDD_2.775", | ||
349 | .min_uV = 2500000, | ||
350 | .max_uV = 2500000, | ||
351 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
352 | .apply_uV = 1, | ||
353 | .always_on = 1, | ||
354 | .boot_on = 1, | ||
355 | }, | ||
356 | }; | ||
357 | |||
358 | static struct wm8350_led_platform_data wm8350_led_data = { | ||
359 | .name = "wm8350:white", | ||
360 | .default_trigger = "heartbeat", | ||
361 | .max_uA = 27899, | ||
362 | }; | ||
363 | |||
364 | static struct wm8350_audio_platform_data imx32ads_wm8350_setup = { | ||
365 | .vmid_discharge_msecs = 1000, | ||
366 | .drain_msecs = 30, | ||
367 | .cap_discharge_msecs = 700, | ||
368 | .vmid_charge_msecs = 700, | ||
369 | .vmid_s_curve = WM8350_S_CURVE_SLOW, | ||
370 | .dis_out4 = WM8350_DISCHARGE_SLOW, | ||
371 | .dis_out3 = WM8350_DISCHARGE_SLOW, | ||
372 | .dis_out2 = WM8350_DISCHARGE_SLOW, | ||
373 | .dis_out1 = WM8350_DISCHARGE_SLOW, | ||
374 | .vroi_out4 = WM8350_TIE_OFF_500R, | ||
375 | .vroi_out3 = WM8350_TIE_OFF_500R, | ||
376 | .vroi_out2 = WM8350_TIE_OFF_500R, | ||
377 | .vroi_out1 = WM8350_TIE_OFF_500R, | ||
378 | .vroi_enable = 0, | ||
379 | .codec_current_on = WM8350_CODEC_ISEL_1_0, | ||
380 | .codec_current_standby = WM8350_CODEC_ISEL_0_5, | ||
381 | .codec_current_charge = WM8350_CODEC_ISEL_1_5, | ||
382 | }; | ||
383 | |||
384 | static int mx31_wm8350_init(struct wm8350 *wm8350) | ||
385 | { | ||
386 | wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN, | ||
387 | WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW, | ||
388 | WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF, | ||
389 | WM8350_GPIO_DEBOUNCE_ON); | ||
390 | |||
391 | wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN, | ||
392 | WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH, | ||
393 | WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, | ||
394 | WM8350_GPIO_DEBOUNCE_ON); | ||
395 | |||
396 | wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN, | ||
397 | WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH, | ||
398 | WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, | ||
399 | WM8350_GPIO_DEBOUNCE_OFF); | ||
400 | |||
401 | wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN, | ||
402 | WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH, | ||
403 | WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, | ||
404 | WM8350_GPIO_DEBOUNCE_OFF); | ||
405 | |||
406 | wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT, | ||
407 | WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH, | ||
408 | WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, | ||
409 | WM8350_GPIO_DEBOUNCE_OFF); | ||
410 | |||
411 | wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT, | ||
412 | WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, | ||
413 | WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, | ||
414 | WM8350_GPIO_DEBOUNCE_OFF); | ||
415 | |||
416 | wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT, | ||
417 | WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, | ||
418 | WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, | ||
419 | WM8350_GPIO_DEBOUNCE_OFF); | ||
420 | |||
421 | wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data); | ||
422 | wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data); | ||
423 | wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data); | ||
424 | wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data); | ||
425 | wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data); | ||
426 | wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data); | ||
427 | wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data); | ||
428 | wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data); | ||
429 | |||
430 | /* LEDs */ | ||
431 | wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1, | ||
432 | WM8350_DC5_ERRACT_SHUTDOWN_CONV); | ||
433 | wm8350_isink_set_flash(wm8350, WM8350_ISINK_A, | ||
434 | WM8350_ISINK_FLASH_DISABLE, | ||
435 | WM8350_ISINK_FLASH_TRIG_BIT, | ||
436 | WM8350_ISINK_FLASH_DUR_32MS, | ||
437 | WM8350_ISINK_FLASH_ON_INSTANT, | ||
438 | WM8350_ISINK_FLASH_OFF_INSTANT, | ||
439 | WM8350_ISINK_FLASH_MODE_EN); | ||
440 | wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5, | ||
441 | WM8350_ISINK_MODE_BOOST, | ||
442 | WM8350_ISINK_ILIM_NORMAL, | ||
443 | WM8350_DC5_RMP_20V, | ||
444 | WM8350_DC5_FBSRC_ISINKA); | ||
445 | wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A, | ||
446 | &wm8350_led_data); | ||
447 | |||
448 | wm8350->codec.platform_data = &imx32ads_wm8350_setup; | ||
449 | |||
450 | regulator_has_full_constraints(); | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static struct wm8350_platform_data __initdata mx31_wm8350_pdata = { | ||
456 | .init = mx31_wm8350_init, | ||
457 | .irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES, | ||
458 | }; | ||
459 | #endif | ||
460 | |||
461 | static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { | ||
462 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | ||
463 | { | ||
464 | I2C_BOARD_INFO("wm8350", 0x1a), | ||
465 | .platform_data = &mx31_wm8350_pdata, | ||
466 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
467 | }, | ||
468 | #endif | ||
469 | }; | ||
470 | |||
471 | static void mxc_init_i2c(void) | ||
472 | { | ||
473 | i2c_register_board_info(1, mx31ads_i2c1_devices, | ||
474 | ARRAY_SIZE(mx31ads_i2c1_devices)); | ||
475 | |||
476 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1)); | ||
477 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1)); | ||
478 | |||
479 | imx31_add_imx_i2c1(NULL); | ||
480 | } | ||
481 | |||
482 | static unsigned int ssi_pins[] = { | ||
483 | MX31_PIN_SFS5__SFS5, | ||
484 | MX31_PIN_SCK5__SCK5, | ||
485 | MX31_PIN_SRXD5__SRXD5, | ||
486 | MX31_PIN_STXD5__STXD5, | ||
487 | }; | ||
488 | |||
489 | static void mxc_init_audio(void) | ||
490 | { | ||
491 | imx31_add_imx_ssi(0, NULL); | ||
492 | mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); | ||
493 | } | ||
494 | |||
495 | /* static mappings */ | ||
496 | static struct map_desc mx31ads_io_desc[] __initdata = { | ||
497 | { | ||
498 | .virtual = MX31_CS4_BASE_ADDR_VIRT, | ||
499 | .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), | ||
500 | .length = MX31_CS4_SIZE / 2, | ||
501 | .type = MT_DEVICE | ||
502 | }, | ||
503 | }; | ||
504 | |||
505 | static void __init mx31ads_map_io(void) | ||
506 | { | ||
507 | mx31_map_io(); | ||
508 | iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); | ||
509 | } | ||
510 | |||
511 | static void __init mx31ads_init_irq(void) | ||
512 | { | ||
513 | mx31_init_irq(); | ||
514 | mx31ads_init_expio(); | ||
515 | } | ||
516 | |||
517 | static void __init mx31ads_init(void) | ||
518 | { | ||
519 | mxc_init_extuart(); | ||
520 | mxc_init_imx_uart(); | ||
521 | mxc_init_i2c(); | ||
522 | mxc_init_audio(); | ||
523 | } | ||
524 | |||
525 | static void __init mx31ads_timer_init(void) | ||
526 | { | ||
527 | mx31_clocks_init(26000000); | ||
528 | } | ||
529 | |||
530 | static struct sys_timer mx31ads_timer = { | ||
531 | .init = mx31ads_timer_init, | ||
532 | }; | ||
533 | |||
534 | MACHINE_START(MX31ADS, "Freescale MX31ADS") | ||
535 | /* Maintainer: Freescale Semiconductor, Inc. */ | ||
536 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
537 | .map_io = mx31ads_map_io, | ||
538 | .init_early = imx31_init_early, | ||
539 | .init_irq = mx31ads_init_irq, | ||
540 | .timer = &mx31ads_timer, | ||
541 | .init_machine = mx31ads_init, | ||
542 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c new file mode 100644 index 000000000000..410e676ae087 --- /dev/null +++ b/arch/arm/mach-imx/mach-mx31lilly.c | |||
@@ -0,0 +1,302 @@ | |||
1 | /* | ||
2 | * LILLY-1131 module support | ||
3 | * | ||
4 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
5 | * | ||
6 | * based on code for other MX31 boards, | ||
7 | * | ||
8 | * Copyright 2005-2007 Freescale Semiconductor | ||
9 | * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
10 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | */ | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/smsc911x.h> | ||
31 | #include <linux/mtd/physmap.h> | ||
32 | #include <linux/spi/spi.h> | ||
33 | #include <linux/mfd/mc13783.h> | ||
34 | #include <linux/usb/otg.h> | ||
35 | #include <linux/usb/ulpi.h> | ||
36 | |||
37 | #include <asm/mach-types.h> | ||
38 | #include <asm/mach/arch.h> | ||
39 | #include <asm/mach/time.h> | ||
40 | #include <asm/mach/map.h> | ||
41 | |||
42 | #include <mach/hardware.h> | ||
43 | #include <mach/common.h> | ||
44 | #include <mach/iomux-mx3.h> | ||
45 | #include <mach/board-mx31lilly.h> | ||
46 | #include <mach/ulpi.h> | ||
47 | |||
48 | #include "devices-imx31.h" | ||
49 | |||
50 | /* | ||
51 | * This file contains module-specific initialization routines for LILLY-1131. | ||
52 | * Initialization of peripherals found on the baseboard is implemented in the | ||
53 | * appropriate baseboard support code. | ||
54 | */ | ||
55 | |||
56 | /* SMSC ethernet support */ | ||
57 | |||
58 | static struct resource smsc91x_resources[] = { | ||
59 | { | ||
60 | .start = MX31_CS4_BASE_ADDR, | ||
61 | .end = MX31_CS4_BASE_ADDR + 0xffff, | ||
62 | .flags = IORESOURCE_MEM, | ||
63 | }, | ||
64 | { | ||
65 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), | ||
66 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), | ||
67 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, | ||
68 | } | ||
69 | }; | ||
70 | |||
71 | static struct smsc911x_platform_config smsc911x_config = { | ||
72 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
73 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
74 | .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, | ||
75 | .flags = SMSC911X_USE_32BIT | | ||
76 | SMSC911X_SAVE_MAC_ADDRESS | | ||
77 | SMSC911X_FORCE_INTERNAL_PHY, | ||
78 | }; | ||
79 | |||
80 | static struct platform_device smsc91x_device = { | ||
81 | .name = "smsc911x", | ||
82 | .id = -1, | ||
83 | .num_resources = ARRAY_SIZE(smsc91x_resources), | ||
84 | .resource = smsc91x_resources, | ||
85 | .dev = { | ||
86 | .platform_data = &smsc911x_config, | ||
87 | } | ||
88 | }; | ||
89 | |||
90 | /* NOR flash */ | ||
91 | static struct physmap_flash_data nor_flash_data = { | ||
92 | .width = 2, | ||
93 | }; | ||
94 | |||
95 | static struct resource nor_flash_resource = { | ||
96 | .start = 0xa0000000, | ||
97 | .end = 0xa1ffffff, | ||
98 | .flags = IORESOURCE_MEM, | ||
99 | }; | ||
100 | |||
101 | static struct platform_device physmap_flash_device = { | ||
102 | .name = "physmap-flash", | ||
103 | .id = 0, | ||
104 | .dev = { | ||
105 | .platform_data = &nor_flash_data, | ||
106 | }, | ||
107 | .resource = &nor_flash_resource, | ||
108 | .num_resources = 1, | ||
109 | }; | ||
110 | |||
111 | /* USB */ | ||
112 | |||
113 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
114 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
115 | |||
116 | static int usbh1_init(struct platform_device *pdev) | ||
117 | { | ||
118 | int pins[] = { | ||
119 | MX31_PIN_CSPI1_MOSI__USBH1_RXDM, | ||
120 | MX31_PIN_CSPI1_MISO__USBH1_RXDP, | ||
121 | MX31_PIN_CSPI1_SS0__USBH1_TXDM, | ||
122 | MX31_PIN_CSPI1_SS1__USBH1_TXDP, | ||
123 | MX31_PIN_CSPI1_SS2__USBH1_RCV, | ||
124 | MX31_PIN_CSPI1_SCLK__USBH1_OEB, | ||
125 | MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, | ||
126 | }; | ||
127 | |||
128 | mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H1"); | ||
129 | |||
130 | mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); | ||
131 | mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); | ||
132 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); | ||
133 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); | ||
134 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); | ||
135 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); | ||
136 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); | ||
137 | |||
138 | mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); | ||
139 | |||
140 | mdelay(10); | ||
141 | |||
142 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | | ||
143 | MXC_EHCI_INTERFACE_SINGLE_UNI); | ||
144 | } | ||
145 | |||
146 | static int usbh2_init(struct platform_device *pdev) | ||
147 | { | ||
148 | int pins[] = { | ||
149 | MX31_PIN_USBH2_DATA0__USBH2_DATA0, | ||
150 | MX31_PIN_USBH2_DATA1__USBH2_DATA1, | ||
151 | MX31_PIN_USBH2_CLK__USBH2_CLK, | ||
152 | MX31_PIN_USBH2_DIR__USBH2_DIR, | ||
153 | MX31_PIN_USBH2_NXT__USBH2_NXT, | ||
154 | MX31_PIN_USBH2_STP__USBH2_STP, | ||
155 | }; | ||
156 | |||
157 | mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2"); | ||
158 | |||
159 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); | ||
160 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); | ||
161 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); | ||
162 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); | ||
163 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); | ||
164 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); | ||
165 | mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); | ||
166 | mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); | ||
167 | mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); | ||
168 | mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); | ||
169 | mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); | ||
170 | mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); | ||
171 | |||
172 | mxc_iomux_set_gpr(MUX_PGP_UH2, true); | ||
173 | |||
174 | /* chip select */ | ||
175 | mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO), | ||
176 | "USBH2_CS"); | ||
177 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS"); | ||
178 | gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0); | ||
179 | |||
180 | mdelay(10); | ||
181 | |||
182 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); | ||
183 | } | ||
184 | |||
185 | static const struct mxc_usbh_platform_data usbh1_pdata __initconst = { | ||
186 | .init = usbh1_init, | ||
187 | .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, | ||
188 | }; | ||
189 | |||
190 | static struct mxc_usbh_platform_data usbh2_pdata __initdata = { | ||
191 | .init = usbh2_init, | ||
192 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
193 | }; | ||
194 | |||
195 | static void lilly1131_usb_init(void) | ||
196 | { | ||
197 | imx31_add_mxc_ehci_hs(1, &usbh1_pdata); | ||
198 | |||
199 | usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
200 | ULPI_OTG_DRVVBUS_EXT); | ||
201 | if (usbh2_pdata.otg) | ||
202 | imx31_add_mxc_ehci_hs(2, &usbh2_pdata); | ||
203 | } | ||
204 | |||
205 | /* SPI */ | ||
206 | |||
207 | static int spi_internal_chipselect[] = { | ||
208 | MXC_SPI_CS(0), | ||
209 | MXC_SPI_CS(1), | ||
210 | MXC_SPI_CS(2), | ||
211 | }; | ||
212 | |||
213 | static const struct spi_imx_master spi0_pdata __initconst = { | ||
214 | .chipselect = spi_internal_chipselect, | ||
215 | .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), | ||
216 | }; | ||
217 | |||
218 | static const struct spi_imx_master spi1_pdata __initconst = { | ||
219 | .chipselect = spi_internal_chipselect, | ||
220 | .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), | ||
221 | }; | ||
222 | |||
223 | static struct mc13xxx_platform_data mc13783_pdata __initdata = { | ||
224 | .flags = MC13XXX_USE_RTC | MC13XXX_USE_TOUCHSCREEN, | ||
225 | }; | ||
226 | |||
227 | static struct spi_board_info mc13783_dev __initdata = { | ||
228 | .modalias = "mc13783", | ||
229 | .max_speed_hz = 1000000, | ||
230 | .bus_num = 1, | ||
231 | .chip_select = 0, | ||
232 | .platform_data = &mc13783_pdata, | ||
233 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
234 | }; | ||
235 | |||
236 | static struct platform_device *devices[] __initdata = { | ||
237 | &smsc91x_device, | ||
238 | &physmap_flash_device, | ||
239 | }; | ||
240 | |||
241 | static int mx31lilly_baseboard; | ||
242 | core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444); | ||
243 | |||
244 | static void __init mx31lilly_board_init(void) | ||
245 | { | ||
246 | switch (mx31lilly_baseboard) { | ||
247 | case MX31LILLY_NOBOARD: | ||
248 | break; | ||
249 | case MX31LILLY_DB: | ||
250 | mx31lilly_db_init(); | ||
251 | break; | ||
252 | default: | ||
253 | printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n", | ||
254 | mx31lilly_baseboard); | ||
255 | } | ||
256 | |||
257 | mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS"); | ||
258 | |||
259 | /* SPI */ | ||
260 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK"); | ||
261 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX"); | ||
262 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX"); | ||
263 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY"); | ||
264 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0"); | ||
265 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1"); | ||
266 | mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2"); | ||
267 | |||
268 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK"); | ||
269 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX"); | ||
270 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX"); | ||
271 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY"); | ||
272 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0"); | ||
273 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1"); | ||
274 | mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2"); | ||
275 | |||
276 | imx31_add_spi_imx0(&spi0_pdata); | ||
277 | imx31_add_spi_imx1(&spi1_pdata); | ||
278 | spi_register_board_info(&mc13783_dev, 1); | ||
279 | |||
280 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
281 | |||
282 | /* USB */ | ||
283 | lilly1131_usb_init(); | ||
284 | } | ||
285 | |||
286 | static void __init mx31lilly_timer_init(void) | ||
287 | { | ||
288 | mx31_clocks_init(26000000); | ||
289 | } | ||
290 | |||
291 | static struct sys_timer mx31lilly_timer = { | ||
292 | .init = mx31lilly_timer_init, | ||
293 | }; | ||
294 | |||
295 | MACHINE_START(LILLY1131, "INCO startec LILLY-1131") | ||
296 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
297 | .map_io = mx31_map_io, | ||
298 | .init_early = imx31_init_early, | ||
299 | .init_irq = mx31_init_irq, | ||
300 | .timer = &mx31lilly_timer, | ||
301 | .init_machine = mx31lilly_board_init, | ||
302 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c new file mode 100644 index 000000000000..ac9b4cad320e --- /dev/null +++ b/arch/arm/mach-imx/mach-mx31lite.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
3 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
4 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
5 | * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/memory.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/smsc911x.h> | ||
25 | #include <linux/mfd/mc13783.h> | ||
26 | #include <linux/spi/spi.h> | ||
27 | #include <linux/usb/otg.h> | ||
28 | #include <linux/usb/ulpi.h> | ||
29 | #include <linux/mtd/physmap.h> | ||
30 | #include <linux/delay.h> | ||
31 | |||
32 | #include <asm/mach-types.h> | ||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/time.h> | ||
35 | #include <asm/mach/map.h> | ||
36 | #include <asm/page.h> | ||
37 | #include <asm/setup.h> | ||
38 | |||
39 | #include <mach/hardware.h> | ||
40 | #include <mach/common.h> | ||
41 | #include <mach/board-mx31lite.h> | ||
42 | #include <mach/iomux-mx3.h> | ||
43 | #include <mach/irqs.h> | ||
44 | #include <mach/ulpi.h> | ||
45 | |||
46 | #include "devices-imx31.h" | ||
47 | |||
48 | /* | ||
49 | * This file contains the module-specific initialization routines. | ||
50 | */ | ||
51 | |||
52 | static unsigned int mx31lite_pins[] = { | ||
53 | /* LAN9117 IRQ pin */ | ||
54 | IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), | ||
55 | /* SPI 1 */ | ||
56 | MX31_PIN_CSPI2_SCLK__SCLK, | ||
57 | MX31_PIN_CSPI2_MOSI__MOSI, | ||
58 | MX31_PIN_CSPI2_MISO__MISO, | ||
59 | MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, | ||
60 | MX31_PIN_CSPI2_SS0__SS0, | ||
61 | MX31_PIN_CSPI2_SS1__SS1, | ||
62 | MX31_PIN_CSPI2_SS2__SS2, | ||
63 | }; | ||
64 | |||
65 | static const struct mxc_nand_platform_data | ||
66 | mx31lite_nand_board_info __initconst = { | ||
67 | .width = 1, | ||
68 | .hw_ecc = 1, | ||
69 | }; | ||
70 | |||
71 | static struct smsc911x_platform_config smsc911x_config = { | ||
72 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
73 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | ||
74 | .flags = SMSC911X_USE_16BIT, | ||
75 | }; | ||
76 | |||
77 | static struct resource smsc911x_resources[] = { | ||
78 | { | ||
79 | .start = MX31_CS4_BASE_ADDR, | ||
80 | .end = MX31_CS4_BASE_ADDR + 0x100, | ||
81 | .flags = IORESOURCE_MEM, | ||
82 | }, { | ||
83 | .start = IOMUX_TO_IRQ(MX31_PIN_SFS6), | ||
84 | .end = IOMUX_TO_IRQ(MX31_PIN_SFS6), | ||
85 | .flags = IORESOURCE_IRQ, | ||
86 | }, | ||
87 | }; | ||
88 | |||
89 | static struct platform_device smsc911x_device = { | ||
90 | .name = "smsc911x", | ||
91 | .id = -1, | ||
92 | .num_resources = ARRAY_SIZE(smsc911x_resources), | ||
93 | .resource = smsc911x_resources, | ||
94 | .dev = { | ||
95 | .platform_data = &smsc911x_config, | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | /* | ||
100 | * SPI | ||
101 | * | ||
102 | * The MC13783 is the only hard-wired SPI device on the module. | ||
103 | */ | ||
104 | |||
105 | static int spi_internal_chipselect[] = { | ||
106 | MXC_SPI_CS(0), | ||
107 | }; | ||
108 | |||
109 | static const struct spi_imx_master spi1_pdata __initconst = { | ||
110 | .chipselect = spi_internal_chipselect, | ||
111 | .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), | ||
112 | }; | ||
113 | |||
114 | static struct mc13xxx_platform_data mc13783_pdata __initdata = { | ||
115 | .flags = MC13XXX_USE_RTC | | ||
116 | MC13XXX_USE_REGULATOR, | ||
117 | }; | ||
118 | |||
119 | static struct spi_board_info mc13783_spi_dev __initdata = { | ||
120 | .modalias = "mc13783", | ||
121 | .max_speed_hz = 1000000, | ||
122 | .bus_num = 1, | ||
123 | .chip_select = 0, | ||
124 | .platform_data = &mc13783_pdata, | ||
125 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * USB | ||
130 | */ | ||
131 | |||
132 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
133 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
134 | |||
135 | static int usbh2_init(struct platform_device *pdev) | ||
136 | { | ||
137 | int pins[] = { | ||
138 | MX31_PIN_USBH2_DATA0__USBH2_DATA0, | ||
139 | MX31_PIN_USBH2_DATA1__USBH2_DATA1, | ||
140 | MX31_PIN_USBH2_CLK__USBH2_CLK, | ||
141 | MX31_PIN_USBH2_DIR__USBH2_DIR, | ||
142 | MX31_PIN_USBH2_NXT__USBH2_NXT, | ||
143 | MX31_PIN_USBH2_STP__USBH2_STP, | ||
144 | }; | ||
145 | |||
146 | mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2"); | ||
147 | |||
148 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); | ||
149 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); | ||
150 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); | ||
151 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); | ||
152 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); | ||
153 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); | ||
154 | mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); | ||
155 | mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); | ||
156 | mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); | ||
157 | mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); | ||
158 | mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); | ||
159 | mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); | ||
160 | |||
161 | mxc_iomux_set_gpr(MUX_PGP_UH2, true); | ||
162 | |||
163 | /* chip select */ | ||
164 | mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO), | ||
165 | "USBH2_CS"); | ||
166 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS"); | ||
167 | gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0); | ||
168 | |||
169 | mdelay(10); | ||
170 | |||
171 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); | ||
172 | } | ||
173 | |||
174 | static struct mxc_usbh_platform_data usbh2_pdata __initdata = { | ||
175 | .init = usbh2_init, | ||
176 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
177 | }; | ||
178 | |||
179 | /* | ||
180 | * NOR flash | ||
181 | */ | ||
182 | |||
183 | static struct physmap_flash_data nor_flash_data = { | ||
184 | .width = 2, | ||
185 | }; | ||
186 | |||
187 | static struct resource nor_flash_resource = { | ||
188 | .start = 0xa0000000, | ||
189 | .end = 0xa1ffffff, | ||
190 | .flags = IORESOURCE_MEM, | ||
191 | }; | ||
192 | |||
193 | static struct platform_device physmap_flash_device = { | ||
194 | .name = "physmap-flash", | ||
195 | .id = 0, | ||
196 | .dev = { | ||
197 | .platform_data = &nor_flash_data, | ||
198 | }, | ||
199 | .resource = &nor_flash_resource, | ||
200 | .num_resources = 1, | ||
201 | }; | ||
202 | |||
203 | |||
204 | |||
205 | /* | ||
206 | * This structure defines the MX31 memory map. | ||
207 | */ | ||
208 | static struct map_desc mx31lite_io_desc[] __initdata = { | ||
209 | { | ||
210 | .virtual = MX31_CS4_BASE_ADDR_VIRT, | ||
211 | .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), | ||
212 | .length = MX31_CS4_SIZE, | ||
213 | .type = MT_DEVICE | ||
214 | } | ||
215 | }; | ||
216 | |||
217 | /* | ||
218 | * Set up static virtual mappings. | ||
219 | */ | ||
220 | void __init mx31lite_map_io(void) | ||
221 | { | ||
222 | mx31_map_io(); | ||
223 | iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc)); | ||
224 | } | ||
225 | |||
226 | static int mx31lite_baseboard; | ||
227 | core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444); | ||
228 | |||
229 | static void __init mx31lite_init(void) | ||
230 | { | ||
231 | int ret; | ||
232 | |||
233 | switch (mx31lite_baseboard) { | ||
234 | case MX31LITE_NOBOARD: | ||
235 | break; | ||
236 | case MX31LITE_DB: | ||
237 | mx31lite_db_init(); | ||
238 | break; | ||
239 | default: | ||
240 | printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n", | ||
241 | mx31lite_baseboard); | ||
242 | } | ||
243 | |||
244 | mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins), | ||
245 | "mx31lite"); | ||
246 | |||
247 | /* NOR and NAND flash */ | ||
248 | platform_device_register(&physmap_flash_device); | ||
249 | imx31_add_mxc_nand(&mx31lite_nand_board_info); | ||
250 | |||
251 | imx31_add_spi_imx1(&spi1_pdata); | ||
252 | spi_register_board_info(&mc13783_spi_dev, 1); | ||
253 | |||
254 | /* USB */ | ||
255 | usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
256 | ULPI_OTG_DRVVBUS_EXT); | ||
257 | if (usbh2_pdata.otg) | ||
258 | imx31_add_mxc_ehci_hs(2, &usbh2_pdata); | ||
259 | |||
260 | /* SMSC9117 IRQ pin */ | ||
261 | ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); | ||
262 | if (ret) | ||
263 | pr_warning("could not get LAN irq gpio\n"); | ||
264 | else { | ||
265 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6)); | ||
266 | platform_device_register(&smsc911x_device); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static void __init mx31lite_timer_init(void) | ||
271 | { | ||
272 | mx31_clocks_init(26000000); | ||
273 | } | ||
274 | |||
275 | struct sys_timer mx31lite_timer = { | ||
276 | .init = mx31lite_timer_init, | ||
277 | }; | ||
278 | |||
279 | MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM") | ||
280 | /* Maintainer: Freescale Semiconductor, Inc. */ | ||
281 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
282 | .map_io = mx31lite_map_io, | ||
283 | .init_early = imx31_init_early, | ||
284 | .init_irq = mx31_init_irq, | ||
285 | .timer = &mx31lite_timer, | ||
286 | .init_machine = mx31lite_init, | ||
287 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c new file mode 100644 index 000000000000..eaa51e49ca95 --- /dev/null +++ b/arch/arm/mach-imx/mach-mx31moboard.c | |||
@@ -0,0 +1,583 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Valentin Longchamp, EPFL Mobots group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/delay.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/gfp.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/leds.h> | ||
22 | #include <linux/memory.h> | ||
23 | #include <linux/mtd/physmap.h> | ||
24 | #include <linux/mtd/partitions.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/regulator/machine.h> | ||
27 | #include <linux/mfd/mc13783.h> | ||
28 | #include <linux/spi/spi.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/memblock.h> | ||
31 | |||
32 | #include <linux/usb/otg.h> | ||
33 | #include <linux/usb/ulpi.h> | ||
34 | |||
35 | #include <asm/mach-types.h> | ||
36 | #include <asm/mach/arch.h> | ||
37 | #include <asm/mach/time.h> | ||
38 | #include <asm/mach/map.h> | ||
39 | #include <mach/board-mx31moboard.h> | ||
40 | #include <mach/common.h> | ||
41 | #include <mach/hardware.h> | ||
42 | #include <mach/iomux-mx3.h> | ||
43 | #include <mach/ulpi.h> | ||
44 | |||
45 | #include "devices-imx31.h" | ||
46 | |||
47 | static unsigned int moboard_pins[] = { | ||
48 | /* UART0 */ | ||
49 | MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, | ||
50 | MX31_PIN_CTS1__GPIO2_7, | ||
51 | /* UART4 */ | ||
52 | MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5, | ||
53 | MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5, | ||
54 | /* I2C0 */ | ||
55 | MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL, | ||
56 | /* I2C1 */ | ||
57 | MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL, | ||
58 | /* SDHC1 */ | ||
59 | MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
60 | MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
61 | MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD, | ||
62 | MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27, | ||
63 | /* USB reset */ | ||
64 | MX31_PIN_GPIO1_0__GPIO1_0, | ||
65 | /* USB OTG */ | ||
66 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
67 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
68 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
69 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
70 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
71 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
72 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
73 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
74 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
75 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
76 | MX31_PIN_USB_OC__GPIO1_30, | ||
77 | /* USB H2 */ | ||
78 | MX31_PIN_USBH2_DATA0__USBH2_DATA0, | ||
79 | MX31_PIN_USBH2_DATA1__USBH2_DATA1, | ||
80 | MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3, | ||
81 | MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5, | ||
82 | MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7, | ||
83 | MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR, | ||
84 | MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP, | ||
85 | MX31_PIN_SCK6__GPIO1_25, | ||
86 | /* LEDs */ | ||
87 | MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1, | ||
88 | MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3, | ||
89 | /* SPI1 */ | ||
90 | MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO, | ||
91 | MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, | ||
92 | MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2, | ||
93 | /* Atlas IRQ */ | ||
94 | MX31_PIN_GPIO1_3__GPIO1_3, | ||
95 | /* SPI2 */ | ||
96 | MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO, | ||
97 | MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY, | ||
98 | MX31_PIN_CSPI2_SS1__CSPI3_SS1, | ||
99 | }; | ||
100 | |||
101 | static struct physmap_flash_data mx31moboard_flash_data = { | ||
102 | .width = 2, | ||
103 | }; | ||
104 | |||
105 | static struct resource mx31moboard_flash_resource = { | ||
106 | .start = 0xa0000000, | ||
107 | .end = 0xa1ffffff, | ||
108 | .flags = IORESOURCE_MEM, | ||
109 | }; | ||
110 | |||
111 | static struct platform_device mx31moboard_flash = { | ||
112 | .name = "physmap-flash", | ||
113 | .id = 0, | ||
114 | .dev = { | ||
115 | .platform_data = &mx31moboard_flash_data, | ||
116 | }, | ||
117 | .resource = &mx31moboard_flash_resource, | ||
118 | .num_resources = 1, | ||
119 | }; | ||
120 | |||
121 | static int moboard_uart0_init(struct platform_device *pdev) | ||
122 | { | ||
123 | int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack"); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
127 | ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); | ||
128 | if (ret) | ||
129 | gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static void moboard_uart0_exit(struct platform_device *pdev) | ||
135 | { | ||
136 | gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); | ||
137 | } | ||
138 | |||
139 | static const struct imxuart_platform_data uart0_pdata __initconst = { | ||
140 | .init = moboard_uart0_init, | ||
141 | .exit = moboard_uart0_exit, | ||
142 | }; | ||
143 | |||
144 | static const struct imxuart_platform_data uart4_pdata __initconst = { | ||
145 | .flags = IMXUART_HAVE_RTSCTS, | ||
146 | }; | ||
147 | |||
148 | static const struct imxi2c_platform_data moboard_i2c0_data __initconst = { | ||
149 | .bitrate = 400000, | ||
150 | }; | ||
151 | |||
152 | static const struct imxi2c_platform_data moboard_i2c1_data __initconst = { | ||
153 | .bitrate = 100000, | ||
154 | }; | ||
155 | |||
156 | static int moboard_spi1_cs[] = { | ||
157 | MXC_SPI_CS(0), | ||
158 | MXC_SPI_CS(2), | ||
159 | }; | ||
160 | |||
161 | static const struct spi_imx_master moboard_spi1_pdata __initconst = { | ||
162 | .chipselect = moboard_spi1_cs, | ||
163 | .num_chipselect = ARRAY_SIZE(moboard_spi1_cs), | ||
164 | }; | ||
165 | |||
166 | static struct regulator_consumer_supply sdhc_consumers[] = { | ||
167 | { | ||
168 | .dev_name = "mxc-mmc.0", | ||
169 | .supply = "sdhc0_vcc", | ||
170 | }, | ||
171 | { | ||
172 | .dev_name = "mxc-mmc.1", | ||
173 | .supply = "sdhc1_vcc", | ||
174 | }, | ||
175 | }; | ||
176 | |||
177 | static struct regulator_init_data sdhc_vreg_data = { | ||
178 | .constraints = { | ||
179 | .min_uV = 2700000, | ||
180 | .max_uV = 3000000, | ||
181 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
182 | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, | ||
183 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
184 | REGULATOR_MODE_FAST, | ||
185 | .always_on = 0, | ||
186 | .boot_on = 1, | ||
187 | }, | ||
188 | .num_consumer_supplies = ARRAY_SIZE(sdhc_consumers), | ||
189 | .consumer_supplies = sdhc_consumers, | ||
190 | }; | ||
191 | |||
192 | static struct regulator_consumer_supply cam_consumers[] = { | ||
193 | { | ||
194 | .dev_name = "mx3_camera.0", | ||
195 | .supply = "cam_vcc", | ||
196 | }, | ||
197 | }; | ||
198 | |||
199 | static struct regulator_init_data cam_vreg_data = { | ||
200 | .constraints = { | ||
201 | .min_uV = 2700000, | ||
202 | .max_uV = 3000000, | ||
203 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
204 | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, | ||
205 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
206 | REGULATOR_MODE_FAST, | ||
207 | .always_on = 0, | ||
208 | .boot_on = 1, | ||
209 | }, | ||
210 | .num_consumer_supplies = ARRAY_SIZE(cam_consumers), | ||
211 | .consumer_supplies = cam_consumers, | ||
212 | }; | ||
213 | |||
214 | static struct mc13xxx_regulator_init_data moboard_regulators[] = { | ||
215 | { | ||
216 | .id = MC13783_REG_VMMC1, | ||
217 | .init_data = &sdhc_vreg_data, | ||
218 | }, | ||
219 | { | ||
220 | .id = MC13783_REG_VCAM, | ||
221 | .init_data = &cam_vreg_data, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | static struct mc13783_led_platform_data moboard_led[] = { | ||
226 | { | ||
227 | .id = MC13783_LED_R1, | ||
228 | .name = "coreboard-led-4:red", | ||
229 | .max_current = 2, | ||
230 | }, | ||
231 | { | ||
232 | .id = MC13783_LED_G1, | ||
233 | .name = "coreboard-led-4:green", | ||
234 | .max_current = 2, | ||
235 | }, | ||
236 | { | ||
237 | .id = MC13783_LED_B1, | ||
238 | .name = "coreboard-led-4:blue", | ||
239 | .max_current = 2, | ||
240 | }, | ||
241 | { | ||
242 | .id = MC13783_LED_R2, | ||
243 | .name = "coreboard-led-5:red", | ||
244 | .max_current = 3, | ||
245 | }, | ||
246 | { | ||
247 | .id = MC13783_LED_G2, | ||
248 | .name = "coreboard-led-5:green", | ||
249 | .max_current = 3, | ||
250 | }, | ||
251 | { | ||
252 | .id = MC13783_LED_B2, | ||
253 | .name = "coreboard-led-5:blue", | ||
254 | .max_current = 3, | ||
255 | }, | ||
256 | }; | ||
257 | |||
258 | static struct mc13783_leds_platform_data moboard_leds = { | ||
259 | .num_leds = ARRAY_SIZE(moboard_led), | ||
260 | .led = moboard_led, | ||
261 | .flags = MC13783_LED_SLEWLIMTC, | ||
262 | .abmode = MC13783_LED_AB_DISABLED, | ||
263 | .tc1_period = MC13783_LED_PERIOD_10MS, | ||
264 | .tc2_period = MC13783_LED_PERIOD_10MS, | ||
265 | }; | ||
266 | |||
267 | static struct mc13xxx_platform_data moboard_pmic = { | ||
268 | .regulators = { | ||
269 | .regulators = moboard_regulators, | ||
270 | .num_regulators = ARRAY_SIZE(moboard_regulators), | ||
271 | }, | ||
272 | .leds = &moboard_leds, | ||
273 | .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC | | ||
274 | MC13XXX_USE_ADC | MC13XXX_USE_LED, | ||
275 | }; | ||
276 | |||
277 | static struct spi_board_info moboard_spi_board_info[] __initdata = { | ||
278 | { | ||
279 | .modalias = "mc13783", | ||
280 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
281 | .max_speed_hz = 300000, | ||
282 | .bus_num = 1, | ||
283 | .chip_select = 0, | ||
284 | .platform_data = &moboard_pmic, | ||
285 | .mode = SPI_CS_HIGH, | ||
286 | }, | ||
287 | }; | ||
288 | |||
289 | static int moboard_spi2_cs[] = { | ||
290 | MXC_SPI_CS(1), | ||
291 | }; | ||
292 | |||
293 | static const struct spi_imx_master moboard_spi2_pdata __initconst = { | ||
294 | .chipselect = moboard_spi2_cs, | ||
295 | .num_chipselect = ARRAY_SIZE(moboard_spi2_cs), | ||
296 | }; | ||
297 | |||
298 | #define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0) | ||
299 | #define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1) | ||
300 | |||
301 | static int moboard_sdhc1_get_ro(struct device *dev) | ||
302 | { | ||
303 | return !gpio_get_value(SDHC1_WP); | ||
304 | } | ||
305 | |||
306 | static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq, | ||
307 | void *data) | ||
308 | { | ||
309 | int ret; | ||
310 | |||
311 | ret = gpio_request(SDHC1_CD, "sdhc-detect"); | ||
312 | if (ret) | ||
313 | return ret; | ||
314 | |||
315 | gpio_direction_input(SDHC1_CD); | ||
316 | |||
317 | ret = gpio_request(SDHC1_WP, "sdhc-wp"); | ||
318 | if (ret) | ||
319 | goto err_gpio_free; | ||
320 | gpio_direction_input(SDHC1_WP); | ||
321 | |||
322 | ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq, | ||
323 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
324 | "sdhc1-card-detect", data); | ||
325 | if (ret) | ||
326 | goto err_gpio_free_2; | ||
327 | |||
328 | return 0; | ||
329 | |||
330 | err_gpio_free_2: | ||
331 | gpio_free(SDHC1_WP); | ||
332 | err_gpio_free: | ||
333 | gpio_free(SDHC1_CD); | ||
334 | |||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | static void moboard_sdhc1_exit(struct device *dev, void *data) | ||
339 | { | ||
340 | free_irq(gpio_to_irq(SDHC1_CD), data); | ||
341 | gpio_free(SDHC1_WP); | ||
342 | gpio_free(SDHC1_CD); | ||
343 | } | ||
344 | |||
345 | static const struct imxmmc_platform_data sdhc1_pdata __initconst = { | ||
346 | .get_ro = moboard_sdhc1_get_ro, | ||
347 | .init = moboard_sdhc1_init, | ||
348 | .exit = moboard_sdhc1_exit, | ||
349 | }; | ||
350 | |||
351 | /* | ||
352 | * this pin is dedicated for all mx31moboard systems, so we do it here | ||
353 | */ | ||
354 | #define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0) | ||
355 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
356 | PAD_CTL_ODE_CMOS) | ||
357 | |||
358 | #define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC) | ||
359 | #define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6) | ||
360 | |||
361 | static void usb_xcvr_reset(void) | ||
362 | { | ||
363 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
364 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
365 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
366 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
367 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
368 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
369 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
370 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
371 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
372 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
373 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
374 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
375 | |||
376 | mxc_iomux_set_gpr(MUX_PGP_UH2, true); | ||
377 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
378 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
379 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
380 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG | PAD_CTL_100K_PU); | ||
381 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
382 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
383 | mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
384 | mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
385 | mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
386 | mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
387 | mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
388 | mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG | PAD_CTL_100K_PD); | ||
389 | |||
390 | gpio_request(OTG_EN_B, "usb-udc-en"); | ||
391 | gpio_direction_output(OTG_EN_B, 0); | ||
392 | gpio_request(USBH2_EN_B, "usbh2-en"); | ||
393 | gpio_direction_output(USBH2_EN_B, 0); | ||
394 | |||
395 | gpio_request(USB_RESET_B, "usb-reset"); | ||
396 | gpio_direction_output(USB_RESET_B, 0); | ||
397 | mdelay(1); | ||
398 | gpio_set_value(USB_RESET_B, 1); | ||
399 | mdelay(1); | ||
400 | } | ||
401 | |||
402 | static int moboard_usbh2_init_hw(struct platform_device *pdev) | ||
403 | { | ||
404 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); | ||
405 | } | ||
406 | |||
407 | static struct mxc_usbh_platform_data usbh2_pdata __initdata = { | ||
408 | .init = moboard_usbh2_init_hw, | ||
409 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
410 | }; | ||
411 | |||
412 | static int __init moboard_usbh2_init(void) | ||
413 | { | ||
414 | struct platform_device *pdev; | ||
415 | |||
416 | usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
417 | ULPI_OTG_DRVVBUS_EXT); | ||
418 | if (!usbh2_pdata.otg) | ||
419 | return -ENODEV; | ||
420 | |||
421 | pdev = imx31_add_mxc_ehci_hs(2, &usbh2_pdata); | ||
422 | if (IS_ERR(pdev)) | ||
423 | return PTR_ERR(pdev); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static struct gpio_led mx31moboard_leds[] = { | ||
429 | { | ||
430 | .name = "coreboard-led-0:red:running", | ||
431 | .default_trigger = "heartbeat", | ||
432 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0), | ||
433 | }, { | ||
434 | .name = "coreboard-led-1:red", | ||
435 | .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0), | ||
436 | }, { | ||
437 | .name = "coreboard-led-2:red", | ||
438 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0), | ||
439 | }, { | ||
440 | .name = "coreboard-led-3:red", | ||
441 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0), | ||
442 | }, | ||
443 | }; | ||
444 | |||
445 | static struct gpio_led_platform_data mx31moboard_led_pdata = { | ||
446 | .num_leds = ARRAY_SIZE(mx31moboard_leds), | ||
447 | .leds = mx31moboard_leds, | ||
448 | }; | ||
449 | |||
450 | static struct platform_device mx31moboard_leds_device = { | ||
451 | .name = "leds-gpio", | ||
452 | .id = -1, | ||
453 | .dev = { | ||
454 | .platform_data = &mx31moboard_led_pdata, | ||
455 | }, | ||
456 | }; | ||
457 | |||
458 | static const struct ipu_platform_data mx3_ipu_data __initconst = { | ||
459 | .irq_base = MXC_IPU_IRQ_START, | ||
460 | }; | ||
461 | |||
462 | static struct platform_device *devices[] __initdata = { | ||
463 | &mx31moboard_flash, | ||
464 | &mx31moboard_leds_device, | ||
465 | }; | ||
466 | |||
467 | static struct mx3_camera_pdata camera_pdata __initdata = { | ||
468 | .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, | ||
469 | .mclk_10khz = 4800, | ||
470 | }; | ||
471 | |||
472 | static phys_addr_t mx3_camera_base __initdata; | ||
473 | #define MX3_CAMERA_BUF_SIZE SZ_4M | ||
474 | |||
475 | static int __init mx31moboard_init_cam(void) | ||
476 | { | ||
477 | int dma, ret = -ENOMEM; | ||
478 | struct platform_device *pdev; | ||
479 | |||
480 | imx31_add_ipu_core(&mx3_ipu_data); | ||
481 | |||
482 | pdev = imx31_alloc_mx3_camera(&camera_pdata); | ||
483 | if (IS_ERR(pdev)) | ||
484 | return PTR_ERR(pdev); | ||
485 | |||
486 | dma = dma_declare_coherent_memory(&pdev->dev, | ||
487 | mx3_camera_base, mx3_camera_base, | ||
488 | MX3_CAMERA_BUF_SIZE, | ||
489 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); | ||
490 | if (!(dma & DMA_MEMORY_MAP)) | ||
491 | goto err; | ||
492 | |||
493 | ret = platform_device_add(pdev); | ||
494 | if (ret) | ||
495 | err: | ||
496 | platform_device_put(pdev); | ||
497 | |||
498 | return ret; | ||
499 | |||
500 | } | ||
501 | |||
502 | static int mx31moboard_baseboard; | ||
503 | core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); | ||
504 | |||
505 | /* | ||
506 | * Board specific initialization. | ||
507 | */ | ||
508 | static void __init mx31moboard_init(void) | ||
509 | { | ||
510 | mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins), | ||
511 | "moboard"); | ||
512 | |||
513 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
514 | |||
515 | imx31_add_imx_uart0(&uart0_pdata); | ||
516 | imx31_add_imx_uart4(&uart4_pdata); | ||
517 | |||
518 | imx31_add_imx_i2c0(&moboard_i2c0_data); | ||
519 | imx31_add_imx_i2c1(&moboard_i2c1_data); | ||
520 | |||
521 | imx31_add_spi_imx1(&moboard_spi1_pdata); | ||
522 | imx31_add_spi_imx2(&moboard_spi2_pdata); | ||
523 | |||
524 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq"); | ||
525 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); | ||
526 | spi_register_board_info(moboard_spi_board_info, | ||
527 | ARRAY_SIZE(moboard_spi_board_info)); | ||
528 | |||
529 | imx31_add_mxc_mmc(0, &sdhc1_pdata); | ||
530 | |||
531 | mx31moboard_init_cam(); | ||
532 | |||
533 | usb_xcvr_reset(); | ||
534 | |||
535 | moboard_usbh2_init(); | ||
536 | |||
537 | switch (mx31moboard_baseboard) { | ||
538 | case MX31NOBOARD: | ||
539 | break; | ||
540 | case MX31DEVBOARD: | ||
541 | mx31moboard_devboard_init(); | ||
542 | break; | ||
543 | case MX31MARXBOT: | ||
544 | mx31moboard_marxbot_init(); | ||
545 | break; | ||
546 | case MX31SMARTBOT: | ||
547 | case MX31EYEBOT: | ||
548 | mx31moboard_smartbot_init(mx31moboard_baseboard); | ||
549 | break; | ||
550 | default: | ||
551 | printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", | ||
552 | mx31moboard_baseboard); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | static void __init mx31moboard_timer_init(void) | ||
557 | { | ||
558 | mx31_clocks_init(26000000); | ||
559 | } | ||
560 | |||
561 | struct sys_timer mx31moboard_timer = { | ||
562 | .init = mx31moboard_timer_init, | ||
563 | }; | ||
564 | |||
565 | static void __init mx31moboard_reserve(void) | ||
566 | { | ||
567 | /* reserve 4 MiB for mx3-camera */ | ||
568 | mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE, | ||
569 | MX3_CAMERA_BUF_SIZE); | ||
570 | memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE); | ||
571 | memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE); | ||
572 | } | ||
573 | |||
574 | MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard") | ||
575 | /* Maintainer: Valentin Longchamp, EPFL Mobots group */ | ||
576 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
577 | .reserve = mx31moboard_reserve, | ||
578 | .map_io = mx31_map_io, | ||
579 | .init_early = imx31_init_early, | ||
580 | .init_irq = mx31_init_irq, | ||
581 | .timer = &mx31moboard_timer, | ||
582 | .init_machine = mx31moboard_init, | ||
583 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c new file mode 100644 index 000000000000..882880ac1bbc --- /dev/null +++ b/arch/arm/mach-imx/mach-mx35_3ds.c | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix | ||
4 | * | ||
5 | * Author: Fabio Estevam <fabio.estevam@freescale.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * This machine is known as: | ||
20 | * - i.MX35 3-Stack Development System | ||
21 | * - i.MX35 Platform Development Kit (i.MX35 PDK) | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/memory.h> | ||
28 | #include <linux/gpio.h> | ||
29 | #include <linux/usb/otg.h> | ||
30 | |||
31 | #include <linux/mtd/physmap.h> | ||
32 | |||
33 | #include <asm/mach-types.h> | ||
34 | #include <asm/mach/arch.h> | ||
35 | #include <asm/mach/time.h> | ||
36 | #include <asm/mach/map.h> | ||
37 | |||
38 | #include <mach/hardware.h> | ||
39 | #include <mach/common.h> | ||
40 | #include <mach/iomux-mx35.h> | ||
41 | #include <mach/irqs.h> | ||
42 | #include <mach/3ds_debugboard.h> | ||
43 | |||
44 | #include "devices-imx35.h" | ||
45 | |||
46 | #define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 1) | ||
47 | |||
48 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
49 | .flags = IMXUART_HAVE_RTSCTS, | ||
50 | }; | ||
51 | |||
52 | static struct physmap_flash_data mx35pdk_flash_data = { | ||
53 | .width = 2, | ||
54 | }; | ||
55 | |||
56 | static struct resource mx35pdk_flash_resource = { | ||
57 | .start = MX35_CS0_BASE_ADDR, | ||
58 | .end = MX35_CS0_BASE_ADDR + SZ_64M - 1, | ||
59 | .flags = IORESOURCE_MEM, | ||
60 | }; | ||
61 | |||
62 | static struct platform_device mx35pdk_flash = { | ||
63 | .name = "physmap-flash", | ||
64 | .id = 0, | ||
65 | .dev = { | ||
66 | .platform_data = &mx35pdk_flash_data, | ||
67 | }, | ||
68 | .resource = &mx35pdk_flash_resource, | ||
69 | .num_resources = 1, | ||
70 | }; | ||
71 | |||
72 | static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = { | ||
73 | .width = 1, | ||
74 | .hw_ecc = 1, | ||
75 | .flash_bbt = 1, | ||
76 | }; | ||
77 | |||
78 | static struct platform_device *devices[] __initdata = { | ||
79 | &mx35pdk_flash, | ||
80 | }; | ||
81 | |||
82 | static iomux_v3_cfg_t mx35pdk_pads[] = { | ||
83 | /* UART1 */ | ||
84 | MX35_PAD_CTS1__UART1_CTS, | ||
85 | MX35_PAD_RTS1__UART1_RTS, | ||
86 | MX35_PAD_TXD1__UART1_TXD_MUX, | ||
87 | MX35_PAD_RXD1__UART1_RXD_MUX, | ||
88 | /* FEC */ | ||
89 | MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, | ||
90 | MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, | ||
91 | MX35_PAD_FEC_RX_DV__FEC_RX_DV, | ||
92 | MX35_PAD_FEC_COL__FEC_COL, | ||
93 | MX35_PAD_FEC_RDATA0__FEC_RDATA_0, | ||
94 | MX35_PAD_FEC_TDATA0__FEC_TDATA_0, | ||
95 | MX35_PAD_FEC_TX_EN__FEC_TX_EN, | ||
96 | MX35_PAD_FEC_MDC__FEC_MDC, | ||
97 | MX35_PAD_FEC_MDIO__FEC_MDIO, | ||
98 | MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, | ||
99 | MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, | ||
100 | MX35_PAD_FEC_CRS__FEC_CRS, | ||
101 | MX35_PAD_FEC_RDATA1__FEC_RDATA_1, | ||
102 | MX35_PAD_FEC_TDATA1__FEC_TDATA_1, | ||
103 | MX35_PAD_FEC_RDATA2__FEC_RDATA_2, | ||
104 | MX35_PAD_FEC_TDATA2__FEC_TDATA_2, | ||
105 | MX35_PAD_FEC_RDATA3__FEC_RDATA_3, | ||
106 | MX35_PAD_FEC_TDATA3__FEC_TDATA_3, | ||
107 | /* USBOTG */ | ||
108 | MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, | ||
109 | MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, | ||
110 | /* USBH1 */ | ||
111 | MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, | ||
112 | MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, | ||
113 | /* SDCARD */ | ||
114 | MX35_PAD_SD1_CMD__ESDHC1_CMD, | ||
115 | MX35_PAD_SD1_CLK__ESDHC1_CLK, | ||
116 | MX35_PAD_SD1_DATA0__ESDHC1_DAT0, | ||
117 | MX35_PAD_SD1_DATA1__ESDHC1_DAT1, | ||
118 | MX35_PAD_SD1_DATA2__ESDHC1_DAT2, | ||
119 | MX35_PAD_SD1_DATA3__ESDHC1_DAT3, | ||
120 | /* I2C1 */ | ||
121 | MX35_PAD_I2C1_CLK__I2C1_SCL, | ||
122 | MX35_PAD_I2C1_DAT__I2C1_SDA, | ||
123 | }; | ||
124 | |||
125 | static int mx35_3ds_otg_init(struct platform_device *pdev) | ||
126 | { | ||
127 | return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY); | ||
128 | } | ||
129 | |||
130 | /* OTG config */ | ||
131 | static const struct fsl_usb2_platform_data usb_otg_pdata __initconst = { | ||
132 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
133 | .phy_mode = FSL_USB2_PHY_UTMI_WIDE, | ||
134 | .workaround = FLS_USB2_WORKAROUND_ENGCM09152, | ||
135 | /* | ||
136 | * ENGCM09152 also requires a hardware change. | ||
137 | * Please check the MX35 Chip Errata document for details. | ||
138 | */ | ||
139 | }; | ||
140 | |||
141 | static struct mxc_usbh_platform_data otg_pdata __initdata = { | ||
142 | .init = mx35_3ds_otg_init, | ||
143 | .portsc = MXC_EHCI_MODE_UTMI, | ||
144 | }; | ||
145 | |||
146 | static int mx35_3ds_usbh_init(struct platform_device *pdev) | ||
147 | { | ||
148 | return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI | | ||
149 | MXC_EHCI_INTERNAL_PHY); | ||
150 | } | ||
151 | |||
152 | /* USB HOST config */ | ||
153 | static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { | ||
154 | .init = mx35_3ds_usbh_init, | ||
155 | .portsc = MXC_EHCI_MODE_SERIAL, | ||
156 | }; | ||
157 | |||
158 | static int otg_mode_host; | ||
159 | |||
160 | static int __init mx35_3ds_otg_mode(char *options) | ||
161 | { | ||
162 | if (!strcmp(options, "host")) | ||
163 | otg_mode_host = 1; | ||
164 | else if (!strcmp(options, "device")) | ||
165 | otg_mode_host = 0; | ||
166 | else | ||
167 | pr_info("otg_mode neither \"host\" nor \"device\". " | ||
168 | "Defaulting to device\n"); | ||
169 | return 0; | ||
170 | } | ||
171 | __setup("otg_mode=", mx35_3ds_otg_mode); | ||
172 | |||
173 | static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = { | ||
174 | .bitrate = 100000, | ||
175 | }; | ||
176 | |||
177 | /* | ||
178 | * Board specific initialization. | ||
179 | */ | ||
180 | static void __init mx35_3ds_init(void) | ||
181 | { | ||
182 | mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); | ||
183 | |||
184 | imx35_add_fec(NULL); | ||
185 | imx35_add_imx2_wdt(NULL); | ||
186 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
187 | |||
188 | imx35_add_imx_uart0(&uart_pdata); | ||
189 | |||
190 | if (otg_mode_host) | ||
191 | imx35_add_mxc_ehci_otg(&otg_pdata); | ||
192 | |||
193 | imx35_add_mxc_ehci_hs(&usb_host_pdata); | ||
194 | |||
195 | if (!otg_mode_host) | ||
196 | imx35_add_fsl_usb2_udc(&usb_otg_pdata); | ||
197 | |||
198 | imx35_add_mxc_nand(&mx35pdk_nand_board_info); | ||
199 | imx35_add_sdhci_esdhc_imx(0, NULL); | ||
200 | |||
201 | if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT)) | ||
202 | pr_warn("Init of the debugboard failed, all " | ||
203 | "devices on the debugboard are unusable.\n"); | ||
204 | imx35_add_imx_i2c0(&mx35_3ds_i2c0_data); | ||
205 | } | ||
206 | |||
207 | static void __init mx35pdk_timer_init(void) | ||
208 | { | ||
209 | mx35_clocks_init(); | ||
210 | } | ||
211 | |||
212 | struct sys_timer mx35pdk_timer = { | ||
213 | .init = mx35pdk_timer_init, | ||
214 | }; | ||
215 | |||
216 | MACHINE_START(MX35_3DS, "Freescale MX35PDK") | ||
217 | /* Maintainer: Freescale Semiconductor, Inc */ | ||
218 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
219 | .map_io = mx35_map_io, | ||
220 | .init_early = imx35_init_early, | ||
221 | .init_irq = mx35_init_irq, | ||
222 | .timer = &mx35pdk_timer, | ||
223 | .init_machine = mx35_3ds_init, | ||
224 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c new file mode 100644 index 000000000000..89c213b81295 --- /dev/null +++ b/arch/arm/mach-imx/mach-pcm037.c | |||
@@ -0,0 +1,696 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Sascha Hauer, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/mtd/physmap.h> | ||
20 | #include <linux/mtd/plat-ram.h> | ||
21 | #include <linux/memory.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/smsc911x.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/i2c/at24.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/spi/spi.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <linux/can/platform/sja1000.h> | ||
31 | #include <linux/usb/otg.h> | ||
32 | #include <linux/usb/ulpi.h> | ||
33 | #include <linux/gfp.h> | ||
34 | #include <linux/memblock.h> | ||
35 | |||
36 | #include <media/soc_camera.h> | ||
37 | |||
38 | #include <asm/mach-types.h> | ||
39 | #include <asm/mach/arch.h> | ||
40 | #include <asm/mach/time.h> | ||
41 | #include <asm/mach/map.h> | ||
42 | #include <mach/common.h> | ||
43 | #include <mach/hardware.h> | ||
44 | #include <mach/iomux-mx3.h> | ||
45 | #include <mach/ulpi.h> | ||
46 | |||
47 | #include "devices-imx31.h" | ||
48 | #include "pcm037.h" | ||
49 | |||
50 | static enum pcm037_board_variant pcm037_instance = PCM037_PCM970; | ||
51 | |||
52 | static int __init pcm037_variant_setup(char *str) | ||
53 | { | ||
54 | if (!strcmp("eet", str)) | ||
55 | pcm037_instance = PCM037_EET; | ||
56 | else if (strcmp("pcm970", str)) | ||
57 | pr_warning("Unknown pcm037 baseboard variant %s\n", str); | ||
58 | |||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | /* Supported values: "pcm970" (default) and "eet" */ | ||
63 | __setup("pcm037_variant=", pcm037_variant_setup); | ||
64 | |||
65 | enum pcm037_board_variant pcm037_variant(void) | ||
66 | { | ||
67 | return pcm037_instance; | ||
68 | } | ||
69 | |||
70 | /* UART1 with RTS/CTS handshake signals */ | ||
71 | static unsigned int pcm037_uart1_handshake_pins[] = { | ||
72 | MX31_PIN_CTS1__CTS1, | ||
73 | MX31_PIN_RTS1__RTS1, | ||
74 | MX31_PIN_TXD1__TXD1, | ||
75 | MX31_PIN_RXD1__RXD1, | ||
76 | }; | ||
77 | |||
78 | /* UART1 without RTS/CTS handshake signals */ | ||
79 | static unsigned int pcm037_uart1_pins[] = { | ||
80 | MX31_PIN_TXD1__TXD1, | ||
81 | MX31_PIN_RXD1__RXD1, | ||
82 | }; | ||
83 | |||
84 | static unsigned int pcm037_pins[] = { | ||
85 | /* I2C */ | ||
86 | MX31_PIN_CSPI2_MOSI__SCL, | ||
87 | MX31_PIN_CSPI2_MISO__SDA, | ||
88 | MX31_PIN_CSPI2_SS2__I2C3_SDA, | ||
89 | MX31_PIN_CSPI2_SCLK__I2C3_SCL, | ||
90 | /* SDHC1 */ | ||
91 | MX31_PIN_SD1_DATA3__SD1_DATA3, | ||
92 | MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
93 | MX31_PIN_SD1_DATA1__SD1_DATA1, | ||
94 | MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
95 | MX31_PIN_SD1_CLK__SD1_CLK, | ||
96 | MX31_PIN_SD1_CMD__SD1_CMD, | ||
97 | IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */ | ||
98 | IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */ | ||
99 | /* SPI1 */ | ||
100 | MX31_PIN_CSPI1_MOSI__MOSI, | ||
101 | MX31_PIN_CSPI1_MISO__MISO, | ||
102 | MX31_PIN_CSPI1_SCLK__SCLK, | ||
103 | MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, | ||
104 | MX31_PIN_CSPI1_SS0__SS0, | ||
105 | MX31_PIN_CSPI1_SS1__SS1, | ||
106 | MX31_PIN_CSPI1_SS2__SS2, | ||
107 | /* UART2 */ | ||
108 | MX31_PIN_TXD2__TXD2, | ||
109 | MX31_PIN_RXD2__RXD2, | ||
110 | MX31_PIN_CTS2__CTS2, | ||
111 | MX31_PIN_RTS2__RTS2, | ||
112 | /* UART3 */ | ||
113 | MX31_PIN_CSPI3_MOSI__RXD3, | ||
114 | MX31_PIN_CSPI3_MISO__TXD3, | ||
115 | MX31_PIN_CSPI3_SCLK__RTS3, | ||
116 | MX31_PIN_CSPI3_SPI_RDY__CTS3, | ||
117 | /* LAN9217 irq pin */ | ||
118 | IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO), | ||
119 | /* Onewire */ | ||
120 | MX31_PIN_BATT_LINE__OWIRE, | ||
121 | /* Framebuffer */ | ||
122 | MX31_PIN_LD0__LD0, | ||
123 | MX31_PIN_LD1__LD1, | ||
124 | MX31_PIN_LD2__LD2, | ||
125 | MX31_PIN_LD3__LD3, | ||
126 | MX31_PIN_LD4__LD4, | ||
127 | MX31_PIN_LD5__LD5, | ||
128 | MX31_PIN_LD6__LD6, | ||
129 | MX31_PIN_LD7__LD7, | ||
130 | MX31_PIN_LD8__LD8, | ||
131 | MX31_PIN_LD9__LD9, | ||
132 | MX31_PIN_LD10__LD10, | ||
133 | MX31_PIN_LD11__LD11, | ||
134 | MX31_PIN_LD12__LD12, | ||
135 | MX31_PIN_LD13__LD13, | ||
136 | MX31_PIN_LD14__LD14, | ||
137 | MX31_PIN_LD15__LD15, | ||
138 | MX31_PIN_LD16__LD16, | ||
139 | MX31_PIN_LD17__LD17, | ||
140 | MX31_PIN_VSYNC3__VSYNC3, | ||
141 | MX31_PIN_HSYNC__HSYNC, | ||
142 | MX31_PIN_FPSHIFT__FPSHIFT, | ||
143 | MX31_PIN_DRDY0__DRDY0, | ||
144 | MX31_PIN_D3_REV__D3_REV, | ||
145 | MX31_PIN_CONTRAST__CONTRAST, | ||
146 | MX31_PIN_D3_SPL__D3_SPL, | ||
147 | MX31_PIN_D3_CLS__D3_CLS, | ||
148 | MX31_PIN_LCS0__GPI03_23, | ||
149 | /* CSI */ | ||
150 | IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO), | ||
151 | MX31_PIN_CSI_D6__CSI_D6, | ||
152 | MX31_PIN_CSI_D7__CSI_D7, | ||
153 | MX31_PIN_CSI_D8__CSI_D8, | ||
154 | MX31_PIN_CSI_D9__CSI_D9, | ||
155 | MX31_PIN_CSI_D10__CSI_D10, | ||
156 | MX31_PIN_CSI_D11__CSI_D11, | ||
157 | MX31_PIN_CSI_D12__CSI_D12, | ||
158 | MX31_PIN_CSI_D13__CSI_D13, | ||
159 | MX31_PIN_CSI_D14__CSI_D14, | ||
160 | MX31_PIN_CSI_D15__CSI_D15, | ||
161 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, | ||
162 | MX31_PIN_CSI_MCLK__CSI_MCLK, | ||
163 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, | ||
164 | MX31_PIN_CSI_VSYNC__CSI_VSYNC, | ||
165 | /* GPIO */ | ||
166 | IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO), | ||
167 | /* OTG */ | ||
168 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
169 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
170 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
171 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
172 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
173 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
174 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
175 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
176 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, | ||
177 | MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
178 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, | ||
179 | MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
180 | /* USB host 2 */ | ||
181 | IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), | ||
182 | IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), | ||
183 | IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), | ||
184 | IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), | ||
185 | IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), | ||
186 | IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), | ||
187 | IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), | ||
188 | IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), | ||
189 | IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), | ||
190 | IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), | ||
191 | IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), | ||
192 | IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), | ||
193 | }; | ||
194 | |||
195 | static struct physmap_flash_data pcm037_flash_data = { | ||
196 | .width = 2, | ||
197 | }; | ||
198 | |||
199 | static struct resource pcm037_flash_resource = { | ||
200 | .start = 0xa0000000, | ||
201 | .end = 0xa1ffffff, | ||
202 | .flags = IORESOURCE_MEM, | ||
203 | }; | ||
204 | |||
205 | static struct platform_device pcm037_flash = { | ||
206 | .name = "physmap-flash", | ||
207 | .id = 0, | ||
208 | .dev = { | ||
209 | .platform_data = &pcm037_flash_data, | ||
210 | }, | ||
211 | .resource = &pcm037_flash_resource, | ||
212 | .num_resources = 1, | ||
213 | }; | ||
214 | |||
215 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
216 | .flags = IMXUART_HAVE_RTSCTS, | ||
217 | }; | ||
218 | |||
219 | static struct resource smsc911x_resources[] = { | ||
220 | { | ||
221 | .start = MX31_CS1_BASE_ADDR + 0x300, | ||
222 | .end = MX31_CS1_BASE_ADDR + 0x300 + SZ_64K - 1, | ||
223 | .flags = IORESOURCE_MEM, | ||
224 | }, { | ||
225 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), | ||
226 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), | ||
227 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | ||
228 | }, | ||
229 | }; | ||
230 | |||
231 | static struct smsc911x_platform_config smsc911x_info = { | ||
232 | .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY | | ||
233 | SMSC911X_SAVE_MAC_ADDRESS, | ||
234 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
235 | .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, | ||
236 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
237 | }; | ||
238 | |||
239 | static struct platform_device pcm037_eth = { | ||
240 | .name = "smsc911x", | ||
241 | .id = -1, | ||
242 | .num_resources = ARRAY_SIZE(smsc911x_resources), | ||
243 | .resource = smsc911x_resources, | ||
244 | .dev = { | ||
245 | .platform_data = &smsc911x_info, | ||
246 | }, | ||
247 | }; | ||
248 | |||
249 | static struct platdata_mtd_ram pcm038_sram_data = { | ||
250 | .bankwidth = 2, | ||
251 | }; | ||
252 | |||
253 | static struct resource pcm038_sram_resource = { | ||
254 | .start = MX31_CS4_BASE_ADDR, | ||
255 | .end = MX31_CS4_BASE_ADDR + 512 * 1024 - 1, | ||
256 | .flags = IORESOURCE_MEM, | ||
257 | }; | ||
258 | |||
259 | static struct platform_device pcm037_sram_device = { | ||
260 | .name = "mtd-ram", | ||
261 | .id = 0, | ||
262 | .dev = { | ||
263 | .platform_data = &pcm038_sram_data, | ||
264 | }, | ||
265 | .num_resources = 1, | ||
266 | .resource = &pcm038_sram_resource, | ||
267 | }; | ||
268 | |||
269 | static const struct mxc_nand_platform_data | ||
270 | pcm037_nand_board_info __initconst = { | ||
271 | .width = 1, | ||
272 | .hw_ecc = 1, | ||
273 | }; | ||
274 | |||
275 | static const struct imxi2c_platform_data pcm037_i2c1_data __initconst = { | ||
276 | .bitrate = 100000, | ||
277 | }; | ||
278 | |||
279 | static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = { | ||
280 | .bitrate = 20000, | ||
281 | }; | ||
282 | |||
283 | static struct at24_platform_data board_eeprom = { | ||
284 | .byte_len = 4096, | ||
285 | .page_size = 32, | ||
286 | .flags = AT24_FLAG_ADDR16, | ||
287 | }; | ||
288 | |||
289 | static int pcm037_camera_power(struct device *dev, int on) | ||
290 | { | ||
291 | /* disable or enable the camera in X7 or X8 PCM970 connector */ | ||
292 | gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static struct i2c_board_info pcm037_i2c_camera[] = { | ||
297 | { | ||
298 | I2C_BOARD_INFO("mt9t031", 0x5d), | ||
299 | }, { | ||
300 | I2C_BOARD_INFO("mt9v022", 0x48), | ||
301 | }, | ||
302 | }; | ||
303 | |||
304 | static struct soc_camera_link iclink_mt9v022 = { | ||
305 | .bus_id = 0, /* Must match with the camera ID */ | ||
306 | .board_info = &pcm037_i2c_camera[1], | ||
307 | .i2c_adapter_id = 2, | ||
308 | }; | ||
309 | |||
310 | static struct soc_camera_link iclink_mt9t031 = { | ||
311 | .bus_id = 0, /* Must match with the camera ID */ | ||
312 | .power = pcm037_camera_power, | ||
313 | .board_info = &pcm037_i2c_camera[0], | ||
314 | .i2c_adapter_id = 2, | ||
315 | }; | ||
316 | |||
317 | static struct i2c_board_info pcm037_i2c_devices[] = { | ||
318 | { | ||
319 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | ||
320 | .platform_data = &board_eeprom, | ||
321 | }, { | ||
322 | I2C_BOARD_INFO("pcf8563", 0x51), | ||
323 | } | ||
324 | }; | ||
325 | |||
326 | static struct platform_device pcm037_mt9t031 = { | ||
327 | .name = "soc-camera-pdrv", | ||
328 | .id = 0, | ||
329 | .dev = { | ||
330 | .platform_data = &iclink_mt9t031, | ||
331 | }, | ||
332 | }; | ||
333 | |||
334 | static struct platform_device pcm037_mt9v022 = { | ||
335 | .name = "soc-camera-pdrv", | ||
336 | .id = 1, | ||
337 | .dev = { | ||
338 | .platform_data = &iclink_mt9v022, | ||
339 | }, | ||
340 | }; | ||
341 | |||
342 | /* Not connected by default */ | ||
343 | #ifdef PCM970_SDHC_RW_SWITCH | ||
344 | static int pcm970_sdhc1_get_ro(struct device *dev) | ||
345 | { | ||
346 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6)); | ||
347 | } | ||
348 | #endif | ||
349 | |||
350 | #define SDHC1_GPIO_WP IOMUX_TO_GPIO(MX31_PIN_SFS6) | ||
351 | #define SDHC1_GPIO_DET IOMUX_TO_GPIO(MX31_PIN_SCK6) | ||
352 | |||
353 | static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq, | ||
354 | void *data) | ||
355 | { | ||
356 | int ret; | ||
357 | |||
358 | ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect"); | ||
359 | if (ret) | ||
360 | return ret; | ||
361 | |||
362 | gpio_direction_input(SDHC1_GPIO_DET); | ||
363 | |||
364 | #ifdef PCM970_SDHC_RW_SWITCH | ||
365 | ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp"); | ||
366 | if (ret) | ||
367 | goto err_gpio_free; | ||
368 | gpio_direction_input(SDHC1_GPIO_WP); | ||
369 | #endif | ||
370 | |||
371 | ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq, | ||
372 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
373 | "sdhc-detect", data); | ||
374 | if (ret) | ||
375 | goto err_gpio_free_2; | ||
376 | |||
377 | return 0; | ||
378 | |||
379 | err_gpio_free_2: | ||
380 | #ifdef PCM970_SDHC_RW_SWITCH | ||
381 | gpio_free(SDHC1_GPIO_WP); | ||
382 | err_gpio_free: | ||
383 | #endif | ||
384 | gpio_free(SDHC1_GPIO_DET); | ||
385 | |||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | static void pcm970_sdhc1_exit(struct device *dev, void *data) | ||
390 | { | ||
391 | free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data); | ||
392 | gpio_free(SDHC1_GPIO_DET); | ||
393 | gpio_free(SDHC1_GPIO_WP); | ||
394 | } | ||
395 | |||
396 | static const struct imxmmc_platform_data sdhc_pdata __initconst = { | ||
397 | #ifdef PCM970_SDHC_RW_SWITCH | ||
398 | .get_ro = pcm970_sdhc1_get_ro, | ||
399 | #endif | ||
400 | .init = pcm970_sdhc1_init, | ||
401 | .exit = pcm970_sdhc1_exit, | ||
402 | }; | ||
403 | |||
404 | struct mx3_camera_pdata camera_pdata __initdata = { | ||
405 | .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, | ||
406 | .mclk_10khz = 2000, | ||
407 | }; | ||
408 | |||
409 | static phys_addr_t mx3_camera_base __initdata; | ||
410 | #define MX3_CAMERA_BUF_SIZE SZ_4M | ||
411 | |||
412 | static int __init pcm037_init_camera(void) | ||
413 | { | ||
414 | int dma, ret = -ENOMEM; | ||
415 | struct platform_device *pdev = imx31_alloc_mx3_camera(&camera_pdata); | ||
416 | |||
417 | if (IS_ERR(pdev)) | ||
418 | return PTR_ERR(pdev); | ||
419 | |||
420 | dma = dma_declare_coherent_memory(&pdev->dev, | ||
421 | mx3_camera_base, mx3_camera_base, | ||
422 | MX3_CAMERA_BUF_SIZE, | ||
423 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); | ||
424 | if (!(dma & DMA_MEMORY_MAP)) | ||
425 | goto err; | ||
426 | |||
427 | ret = platform_device_add(pdev); | ||
428 | if (ret) | ||
429 | err: | ||
430 | platform_device_put(pdev); | ||
431 | |||
432 | return ret; | ||
433 | } | ||
434 | |||
435 | static struct platform_device *devices[] __initdata = { | ||
436 | &pcm037_flash, | ||
437 | &pcm037_sram_device, | ||
438 | &pcm037_mt9t031, | ||
439 | &pcm037_mt9v022, | ||
440 | }; | ||
441 | |||
442 | static const struct ipu_platform_data mx3_ipu_data __initconst = { | ||
443 | .irq_base = MXC_IPU_IRQ_START, | ||
444 | }; | ||
445 | |||
446 | static const struct fb_videomode fb_modedb[] = { | ||
447 | { | ||
448 | /* 240x320 @ 60 Hz Sharp */ | ||
449 | .name = "Sharp-LQ035Q7DH06-QVGA", | ||
450 | .refresh = 60, | ||
451 | .xres = 240, | ||
452 | .yres = 320, | ||
453 | .pixclock = 185925, | ||
454 | .left_margin = 9, | ||
455 | .right_margin = 16, | ||
456 | .upper_margin = 7, | ||
457 | .lower_margin = 9, | ||
458 | .hsync_len = 1, | ||
459 | .vsync_len = 1, | ||
460 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | | ||
461 | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN, | ||
462 | .vmode = FB_VMODE_NONINTERLACED, | ||
463 | .flag = 0, | ||
464 | }, { | ||
465 | /* 240x320 @ 60 Hz */ | ||
466 | .name = "TX090", | ||
467 | .refresh = 60, | ||
468 | .xres = 240, | ||
469 | .yres = 320, | ||
470 | .pixclock = 38255, | ||
471 | .left_margin = 144, | ||
472 | .right_margin = 0, | ||
473 | .upper_margin = 7, | ||
474 | .lower_margin = 40, | ||
475 | .hsync_len = 96, | ||
476 | .vsync_len = 1, | ||
477 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, | ||
478 | .vmode = FB_VMODE_NONINTERLACED, | ||
479 | .flag = 0, | ||
480 | }, { | ||
481 | /* 240x320 @ 60 Hz */ | ||
482 | .name = "CMEL-OLED", | ||
483 | .refresh = 60, | ||
484 | .xres = 240, | ||
485 | .yres = 320, | ||
486 | .pixclock = 185925, | ||
487 | .left_margin = 9, | ||
488 | .right_margin = 16, | ||
489 | .upper_margin = 7, | ||
490 | .lower_margin = 9, | ||
491 | .hsync_len = 1, | ||
492 | .vsync_len = 1, | ||
493 | .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, | ||
494 | .vmode = FB_VMODE_NONINTERLACED, | ||
495 | .flag = 0, | ||
496 | }, | ||
497 | }; | ||
498 | |||
499 | static struct mx3fb_platform_data mx3fb_pdata = { | ||
500 | .name = "Sharp-LQ035Q7DH06-QVGA", | ||
501 | .mode = fb_modedb, | ||
502 | .num_modes = ARRAY_SIZE(fb_modedb), | ||
503 | }; | ||
504 | |||
505 | static struct resource pcm970_sja1000_resources[] = { | ||
506 | { | ||
507 | .start = MX31_CS5_BASE_ADDR, | ||
508 | .end = MX31_CS5_BASE_ADDR + 0x100 - 1, | ||
509 | .flags = IORESOURCE_MEM, | ||
510 | }, { | ||
511 | .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)), | ||
512 | .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)), | ||
513 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, | ||
514 | }, | ||
515 | }; | ||
516 | |||
517 | struct sja1000_platform_data pcm970_sja1000_platform_data = { | ||
518 | .osc_freq = 16000000, | ||
519 | .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL, | ||
520 | .cdr = CDR_CBP, | ||
521 | }; | ||
522 | |||
523 | static struct platform_device pcm970_sja1000 = { | ||
524 | .name = "sja1000_platform", | ||
525 | .dev = { | ||
526 | .platform_data = &pcm970_sja1000_platform_data, | ||
527 | }, | ||
528 | .resource = pcm970_sja1000_resources, | ||
529 | .num_resources = ARRAY_SIZE(pcm970_sja1000_resources), | ||
530 | }; | ||
531 | |||
532 | static int pcm037_otg_init(struct platform_device *pdev) | ||
533 | { | ||
534 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); | ||
535 | } | ||
536 | |||
537 | static struct mxc_usbh_platform_data otg_pdata __initdata = { | ||
538 | .init = pcm037_otg_init, | ||
539 | .portsc = MXC_EHCI_MODE_ULPI, | ||
540 | }; | ||
541 | |||
542 | static int pcm037_usbh2_init(struct platform_device *pdev) | ||
543 | { | ||
544 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); | ||
545 | } | ||
546 | |||
547 | static struct mxc_usbh_platform_data usbh2_pdata __initdata = { | ||
548 | .init = pcm037_usbh2_init, | ||
549 | .portsc = MXC_EHCI_MODE_ULPI, | ||
550 | }; | ||
551 | |||
552 | static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { | ||
553 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
554 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
555 | }; | ||
556 | |||
557 | static int otg_mode_host; | ||
558 | |||
559 | static int __init pcm037_otg_mode(char *options) | ||
560 | { | ||
561 | if (!strcmp(options, "host")) | ||
562 | otg_mode_host = 1; | ||
563 | else if (!strcmp(options, "device")) | ||
564 | otg_mode_host = 0; | ||
565 | else | ||
566 | pr_info("otg_mode neither \"host\" nor \"device\". " | ||
567 | "Defaulting to device\n"); | ||
568 | return 0; | ||
569 | } | ||
570 | __setup("otg_mode=", pcm037_otg_mode); | ||
571 | |||
572 | /* | ||
573 | * Board specific initialization. | ||
574 | */ | ||
575 | static void __init pcm037_init(void) | ||
576 | { | ||
577 | int ret; | ||
578 | |||
579 | mxc_iomux_set_gpr(MUX_PGP_UH2, 1); | ||
580 | |||
581 | mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), | ||
582 | "pcm037"); | ||
583 | |||
584 | #define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS \ | ||
585 | | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
586 | |||
587 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG); | ||
588 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG); | ||
589 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG); | ||
590 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG); | ||
591 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); /* USBH2_DATA0 */ | ||
592 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); /* USBH2_DATA1 */ | ||
593 | mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */ | ||
594 | mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */ | ||
595 | mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */ | ||
596 | mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */ | ||
597 | mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */ | ||
598 | mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */ | ||
599 | |||
600 | if (pcm037_variant() == PCM037_EET) | ||
601 | mxc_iomux_setup_multiple_pins(pcm037_uart1_pins, | ||
602 | ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1"); | ||
603 | else | ||
604 | mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins, | ||
605 | ARRAY_SIZE(pcm037_uart1_handshake_pins), | ||
606 | "pcm037_uart1"); | ||
607 | |||
608 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
609 | |||
610 | imx31_add_imx2_wdt(NULL); | ||
611 | imx31_add_imx_uart0(&uart_pdata); | ||
612 | /* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */ | ||
613 | imx31_add_imx_uart1(&uart_pdata); | ||
614 | imx31_add_imx_uart2(&uart_pdata); | ||
615 | |||
616 | imx31_add_mxc_w1(NULL); | ||
617 | |||
618 | /* LAN9217 IRQ pin */ | ||
619 | ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq"); | ||
620 | if (ret) | ||
621 | pr_warning("could not get LAN irq gpio\n"); | ||
622 | else { | ||
623 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); | ||
624 | platform_device_register(&pcm037_eth); | ||
625 | } | ||
626 | |||
627 | |||
628 | /* I2C adapters and devices */ | ||
629 | i2c_register_board_info(1, pcm037_i2c_devices, | ||
630 | ARRAY_SIZE(pcm037_i2c_devices)); | ||
631 | |||
632 | imx31_add_imx_i2c1(&pcm037_i2c1_data); | ||
633 | imx31_add_imx_i2c2(&pcm037_i2c2_data); | ||
634 | |||
635 | imx31_add_mxc_nand(&pcm037_nand_board_info); | ||
636 | imx31_add_mxc_mmc(0, &sdhc_pdata); | ||
637 | imx31_add_ipu_core(&mx3_ipu_data); | ||
638 | imx31_add_mx3_sdc_fb(&mx3fb_pdata); | ||
639 | |||
640 | /* CSI */ | ||
641 | /* Camera power: default - off */ | ||
642 | ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power"); | ||
643 | if (!ret) | ||
644 | gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1); | ||
645 | else | ||
646 | iclink_mt9t031.power = NULL; | ||
647 | |||
648 | pcm037_init_camera(); | ||
649 | |||
650 | platform_device_register(&pcm970_sja1000); | ||
651 | |||
652 | if (otg_mode_host) { | ||
653 | otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
654 | ULPI_OTG_DRVVBUS_EXT); | ||
655 | if (otg_pdata.otg) | ||
656 | imx31_add_mxc_ehci_otg(&otg_pdata); | ||
657 | } | ||
658 | |||
659 | usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
660 | ULPI_OTG_DRVVBUS_EXT); | ||
661 | if (usbh2_pdata.otg) | ||
662 | imx31_add_mxc_ehci_hs(2, &usbh2_pdata); | ||
663 | |||
664 | if (!otg_mode_host) | ||
665 | imx31_add_fsl_usb2_udc(&otg_device_pdata); | ||
666 | |||
667 | } | ||
668 | |||
669 | static void __init pcm037_timer_init(void) | ||
670 | { | ||
671 | mx31_clocks_init(26000000); | ||
672 | } | ||
673 | |||
674 | struct sys_timer pcm037_timer = { | ||
675 | .init = pcm037_timer_init, | ||
676 | }; | ||
677 | |||
678 | static void __init pcm037_reserve(void) | ||
679 | { | ||
680 | /* reserve 4 MiB for mx3-camera */ | ||
681 | mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE, | ||
682 | MX3_CAMERA_BUF_SIZE); | ||
683 | memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE); | ||
684 | memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE); | ||
685 | } | ||
686 | |||
687 | MACHINE_START(PCM037, "Phytec Phycore pcm037") | ||
688 | /* Maintainer: Pengutronix */ | ||
689 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
690 | .reserve = pcm037_reserve, | ||
691 | .map_io = mx31_map_io, | ||
692 | .init_early = imx31_init_early, | ||
693 | .init_irq = mx31_init_irq, | ||
694 | .timer = &pcm037_timer, | ||
695 | .init_machine = pcm037_init, | ||
696 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c new file mode 100644 index 000000000000..1b7606bef8f4 --- /dev/null +++ b/arch/arm/mach-imx/mach-pcm037_eet.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 | ||
3 | * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | #include <linux/gpio.h> | ||
10 | #include <linux/input.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/spi/spi.h> | ||
13 | |||
14 | #include <mach/common.h> | ||
15 | #include <mach/iomux-mx3.h> | ||
16 | |||
17 | #include <asm/mach-types.h> | ||
18 | |||
19 | #include "pcm037.h" | ||
20 | #include "devices-imx31.h" | ||
21 | |||
22 | static unsigned int pcm037_eet_pins[] = { | ||
23 | /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ | ||
24 | IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO), | ||
25 | /* GPIO keys */ | ||
26 | IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), /* 0 */ | ||
27 | IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), /* 1 */ | ||
28 | IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO), /* 2 */ | ||
29 | IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), /* 3 */ | ||
30 | IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO), /* 32 */ | ||
31 | IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO), /* 33 */ | ||
32 | IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO), /* 34 */ | ||
33 | IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO), /* 35 */ | ||
34 | IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO), /* 38 */ | ||
35 | IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO), /* 39 */ | ||
36 | IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO), /* 50 */ | ||
37 | IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_GPIO), /* 51 */ | ||
38 | IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_GPIO), /* 52 */ | ||
39 | IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_GPIO), /* 53 */ | ||
40 | |||
41 | /* LEDs */ | ||
42 | IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_CONFIG_GPIO), /* 44 */ | ||
43 | IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_GPIO), /* 45 */ | ||
44 | IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_GPIO), /* 55 */ | ||
45 | IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_GPIO), /* 56 */ | ||
46 | }; | ||
47 | |||
48 | /* SPI */ | ||
49 | static struct spi_board_info pcm037_spi_dev[] = { | ||
50 | { | ||
51 | .modalias = "dac124s085", | ||
52 | .max_speed_hz = 400000, | ||
53 | .bus_num = 0, | ||
54 | .chip_select = 0, /* Index in pcm037_spi1_cs[] */ | ||
55 | .mode = SPI_CPHA, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | /* Platform Data for MXC CSPI */ | ||
60 | static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)}; | ||
61 | |||
62 | static const struct spi_imx_master pcm037_spi1_pdata __initconst = { | ||
63 | .chipselect = pcm037_spi1_cs, | ||
64 | .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs), | ||
65 | }; | ||
66 | |||
67 | /* GPIO-keys input device */ | ||
68 | static struct gpio_keys_button pcm037_gpio_keys[] = { | ||
69 | { | ||
70 | .type = EV_KEY, | ||
71 | .code = KEY_L, | ||
72 | .gpio = 0, | ||
73 | .desc = "Wheel Manual", | ||
74 | .wakeup = 0, | ||
75 | }, { | ||
76 | .type = EV_KEY, | ||
77 | .code = KEY_A, | ||
78 | .gpio = 1, | ||
79 | .desc = "Wheel AF", | ||
80 | .wakeup = 0, | ||
81 | }, { | ||
82 | .type = EV_KEY, | ||
83 | .code = KEY_V, | ||
84 | .gpio = 2, | ||
85 | .desc = "Wheel View", | ||
86 | .wakeup = 0, | ||
87 | }, { | ||
88 | .type = EV_KEY, | ||
89 | .code = KEY_M, | ||
90 | .gpio = 3, | ||
91 | .desc = "Wheel Menu", | ||
92 | .wakeup = 0, | ||
93 | }, { | ||
94 | .type = EV_KEY, | ||
95 | .code = KEY_UP, | ||
96 | .gpio = 32, | ||
97 | .desc = "Nav Pad Up", | ||
98 | .wakeup = 0, | ||
99 | }, { | ||
100 | .type = EV_KEY, | ||
101 | .code = KEY_RIGHT, | ||
102 | .gpio = 33, | ||
103 | .desc = "Nav Pad Right", | ||
104 | .wakeup = 0, | ||
105 | }, { | ||
106 | .type = EV_KEY, | ||
107 | .code = KEY_DOWN, | ||
108 | .gpio = 34, | ||
109 | .desc = "Nav Pad Down", | ||
110 | .wakeup = 0, | ||
111 | }, { | ||
112 | .type = EV_KEY, | ||
113 | .code = KEY_LEFT, | ||
114 | .gpio = 35, | ||
115 | .desc = "Nav Pad Left", | ||
116 | .wakeup = 0, | ||
117 | }, { | ||
118 | .type = EV_KEY, | ||
119 | .code = KEY_ENTER, | ||
120 | .gpio = 38, | ||
121 | .desc = "Nav Pad Ok", | ||
122 | .wakeup = 0, | ||
123 | }, { | ||
124 | .type = EV_KEY, | ||
125 | .code = KEY_O, | ||
126 | .gpio = 39, | ||
127 | .desc = "Wheel Off", | ||
128 | .wakeup = 0, | ||
129 | }, { | ||
130 | .type = EV_KEY, | ||
131 | .code = BTN_FORWARD, | ||
132 | .gpio = 50, | ||
133 | .desc = "Focus Forward", | ||
134 | .wakeup = 0, | ||
135 | }, { | ||
136 | .type = EV_KEY, | ||
137 | .code = BTN_BACK, | ||
138 | .gpio = 51, | ||
139 | .desc = "Focus Backward", | ||
140 | .wakeup = 0, | ||
141 | }, { | ||
142 | .type = EV_KEY, | ||
143 | .code = BTN_MIDDLE, | ||
144 | .gpio = 52, | ||
145 | .desc = "Release Half", | ||
146 | .wakeup = 0, | ||
147 | }, { | ||
148 | .type = EV_KEY, | ||
149 | .code = BTN_EXTRA, | ||
150 | .gpio = 53, | ||
151 | .desc = "Release Full", | ||
152 | .wakeup = 0, | ||
153 | }, | ||
154 | }; | ||
155 | |||
156 | static const struct gpio_keys_platform_data | ||
157 | pcm037_gpio_keys_platform_data __initconst = { | ||
158 | .buttons = pcm037_gpio_keys, | ||
159 | .nbuttons = ARRAY_SIZE(pcm037_gpio_keys), | ||
160 | .rep = 0, /* No auto-repeat */ | ||
161 | }; | ||
162 | |||
163 | static int __init eet_init_devices(void) | ||
164 | { | ||
165 | if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) | ||
166 | return 0; | ||
167 | |||
168 | mxc_iomux_setup_multiple_pins(pcm037_eet_pins, | ||
169 | ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet"); | ||
170 | |||
171 | /* SPI */ | ||
172 | spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev)); | ||
173 | imx31_add_spi_imx0(&pcm037_spi1_pdata); | ||
174 | |||
175 | imx_add_gpio_keys(&pcm037_gpio_keys_platform_data); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | late_initcall(eet_init_devices); | ||
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c new file mode 100644 index 000000000000..026441628dfa --- /dev/null +++ b/arch/arm/mach-imx/mach-pcm043.c | |||
@@ -0,0 +1,423 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Sascha Hauer, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | #include <linux/init.h> | ||
17 | |||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/mtd/physmap.h> | ||
20 | #include <linux/mtd/plat-ram.h> | ||
21 | #include <linux/memory.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/smc911x.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/i2c/at24.h> | ||
28 | #include <linux/usb/otg.h> | ||
29 | #include <linux/usb/ulpi.h> | ||
30 | |||
31 | #include <asm/mach-types.h> | ||
32 | #include <asm/mach/arch.h> | ||
33 | #include <asm/mach/time.h> | ||
34 | #include <asm/mach/map.h> | ||
35 | |||
36 | #include <mach/hardware.h> | ||
37 | #include <mach/common.h> | ||
38 | #include <mach/iomux-mx35.h> | ||
39 | #include <mach/ulpi.h> | ||
40 | #include <mach/audmux.h> | ||
41 | |||
42 | #include "devices-imx35.h" | ||
43 | |||
44 | static const struct fb_videomode fb_modedb[] = { | ||
45 | { | ||
46 | /* 240x320 @ 60 Hz */ | ||
47 | .name = "Sharp-LQ035Q7", | ||
48 | .refresh = 60, | ||
49 | .xres = 240, | ||
50 | .yres = 320, | ||
51 | .pixclock = 185925, | ||
52 | .left_margin = 9, | ||
53 | .right_margin = 16, | ||
54 | .upper_margin = 7, | ||
55 | .lower_margin = 9, | ||
56 | .hsync_len = 1, | ||
57 | .vsync_len = 1, | ||
58 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN, | ||
59 | .vmode = FB_VMODE_NONINTERLACED, | ||
60 | .flag = 0, | ||
61 | }, { | ||
62 | /* 240x320 @ 60 Hz */ | ||
63 | .name = "TX090", | ||
64 | .refresh = 60, | ||
65 | .xres = 240, | ||
66 | .yres = 320, | ||
67 | .pixclock = 38255, | ||
68 | .left_margin = 144, | ||
69 | .right_margin = 0, | ||
70 | .upper_margin = 7, | ||
71 | .lower_margin = 40, | ||
72 | .hsync_len = 96, | ||
73 | .vsync_len = 1, | ||
74 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, | ||
75 | .vmode = FB_VMODE_NONINTERLACED, | ||
76 | .flag = 0, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static const struct ipu_platform_data mx3_ipu_data __initconst = { | ||
81 | .irq_base = MXC_IPU_IRQ_START, | ||
82 | }; | ||
83 | |||
84 | static struct mx3fb_platform_data mx3fb_pdata __initdata = { | ||
85 | .name = "Sharp-LQ035Q7", | ||
86 | .mode = fb_modedb, | ||
87 | .num_modes = ARRAY_SIZE(fb_modedb), | ||
88 | }; | ||
89 | |||
90 | static struct physmap_flash_data pcm043_flash_data = { | ||
91 | .width = 2, | ||
92 | }; | ||
93 | |||
94 | static struct resource pcm043_flash_resource = { | ||
95 | .start = 0xa0000000, | ||
96 | .end = 0xa1ffffff, | ||
97 | .flags = IORESOURCE_MEM, | ||
98 | }; | ||
99 | |||
100 | static struct platform_device pcm043_flash = { | ||
101 | .name = "physmap-flash", | ||
102 | .id = 0, | ||
103 | .dev = { | ||
104 | .platform_data = &pcm043_flash_data, | ||
105 | }, | ||
106 | .resource = &pcm043_flash_resource, | ||
107 | .num_resources = 1, | ||
108 | }; | ||
109 | |||
110 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
111 | .flags = IMXUART_HAVE_RTSCTS, | ||
112 | }; | ||
113 | |||
114 | static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = { | ||
115 | .bitrate = 50000, | ||
116 | }; | ||
117 | |||
118 | static struct at24_platform_data board_eeprom = { | ||
119 | .byte_len = 4096, | ||
120 | .page_size = 32, | ||
121 | .flags = AT24_FLAG_ADDR16, | ||
122 | }; | ||
123 | |||
124 | static struct i2c_board_info pcm043_i2c_devices[] = { | ||
125 | { | ||
126 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | ||
127 | .platform_data = &board_eeprom, | ||
128 | }, { | ||
129 | I2C_BOARD_INFO("pcf8563", 0x51), | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | static struct platform_device *devices[] __initdata = { | ||
134 | &pcm043_flash, | ||
135 | }; | ||
136 | |||
137 | static iomux_v3_cfg_t pcm043_pads[] = { | ||
138 | /* UART1 */ | ||
139 | MX35_PAD_CTS1__UART1_CTS, | ||
140 | MX35_PAD_RTS1__UART1_RTS, | ||
141 | MX35_PAD_TXD1__UART1_TXD_MUX, | ||
142 | MX35_PAD_RXD1__UART1_RXD_MUX, | ||
143 | /* UART2 */ | ||
144 | MX35_PAD_CTS2__UART2_CTS, | ||
145 | MX35_PAD_RTS2__UART2_RTS, | ||
146 | MX35_PAD_TXD2__UART2_TXD_MUX, | ||
147 | MX35_PAD_RXD2__UART2_RXD_MUX, | ||
148 | /* FEC */ | ||
149 | MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, | ||
150 | MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, | ||
151 | MX35_PAD_FEC_RX_DV__FEC_RX_DV, | ||
152 | MX35_PAD_FEC_COL__FEC_COL, | ||
153 | MX35_PAD_FEC_RDATA0__FEC_RDATA_0, | ||
154 | MX35_PAD_FEC_TDATA0__FEC_TDATA_0, | ||
155 | MX35_PAD_FEC_TX_EN__FEC_TX_EN, | ||
156 | MX35_PAD_FEC_MDC__FEC_MDC, | ||
157 | MX35_PAD_FEC_MDIO__FEC_MDIO, | ||
158 | MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, | ||
159 | MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, | ||
160 | MX35_PAD_FEC_CRS__FEC_CRS, | ||
161 | MX35_PAD_FEC_RDATA1__FEC_RDATA_1, | ||
162 | MX35_PAD_FEC_TDATA1__FEC_TDATA_1, | ||
163 | MX35_PAD_FEC_RDATA2__FEC_RDATA_2, | ||
164 | MX35_PAD_FEC_TDATA2__FEC_TDATA_2, | ||
165 | MX35_PAD_FEC_RDATA3__FEC_RDATA_3, | ||
166 | MX35_PAD_FEC_TDATA3__FEC_TDATA_3, | ||
167 | /* I2C1 */ | ||
168 | MX35_PAD_I2C1_CLK__I2C1_SCL, | ||
169 | MX35_PAD_I2C1_DAT__I2C1_SDA, | ||
170 | /* Display */ | ||
171 | MX35_PAD_LD0__IPU_DISPB_DAT_0, | ||
172 | MX35_PAD_LD1__IPU_DISPB_DAT_1, | ||
173 | MX35_PAD_LD2__IPU_DISPB_DAT_2, | ||
174 | MX35_PAD_LD3__IPU_DISPB_DAT_3, | ||
175 | MX35_PAD_LD4__IPU_DISPB_DAT_4, | ||
176 | MX35_PAD_LD5__IPU_DISPB_DAT_5, | ||
177 | MX35_PAD_LD6__IPU_DISPB_DAT_6, | ||
178 | MX35_PAD_LD7__IPU_DISPB_DAT_7, | ||
179 | MX35_PAD_LD8__IPU_DISPB_DAT_8, | ||
180 | MX35_PAD_LD9__IPU_DISPB_DAT_9, | ||
181 | MX35_PAD_LD10__IPU_DISPB_DAT_10, | ||
182 | MX35_PAD_LD11__IPU_DISPB_DAT_11, | ||
183 | MX35_PAD_LD12__IPU_DISPB_DAT_12, | ||
184 | MX35_PAD_LD13__IPU_DISPB_DAT_13, | ||
185 | MX35_PAD_LD14__IPU_DISPB_DAT_14, | ||
186 | MX35_PAD_LD15__IPU_DISPB_DAT_15, | ||
187 | MX35_PAD_LD16__IPU_DISPB_DAT_16, | ||
188 | MX35_PAD_LD17__IPU_DISPB_DAT_17, | ||
189 | MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC, | ||
190 | MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, | ||
191 | MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, | ||
192 | MX35_PAD_CONTRAST__IPU_DISPB_CONTR, | ||
193 | MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, | ||
194 | MX35_PAD_D3_REV__IPU_DISPB_D3_REV, | ||
195 | MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, | ||
196 | /* gpio */ | ||
197 | MX35_PAD_ATA_CS0__GPIO2_6, | ||
198 | /* USB host */ | ||
199 | MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, | ||
200 | MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, | ||
201 | /* SSI */ | ||
202 | MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS, | ||
203 | MX35_PAD_STXD4__AUDMUX_AUD4_TXD, | ||
204 | MX35_PAD_SRXD4__AUDMUX_AUD4_RXD, | ||
205 | MX35_PAD_SCK4__AUDMUX_AUD4_TXC, | ||
206 | /* CAN2 */ | ||
207 | MX35_PAD_TX5_RX0__CAN2_TXCAN, | ||
208 | MX35_PAD_TX4_RX1__CAN2_RXCAN, | ||
209 | /* esdhc */ | ||
210 | MX35_PAD_SD1_CMD__ESDHC1_CMD, | ||
211 | MX35_PAD_SD1_CLK__ESDHC1_CLK, | ||
212 | MX35_PAD_SD1_DATA0__ESDHC1_DAT0, | ||
213 | MX35_PAD_SD1_DATA1__ESDHC1_DAT1, | ||
214 | MX35_PAD_SD1_DATA2__ESDHC1_DAT2, | ||
215 | MX35_PAD_SD1_DATA3__ESDHC1_DAT3, | ||
216 | MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */ | ||
217 | MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */ | ||
218 | }; | ||
219 | |||
220 | #define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31) | ||
221 | #define AC97_GPIO_TXD IMX_GPIO_NR(2, 28) | ||
222 | #define AC97_GPIO_RESET IMX_GPIO_NR(2, 0) | ||
223 | #define SD1_GPIO_WP IMX_GPIO_NR(2, 23) | ||
224 | #define SD1_GPIO_CD IMX_GPIO_NR(2, 24) | ||
225 | |||
226 | static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97) | ||
227 | { | ||
228 | iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31; | ||
229 | iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS; | ||
230 | int ret; | ||
231 | |||
232 | ret = gpio_request(AC97_GPIO_TXFS, "SSI"); | ||
233 | if (ret) { | ||
234 | printk("failed to get GPIO_TXFS: %d\n", ret); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | mxc_iomux_v3_setup_pad(txfs_gpio); | ||
239 | |||
240 | /* warm reset */ | ||
241 | gpio_direction_output(AC97_GPIO_TXFS, 1); | ||
242 | udelay(2); | ||
243 | gpio_set_value(AC97_GPIO_TXFS, 0); | ||
244 | |||
245 | gpio_free(AC97_GPIO_TXFS); | ||
246 | mxc_iomux_v3_setup_pad(txfs); | ||
247 | } | ||
248 | |||
249 | static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97) | ||
250 | { | ||
251 | iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31; | ||
252 | iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS; | ||
253 | iomux_v3_cfg_t txd_gpio = MX35_PAD_STXD4__GPIO2_28; | ||
254 | iomux_v3_cfg_t txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD; | ||
255 | iomux_v3_cfg_t reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0; | ||
256 | int ret; | ||
257 | |||
258 | ret = gpio_request(AC97_GPIO_TXFS, "SSI"); | ||
259 | if (ret) | ||
260 | goto err1; | ||
261 | |||
262 | ret = gpio_request(AC97_GPIO_TXD, "SSI"); | ||
263 | if (ret) | ||
264 | goto err2; | ||
265 | |||
266 | ret = gpio_request(AC97_GPIO_RESET, "SSI"); | ||
267 | if (ret) | ||
268 | goto err3; | ||
269 | |||
270 | mxc_iomux_v3_setup_pad(txfs_gpio); | ||
271 | mxc_iomux_v3_setup_pad(txd_gpio); | ||
272 | mxc_iomux_v3_setup_pad(reset_gpio); | ||
273 | |||
274 | gpio_direction_output(AC97_GPIO_TXFS, 0); | ||
275 | gpio_direction_output(AC97_GPIO_TXD, 0); | ||
276 | |||
277 | /* cold reset */ | ||
278 | gpio_direction_output(AC97_GPIO_RESET, 0); | ||
279 | udelay(10); | ||
280 | gpio_direction_output(AC97_GPIO_RESET, 1); | ||
281 | |||
282 | mxc_iomux_v3_setup_pad(txd); | ||
283 | mxc_iomux_v3_setup_pad(txfs); | ||
284 | |||
285 | gpio_free(AC97_GPIO_RESET); | ||
286 | err3: | ||
287 | gpio_free(AC97_GPIO_TXD); | ||
288 | err2: | ||
289 | gpio_free(AC97_GPIO_TXFS); | ||
290 | err1: | ||
291 | if (ret) | ||
292 | printk("%s failed with %d\n", __func__, ret); | ||
293 | mdelay(1); | ||
294 | } | ||
295 | |||
296 | static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = { | ||
297 | .ac97_reset = pcm043_ac97_cold_reset, | ||
298 | .ac97_warm_reset = pcm043_ac97_warm_reset, | ||
299 | .flags = IMX_SSI_USE_AC97, | ||
300 | }; | ||
301 | |||
302 | static const struct mxc_nand_platform_data | ||
303 | pcm037_nand_board_info __initconst = { | ||
304 | .width = 1, | ||
305 | .hw_ecc = 1, | ||
306 | }; | ||
307 | |||
308 | static int pcm043_otg_init(struct platform_device *pdev) | ||
309 | { | ||
310 | return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); | ||
311 | } | ||
312 | |||
313 | static struct mxc_usbh_platform_data otg_pdata __initdata = { | ||
314 | .init = pcm043_otg_init, | ||
315 | .portsc = MXC_EHCI_MODE_UTMI, | ||
316 | }; | ||
317 | |||
318 | static int pcm043_usbh1_init(struct platform_device *pdev) | ||
319 | { | ||
320 | return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI | | ||
321 | MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN); | ||
322 | } | ||
323 | |||
324 | static const struct mxc_usbh_platform_data usbh1_pdata __initconst = { | ||
325 | .init = pcm043_usbh1_init, | ||
326 | .portsc = MXC_EHCI_MODE_SERIAL, | ||
327 | }; | ||
328 | |||
329 | static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { | ||
330 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
331 | .phy_mode = FSL_USB2_PHY_UTMI, | ||
332 | }; | ||
333 | |||
334 | static int otg_mode_host; | ||
335 | |||
336 | static int __init pcm043_otg_mode(char *options) | ||
337 | { | ||
338 | if (!strcmp(options, "host")) | ||
339 | otg_mode_host = 1; | ||
340 | else if (!strcmp(options, "device")) | ||
341 | otg_mode_host = 0; | ||
342 | else | ||
343 | pr_info("otg_mode neither \"host\" nor \"device\". " | ||
344 | "Defaulting to device\n"); | ||
345 | return 0; | ||
346 | } | ||
347 | __setup("otg_mode=", pcm043_otg_mode); | ||
348 | |||
349 | static struct esdhc_platform_data sd1_pdata = { | ||
350 | .wp_gpio = SD1_GPIO_WP, | ||
351 | .cd_gpio = SD1_GPIO_CD, | ||
352 | }; | ||
353 | |||
354 | /* | ||
355 | * Board specific initialization. | ||
356 | */ | ||
357 | static void __init pcm043_init(void) | ||
358 | { | ||
359 | mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); | ||
360 | |||
361 | mxc_audmux_v2_configure_port(3, | ||
362 | MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */ | ||
363 | MXC_AUDMUX_V2_PTCR_TFSEL(0) | | ||
364 | MXC_AUDMUX_V2_PTCR_TFSDIR, | ||
365 | MXC_AUDMUX_V2_PDCR_RXDSEL(0)); | ||
366 | |||
367 | mxc_audmux_v2_configure_port(0, | ||
368 | MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */ | ||
369 | MXC_AUDMUX_V2_PTCR_TCSEL(3) | | ||
370 | MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */ | ||
371 | MXC_AUDMUX_V2_PDCR_RXDSEL(3)); | ||
372 | |||
373 | imx35_add_fec(NULL); | ||
374 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
375 | imx35_add_imx2_wdt(NULL); | ||
376 | |||
377 | imx35_add_imx_uart0(&uart_pdata); | ||
378 | imx35_add_mxc_nand(&pcm037_nand_board_info); | ||
379 | imx35_add_imx_ssi(0, &pcm043_ssi_pdata); | ||
380 | |||
381 | imx35_add_imx_uart1(&uart_pdata); | ||
382 | |||
383 | i2c_register_board_info(0, pcm043_i2c_devices, | ||
384 | ARRAY_SIZE(pcm043_i2c_devices)); | ||
385 | |||
386 | imx35_add_imx_i2c0(&pcm043_i2c0_data); | ||
387 | |||
388 | imx35_add_ipu_core(&mx3_ipu_data); | ||
389 | imx35_add_mx3_sdc_fb(&mx3fb_pdata); | ||
390 | |||
391 | if (otg_mode_host) { | ||
392 | otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
393 | ULPI_OTG_DRVVBUS_EXT); | ||
394 | if (otg_pdata.otg) | ||
395 | imx35_add_mxc_ehci_otg(&otg_pdata); | ||
396 | } | ||
397 | imx35_add_mxc_ehci_hs(&usbh1_pdata); | ||
398 | |||
399 | if (!otg_mode_host) | ||
400 | imx35_add_fsl_usb2_udc(&otg_device_pdata); | ||
401 | |||
402 | imx35_add_flexcan1(NULL); | ||
403 | imx35_add_sdhci_esdhc_imx(0, &sd1_pdata); | ||
404 | } | ||
405 | |||
406 | static void __init pcm043_timer_init(void) | ||
407 | { | ||
408 | mx35_clocks_init(); | ||
409 | } | ||
410 | |||
411 | struct sys_timer pcm043_timer = { | ||
412 | .init = pcm043_timer_init, | ||
413 | }; | ||
414 | |||
415 | MACHINE_START(PCM043, "Phytec Phycore pcm043") | ||
416 | /* Maintainer: Pengutronix */ | ||
417 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
418 | .map_io = mx35_map_io, | ||
419 | .init_early = imx35_init_early, | ||
420 | .init_irq = mx35_init_irq, | ||
421 | .timer = &pcm043_timer, | ||
422 | .init_machine = pcm043_init, | ||
423 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c new file mode 100644 index 000000000000..c16328715939 --- /dev/null +++ b/arch/arm/mach-imx/mach-qong.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/memory.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/mtd/physmap.h> | ||
21 | #include <linux/mtd/nand.h> | ||
22 | #include <linux/gpio.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/irqs.h> | ||
26 | #include <asm/mach-types.h> | ||
27 | #include <asm/mach/arch.h> | ||
28 | #include <asm/mach/time.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | #include <mach/common.h> | ||
31 | #include <asm/page.h> | ||
32 | #include <asm/setup.h> | ||
33 | #include <mach/iomux-mx3.h> | ||
34 | |||
35 | #include "devices-imx31.h" | ||
36 | |||
37 | /* FPGA defines */ | ||
38 | #define QONG_FPGA_VERSION(major, minor, rev) \ | ||
39 | (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF)) | ||
40 | |||
41 | #define QONG_FPGA_BASEADDR MX31_CS1_BASE_ADDR | ||
42 | #define QONG_FPGA_PERIPH_SIZE (1 << 24) | ||
43 | |||
44 | #define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR | ||
45 | #define QONG_FPGA_CTRL_SIZE 0x10 | ||
46 | /* FPGA control registers */ | ||
47 | #define QONG_FPGA_CTRL_VERSION 0x00 | ||
48 | |||
49 | #define QONG_DNET_ID 1 | ||
50 | #define QONG_DNET_BASEADDR \ | ||
51 | (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE) | ||
52 | #define QONG_DNET_SIZE 0x00001000 | ||
53 | |||
54 | #define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1) | ||
55 | |||
56 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
57 | .flags = IMXUART_HAVE_RTSCTS, | ||
58 | }; | ||
59 | |||
60 | static int uart_pins[] = { | ||
61 | MX31_PIN_CTS1__CTS1, | ||
62 | MX31_PIN_RTS1__RTS1, | ||
63 | MX31_PIN_TXD1__TXD1, | ||
64 | MX31_PIN_RXD1__RXD1 | ||
65 | }; | ||
66 | |||
67 | static inline void __init mxc_init_imx_uart(void) | ||
68 | { | ||
69 | mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), | ||
70 | "uart-0"); | ||
71 | imx31_add_imx_uart0(&uart_pdata); | ||
72 | } | ||
73 | |||
74 | static struct resource dnet_resources[] = { | ||
75 | { | ||
76 | .name = "dnet-memory", | ||
77 | .start = QONG_DNET_BASEADDR, | ||
78 | .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, | ||
79 | .flags = IORESOURCE_MEM, | ||
80 | }, { | ||
81 | .start = QONG_FPGA_IRQ, | ||
82 | .end = QONG_FPGA_IRQ, | ||
83 | .flags = IORESOURCE_IRQ, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | static struct platform_device dnet_device = { | ||
88 | .name = "dnet", | ||
89 | .id = -1, | ||
90 | .num_resources = ARRAY_SIZE(dnet_resources), | ||
91 | .resource = dnet_resources, | ||
92 | }; | ||
93 | |||
94 | static int __init qong_init_dnet(void) | ||
95 | { | ||
96 | int ret; | ||
97 | |||
98 | ret = platform_device_register(&dnet_device); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* MTD NOR flash */ | ||
103 | |||
104 | static struct physmap_flash_data qong_flash_data = { | ||
105 | .width = 2, | ||
106 | }; | ||
107 | |||
108 | static struct resource qong_flash_resource = { | ||
109 | .start = MX31_CS0_BASE_ADDR, | ||
110 | .end = MX31_CS0_BASE_ADDR + SZ_128M - 1, | ||
111 | .flags = IORESOURCE_MEM, | ||
112 | }; | ||
113 | |||
114 | static struct platform_device qong_nor_mtd_device = { | ||
115 | .name = "physmap-flash", | ||
116 | .id = 0, | ||
117 | .dev = { | ||
118 | .platform_data = &qong_flash_data, | ||
119 | }, | ||
120 | .resource = &qong_flash_resource, | ||
121 | .num_resources = 1, | ||
122 | }; | ||
123 | |||
124 | static void qong_init_nor_mtd(void) | ||
125 | { | ||
126 | (void)platform_device_register(&qong_nor_mtd_device); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Hardware specific access to control-lines | ||
131 | */ | ||
132 | static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | ||
133 | { | ||
134 | struct nand_chip *nand_chip = mtd->priv; | ||
135 | |||
136 | if (cmd == NAND_CMD_NONE) | ||
137 | return; | ||
138 | |||
139 | if (ctrl & NAND_CLE) | ||
140 | writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24)); | ||
141 | else | ||
142 | writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23)); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Read the Device Ready pin. | ||
147 | */ | ||
148 | static int qong_nand_device_ready(struct mtd_info *mtd) | ||
149 | { | ||
150 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB)); | ||
151 | } | ||
152 | |||
153 | static void qong_nand_select_chip(struct mtd_info *mtd, int chip) | ||
154 | { | ||
155 | if (chip >= 0) | ||
156 | gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); | ||
157 | else | ||
158 | gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1); | ||
159 | } | ||
160 | |||
161 | static struct platform_nand_data qong_nand_data = { | ||
162 | .chip = { | ||
163 | .nr_chips = 1, | ||
164 | .chip_delay = 20, | ||
165 | .options = 0, | ||
166 | }, | ||
167 | .ctrl = { | ||
168 | .cmd_ctrl = qong_nand_cmd_ctrl, | ||
169 | .dev_ready = qong_nand_device_ready, | ||
170 | .select_chip = qong_nand_select_chip, | ||
171 | } | ||
172 | }; | ||
173 | |||
174 | static struct resource qong_nand_resource = { | ||
175 | .start = MX31_CS3_BASE_ADDR, | ||
176 | .end = MX31_CS3_BASE_ADDR + SZ_32M - 1, | ||
177 | .flags = IORESOURCE_MEM, | ||
178 | }; | ||
179 | |||
180 | static struct platform_device qong_nand_device = { | ||
181 | .name = "gen_nand", | ||
182 | .id = -1, | ||
183 | .dev = { | ||
184 | .platform_data = &qong_nand_data, | ||
185 | }, | ||
186 | .num_resources = 1, | ||
187 | .resource = &qong_nand_resource, | ||
188 | }; | ||
189 | |||
190 | static void __init qong_init_nand_mtd(void) | ||
191 | { | ||
192 | /* init CS */ | ||
193 | mx31_setup_weimcs(3, 0x00004f00, 0x20013b31, 0x00020800); | ||
194 | mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); | ||
195 | |||
196 | /* enable pin */ | ||
197 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO)); | ||
198 | if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable")) | ||
199 | gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); | ||
200 | |||
201 | /* ready/busy pin */ | ||
202 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO)); | ||
203 | if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy")) | ||
204 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB)); | ||
205 | |||
206 | /* write protect pin */ | ||
207 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO)); | ||
208 | if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp")) | ||
209 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B)); | ||
210 | |||
211 | platform_device_register(&qong_nand_device); | ||
212 | } | ||
213 | |||
214 | static void __init qong_init_fpga(void) | ||
215 | { | ||
216 | void __iomem *regs; | ||
217 | u32 fpga_ver; | ||
218 | |||
219 | regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE); | ||
220 | if (!regs) { | ||
221 | printk(KERN_ERR "%s: failed to map registers, aborting.\n", | ||
222 | __func__); | ||
223 | return; | ||
224 | } | ||
225 | |||
226 | fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION); | ||
227 | iounmap(regs); | ||
228 | printk(KERN_INFO "Qong FPGA version %d.%d.%d\n", | ||
229 | (fpga_ver & 0xF000) >> 12, | ||
230 | (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF); | ||
231 | if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) { | ||
232 | printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based " | ||
233 | "devices won't be registered!\n"); | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | /* register FPGA-based devices */ | ||
238 | qong_init_nand_mtd(); | ||
239 | qong_init_dnet(); | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Board specific initialization. | ||
244 | */ | ||
245 | static void __init qong_init(void) | ||
246 | { | ||
247 | mxc_init_imx_uart(); | ||
248 | qong_init_nor_mtd(); | ||
249 | qong_init_fpga(); | ||
250 | } | ||
251 | |||
252 | static void __init qong_timer_init(void) | ||
253 | { | ||
254 | mx31_clocks_init(26000000); | ||
255 | } | ||
256 | |||
257 | static struct sys_timer qong_timer = { | ||
258 | .init = qong_timer_init, | ||
259 | }; | ||
260 | |||
261 | MACHINE_START(QONG, "Dave/DENX QongEVB-LITE") | ||
262 | /* Maintainer: DENX Software Engineering GmbH */ | ||
263 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | ||
264 | .map_io = mx31_map_io, | ||
265 | .init_early = imx31_init_early, | ||
266 | .init_irq = mx31_init_irq, | ||
267 | .timer = &qong_timer, | ||
268 | .init_machine = qong_init, | ||
269 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c new file mode 100644 index 000000000000..d74e3473d236 --- /dev/null +++ b/arch/arm/mach-imx/mach-vpr200.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix | ||
4 | * Copyright 2010 Creative Product Design | ||
5 | * | ||
6 | * Derived from mx35 3stack. | ||
7 | * Original author: Fabio Estevam <fabio.estevam@freescale.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mtd/physmap.h> | ||
24 | #include <linux/memory.h> | ||
25 | #include <linux/gpio.h> | ||
26 | |||
27 | #include <asm/mach-types.h> | ||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/mach/time.h> | ||
30 | |||
31 | #include <mach/hardware.h> | ||
32 | #include <mach/common.h> | ||
33 | #include <mach/iomux-mx35.h> | ||
34 | #include <mach/irqs.h> | ||
35 | |||
36 | #include <linux/i2c.h> | ||
37 | #include <linux/i2c/at24.h> | ||
38 | #include <linux/mfd/mc13xxx.h> | ||
39 | |||
40 | #include "devices-imx35.h" | ||
41 | |||
42 | #define GPIO_LCDPWR IMX_GPIO_NR(1, 2) | ||
43 | #define GPIO_PMIC_INT IMX_GPIO_NR(2, 0) | ||
44 | |||
45 | #define GPIO_BUTTON1 IMX_GPIO_NR(1, 4) | ||
46 | #define GPIO_BUTTON2 IMX_GPIO_NR(1, 5) | ||
47 | #define GPIO_BUTTON3 IMX_GPIO_NR(1, 7) | ||
48 | #define GPIO_BUTTON4 IMX_GPIO_NR(1, 8) | ||
49 | #define GPIO_BUTTON5 IMX_GPIO_NR(1, 9) | ||
50 | #define GPIO_BUTTON6 IMX_GPIO_NR(1, 10) | ||
51 | #define GPIO_BUTTON7 IMX_GPIO_NR(1, 11) | ||
52 | #define GPIO_BUTTON8 IMX_GPIO_NR(1, 12) | ||
53 | |||
54 | static const struct fb_videomode fb_modedb[] = { | ||
55 | { | ||
56 | /* 800x480 @ 60 Hz */ | ||
57 | .name = "PT0708048", | ||
58 | .refresh = 60, | ||
59 | .xres = 800, | ||
60 | .yres = 480, | ||
61 | .pixclock = KHZ2PICOS(33260), | ||
62 | .left_margin = 50, | ||
63 | .right_margin = 156, | ||
64 | .upper_margin = 10, | ||
65 | .lower_margin = 10, | ||
66 | .hsync_len = 1, /* note: DE only display */ | ||
67 | .vsync_len = 1, /* note: DE only display */ | ||
68 | .sync = FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH, | ||
69 | .vmode = FB_VMODE_NONINTERLACED, | ||
70 | .flag = 0, | ||
71 | }, { | ||
72 | /* 800x480 @ 60 Hz */ | ||
73 | .name = "CTP-CLAA070LC0ACW", | ||
74 | .refresh = 60, | ||
75 | .xres = 800, | ||
76 | .yres = 480, | ||
77 | .pixclock = KHZ2PICOS(27000), | ||
78 | .left_margin = 50, | ||
79 | .right_margin = 50, /* whole line should have 900 clocks */ | ||
80 | .upper_margin = 10, | ||
81 | .lower_margin = 10, /* whole frame should have 500 lines */ | ||
82 | .hsync_len = 1, /* note: DE only display */ | ||
83 | .vsync_len = 1, /* note: DE only display */ | ||
84 | .sync = FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH, | ||
85 | .vmode = FB_VMODE_NONINTERLACED, | ||
86 | .flag = 0, | ||
87 | } | ||
88 | }; | ||
89 | |||
90 | static const struct ipu_platform_data mx3_ipu_data __initconst = { | ||
91 | .irq_base = MXC_IPU_IRQ_START, | ||
92 | }; | ||
93 | |||
94 | static struct mx3fb_platform_data mx3fb_pdata __initdata = { | ||
95 | .name = "PT0708048", | ||
96 | .mode = fb_modedb, | ||
97 | .num_modes = ARRAY_SIZE(fb_modedb), | ||
98 | }; | ||
99 | |||
100 | static struct physmap_flash_data vpr200_flash_data = { | ||
101 | .width = 2, | ||
102 | }; | ||
103 | |||
104 | static struct resource vpr200_flash_resource = { | ||
105 | .start = MX35_CS0_BASE_ADDR, | ||
106 | .end = MX35_CS0_BASE_ADDR + SZ_64M - 1, | ||
107 | .flags = IORESOURCE_MEM, | ||
108 | }; | ||
109 | |||
110 | static struct platform_device vpr200_flash = { | ||
111 | .name = "physmap-flash", | ||
112 | .id = 0, | ||
113 | .dev = { | ||
114 | .platform_data = &vpr200_flash_data, | ||
115 | }, | ||
116 | .resource = &vpr200_flash_resource, | ||
117 | .num_resources = 1, | ||
118 | }; | ||
119 | |||
120 | static const struct mxc_nand_platform_data | ||
121 | vpr200_nand_board_info __initconst = { | ||
122 | .width = 1, | ||
123 | .hw_ecc = 1, | ||
124 | .flash_bbt = 1, | ||
125 | }; | ||
126 | |||
127 | #define VPR_KEY_DEBOUNCE 500 | ||
128 | static struct gpio_keys_button vpr200_gpio_keys_table[] = { | ||
129 | {KEY_F2, GPIO_BUTTON1, 1, "vpr-keys: F2", 0, VPR_KEY_DEBOUNCE}, | ||
130 | {KEY_F3, GPIO_BUTTON2, 1, "vpr-keys: F3", 0, VPR_KEY_DEBOUNCE}, | ||
131 | {KEY_F4, GPIO_BUTTON3, 1, "vpr-keys: F4", 0, VPR_KEY_DEBOUNCE}, | ||
132 | {KEY_F5, GPIO_BUTTON4, 1, "vpr-keys: F5", 0, VPR_KEY_DEBOUNCE}, | ||
133 | {KEY_F6, GPIO_BUTTON5, 1, "vpr-keys: F6", 0, VPR_KEY_DEBOUNCE}, | ||
134 | {KEY_F7, GPIO_BUTTON6, 1, "vpr-keys: F7", 0, VPR_KEY_DEBOUNCE}, | ||
135 | {KEY_F8, GPIO_BUTTON7, 1, "vpr-keys: F8", 1, VPR_KEY_DEBOUNCE}, | ||
136 | {KEY_F9, GPIO_BUTTON8, 1, "vpr-keys: F9", 1, VPR_KEY_DEBOUNCE}, | ||
137 | }; | ||
138 | |||
139 | static const struct gpio_keys_platform_data | ||
140 | vpr200_gpio_keys_data __initconst = { | ||
141 | .buttons = vpr200_gpio_keys_table, | ||
142 | .nbuttons = ARRAY_SIZE(vpr200_gpio_keys_table), | ||
143 | }; | ||
144 | |||
145 | static struct mc13xxx_platform_data vpr200_pmic = { | ||
146 | .flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN, | ||
147 | }; | ||
148 | |||
149 | static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = { | ||
150 | .bitrate = 50000, | ||
151 | }; | ||
152 | |||
153 | static struct at24_platform_data vpr200_eeprom = { | ||
154 | .byte_len = 2048 / 8, | ||
155 | .page_size = 1, | ||
156 | }; | ||
157 | |||
158 | static struct i2c_board_info vpr200_i2c_devices[] = { | ||
159 | { | ||
160 | I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */ | ||
161 | .platform_data = &vpr200_eeprom, | ||
162 | }, { | ||
163 | I2C_BOARD_INFO("mc13892", 0x08), | ||
164 | .platform_data = &vpr200_pmic, | ||
165 | .irq = gpio_to_irq(GPIO_PMIC_INT), | ||
166 | } | ||
167 | }; | ||
168 | |||
169 | static iomux_v3_cfg_t vpr200_pads[] = { | ||
170 | /* UART1 */ | ||
171 | MX35_PAD_TXD1__UART1_TXD_MUX, | ||
172 | MX35_PAD_RXD1__UART1_RXD_MUX, | ||
173 | /* UART3 */ | ||
174 | MX35_PAD_ATA_DATA10__UART3_RXD_MUX, | ||
175 | MX35_PAD_ATA_DATA11__UART3_TXD_MUX, | ||
176 | /* FEC */ | ||
177 | MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, | ||
178 | MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, | ||
179 | MX35_PAD_FEC_RX_DV__FEC_RX_DV, | ||
180 | MX35_PAD_FEC_COL__FEC_COL, | ||
181 | MX35_PAD_FEC_RDATA0__FEC_RDATA_0, | ||
182 | MX35_PAD_FEC_TDATA0__FEC_TDATA_0, | ||
183 | MX35_PAD_FEC_TX_EN__FEC_TX_EN, | ||
184 | MX35_PAD_FEC_MDC__FEC_MDC, | ||
185 | MX35_PAD_FEC_MDIO__FEC_MDIO, | ||
186 | MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, | ||
187 | MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, | ||
188 | MX35_PAD_FEC_CRS__FEC_CRS, | ||
189 | MX35_PAD_FEC_RDATA1__FEC_RDATA_1, | ||
190 | MX35_PAD_FEC_TDATA1__FEC_TDATA_1, | ||
191 | MX35_PAD_FEC_RDATA2__FEC_RDATA_2, | ||
192 | MX35_PAD_FEC_TDATA2__FEC_TDATA_2, | ||
193 | MX35_PAD_FEC_RDATA3__FEC_RDATA_3, | ||
194 | MX35_PAD_FEC_TDATA3__FEC_TDATA_3, | ||
195 | /* Display */ | ||
196 | MX35_PAD_LD0__IPU_DISPB_DAT_0, | ||
197 | MX35_PAD_LD1__IPU_DISPB_DAT_1, | ||
198 | MX35_PAD_LD2__IPU_DISPB_DAT_2, | ||
199 | MX35_PAD_LD3__IPU_DISPB_DAT_3, | ||
200 | MX35_PAD_LD4__IPU_DISPB_DAT_4, | ||
201 | MX35_PAD_LD5__IPU_DISPB_DAT_5, | ||
202 | MX35_PAD_LD6__IPU_DISPB_DAT_6, | ||
203 | MX35_PAD_LD7__IPU_DISPB_DAT_7, | ||
204 | MX35_PAD_LD8__IPU_DISPB_DAT_8, | ||
205 | MX35_PAD_LD9__IPU_DISPB_DAT_9, | ||
206 | MX35_PAD_LD10__IPU_DISPB_DAT_10, | ||
207 | MX35_PAD_LD11__IPU_DISPB_DAT_11, | ||
208 | MX35_PAD_LD12__IPU_DISPB_DAT_12, | ||
209 | MX35_PAD_LD13__IPU_DISPB_DAT_13, | ||
210 | MX35_PAD_LD14__IPU_DISPB_DAT_14, | ||
211 | MX35_PAD_LD15__IPU_DISPB_DAT_15, | ||
212 | MX35_PAD_LD16__IPU_DISPB_DAT_16, | ||
213 | MX35_PAD_LD17__IPU_DISPB_DAT_17, | ||
214 | MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, | ||
215 | MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, | ||
216 | MX35_PAD_CONTRAST__IPU_DISPB_CONTR, | ||
217 | /* LCD Enable */ | ||
218 | MX35_PAD_D3_VSYNC__GPIO1_2, | ||
219 | /* USBOTG */ | ||
220 | MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, | ||
221 | MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, | ||
222 | /* SDCARD */ | ||
223 | MX35_PAD_SD1_CMD__ESDHC1_CMD, | ||
224 | MX35_PAD_SD1_CLK__ESDHC1_CLK, | ||
225 | MX35_PAD_SD1_DATA0__ESDHC1_DAT0, | ||
226 | MX35_PAD_SD1_DATA1__ESDHC1_DAT1, | ||
227 | MX35_PAD_SD1_DATA2__ESDHC1_DAT2, | ||
228 | MX35_PAD_SD1_DATA3__ESDHC1_DAT3, | ||
229 | /* PMIC */ | ||
230 | MX35_PAD_GPIO2_0__GPIO2_0, | ||
231 | /* GPIO keys */ | ||
232 | MX35_PAD_SCKR__GPIO1_4, | ||
233 | MX35_PAD_COMPARE__GPIO1_5, | ||
234 | MX35_PAD_SCKT__GPIO1_7, | ||
235 | MX35_PAD_FST__GPIO1_8, | ||
236 | MX35_PAD_HCKT__GPIO1_9, | ||
237 | MX35_PAD_TX5_RX0__GPIO1_10, | ||
238 | MX35_PAD_TX4_RX1__GPIO1_11, | ||
239 | MX35_PAD_TX3_RX2__GPIO1_12, | ||
240 | }; | ||
241 | |||
242 | /* USB Device config */ | ||
243 | static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { | ||
244 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
245 | .phy_mode = FSL_USB2_PHY_UTMI, | ||
246 | .workaround = FLS_USB2_WORKAROUND_ENGCM09152, | ||
247 | }; | ||
248 | |||
249 | static int vpr200_usbh_init(struct platform_device *pdev) | ||
250 | { | ||
251 | return mx35_initialize_usb_hw(pdev->id, | ||
252 | MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY); | ||
253 | } | ||
254 | |||
255 | /* USB HOST config */ | ||
256 | static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { | ||
257 | .init = vpr200_usbh_init, | ||
258 | .portsc = MXC_EHCI_MODE_SERIAL, | ||
259 | }; | ||
260 | |||
261 | static struct platform_device *devices[] __initdata = { | ||
262 | &vpr200_flash, | ||
263 | }; | ||
264 | |||
265 | /* | ||
266 | * Board specific initialization. | ||
267 | */ | ||
268 | static void __init vpr200_board_init(void) | ||
269 | { | ||
270 | mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads)); | ||
271 | |||
272 | imx35_add_fec(NULL); | ||
273 | imx35_add_imx2_wdt(NULL); | ||
274 | imx_add_gpio_keys(&vpr200_gpio_keys_data); | ||
275 | |||
276 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
277 | |||
278 | if (0 != gpio_request(GPIO_LCDPWR, "LCDPWR")) | ||
279 | printk(KERN_WARNING "vpr200: Couldn't get LCDPWR gpio\n"); | ||
280 | else | ||
281 | gpio_direction_output(GPIO_LCDPWR, 0); | ||
282 | |||
283 | if (0 != gpio_request(GPIO_PMIC_INT, "PMIC_INT")) | ||
284 | printk(KERN_WARNING "vpr200: Couldn't get PMIC_INT gpio\n"); | ||
285 | else | ||
286 | gpio_direction_input(GPIO_PMIC_INT); | ||
287 | |||
288 | imx35_add_imx_uart0(NULL); | ||
289 | imx35_add_imx_uart2(NULL); | ||
290 | |||
291 | imx35_add_ipu_core(&mx3_ipu_data); | ||
292 | imx35_add_mx3_sdc_fb(&mx3fb_pdata); | ||
293 | |||
294 | imx35_add_fsl_usb2_udc(&otg_device_pdata); | ||
295 | imx35_add_mxc_ehci_hs(&usb_host_pdata); | ||
296 | |||
297 | imx35_add_mxc_nand(&vpr200_nand_board_info); | ||
298 | imx35_add_sdhci_esdhc_imx(0, NULL); | ||
299 | |||
300 | i2c_register_board_info(0, vpr200_i2c_devices, | ||
301 | ARRAY_SIZE(vpr200_i2c_devices)); | ||
302 | |||
303 | imx35_add_imx_i2c0(&vpr200_i2c0_data); | ||
304 | } | ||
305 | |||
306 | static void __init vpr200_timer_init(void) | ||
307 | { | ||
308 | mx35_clocks_init(); | ||
309 | } | ||
310 | |||
311 | struct sys_timer vpr200_timer = { | ||
312 | .init = vpr200_timer_init, | ||
313 | }; | ||
314 | |||
315 | MACHINE_START(VPR200, "VPR200") | ||
316 | /* Maintainer: Creative Product Design */ | ||
317 | .map_io = mx35_map_io, | ||
318 | .init_early = imx35_init_early, | ||
319 | .init_irq = mx35_init_irq, | ||
320 | .timer = &vpr200_timer, | ||
321 | .init_machine = vpr200_board_init, | ||
322 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c new file mode 100644 index 000000000000..86b9b45864d2 --- /dev/null +++ b/arch/arm/mach-imx/mm-imx31.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1999,2000 Arm Limited | ||
3 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
4 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
5 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
6 | * - add MX31 specific definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/mm.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/err.h> | ||
22 | |||
23 | #include <asm/pgtable.h> | ||
24 | #include <asm/mach/map.h> | ||
25 | |||
26 | #include <mach/common.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/iomux-v3.h> | ||
29 | #include <mach/gpio.h> | ||
30 | #include <mach/irqs.h> | ||
31 | |||
32 | static struct map_desc mx31_io_desc[] __initdata = { | ||
33 | imx_map_entry(MX31, X_MEMC, MT_DEVICE), | ||
34 | imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED), | ||
35 | imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED), | ||
36 | imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED), | ||
37 | imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED), | ||
38 | }; | ||
39 | |||
40 | /* | ||
41 | * This function initializes the memory map. It is called during the | ||
42 | * system startup to create static physical to virtual memory mappings | ||
43 | * for the IO modules. | ||
44 | */ | ||
45 | void __init mx31_map_io(void) | ||
46 | { | ||
47 | iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc)); | ||
48 | } | ||
49 | |||
50 | void __init imx31_init_early(void) | ||
51 | { | ||
52 | mxc_set_cpu_type(MXC_CPU_MX31); | ||
53 | mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); | ||
54 | } | ||
55 | |||
56 | static struct mxc_gpio_port imx31_gpio_ports[] = { | ||
57 | DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1), | ||
58 | DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2), | ||
59 | DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3), | ||
60 | }; | ||
61 | |||
62 | void __init mx31_init_irq(void) | ||
63 | { | ||
64 | mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR)); | ||
65 | mxc_gpio_init(imx31_gpio_ports, ARRAY_SIZE(imx31_gpio_ports)); | ||
66 | } | ||
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c new file mode 100644 index 000000000000..c880e6d1ae55 --- /dev/null +++ b/arch/arm/mach-imx/mm-imx35.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1999,2000 Arm Limited | ||
3 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
4 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
5 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
6 | * - add MX31 specific definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/mm.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/err.h> | ||
22 | |||
23 | #include <asm/pgtable.h> | ||
24 | #include <asm/mach/map.h> | ||
25 | #include <asm/hardware/cache-l2x0.h> | ||
26 | |||
27 | #include <mach/common.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/iomux-v3.h> | ||
30 | #include <mach/gpio.h> | ||
31 | #include <mach/irqs.h> | ||
32 | |||
33 | static struct map_desc mx35_io_desc[] __initdata = { | ||
34 | imx_map_entry(MX35, X_MEMC, MT_DEVICE), | ||
35 | imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED), | ||
36 | imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED), | ||
37 | imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED), | ||
38 | imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED), | ||
39 | }; | ||
40 | |||
41 | void __init mx35_map_io(void) | ||
42 | { | ||
43 | iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc)); | ||
44 | } | ||
45 | |||
46 | void __init imx35_init_early(void) | ||
47 | { | ||
48 | mxc_set_cpu_type(MXC_CPU_MX35); | ||
49 | mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR)); | ||
50 | mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); | ||
51 | } | ||
52 | |||
53 | static struct mxc_gpio_port imx35_gpio_ports[] = { | ||
54 | DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1), | ||
55 | DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2), | ||
56 | DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3), | ||
57 | }; | ||
58 | |||
59 | void __init mx35_init_irq(void) | ||
60 | { | ||
61 | mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR)); | ||
62 | mxc_gpio_init(imx35_gpio_ports, ARRAY_SIZE(imx35_gpio_ports)); | ||
63 | } | ||
diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c new file mode 100644 index 000000000000..7d26f766a4ee --- /dev/null +++ b/arch/arm/mach-imx/mx31lilly-db.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * LILLY-1131 development board support | ||
3 | * | ||
4 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
5 | * | ||
6 | * based on code for other MX31 boards, | ||
7 | * | ||
8 | * Copyright 2005-2007 Freescale Semiconductor | ||
9 | * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
10 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | |||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/mach/arch.h> | ||
31 | #include <asm/mach/map.h> | ||
32 | |||
33 | #include <mach/hardware.h> | ||
34 | #include <mach/common.h> | ||
35 | #include <mach/iomux-mx3.h> | ||
36 | #include <mach/board-mx31lilly.h> | ||
37 | |||
38 | #include "devices-imx31.h" | ||
39 | |||
40 | /* | ||
41 | * This file contains board-specific initialization routines for the | ||
42 | * LILLY-1131 development board. If you design an own baseboard for the | ||
43 | * module, use this file as base for support code. | ||
44 | */ | ||
45 | |||
46 | static unsigned int lilly_db_board_pins[] __initdata = { | ||
47 | MX31_PIN_CTS1__CTS1, | ||
48 | MX31_PIN_RTS1__RTS1, | ||
49 | MX31_PIN_TXD1__TXD1, | ||
50 | MX31_PIN_RXD1__RXD1, | ||
51 | MX31_PIN_CTS2__CTS2, | ||
52 | MX31_PIN_RTS2__RTS2, | ||
53 | MX31_PIN_TXD2__TXD2, | ||
54 | MX31_PIN_RXD2__RXD2, | ||
55 | MX31_PIN_CSPI3_MOSI__RXD3, | ||
56 | MX31_PIN_CSPI3_MISO__TXD3, | ||
57 | MX31_PIN_CSPI3_SCLK__RTS3, | ||
58 | MX31_PIN_CSPI3_SPI_RDY__CTS3, | ||
59 | MX31_PIN_SD1_DATA3__SD1_DATA3, | ||
60 | MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
61 | MX31_PIN_SD1_DATA1__SD1_DATA1, | ||
62 | MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
63 | MX31_PIN_SD1_CLK__SD1_CLK, | ||
64 | MX31_PIN_SD1_CMD__SD1_CMD, | ||
65 | MX31_PIN_LD0__LD0, | ||
66 | MX31_PIN_LD1__LD1, | ||
67 | MX31_PIN_LD2__LD2, | ||
68 | MX31_PIN_LD3__LD3, | ||
69 | MX31_PIN_LD4__LD4, | ||
70 | MX31_PIN_LD5__LD5, | ||
71 | MX31_PIN_LD6__LD6, | ||
72 | MX31_PIN_LD7__LD7, | ||
73 | MX31_PIN_LD8__LD8, | ||
74 | MX31_PIN_LD9__LD9, | ||
75 | MX31_PIN_LD10__LD10, | ||
76 | MX31_PIN_LD11__LD11, | ||
77 | MX31_PIN_LD12__LD12, | ||
78 | MX31_PIN_LD13__LD13, | ||
79 | MX31_PIN_LD14__LD14, | ||
80 | MX31_PIN_LD15__LD15, | ||
81 | MX31_PIN_LD16__LD16, | ||
82 | MX31_PIN_LD17__LD17, | ||
83 | MX31_PIN_VSYNC3__VSYNC3, | ||
84 | MX31_PIN_HSYNC__HSYNC, | ||
85 | MX31_PIN_FPSHIFT__FPSHIFT, | ||
86 | MX31_PIN_DRDY0__DRDY0, | ||
87 | MX31_PIN_CONTRAST__CONTRAST, | ||
88 | }; | ||
89 | |||
90 | /* UART */ | ||
91 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
92 | .flags = IMXUART_HAVE_RTSCTS, | ||
93 | }; | ||
94 | |||
95 | /* MMC support */ | ||
96 | |||
97 | static int mxc_mmc1_get_ro(struct device *dev) | ||
98 | { | ||
99 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0)); | ||
100 | } | ||
101 | |||
102 | static int gpio_det, gpio_wp; | ||
103 | |||
104 | #define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
105 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
106 | |||
107 | static int mxc_mmc1_init(struct device *dev, | ||
108 | irq_handler_t detect_irq, void *data) | ||
109 | { | ||
110 | int ret; | ||
111 | |||
112 | gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1); | ||
113 | gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0); | ||
114 | |||
115 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG); | ||
116 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG); | ||
117 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG); | ||
118 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG); | ||
119 | mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); | ||
120 | mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG); | ||
121 | |||
122 | ret = gpio_request(gpio_det, "MMC detect"); | ||
123 | if (ret) | ||
124 | return ret; | ||
125 | |||
126 | ret = gpio_request(gpio_wp, "MMC w/p"); | ||
127 | if (ret) | ||
128 | goto exit_free_det; | ||
129 | |||
130 | gpio_direction_input(gpio_det); | ||
131 | gpio_direction_input(gpio_wp); | ||
132 | |||
133 | ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq, | ||
134 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
135 | "MMC detect", data); | ||
136 | if (ret) | ||
137 | goto exit_free_wp; | ||
138 | |||
139 | return 0; | ||
140 | |||
141 | exit_free_wp: | ||
142 | gpio_free(gpio_wp); | ||
143 | |||
144 | exit_free_det: | ||
145 | gpio_free(gpio_det); | ||
146 | |||
147 | return ret; | ||
148 | } | ||
149 | |||
150 | static void mxc_mmc1_exit(struct device *dev, void *data) | ||
151 | { | ||
152 | gpio_free(gpio_det); | ||
153 | gpio_free(gpio_wp); | ||
154 | free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data); | ||
155 | } | ||
156 | |||
157 | static const struct imxmmc_platform_data mmc_pdata __initconst = { | ||
158 | .get_ro = mxc_mmc1_get_ro, | ||
159 | .init = mxc_mmc1_init, | ||
160 | .exit = mxc_mmc1_exit, | ||
161 | }; | ||
162 | |||
163 | /* Framebuffer support */ | ||
164 | static const struct ipu_platform_data ipu_data __initconst = { | ||
165 | .irq_base = MXC_IPU_IRQ_START, | ||
166 | }; | ||
167 | |||
168 | static const struct fb_videomode fb_modedb = { | ||
169 | /* 640x480 TFT panel (IPS-056T) */ | ||
170 | .name = "CRT-VGA", | ||
171 | .refresh = 64, | ||
172 | .xres = 640, | ||
173 | .yres = 480, | ||
174 | .pixclock = 30000, | ||
175 | .left_margin = 200, | ||
176 | .right_margin = 2, | ||
177 | .upper_margin = 2, | ||
178 | .lower_margin = 2, | ||
179 | .hsync_len = 3, | ||
180 | .vsync_len = 1, | ||
181 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, | ||
182 | .vmode = FB_VMODE_NONINTERLACED, | ||
183 | .flag = 0, | ||
184 | }; | ||
185 | |||
186 | static struct mx3fb_platform_data fb_pdata __initdata = { | ||
187 | .name = "CRT-VGA", | ||
188 | .mode = &fb_modedb, | ||
189 | .num_modes = 1, | ||
190 | }; | ||
191 | |||
192 | #define LCD_VCC_EN_GPIO (7) | ||
193 | |||
194 | static void __init mx31lilly_init_fb(void) | ||
195 | { | ||
196 | if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) { | ||
197 | printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n"); | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | imx31_add_ipu_core(&ipu_data); | ||
202 | imx31_add_mx3_sdc_fb(&fb_pdata); | ||
203 | gpio_direction_output(LCD_VCC_EN_GPIO, 1); | ||
204 | } | ||
205 | |||
206 | void __init mx31lilly_db_init(void) | ||
207 | { | ||
208 | mxc_iomux_setup_multiple_pins(lilly_db_board_pins, | ||
209 | ARRAY_SIZE(lilly_db_board_pins), | ||
210 | "development board pins"); | ||
211 | imx31_add_imx_uart0(&uart_pdata); | ||
212 | imx31_add_imx_uart1(&uart_pdata); | ||
213 | imx31_add_imx_uart2(&uart_pdata); | ||
214 | imx31_add_mxc_mmc(0, &mmc_pdata); | ||
215 | mx31lilly_init_fb(); | ||
216 | } | ||
diff --git a/arch/arm/mach-imx/mx31lite-db.c b/arch/arm/mach-imx/mx31lite-db.c new file mode 100644 index 000000000000..5aa053edc17c --- /dev/null +++ b/arch/arm/mach-imx/mx31lite-db.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * LogicPD i.MX31 SOM-LV development board support | ||
3 | * | ||
4 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
5 | * | ||
6 | * based on code for other MX31 boards, | ||
7 | * | ||
8 | * Copyright 2005-2007 Freescale Semiconductor | ||
9 | * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
10 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/leds.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | |||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/mach/arch.h> | ||
32 | #include <asm/mach/map.h> | ||
33 | |||
34 | #include <mach/hardware.h> | ||
35 | #include <mach/common.h> | ||
36 | #include <mach/iomux-mx3.h> | ||
37 | #include <mach/board-mx31lite.h> | ||
38 | |||
39 | #include "devices-imx31.h" | ||
40 | |||
41 | /* | ||
42 | * This file contains board-specific initialization routines for the | ||
43 | * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'. | ||
44 | * If you design an own baseboard for the module, use this file as base | ||
45 | * for support code. | ||
46 | */ | ||
47 | |||
48 | static unsigned int litekit_db_board_pins[] __initdata = { | ||
49 | /* UART1 */ | ||
50 | MX31_PIN_CTS1__CTS1, | ||
51 | MX31_PIN_RTS1__RTS1, | ||
52 | MX31_PIN_TXD1__TXD1, | ||
53 | MX31_PIN_RXD1__RXD1, | ||
54 | /* SPI 0 */ | ||
55 | MX31_PIN_CSPI1_SCLK__SCLK, | ||
56 | MX31_PIN_CSPI1_MOSI__MOSI, | ||
57 | MX31_PIN_CSPI1_MISO__MISO, | ||
58 | MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, | ||
59 | MX31_PIN_CSPI1_SS0__SS0, | ||
60 | MX31_PIN_CSPI1_SS1__SS1, | ||
61 | MX31_PIN_CSPI1_SS2__SS2, | ||
62 | /* SDHC1 */ | ||
63 | MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
64 | MX31_PIN_SD1_DATA1__SD1_DATA1, | ||
65 | MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
66 | MX31_PIN_SD1_DATA3__SD1_DATA3, | ||
67 | MX31_PIN_SD1_CLK__SD1_CLK, | ||
68 | MX31_PIN_SD1_CMD__SD1_CMD, | ||
69 | }; | ||
70 | |||
71 | /* UART */ | ||
72 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
73 | .flags = IMXUART_HAVE_RTSCTS, | ||
74 | }; | ||
75 | |||
76 | /* MMC */ | ||
77 | |||
78 | static int gpio_det, gpio_wp; | ||
79 | |||
80 | #define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
81 | PAD_CTL_ODE_CMOS) | ||
82 | |||
83 | static int mxc_mmc1_get_ro(struct device *dev) | ||
84 | { | ||
85 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6)); | ||
86 | } | ||
87 | |||
88 | static int mxc_mmc1_init(struct device *dev, | ||
89 | irq_handler_t detect_irq, void *data) | ||
90 | { | ||
91 | int ret; | ||
92 | |||
93 | gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1); | ||
94 | gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6); | ||
95 | |||
96 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, | ||
97 | MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); | ||
98 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, | ||
99 | MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); | ||
100 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, | ||
101 | MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); | ||
102 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, | ||
103 | MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); | ||
104 | mxc_iomux_set_pad(MX31_PIN_SD1_CMD, | ||
105 | MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); | ||
106 | mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); | ||
107 | |||
108 | ret = gpio_request(gpio_det, "MMC detect"); | ||
109 | if (ret) | ||
110 | return ret; | ||
111 | |||
112 | ret = gpio_request(gpio_wp, "MMC w/p"); | ||
113 | if (ret) | ||
114 | goto exit_free_det; | ||
115 | |||
116 | gpio_direction_input(gpio_det); | ||
117 | gpio_direction_input(gpio_wp); | ||
118 | |||
119 | ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq, | ||
120 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
121 | "MMC detect", data); | ||
122 | if (ret) | ||
123 | goto exit_free_wp; | ||
124 | |||
125 | return 0; | ||
126 | |||
127 | exit_free_wp: | ||
128 | gpio_free(gpio_wp); | ||
129 | |||
130 | exit_free_det: | ||
131 | gpio_free(gpio_det); | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static void mxc_mmc1_exit(struct device *dev, void *data) | ||
137 | { | ||
138 | gpio_free(gpio_det); | ||
139 | gpio_free(gpio_wp); | ||
140 | free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data); | ||
141 | } | ||
142 | |||
143 | static const struct imxmmc_platform_data mmc_pdata __initconst = { | ||
144 | .get_ro = mxc_mmc1_get_ro, | ||
145 | .init = mxc_mmc1_init, | ||
146 | .exit = mxc_mmc1_exit, | ||
147 | }; | ||
148 | |||
149 | /* SPI */ | ||
150 | |||
151 | static int spi_internal_chipselect[] = { | ||
152 | MXC_SPI_CS(0), | ||
153 | MXC_SPI_CS(1), | ||
154 | MXC_SPI_CS(2), | ||
155 | }; | ||
156 | |||
157 | static const struct spi_imx_master spi0_pdata __initconst = { | ||
158 | .chipselect = spi_internal_chipselect, | ||
159 | .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), | ||
160 | }; | ||
161 | |||
162 | /* GPIO LEDs */ | ||
163 | |||
164 | static struct gpio_led litekit_leds[] = { | ||
165 | { | ||
166 | .name = "GPIO0", | ||
167 | .gpio = IOMUX_TO_GPIO(MX31_PIN_COMPARE), | ||
168 | .active_low = 1, | ||
169 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | ||
170 | }, | ||
171 | { | ||
172 | .name = "GPIO1", | ||
173 | .gpio = IOMUX_TO_GPIO(MX31_PIN_CAPTURE), | ||
174 | .active_low = 1, | ||
175 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | ||
176 | } | ||
177 | }; | ||
178 | |||
179 | static struct gpio_led_platform_data litekit_led_platform_data = { | ||
180 | .leds = litekit_leds, | ||
181 | .num_leds = ARRAY_SIZE(litekit_leds), | ||
182 | }; | ||
183 | |||
184 | static struct platform_device litekit_led_device = { | ||
185 | .name = "leds-gpio", | ||
186 | .id = -1, | ||
187 | .dev = { | ||
188 | .platform_data = &litekit_led_platform_data, | ||
189 | }, | ||
190 | }; | ||
191 | |||
192 | void __init mx31lite_db_init(void) | ||
193 | { | ||
194 | mxc_iomux_setup_multiple_pins(litekit_db_board_pins, | ||
195 | ARRAY_SIZE(litekit_db_board_pins), | ||
196 | "development board pins"); | ||
197 | imx31_add_imx_uart0(&uart_pdata); | ||
198 | imx31_add_mxc_mmc(0, &mmc_pdata); | ||
199 | imx31_add_spi_imx0(&spi0_pdata); | ||
200 | platform_device_register(&litekit_led_device); | ||
201 | imx31_add_imx2_wdt(NULL); | ||
202 | imx31_add_mxc_rtc(NULL); | ||
203 | } | ||
diff --git a/arch/arm/mach-imx/mx31moboard-devboard.c b/arch/arm/mach-imx/mx31moboard-devboard.c new file mode 100644 index 000000000000..0aa25364360d --- /dev/null +++ b/arch/arm/mach-imx/mx31moboard-devboard.c | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/types.h> | ||
22 | |||
23 | #include <linux/usb/otg.h> | ||
24 | |||
25 | #include <mach/common.h> | ||
26 | #include <mach/iomux-mx3.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/ulpi.h> | ||
29 | |||
30 | #include "devices-imx31.h" | ||
31 | |||
32 | static unsigned int devboard_pins[] = { | ||
33 | /* UART1 */ | ||
34 | MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2, | ||
35 | MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, | ||
36 | /* SDHC2 */ | ||
37 | MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2, | ||
38 | MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, | ||
39 | MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, | ||
40 | MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, | ||
41 | /* USB H1 */ | ||
42 | MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM, | ||
43 | MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP, | ||
44 | MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB, | ||
45 | MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND, | ||
46 | MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12, | ||
47 | /* SEL */ | ||
48 | MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, | ||
49 | MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, | ||
50 | }; | ||
51 | |||
52 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
53 | .flags = IMXUART_HAVE_RTSCTS, | ||
54 | }; | ||
55 | |||
56 | #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) | ||
57 | #define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW) | ||
58 | |||
59 | static int devboard_sdhc2_get_ro(struct device *dev) | ||
60 | { | ||
61 | return !gpio_get_value(SDHC2_WP); | ||
62 | } | ||
63 | |||
64 | static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | ||
65 | void *data) | ||
66 | { | ||
67 | int ret; | ||
68 | |||
69 | ret = gpio_request(SDHC2_CD, "sdhc-detect"); | ||
70 | if (ret) | ||
71 | return ret; | ||
72 | |||
73 | gpio_direction_input(SDHC2_CD); | ||
74 | |||
75 | ret = gpio_request(SDHC2_WP, "sdhc-wp"); | ||
76 | if (ret) | ||
77 | goto err_gpio_free; | ||
78 | gpio_direction_input(SDHC2_WP); | ||
79 | |||
80 | ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq, | ||
81 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
82 | "sdhc2-card-detect", data); | ||
83 | if (ret) | ||
84 | goto err_gpio_free_2; | ||
85 | |||
86 | return 0; | ||
87 | |||
88 | err_gpio_free_2: | ||
89 | gpio_free(SDHC2_WP); | ||
90 | err_gpio_free: | ||
91 | gpio_free(SDHC2_CD); | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static void devboard_sdhc2_exit(struct device *dev, void *data) | ||
97 | { | ||
98 | free_irq(gpio_to_irq(SDHC2_CD), data); | ||
99 | gpio_free(SDHC2_WP); | ||
100 | gpio_free(SDHC2_CD); | ||
101 | } | ||
102 | |||
103 | static const struct imxmmc_platform_data sdhc2_pdata __initconst = { | ||
104 | .get_ro = devboard_sdhc2_get_ro, | ||
105 | .init = devboard_sdhc2_init, | ||
106 | .exit = devboard_sdhc2_exit, | ||
107 | }; | ||
108 | |||
109 | #define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) | ||
110 | #define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) | ||
111 | #define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) | ||
112 | #define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) | ||
113 | |||
114 | static void devboard_init_sel_gpios(void) | ||
115 | { | ||
116 | if (!gpio_request(SEL0, "sel0")) { | ||
117 | gpio_direction_input(SEL0); | ||
118 | gpio_export(SEL0, true); | ||
119 | } | ||
120 | |||
121 | if (!gpio_request(SEL1, "sel1")) { | ||
122 | gpio_direction_input(SEL1); | ||
123 | gpio_export(SEL1, true); | ||
124 | } | ||
125 | |||
126 | if (!gpio_request(SEL2, "sel2")) { | ||
127 | gpio_direction_input(SEL2); | ||
128 | gpio_export(SEL2, true); | ||
129 | } | ||
130 | |||
131 | if (!gpio_request(SEL3, "sel3")) { | ||
132 | gpio_direction_input(SEL3); | ||
133 | gpio_export(SEL3, true); | ||
134 | } | ||
135 | } | ||
136 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
137 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
138 | |||
139 | static int devboard_usbh1_hw_init(struct platform_device *pdev) | ||
140 | { | ||
141 | mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); | ||
142 | |||
143 | mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); | ||
144 | mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); | ||
145 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); | ||
146 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); | ||
147 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); | ||
148 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); | ||
149 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); | ||
150 | mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG); | ||
151 | |||
152 | mdelay(10); | ||
153 | |||
154 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | | ||
155 | MXC_EHCI_INTERFACE_SINGLE_UNI); | ||
156 | } | ||
157 | |||
158 | #define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B) | ||
159 | #define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE) | ||
160 | |||
161 | static int devboard_isp1105_init(struct otg_transceiver *otg) | ||
162 | { | ||
163 | int ret = gpio_request(USBH1_MODE, "usbh1-mode"); | ||
164 | if (ret) | ||
165 | return ret; | ||
166 | /* single ended */ | ||
167 | gpio_direction_output(USBH1_MODE, 0); | ||
168 | |||
169 | ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen"); | ||
170 | if (ret) { | ||
171 | gpio_free(USBH1_MODE); | ||
172 | return ret; | ||
173 | } | ||
174 | gpio_direction_output(USBH1_VBUSEN_B, 1); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | |||
180 | static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on) | ||
181 | { | ||
182 | if (on) | ||
183 | gpio_set_value(USBH1_VBUSEN_B, 0); | ||
184 | else | ||
185 | gpio_set_value(USBH1_VBUSEN_B, 1); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static struct mxc_usbh_platform_data usbh1_pdata __initdata = { | ||
191 | .init = devboard_usbh1_hw_init, | ||
192 | .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, | ||
193 | }; | ||
194 | |||
195 | static int __init devboard_usbh1_init(void) | ||
196 | { | ||
197 | struct otg_transceiver *otg; | ||
198 | struct platform_device *pdev; | ||
199 | |||
200 | otg = kzalloc(sizeof(*otg), GFP_KERNEL); | ||
201 | if (!otg) | ||
202 | return -ENOMEM; | ||
203 | |||
204 | otg->label = "ISP1105"; | ||
205 | otg->init = devboard_isp1105_init; | ||
206 | otg->set_vbus = devboard_isp1105_set_vbus; | ||
207 | |||
208 | usbh1_pdata.otg = otg; | ||
209 | |||
210 | pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata); | ||
211 | if (IS_ERR(pdev)) | ||
212 | return PTR_ERR(pdev); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | |||
218 | static const struct fsl_usb2_platform_data usb_pdata __initconst = { | ||
219 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
220 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
221 | }; | ||
222 | |||
223 | /* | ||
224 | * system init for baseboard usage. Will be called by mx31moboard init. | ||
225 | */ | ||
226 | void __init mx31moboard_devboard_init(void) | ||
227 | { | ||
228 | printk(KERN_INFO "Initializing mx31devboard peripherals\n"); | ||
229 | |||
230 | mxc_iomux_setup_multiple_pins(devboard_pins, ARRAY_SIZE(devboard_pins), | ||
231 | "devboard"); | ||
232 | |||
233 | imx31_add_imx_uart1(&uart_pdata); | ||
234 | |||
235 | imx31_add_mxc_mmc(1, &sdhc2_pdata); | ||
236 | |||
237 | devboard_init_sel_gpios(); | ||
238 | |||
239 | imx31_add_fsl_usb2_udc(&usb_pdata); | ||
240 | |||
241 | devboard_usbh1_init(); | ||
242 | } | ||
diff --git a/arch/arm/mach-imx/mx31moboard-marxbot.c b/arch/arm/mach-imx/mx31moboard-marxbot.c new file mode 100644 index 000000000000..bb639cbda4e5 --- /dev/null +++ b/arch/arm/mach-imx/mx31moboard-marxbot.c | |||
@@ -0,0 +1,366 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/delay.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/types.h> | ||
24 | |||
25 | #include <linux/usb/otg.h> | ||
26 | |||
27 | #include <mach/common.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/iomux-mx3.h> | ||
30 | #include <mach/ulpi.h> | ||
31 | |||
32 | #include <media/soc_camera.h> | ||
33 | |||
34 | #include "devices-imx31.h" | ||
35 | |||
36 | static unsigned int marxbot_pins[] = { | ||
37 | /* SDHC2 */ | ||
38 | MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2, | ||
39 | MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, | ||
40 | MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, | ||
41 | MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, | ||
42 | /* CSI */ | ||
43 | MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7, | ||
44 | MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9, | ||
45 | MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11, | ||
46 | MX31_PIN_CSI_D12__CSI_D12, MX31_PIN_CSI_D13__CSI_D13, | ||
47 | MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15, | ||
48 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK, | ||
49 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, | ||
50 | MX31_PIN_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5, | ||
51 | MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, | ||
52 | MX31_PIN_TXD2__GPIO1_28, | ||
53 | /* dsPIC resets */ | ||
54 | MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22, | ||
55 | /*battery detection */ | ||
56 | MX31_PIN_LCS0__GPIO3_23, | ||
57 | /* USB H1 */ | ||
58 | MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM, | ||
59 | MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP, | ||
60 | MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB, | ||
61 | MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND, | ||
62 | MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12, | ||
63 | /* SEL */ | ||
64 | MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, | ||
65 | MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, | ||
66 | }; | ||
67 | |||
68 | #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) | ||
69 | #define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW) | ||
70 | |||
71 | static int marxbot_sdhc2_get_ro(struct device *dev) | ||
72 | { | ||
73 | return !gpio_get_value(SDHC2_WP); | ||
74 | } | ||
75 | |||
76 | static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | ||
77 | void *data) | ||
78 | { | ||
79 | int ret; | ||
80 | |||
81 | ret = gpio_request(SDHC2_CD, "sdhc-detect"); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | |||
85 | gpio_direction_input(SDHC2_CD); | ||
86 | |||
87 | ret = gpio_request(SDHC2_WP, "sdhc-wp"); | ||
88 | if (ret) | ||
89 | goto err_gpio_free; | ||
90 | gpio_direction_input(SDHC2_WP); | ||
91 | |||
92 | ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq, | ||
93 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
94 | "sdhc2-card-detect", data); | ||
95 | if (ret) | ||
96 | goto err_gpio_free_2; | ||
97 | |||
98 | return 0; | ||
99 | |||
100 | err_gpio_free_2: | ||
101 | gpio_free(SDHC2_WP); | ||
102 | err_gpio_free: | ||
103 | gpio_free(SDHC2_CD); | ||
104 | |||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | static void marxbot_sdhc2_exit(struct device *dev, void *data) | ||
109 | { | ||
110 | free_irq(gpio_to_irq(SDHC2_CD), data); | ||
111 | gpio_free(SDHC2_WP); | ||
112 | gpio_free(SDHC2_CD); | ||
113 | } | ||
114 | |||
115 | static const struct imxmmc_platform_data sdhc2_pdata __initconst = { | ||
116 | .get_ro = marxbot_sdhc2_get_ro, | ||
117 | .init = marxbot_sdhc2_init, | ||
118 | .exit = marxbot_sdhc2_exit, | ||
119 | }; | ||
120 | |||
121 | #define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_STXD5) | ||
122 | #define DSPICS_RST_B IOMUX_TO_GPIO(MX31_PIN_SRXD5) | ||
123 | |||
124 | static void dspics_resets_init(void) | ||
125 | { | ||
126 | if (!gpio_request(TRSLAT_RST_B, "translator-rst")) { | ||
127 | gpio_direction_output(TRSLAT_RST_B, 0); | ||
128 | gpio_export(TRSLAT_RST_B, false); | ||
129 | } | ||
130 | |||
131 | if (!gpio_request(DSPICS_RST_B, "dspics-rst")) { | ||
132 | gpio_direction_output(DSPICS_RST_B, 0); | ||
133 | gpio_export(DSPICS_RST_B, false); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | static struct spi_board_info marxbot_spi_board_info[] __initdata = { | ||
138 | { | ||
139 | .modalias = "spidev", | ||
140 | .max_speed_hz = 300000, | ||
141 | .bus_num = 1, | ||
142 | .chip_select = 1, /* according spi1_cs[] ! */ | ||
143 | }, | ||
144 | }; | ||
145 | |||
146 | #define TURRETCAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1) | ||
147 | #define BASECAM_POWER IOMUX_TO_GPIO(MX31_PIN_CSI_D5) | ||
148 | #define TURRETCAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0) | ||
149 | #define BASECAM_RST_B IOMUX_TO_GPIO(MX31_PIN_CSI_D4) | ||
150 | #define CAM_CHOICE IOMUX_TO_GPIO(MX31_PIN_TXD2) | ||
151 | |||
152 | static int marxbot_basecam_power(struct device *dev, int on) | ||
153 | { | ||
154 | gpio_set_value(BASECAM_POWER, !on); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int marxbot_basecam_reset(struct device *dev) | ||
159 | { | ||
160 | gpio_set_value(BASECAM_RST_B, 0); | ||
161 | udelay(100); | ||
162 | gpio_set_value(BASECAM_RST_B, 1); | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static struct i2c_board_info marxbot_i2c_devices[] = { | ||
167 | { | ||
168 | I2C_BOARD_INFO("mt9t031", 0x5d), | ||
169 | }, | ||
170 | }; | ||
171 | |||
172 | static struct soc_camera_link base_iclink = { | ||
173 | .bus_id = 0, /* Must match with the camera ID */ | ||
174 | .power = marxbot_basecam_power, | ||
175 | .reset = marxbot_basecam_reset, | ||
176 | .board_info = &marxbot_i2c_devices[0], | ||
177 | .i2c_adapter_id = 0, | ||
178 | }; | ||
179 | |||
180 | static struct platform_device marxbot_camera[] = { | ||
181 | { | ||
182 | .name = "soc-camera-pdrv", | ||
183 | .id = 0, | ||
184 | .dev = { | ||
185 | .platform_data = &base_iclink, | ||
186 | }, | ||
187 | }, | ||
188 | }; | ||
189 | |||
190 | static struct platform_device *marxbot_cameras[] __initdata = { | ||
191 | &marxbot_camera[0], | ||
192 | }; | ||
193 | |||
194 | static int __init marxbot_cam_init(void) | ||
195 | { | ||
196 | int ret = gpio_request(CAM_CHOICE, "cam-choice"); | ||
197 | if (ret) | ||
198 | return ret; | ||
199 | gpio_direction_output(CAM_CHOICE, 0); | ||
200 | |||
201 | ret = gpio_request(BASECAM_RST_B, "basecam-reset"); | ||
202 | if (ret) | ||
203 | return ret; | ||
204 | gpio_direction_output(BASECAM_RST_B, 1); | ||
205 | ret = gpio_request(BASECAM_POWER, "basecam-standby"); | ||
206 | if (ret) | ||
207 | return ret; | ||
208 | gpio_direction_output(BASECAM_POWER, 0); | ||
209 | |||
210 | ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset"); | ||
211 | if (ret) | ||
212 | return ret; | ||
213 | gpio_direction_output(TURRETCAM_RST_B, 1); | ||
214 | ret = gpio_request(TURRETCAM_POWER, "turretcam-standby"); | ||
215 | if (ret) | ||
216 | return ret; | ||
217 | gpio_direction_output(TURRETCAM_POWER, 0); | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | #define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) | ||
223 | #define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) | ||
224 | #define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) | ||
225 | #define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) | ||
226 | |||
227 | static void marxbot_init_sel_gpios(void) | ||
228 | { | ||
229 | if (!gpio_request(SEL0, "sel0")) { | ||
230 | gpio_direction_input(SEL0); | ||
231 | gpio_export(SEL0, true); | ||
232 | } | ||
233 | |||
234 | if (!gpio_request(SEL1, "sel1")) { | ||
235 | gpio_direction_input(SEL1); | ||
236 | gpio_export(SEL1, true); | ||
237 | } | ||
238 | |||
239 | if (!gpio_request(SEL2, "sel2")) { | ||
240 | gpio_direction_input(SEL2); | ||
241 | gpio_export(SEL2, true); | ||
242 | } | ||
243 | |||
244 | if (!gpio_request(SEL3, "sel3")) { | ||
245 | gpio_direction_input(SEL3); | ||
246 | gpio_export(SEL3, true); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
251 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
252 | |||
253 | static int marxbot_usbh1_hw_init(struct platform_device *pdev) | ||
254 | { | ||
255 | mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); | ||
256 | |||
257 | mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); | ||
258 | mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); | ||
259 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); | ||
260 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); | ||
261 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); | ||
262 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); | ||
263 | mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); | ||
264 | mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG); | ||
265 | |||
266 | mdelay(10); | ||
267 | |||
268 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | | ||
269 | MXC_EHCI_INTERFACE_SINGLE_UNI); | ||
270 | } | ||
271 | |||
272 | #define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B) | ||
273 | #define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE) | ||
274 | |||
275 | static int marxbot_isp1105_init(struct otg_transceiver *otg) | ||
276 | { | ||
277 | int ret = gpio_request(USBH1_MODE, "usbh1-mode"); | ||
278 | if (ret) | ||
279 | return ret; | ||
280 | /* single ended */ | ||
281 | gpio_direction_output(USBH1_MODE, 0); | ||
282 | |||
283 | ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen"); | ||
284 | if (ret) { | ||
285 | gpio_free(USBH1_MODE); | ||
286 | return ret; | ||
287 | } | ||
288 | gpio_direction_output(USBH1_VBUSEN_B, 1); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | |||
294 | static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on) | ||
295 | { | ||
296 | if (on) | ||
297 | gpio_set_value(USBH1_VBUSEN_B, 0); | ||
298 | else | ||
299 | gpio_set_value(USBH1_VBUSEN_B, 1); | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static struct mxc_usbh_platform_data usbh1_pdata __initdata = { | ||
305 | .init = marxbot_usbh1_hw_init, | ||
306 | .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, | ||
307 | }; | ||
308 | |||
309 | static int __init marxbot_usbh1_init(void) | ||
310 | { | ||
311 | struct otg_transceiver *otg; | ||
312 | struct platform_device *pdev; | ||
313 | |||
314 | otg = kzalloc(sizeof(*otg), GFP_KERNEL); | ||
315 | if (!otg) | ||
316 | return -ENOMEM; | ||
317 | |||
318 | otg->label = "ISP1105"; | ||
319 | otg->init = marxbot_isp1105_init; | ||
320 | otg->set_vbus = marxbot_isp1105_set_vbus; | ||
321 | |||
322 | usbh1_pdata.otg = otg; | ||
323 | |||
324 | pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata); | ||
325 | if (IS_ERR(pdev)) | ||
326 | return PTR_ERR(pdev); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static const struct fsl_usb2_platform_data usb_pdata __initconst = { | ||
332 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
333 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
334 | }; | ||
335 | |||
336 | /* | ||
337 | * system init for baseboard usage. Will be called by mx31moboard init. | ||
338 | */ | ||
339 | void __init mx31moboard_marxbot_init(void) | ||
340 | { | ||
341 | printk(KERN_INFO "Initializing mx31marxbot peripherals\n"); | ||
342 | |||
343 | mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins), | ||
344 | "marxbot"); | ||
345 | |||
346 | marxbot_init_sel_gpios(); | ||
347 | |||
348 | dspics_resets_init(); | ||
349 | |||
350 | imx31_add_mxc_mmc(1, &sdhc2_pdata); | ||
351 | |||
352 | spi_register_board_info(marxbot_spi_board_info, | ||
353 | ARRAY_SIZE(marxbot_spi_board_info)); | ||
354 | |||
355 | marxbot_cam_init(); | ||
356 | platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras)); | ||
357 | |||
358 | /* battery present pin */ | ||
359 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present"); | ||
360 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0)); | ||
361 | gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false); | ||
362 | |||
363 | imx31_add_fsl_usb2_udc(&usb_pdata); | ||
364 | |||
365 | marxbot_usbh1_init(); | ||
366 | } | ||
diff --git a/arch/arm/mach-imx/mx31moboard-smartbot.c b/arch/arm/mach-imx/mx31moboard-smartbot.c new file mode 100644 index 000000000000..fabb801e7994 --- /dev/null +++ b/arch/arm/mach-imx/mx31moboard-smartbot.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/delay.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/types.h> | ||
22 | |||
23 | #include <linux/usb/otg.h> | ||
24 | #include <linux/usb/ulpi.h> | ||
25 | |||
26 | #include <mach/common.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/iomux-mx3.h> | ||
29 | #include <mach/board-mx31moboard.h> | ||
30 | #include <mach/ulpi.h> | ||
31 | |||
32 | #include <media/soc_camera.h> | ||
33 | |||
34 | #include "devices-imx31.h" | ||
35 | |||
36 | static unsigned int smartbot_pins[] = { | ||
37 | /* UART1 */ | ||
38 | MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2, | ||
39 | MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, | ||
40 | /* CSI */ | ||
41 | MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5, | ||
42 | MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7, | ||
43 | MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9, | ||
44 | MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11, | ||
45 | MX31_PIN_CSI_D12__CSI_D12, MX31_PIN_CSI_D13__CSI_D13, | ||
46 | MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15, | ||
47 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK, | ||
48 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, | ||
49 | MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, | ||
50 | /* ENABLES */ | ||
51 | MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, | ||
52 | MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, | ||
53 | }; | ||
54 | |||
55 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
56 | .flags = IMXUART_HAVE_RTSCTS, | ||
57 | }; | ||
58 | |||
59 | #define CAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1) | ||
60 | #define CAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0) | ||
61 | |||
62 | static int smartbot_cam_power(struct device *dev, int on) | ||
63 | { | ||
64 | gpio_set_value(CAM_POWER, !on); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int smartbot_cam_reset(struct device *dev) | ||
69 | { | ||
70 | gpio_set_value(CAM_RST_B, 0); | ||
71 | udelay(100); | ||
72 | gpio_set_value(CAM_RST_B, 1); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static struct i2c_board_info smartbot_i2c_devices[] = { | ||
77 | { | ||
78 | I2C_BOARD_INFO("mt9t031", 0x5d), | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | static struct soc_camera_link base_iclink = { | ||
83 | .bus_id = 0, /* Must match with the camera ID */ | ||
84 | .power = smartbot_cam_power, | ||
85 | .reset = smartbot_cam_reset, | ||
86 | .board_info = &smartbot_i2c_devices[0], | ||
87 | .i2c_adapter_id = 0, | ||
88 | }; | ||
89 | |||
90 | static struct platform_device smartbot_camera[] = { | ||
91 | { | ||
92 | .name = "soc-camera-pdrv", | ||
93 | .id = 0, | ||
94 | .dev = { | ||
95 | .platform_data = &base_iclink, | ||
96 | }, | ||
97 | }, | ||
98 | }; | ||
99 | |||
100 | static struct platform_device *smartbot_cameras[] __initdata = { | ||
101 | &smartbot_camera[0], | ||
102 | }; | ||
103 | |||
104 | static int __init smartbot_cam_init(void) | ||
105 | { | ||
106 | int ret = gpio_request(CAM_RST_B, "cam-reset"); | ||
107 | if (ret) | ||
108 | return ret; | ||
109 | gpio_direction_output(CAM_RST_B, 1); | ||
110 | ret = gpio_request(CAM_POWER, "cam-standby"); | ||
111 | if (ret) | ||
112 | return ret; | ||
113 | gpio_direction_output(CAM_POWER, 0); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static const struct fsl_usb2_platform_data usb_pdata __initconst = { | ||
119 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
120 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
121 | }; | ||
122 | |||
123 | #if defined(CONFIG_USB_ULPI) | ||
124 | |||
125 | static int smartbot_otg_init(struct platform_device *pdev) | ||
126 | { | ||
127 | return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); | ||
128 | } | ||
129 | |||
130 | static struct mxc_usbh_platform_data otg_host_pdata __initdata = { | ||
131 | .init = smartbot_otg_init, | ||
132 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
133 | }; | ||
134 | |||
135 | static int __init smartbot_otg_host_init(void) | ||
136 | { | ||
137 | struct platform_device *pdev; | ||
138 | |||
139 | otg_host_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | | ||
140 | ULPI_OTG_DRVVBUS_EXT); | ||
141 | if (!otg_host_pdata.otg) | ||
142 | return -ENODEV; | ||
143 | |||
144 | pdev = imx31_add_mxc_ehci_otg(&otg_host_pdata); | ||
145 | if (IS_ERR(pdev)) | ||
146 | return PTR_ERR(pdev); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | #else | ||
151 | static inline int smartbot_otg_host_init(void) { return 0; } | ||
152 | #endif | ||
153 | |||
154 | #define POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) | ||
155 | #define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) | ||
156 | #define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) | ||
157 | #define TRSLAT_SRC_CHOICE IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) | ||
158 | |||
159 | static void smartbot_resets_init(void) | ||
160 | { | ||
161 | if (!gpio_request(POWER_EN, "power-enable")) { | ||
162 | gpio_direction_output(POWER_EN, 0); | ||
163 | gpio_export(POWER_EN, false); | ||
164 | } | ||
165 | |||
166 | if (!gpio_request(DSPIC_RST_B, "dspic-rst")) { | ||
167 | gpio_direction_output(DSPIC_RST_B, 0); | ||
168 | gpio_export(DSPIC_RST_B, false); | ||
169 | } | ||
170 | |||
171 | if (!gpio_request(TRSLAT_RST_B, "translator-rst")) { | ||
172 | gpio_direction_output(TRSLAT_RST_B, 0); | ||
173 | gpio_export(TRSLAT_RST_B, false); | ||
174 | } | ||
175 | |||
176 | if (!gpio_request(TRSLAT_SRC_CHOICE, "translator-src-choice")) { | ||
177 | gpio_direction_output(TRSLAT_SRC_CHOICE, 0); | ||
178 | gpio_export(TRSLAT_SRC_CHOICE, false); | ||
179 | } | ||
180 | } | ||
181 | /* | ||
182 | * system init for baseboard usage. Will be called by mx31moboard init. | ||
183 | */ | ||
184 | void __init mx31moboard_smartbot_init(int board) | ||
185 | { | ||
186 | printk(KERN_INFO "Initializing mx31smartbot peripherals\n"); | ||
187 | |||
188 | mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins), | ||
189 | "smartbot"); | ||
190 | |||
191 | imx31_add_imx_uart1(&uart_pdata); | ||
192 | |||
193 | switch (board) { | ||
194 | case MX31SMARTBOT: | ||
195 | imx31_add_fsl_usb2_udc(&usb_pdata); | ||
196 | break; | ||
197 | case MX31EYEBOT: | ||
198 | smartbot_otg_host_init(); | ||
199 | break; | ||
200 | default: | ||
201 | printk(KERN_WARNING "Unknown board %d, USB OTG not initialized", | ||
202 | board); | ||
203 | } | ||
204 | |||
205 | smartbot_resets_init(); | ||
206 | |||
207 | smartbot_cam_init(); | ||
208 | platform_add_devices(smartbot_cameras, ARRAY_SIZE(smartbot_cameras)); | ||
209 | } | ||
diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h new file mode 100644 index 000000000000..d6929721a5fd --- /dev/null +++ b/arch/arm/mach-imx/pcm037.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef __PCM037_H__ | ||
2 | #define __PCM037_H__ | ||
3 | |||
4 | enum pcm037_board_variant { | ||
5 | PCM037_PCM970, | ||
6 | PCM037_EET, | ||
7 | }; | ||
8 | |||
9 | extern enum pcm037_board_variant pcm037_variant(void); | ||
10 | |||
11 | #endif | ||