summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/Kconfig389
-rw-r--r--arch/arm/mach-omap2/Makefile273
-rw-r--r--arch/arm/mach-omap2/Makefile.boot3
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c308
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c637
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c222
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c940
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c105
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c520
-rw-r--r--arch/arm/mach-omap2/board-apollon.c361
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c687
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c306
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c667
-rw-r--r--arch/arm/mach-omap2/board-flash.c247
-rw-r--r--arch/arm/mach-omap2/board-flash.h49
-rw-r--r--arch/arm/mach-omap2/board-generic.c172
-rw-r--r--arch/arm/mach-omap2/board-h4.c403
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c691
-rw-r--r--arch/arm/mach-omap2/board-ldp.c441
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c724
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c566
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c697
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c226
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c613
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c461
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c388
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c523
-rw-r--r--arch/arm/mach-omap2/board-overo.c569
-rw-r--r--arch/arm/mach-omap2/board-rm680.c156
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c1152
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c103
-rw-r--r--arch/arm/mach-omap2/board-rx51.c134
-rw-r--r--arch/arm/mach-omap2/board-ti8168evm.c67
-rw-r--r--arch/arm/mach-omap2/board-zoom-debugboard.c127
-rw-r--r--arch/arm/mach-omap2/board-zoom-display.c140
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c309
-rw-r--r--arch/arm/mach-omap2/board-zoom.c154
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c146
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpll.c63
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c173
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_osc.c76
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_sys.c50
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c246
-rw-r--r--arch/arm/mach-omap2/clkt34xx_dpll3m2.c122
-rw-r--r--arch/arm/mach-omap2/clkt_clksel.c509
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c359
-rw-r--r--arch/arm/mach-omap2/clkt_iclk.c82
-rw-r--r--arch/arm/mach-omap2/clock.c545
-rw-r--r--arch/arm/mach-omap2/clock.h166
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c2006
-rw-r--r--arch/arm/mach-omap2/clock2430.c59
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c2106
-rw-r--r--arch/arm/mach-omap2/clock2xxx.c73
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h44
-rw-r--r--arch/arm/mach-omap2/clock34xx.c153
-rw-r--r--arch/arm/mach-omap2/clock34xx.h18
-rw-r--r--arch/arm/mach-omap2/clock3517.c126
-rw-r--r--arch/arm/mach-omap2/clock3517.h14
-rw-r--r--arch/arm/mach-omap2/clock36xx.c72
-rw-r--r--arch/arm/mach-omap2/clock36xx.h13
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c101
-rw-r--r--arch/arm/mach-omap2/clock3xxx.h21
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c3624
-rw-r--r--arch/arm/mach-omap2/clock44xx.h20
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c3461
-rw-r--r--arch/arm/mach-omap2/clock_common_data.c45
-rw-r--r--arch/arm/mach-omap2/clockdomain.c1076
-rw-r--r--arch/arm/mach-omap2/clockdomain.h212
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c272
-rw-r--r--arch/arm/mach-omap2/clockdomain44xx.c130
-rw-r--r--arch/arm/mach-omap2/clockdomains2420_data.c154
-rw-r--r--arch/arm/mach-omap2/clockdomains2430_data.c181
-rw-r--r--arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c101
-rw-r--r--arch/arm/mach-omap2/clockdomains3xxx_data.c398
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c442
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h445
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h812
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h1445
-rw-r--r--arch/arm/mach-omap2/cm.h25
-rw-r--r--arch/arm/mach-omap2/cm1_44xx.h225
-rw-r--r--arch/arm/mach-omap2/cm2_44xx.h457
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c557
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h155
-rw-r--r--arch/arm/mach-omap2/cm44xx.c52
-rw-r--r--arch/arm/mach-omap2/cm44xx.h26
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c351
-rw-r--r--arch/arm/mach-omap2/cminst44xx.h66
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c140
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h15
-rw-r--r--arch/arm/mach-omap2/common.c182
-rw-r--r--arch/arm/mach-omap2/common.h240
-rw-r--r--arch/arm/mach-omap2/control.c565
-rw-r--r--arch/arm/mach-omap2/control.h412
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c453
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c244
-rw-r--r--arch/arm/mach-omap2/devices.c764
-rw-r--r--arch/arm/mach-omap2/devices.h19
-rw-r--r--arch/arm/mach-omap2/display.c369
-rw-r--r--arch/arm/mach-omap2/display.h29
-rw-r--r--arch/arm/mach-omap2/dma.c288
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c617
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c153
-rw-r--r--arch/arm/mach-omap2/dsp.c93
-rw-r--r--arch/arm/mach-omap2/emu.c69
-rw-r--r--arch/arm/mach-omap2/gpio.c128
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c122
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c408
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c190
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c159
-rw-r--r--arch/arm/mach-omap2/gpmc.c920
-rw-r--r--arch/arm/mach-omap2/hsmmc.c528
-rw-r--r--arch/arm/mach-omap2/hsmmc.h45
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c60
-rw-r--r--arch/arm/mach-omap2/i2c.c107
-rw-r--r--arch/arm/mach-omap2/id.c547
-rw-r--r--arch/arm/mach-omap2/include/mach/am35xx.h44
-rw-r--r--arch/arm/mach-omap2/include/mach/barriers.h31
-rw-r--r--arch/arm/mach-omap2/include/mach/board-rx51.h11
-rw-r--r--arch/arm/mach-omap2/include/mach/board-zoom.h12
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h391
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h1409
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h236
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h92
-rw-r--r--arch/arm/mach-omap2/include/mach/debug-macro.S150
-rw-r--r--arch/arm/mach-omap2/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-omap2/include/mach/gpio.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/hardware.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/id.h22
-rw-r--r--arch/arm/mach-omap2/include/mach/io.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/irqs.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-secure.h57
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-wakeupgen.h39
-rw-r--r--arch/arm/mach-omap2/include/mach/smp.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/system.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/timex.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/uncompress.h5
-rw-r--r--arch/arm/mach-omap2/io.c533
-rw-r--r--arch/arm/mach-omap2/iommu2.c361
-rw-r--r--arch/arm/mach-omap2/irq.c317
-rw-r--r--arch/arm/mach-omap2/mailbox.c430
-rw-r--r--arch/arm/mach-omap2/mcbsp.c198
-rw-r--r--arch/arm/mach-omap2/mux.c1159
-rw-r--r--arch/arm/mach-omap2/mux.h342
-rw-r--r--arch/arm/mach-omap2/mux2420.c690
-rw-r--r--arch/arm/mach-omap2/mux2420.h282
-rw-r--r--arch/arm/mach-omap2/mux2430.c793
-rw-r--r--arch/arm/mach-omap2/mux2430.h370
-rw-r--r--arch/arm/mach-omap2/mux34xx.c2061
-rw-r--r--arch/arm/mach-omap2/mux34xx.h398
-rw-r--r--arch/arm/mach-omap2/mux44xx.c1356
-rw-r--r--arch/arm/mach-omap2/mux44xx.h298
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S45
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c72
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c167
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c398
-rw-r--r--arch/arm/mach-omap2/omap-secure.c72
-rw-r--r--arch/arm/mach-omap2/omap-smc.S80
-rw-r--r--arch/arm/mach-omap2/omap-smp.c182
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c389
-rw-r--r--arch/arm/mach-omap2/omap4-common.c209
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h50
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c2787
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c1574
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c2073
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c173
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c304
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c130
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c172
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c3753
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c5641
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.c55
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h118
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.c266
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.h162
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.c296
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.h338
-rw-r--r--arch/arm/mach-omap2/omap_opp_data.h96
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c297
-rw-r--r--arch/arm/mach-omap2/omap_twl.c358
-rw-r--r--arch/arm/mach-omap2/opp.c93
-rw-r--r--arch/arm/mach-omap2/opp2420_data.c128
-rw-r--r--arch/arm/mach-omap2/opp2430_data.c133
-rw-r--r--arch/arm/mach-omap2/opp2xxx.h429
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c172
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c105
-rw-r--r--arch/arm/mach-omap2/pm-debug.c285
-rw-r--r--arch/arm/mach-omap2/pm.c246
-rw-r--r--arch/arm/mach-omap2/pm.h138
-rw-r--r--arch/arm/mach-omap2/pm24xx.c470
-rw-r--r--arch/arm/mach-omap2/pm34xx.c893
-rw-r--r--arch/arm/mach-omap2/pm44xx.c266
-rw-r--r--arch/arm/mach-omap2/powerdomain-common.c109
-rw-r--r--arch/arm/mach-omap2/powerdomain.c1074
-rw-r--r--arch/arm/mach-omap2/powerdomain.h241
-rw-r--r--arch/arm/mach-omap2/powerdomain2xxx_3xxx.c241
-rw-r--r--arch/arm/mach-omap2/powerdomain44xx.c225
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c65
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h22
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c135
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c320
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c358
-rw-r--r--arch/arm/mach-omap2/prcm-common.h489
-rw-r--r--arch/arm/mach-omap2/prcm.c158
-rw-r--r--arch/arm/mach-omap2/prcm44xx.h42
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.c45
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.h103
-rw-r--r--arch/arm/mach-omap2/prm-regbits-24xx.h283
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h600
-rw-r--r--arch/arm/mach-omap2/prm-regbits-44xx.h2327
-rw-r--r--arch/arm/mach-omap2/prm.h56
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c310
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h448
-rw-r--r--arch/arm/mach-omap2/prm44xx.c240
-rw-r--r--arch/arm/mach-omap2/prm44xx.h774
-rw-r--r--arch/arm/mach-omap2/prm_common.c320
-rw-r--r--arch/arm/mach-omap2/prminst44xx.c176
-rw-r--r--arch/arm/mach-omap2/prminst44xx.h33
-rw-r--r--arch/arm/mach-omap2/scrm44xx.h175
-rw-r--r--arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h51
-rw-r--r--arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h55
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.c302
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.h12
-rw-r--r--arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h51
-rw-r--r--arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h54
-rw-r--r--arch/arm/mach-omap2/sdrc.c178
-rw-r--r--arch/arm/mach-omap2/sdrc.h77
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c170
-rw-r--r--arch/arm/mach-omap2/serial.c432
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S126
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S614
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S379
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c59
-rw-r--r--arch/arm/mach-omap2/smartreflex.c1056
-rw-r--r--arch/arm/mach-omap2/smartreflex.h246
-rw-r--r--arch/arm/mach-omap2/sr_device.c138
-rw-r--r--arch/arm/mach-omap2/sram242x.S330
-rw-r--r--arch/arm/mach-omap2/sram243x.S330
-rw-r--r--arch/arm/mach-omap2/sram34xx.S346
-rw-r--r--arch/arm/mach-omap2/timer-mpu.c39
-rw-r--r--arch/arm/mach-omap2/timer.c491
-rw-r--r--arch/arm/mach-omap2/twl-common.c327
-rw-r--r--arch/arm/mach-omap2/twl-common.h62
-rw-r--r--arch/arm/mach-omap2/usb-fs.c359
-rw-r--r--arch/arm/mach-omap2/usb-host.c542
-rw-r--r--arch/arm/mach-omap2/usb-musb.c125
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c350
-rw-r--r--arch/arm/mach-omap2/vc.c365
-rw-r--r--arch/arm/mach-omap2/vc.h125
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c72
-rw-r--r--arch/arm/mach-omap2/vc44xx_data.c89
-rw-r--r--arch/arm/mach-omap2/voltage.c431
-rw-r--r--arch/arm/mach-omap2/voltage.h172
-rw-r--r--arch/arm/mach-omap2/voltagedomains2xxx_data.c32
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c130
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c113
-rw-r--r--arch/arm/mach-omap2/vp.c283
-rw-r--r--arch/arm/mach-omap2/vp.h128
-rw-r--r--arch/arm/mach-omap2/vp3xxx_data.c79
-rw-r--r--arch/arm/mach-omap2/vp44xx_data.c89
-rw-r--r--arch/arm/mach-omap2/wd_timer.c56
-rw-r--r--arch/arm/mach-omap2/wd_timer.h17
261 files changed, 99077 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
new file mode 100644
index 00000000000..e20c8ab80b0
--- /dev/null
+++ b/arch/arm/mach-omap2/Kconfig
@@ -0,0 +1,389 @@
+if ARCH_OMAP2PLUS
+
+menu "TI OMAP2/3/4 Specific Features"
+
+config ARCH_OMAP2PLUS_TYPICAL
+ bool "Typical OMAP configuration"
+ default y
+ select AEABI
+ select REGULATOR
+ select PM_RUNTIME
+ select VFP
+ select NEON if ARCH_OMAP3 || ARCH_OMAP4
+ select SERIAL_OMAP
+ select SERIAL_OMAP_CONSOLE
+ select I2C
+ select I2C_OMAP
+ select MENELAUS if ARCH_OMAP2
+ select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
+ select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
+ help
+ Compile a kernel suitable for booting most boards
+
+config ARCH_OMAP2
+ bool "TI OMAP2"
+ depends on ARCH_OMAP2PLUS
+ default y
+ select CPU_V6
+ select MULTI_IRQ_HANDLER
+
+config ARCH_OMAP3
+ bool "TI OMAP3"
+ depends on ARCH_OMAP2PLUS
+ default y
+ select CPU_V7
+ select USB_ARCH_HAS_EHCI
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
+ select ARM_CPU_SUSPEND if PM
+ select MULTI_IRQ_HANDLER
+
+config ARCH_OMAP4
+ bool "TI OMAP4"
+ default y
+ depends on ARCH_OMAP2PLUS
+ select CACHE_L2X0
+ select CPU_V7
+ select ARM_GIC
+ select HAVE_SMP
+ select LOCAL_TIMERS if SMP
+ select PL310_ERRATA_588369
+ select PL310_ERRATA_727915
+ select ARM_ERRATA_720789
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
+ select USB_ARCH_HAS_EHCI
+ select ARM_CPU_SUSPEND if PM
+
+comment "OMAP Core Type"
+ depends on ARCH_OMAP2
+
+config SOC_OMAP2420
+ bool "OMAP2420 support"
+ depends on ARCH_OMAP2
+ default y
+ select OMAP_DM_TIMER
+ select ARCH_OMAP_OTG
+
+config SOC_OMAP2430
+ bool "OMAP2430 support"
+ depends on ARCH_OMAP2
+ default y
+ select ARCH_OMAP_OTG
+
+config SOC_OMAP3430
+ bool "OMAP3430 support"
+ depends on ARCH_OMAP3
+ default y
+ select ARCH_OMAP_OTG
+
+config SOC_OMAPTI81XX
+ bool "TI81XX support"
+ depends on ARCH_OMAP3
+ default y
+
+config SOC_OMAPAM33XX
+ bool "AM33XX support"
+ depends on ARCH_OMAP3
+ default y
+
+config OMAP_PACKAGE_ZAF
+ bool
+
+config OMAP_PACKAGE_ZAC
+ bool
+
+config OMAP_PACKAGE_CBC
+ bool
+
+config OMAP_PACKAGE_CBB
+ bool
+
+config OMAP_PACKAGE_CUS
+ bool
+
+config OMAP_PACKAGE_CBP
+ bool
+
+config OMAP_PACKAGE_CBL
+ bool
+
+config OMAP_PACKAGE_CBS
+ bool
+
+comment "OMAP Board Type"
+ depends on ARCH_OMAP2PLUS
+
+config MACH_OMAP_GENERIC
+ bool "Generic OMAP2+ board"
+ depends on ARCH_OMAP2PLUS
+ select USE_OF
+ default y
+ help
+ Support for generic TI OMAP2+ boards using Flattened Device Tree.
+ More information at Documentation/devicetree
+
+config MACH_OMAP2_TUSB6010
+ bool
+ depends on ARCH_OMAP2 && SOC_OMAP2420
+ default y if MACH_NOKIA_N8X0
+
+config MACH_OMAP_H4
+ bool "OMAP 2420 H4 board"
+ depends on SOC_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAF
+ select OMAP_DEBUG_DEVICES
+
+config MACH_OMAP_APOLLON
+ bool "OMAP 2420 Apollon board"
+ depends on SOC_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAC
+
+config MACH_OMAP_2430SDP
+ bool "OMAP 2430 SDP board"
+ depends on SOC_OMAP2430
+ default y
+ select OMAP_PACKAGE_ZAC
+
+config MACH_OMAP3_BEAGLE
+ bool "OMAP3 BEAGLE board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_DEVKIT8000
+ bool "DEVKIT8000 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CUS
+
+config MACH_OMAP_LDP
+ bool "OMAP3 LDP board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3530_LV_SOM
+ bool "OMAP3 Logic 3530 LV SOM board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+ default y
+ help
+ Support for the LogicPD OMAP3530 SOM Development kit
+ for full description please see the products webpage at
+ http://www.logicpd.com/products/development-kits/texas-instruments-zoom%E2%84%A2-omap35x-development-kit
+
+config MACH_OMAP3_TORPEDO
+ bool "OMAP3 Logic 35x Torpedo board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+ default y
+ help
+ Support for the LogicPD OMAP35x Torpedo Development kit
+ for full description please see the products webpage at
+ http://www.logicpd.com/products/development-kits/zoom-omap35x-torpedo-development-kit
+
+config MACH_OVERO
+ bool "Gumstix Overo board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3EVM
+ bool "OMAP 3530 EVM board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3517EVM
+ bool "OMAP3517/ AM3517 EVM board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_CRANEBOARD
+ bool "AM3517/05 CRANE board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3_PANDORA
+ bool "OMAP3 Pandora"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+config MACH_OMAP3_TOUCHBOOK
+ bool "OMAP3 Touch Book"
+ depends on ARCH_OMAP3
+ default y
+
+config MACH_OMAP_3430SDP
+ bool "OMAP 3430 SDP board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_NOKIA_N800
+ bool
+
+config MACH_NOKIA_N810
+ bool
+
+config MACH_NOKIA_N810_WIMAX
+ bool
+
+config MACH_NOKIA_N8X0
+ bool "Nokia N800/N810"
+ depends on SOC_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAC
+ select MACH_NOKIA_N800
+ select MACH_NOKIA_N810
+ select MACH_NOKIA_N810_WIMAX
+
+config MACH_NOKIA_RM680
+ bool "Nokia RM-680 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_NOKIA_RX51
+ bool "Nokia RX-51 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP_ZOOM2
+ bool "OMAP3 Zoom2 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+config MACH_OMAP_ZOOM3
+ bool "OMAP3630 Zoom3 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBP
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+config MACH_CM_T35
+ bool "CompuLab CM-T35/CM-T3730 modules"
+ depends on ARCH_OMAP3
+ default y
+ select MACH_CM_T3730
+ select OMAP_PACKAGE_CUS
+
+config MACH_CM_T3517
+ bool "CompuLab CM-T3517 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_CM_T3730
+ bool
+
+config MACH_IGEP0020
+ bool "IGEP v2 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_IGEP0030
+ bool "IGEP OMAP3 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select MACH_IGEP0020
+
+config MACH_SBC3530
+ bool "OMAP3 SBC STALKER board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CUS
+
+config MACH_OMAP_3630SDP
+ bool "OMAP3630 SDP board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBP
+
+config MACH_TI8168EVM
+ bool "TI8168 Evaluation Module"
+ depends on SOC_OMAPTI81XX
+ default y
+
+config MACH_TI8148EVM
+ bool "TI8148 Evaluation Module"
+ depends on SOC_OMAPTI81XX
+ default y
+
+config MACH_OMAP_4430SDP
+ bool "OMAP 4430 SDP board"
+ default y
+ depends on ARCH_OMAP4
+ select OMAP_PACKAGE_CBL
+ select OMAP_PACKAGE_CBS
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+config MACH_OMAP4_PANDA
+ bool "OMAP4 Panda Board"
+ default y
+ depends on ARCH_OMAP4
+ select OMAP_PACKAGE_CBL
+ select OMAP_PACKAGE_CBS
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+config OMAP3_EMU
+ bool "OMAP3 debugging peripherals"
+ depends on ARCH_OMAP3
+ select ARM_AMBA
+ select OC_ETM
+ help
+ Say Y here to enable debugging hardware of omap3
+
+config OMAP3_SDRC_AC_TIMING
+ bool "Enable SDRC AC timing register changes"
+ depends on ARCH_OMAP3
+ default n
+ help
+ If you know that none of your system initiators will attempt to
+ access SDRAM during CORE DVFS, select Y here. This should boost
+ SDRAM performance at lower CORE OPPs. There are relatively few
+ users who will wish to say yes at this point - almost everyone will
+ wish to say no. Selecting yes without understanding what is
+ going on could result in system crashes;
+
+config OMAP4_ERRATA_I688
+ bool "OMAP4 errata: Async Bridge Corruption"
+ depends on ARCH_OMAP4
+ select ARCH_HAS_BARRIERS
+ help
+ If a data is stalled inside asynchronous bridge because of back
+ pressure, it may be accepted multiple times, creating pointer
+ misalignment that will corrupt next transfers on that data path
+ until next reset of the system (No recovery procedure once the
+ issue is hit, the path remains consistently broken). Async bridge
+ can be found on path between MPU to EMIF and MPU to L3 interconnect.
+ This situation can happen only when the idle is initiated by a
+ Master Request Disconnection (which is trigged by software when
+ executing WFI on CPU).
+ The work-around for this errata needs all the initiators connected
+ through async bridge must ensure that data path is properly drained
+ before issuing WFI. This condition will be met if one Strongly ordered
+ access is performed to the target right before executing the WFI.
+ In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
+ IO barrier ensure that there is no synchronisation loss on initiators
+ operating on both interconnect port simultaneously.
+endmenu
+
+endif
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
new file mode 100644
index 00000000000..bd76394ccaf
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile
@@ -0,0 +1,273 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
+ common.o gpio.o dma.o wd_timer.o display.o
+
+omap-2-3-common = irq.o sdrc.o
+hwmod-common = omap_hwmod.o \
+ omap_hwmod_common_data.o
+clock-common = clock.o clock_common_data.o \
+ clkt_dpll.o clkt_clksel.o
+secure-common = omap-smc.o omap-secure.o
+
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
+
+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+
+obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+
+# SMP support ONLY available for OMAP4
+obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
+obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
+obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \
+ sleep44xx.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec)
+
+# Functions loaded to SRAM
+obj-$(CONFIG_SOC_OMAP2420) += sram242x.o
+obj-$(CONFIG_SOC_OMAP2430) += sram243x.o
+obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o
+
+AFLAGS_sram242x.o :=-Wa,-march=armv6
+AFLAGS_sram243x.o :=-Wa,-march=armv6
+AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
+
+# Pin multiplexing
+obj-$(CONFIG_SOC_OMAP2420) += mux2420.o
+obj-$(CONFIG_SOC_OMAP2430) += mux2430.o
+obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
+
+# SMS/SDRC
+obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
+# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
+
+# OPP table initialization
+ifeq ($(CONFIG_PM_OPP),y)
+obj-y += opp.o
+obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
+endif
+
+# Power Management
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
+ cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \
+ cpuidle44xx.o
+obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
+obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
+
+AFLAGS_sleep24xx.o :=-Wa,-march=armv6
+AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
+
+ifeq ($(CONFIG_PM_VERBOSE),y)
+CFLAGS_pm_bus.o += -DDEBUG
+endif
+
+endif
+
+# PRCM
+obj-y += prm_common.o
+obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
+ vc3xxx_data.o vp3xxx_data.o
+# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
+# will be removed once the OMAP4 part of the codebase is converted to
+# use OMAP4-specific PRCM functions.
+obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
+ cm44xx.o prcm_mpu44xx.o \
+ prminst44xx.o vc44xx_data.o \
+ vp44xx_data.o prm44xx.o
+
+# OMAP voltage domains
+voltagedomain-common := voltage.o vc.o vp.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) \
+ voltagedomains2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \
+ voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \
+ voltagedomains44xx_data.o
+
+# OMAP powerdomain framework
+powerdomain-common += powerdomain.o powerdomain-common.o
+obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \
+ powerdomain2xxx_3xxx.o \
+ powerdomains2xxx_data.o \
+ powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \
+ powerdomain2xxx_3xxx.o \
+ powerdomains3xxx_data.o \
+ powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
+ powerdomain44xx.o \
+ powerdomains44xx_data.o
+
+# PRCM clockdomain control
+obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
+ clockdomain2xxx_3xxx.o \
+ clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
+ clockdomain2xxx_3xxx.o \
+ clockdomains2xxx_3xxx_data.o \
+ clockdomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
+ clockdomain44xx.o \
+ clockdomains44xx_data.o
+
+# Clock framework
+obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
+ clkt2xxx_sys.o \
+ clkt2xxx_dpllcore.o \
+ clkt2xxx_virt_prcm_set.o \
+ clkt2xxx_apll.o clkt2xxx_osc.o \
+ clkt2xxx_dpll.o clkt_iclk.o
+obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \
+ clock34xx.o clkt34xx_dpll3m2.o \
+ clock3517.o clock36xx.o \
+ dpll3xxx.o clock3xxx_data.o \
+ clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \
+ dpll3xxx.o dpll44xx.o
+
+# OMAP2 clock rate set data (old "OPP" data)
+obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
+
+# hwmod data
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o \
+ omap_hwmod_2xxx_3xxx_ipblock_data.o \
+ omap_hwmod_2xxx_interconnect_data.o \
+ omap_hwmod_2xxx_3xxx_interconnect_data.o \
+ omap_hwmod_2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o \
+ omap_hwmod_2xxx_3xxx_ipblock_data.o \
+ omap_hwmod_2xxx_interconnect_data.o \
+ omap_hwmod_2xxx_3xxx_interconnect_data.o \
+ omap_hwmod_2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o \
+ omap_hwmod_2xxx_3xxx_interconnect_data.o \
+ omap_hwmod_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
+
+# EMU peripherals
+obj-$(CONFIG_OMAP3_EMU) += emu.o
+
+# L3 interconnect
+obj-$(CONFIG_ARCH_OMAP3) += omap_l3_smx.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_l3_noc.o
+
+obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
+mailbox_mach-objs := mailbox.o
+
+obj-$(CONFIG_OMAP_IOMMU) += iommu2.o
+
+iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
+obj-y += $(iommu-m) $(iommu-y)
+
+i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
+obj-y += $(i2c-omap-m) $(i2c-omap-y)
+
+ifneq ($(CONFIG_TIDSPBRIDGE),)
+obj-y += dsp.o
+endif
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
+obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
+obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
+obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
+obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
+obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
+obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
+obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
+obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o
+obj-$(CONFIG_MACH_OVERO) += board-overo.o
+obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
+obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o
+obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o
+obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
+obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \
+ sdram-nokia.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
+ sdram-nokia.o \
+ board-rx51-peripherals.o \
+ board-rx51-video.o
+obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \
+ board-zoom-peripherals.o \
+ board-zoom-display.o \
+ board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \
+ board-zoom-peripherals.o \
+ board-zoom-display.o \
+ board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
+ board-zoom-peripherals.o \
+ board-zoom-display.o
+obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
+obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
+obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o
+obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o
+obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o
+obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o
+
+obj-$(CONFIG_MACH_PCM049) += board-omap4pcm049.o
+
+obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o
+
+obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
+
+obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o
+obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o
+obj-$(CONFIG_MACH_TI8148EVM) += board-ti8168evm.o
+
+# Platform specific device init code
+
+omap-flash-$(CONFIG_MTD_NAND_OMAP2) := board-flash.o
+omap-flash-$(CONFIG_MTD_ONENAND_OMAP2) := board-flash.o
+obj-y += $(omap-flash-y) $(omap-flash-m)
+
+omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o
+obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y)
+
+
+usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o
+obj-y += $(usbfs-m) $(usbfs-y)
+obj-y += usb-musb.o
+obj-y += omap_phy_internal.o
+
+obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o
+obj-y += usb-host.o
+
+onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o
+obj-y += $(onenand-m) $(onenand-y)
+
+nand-$(CONFIG_MTD_NAND_OMAP2) := gpmc-nand.o
+obj-y += $(nand-m) $(nand-y)
+
+smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o
+obj-y += $(smc91x-m) $(smc91x-y)
+
+smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o
+obj-y += $(smsc911x-m) $(smsc911x-y)
+obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o
+
+obj-y += common-board-devices.o twl-common.o
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
new file mode 100644
index 00000000000..b03e562acc6
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y += 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
new file mode 100644
index 00000000000..7370983f809
--- /dev/null
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -0,0 +1,308 @@
+/*
+ * linux/arch/arm/mach-omap2/board-2430sdp.c
+ *
+ * Copyright (C) 2006 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial Code : Based on a patch from Komal Shah and Richard Woodruff
+ * Updated the Code for 2430 SDP : Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mmc/host.h>
+#include <linux/delay.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <plat/gpmc-smc91x.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define SDP2430_CS0_BASE 0x04000000
+#define SECONDARY_LCD_GPIO 147
+
+static struct mtd_partition sdp2430_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data sdp2430_flash_data = {
+ .width = 2,
+ .parts = sdp2430_partitions,
+ .nr_parts = ARRAY_SIZE(sdp2430_partitions),
+};
+
+static struct resource sdp2430_flash_resource = {
+ .start = SDP2430_CS0_BASE,
+ .end = SDP2430_CS0_BASE + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device sdp2430_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sdp2430_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &sdp2430_flash_resource,
+};
+
+static struct platform_device *sdp2430_devices[] __initdata = {
+ &sdp2430_flash_device,
+};
+
+/* LCD */
+#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
+#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
+
+static int sdp2430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 1);
+ gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 1);
+
+ return 0;
+}
+
+static void sdp2430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 0);
+ gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 0);
+}
+
+static struct panel_generic_dpi_data sdp2430_panel_data = {
+ .name = "nec_nl2432dr22-11b",
+ .platform_enable = sdp2430_panel_enable_lcd,
+ .platform_disable = sdp2430_panel_disable_lcd,
+};
+
+static struct omap_dss_device sdp2430_lcd_device = {
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 16,
+ .data = &sdp2430_panel_data,
+};
+
+static struct omap_dss_device *sdp2430_dss_devices[] = {
+ &sdp2430_lcd_device,
+};
+
+static struct omap_dss_board_info sdp2430_dss_data = {
+ .num_devices = ARRAY_SIZE(sdp2430_dss_devices),
+ .devices = sdp2430_dss_devices,
+ .default_device = &sdp2430_lcd_device,
+};
+
+static void __init sdp2430_display_init(void)
+{
+ int r;
+
+ static struct gpio gpios[] __initdata = {
+ { SDP2430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
+ "LCD reset" },
+ { SDP2430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW,
+ "LCD Backlight" },
+ };
+
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r) {
+ pr_err("Cannot request LCD GPIOs, error %d\n", r);
+ return;
+ }
+
+ omap_display_init(&sdp2430_dss_data);
+}
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 5,
+ .gpio_irq = 149,
+ .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
+ IORESOURCE_IRQ_LOWLEVEL,
+
+};
+
+static void __init board_smc91x_init(void)
+{
+ omap_mux_init_gpio(149, OMAP_PIN_INPUT);
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif
+
+static struct regulator_consumer_supply sdp2430_vmmc1_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data sdp2430_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp2430_vmmc1_supplies),
+ .consumer_supplies = &sdp2430_vmmc1_supplies[0],
+};
+
+static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_platform_data sdp2430_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &sdp2430_gpio_data,
+ .vmmc1 = &sdp2430_vmmc1,
+};
+
+static struct i2c_board_info __initdata sdp2430_i2c1_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2D),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = OMAP_GPIO_IRQ(78),
+ },
+};
+
+static int __init omap2430_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo,
+ ARRAY_SIZE(sdp2430_i2c1_boardinfo));
+ omap_pmic_init(2, 100, "twl4030", INT_24XX_SYS_NIRQ,
+ &sdp2430_twldata);
+ return 0;
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .ext_clock = 1,
+ },
+ {} /* Terminator */
+};
+
+static struct omap_usb_config sdp2430_usb_config __initdata = {
+ .otg = 1,
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 0x0,
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ .hmc_mode = 0x1,
+#endif
+ .pins[0] = 3,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap_2430sdp_init(void)
+{
+ omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+
+ omap2430_i2c_init();
+
+ platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ omap2_hsmmc_init(mmc);
+ omap2_usbfs_init(&sdp2430_usb_config);
+
+ omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
+ usb_musb_init(NULL);
+
+ board_smc91x_init();
+
+ /* Turn off secondary LCD backlight */
+ gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
+ "Secondary LCD backlight");
+
+ sdp2430_display_init();
+}
+
+MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
+ /* Maintainer: Syed Khasim - Texas Instruments Inc */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap243x_map_io,
+ .init_early = omap2430_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = omap_2430sdp_init,
+ .timer = &omap2_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
new file mode 100644
index 00000000000..383717ba63b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -0,0 +1,637 @@
+/*
+ * linux/arch/arm/mach-omap2/board-3430sdp.c
+ *
+ * Copyright (C) 2007 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include <plat/usb.h>
+#include "common.h"
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-dvi.h>
+
+#include <plat/gpmc-smc91x.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "sdram-qimonda-hyb18m512160af-6.h"
+#include "hsmmc.h"
+#include "pm.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#define CONFIG_DISABLE_HFCLK 1
+
+#define SDP3430_TS_GPIO_IRQ_SDPV1 3
+#define SDP3430_TS_GPIO_IRQ_SDPV2 2
+
+#define ENABLE_VAUX3_DEDICATED 0x03
+#define ENABLE_VAUX3_DEV_GRP 0x20
+
+#define TWL4030_MSECURE_GPIO 22
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_A),
+ KEY(0, 3, KEY_B),
+ KEY(0, 4, KEY_C),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_F),
+ KEY(1, 4, KEY_G),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_K),
+ KEY(2, 4, KEY_3),
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P),
+ KEY(3, 4, KEY_Q),
+ KEY(4, 0, KEY_R),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_T),
+ KEY(4, 3, KEY_U),
+ KEY(4, 4, KEY_D),
+ KEY(5, 0, KEY_V),
+ KEY(5, 1, KEY_W),
+ KEY(5, 2, KEY_L),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_H),
+ 0
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data sdp3430_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 5,
+ .cols = 6,
+ .rep = 1,
+};
+
+#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8
+#define SDP3430_LCD_PANEL_ENABLE_GPIO 5
+
+static struct gpio sdp3430_dss_gpios[] __initdata = {
+ {SDP3430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, "LCD reset" },
+ {SDP3430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW, "LCD Backlight"},
+};
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init sdp3430_display_init(void)
+{
+ int r;
+
+ r = gpio_request_array(sdp3430_dss_gpios,
+ ARRAY_SIZE(sdp3430_dss_gpios));
+ if (r)
+ printk(KERN_ERR "failed to get LCD control GPIOs\n");
+
+}
+
+static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 1);
+ gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 1);
+
+ lcd_enabled = 1;
+
+ return 0;
+}
+
+static void sdp3430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ lcd_enabled = 0;
+
+ gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 0);
+ gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 0);
+}
+
+static int sdp3430_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void sdp3430_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static int sdp3430_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void sdp3430_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+
+static struct omap_dss_device sdp3430_lcd_device = {
+ .name = "lcd",
+ .driver_name = "sharp_ls_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 16,
+ .platform_enable = sdp3430_panel_enable_lcd,
+ .platform_disable = sdp3430_panel_disable_lcd,
+};
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = sdp3430_panel_enable_dvi,
+ .platform_disable = sdp3430_panel_disable_dvi,
+};
+
+static struct omap_dss_device sdp3430_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device sdp3430_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = sdp3430_panel_enable_tv,
+ .platform_disable = sdp3430_panel_disable_tv,
+};
+
+
+static struct omap_dss_device *sdp3430_dss_devices[] = {
+ &sdp3430_lcd_device,
+ &sdp3430_dvi_device,
+ &sdp3430_tv_device,
+};
+
+static struct omap_dss_board_info sdp3430_dss_data = {
+ .num_devices = ARRAY_SIZE(sdp3430_dss_devices),
+ .devices = sdp3430_dss_devices,
+ .default_device = &sdp3430_lcd_device,
+};
+
+static struct omap_board_config_kernel sdp3430_config[] __initdata = {
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ /* 8 bits (default) requires S6.3 == ON,
+ * so the SIM card isn't used; else 4 bits.
+ */
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 4,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 7,
+ },
+ {} /* Terminator */
+};
+
+static int sdp3430_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ),
+ * gpio + 1 is "mmc1_cd" (input/IRQ)
+ */
+ mmc[0].gpio_cd = gpio + 0;
+ mmc[1].gpio_cd = gpio + 1;
+ omap2_hsmmc_init(mmc);
+
+ /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl");
+
+ /* gpio + 15 is "sub_lcd_nRST" (output) */
+ gpio_request_one(gpio + 15, GPIOF_OUT_INIT_LOW, "sub_lcd_nRST");
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(2) | BIT(6) | BIT(8) | BIT(13)
+ | BIT(16) | BIT(17),
+ .setup = sdp3430_twl_gpio_setup,
+};
+
+/* regulator consumer mappings */
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply sdp3430_vsim_supplies[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc2_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+/*
+ * Apply all the fixed voltages since most versions of U-Boot
+ * don't bother with that initialization.
+ */
+
+/* VAUX1 for mainboard (irda and sub-lcd) */
+static struct regulator_init_data sdp3430_vaux1 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX2 for camera module */
+static struct regulator_init_data sdp3430_vaux2 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX3 for LCD board */
+static struct regulator_init_data sdp3430_vaux3 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vaux3_supplies),
+ .consumer_supplies = sdp3430_vaux3_supplies,
+};
+
+/* VAUX4 for OMAP VDD_CSI2 (camera) */
+static struct regulator_init_data sdp3430_vaux4 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data sdp3430_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc1_supplies),
+ .consumer_supplies = sdp3430_vmmc1_supplies,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data sdp3430_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 1850000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc2_supplies),
+ .consumer_supplies = sdp3430_vmmc2_supplies,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data sdp3430_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vsim_supplies),
+ .consumer_supplies = sdp3430_vsim_supplies,
+};
+
+static struct twl4030_platform_data sdp3430_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &sdp3430_gpio_data,
+ .keypad = &sdp3430_kp_data,
+
+ .vaux1 = &sdp3430_vaux1,
+ .vaux2 = &sdp3430_vaux2,
+ .vaux3 = &sdp3430_vaux3,
+ .vaux4 = &sdp3430_vaux4,
+ .vmmc1 = &sdp3430_vmmc1,
+ .vmmc2 = &sdp3430_vmmc2,
+ .vsim = &sdp3430_vsim,
+};
+
+static int __init omap3430_i2c_init(void)
+{
+ /* i2c1 for PMIC only */
+ omap3_pmic_get_config(&sdp3430_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_BCI |
+ TWL_COMMON_PDATA_MADC | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+ sdp3430_twldata.vdac->constraints.apply_uV = true;
+ sdp3430_twldata.vpll2->constraints.apply_uV = true;
+ sdp3430_twldata.vpll2->constraints.name = "VDVI";
+
+ omap3_pmic_init("twl4030", &sdp3430_twldata);
+
+ /* i2c2 on camera connector (for sensor control) and optional isp1301 */
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ /* i2c3 on display connector (for DVI, tfp410) */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 3,
+ .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
+ IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+ board_smc91x_data.gpio_irq = 6;
+ else
+ board_smc91x_data.gpio_irq = 29;
+
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif
+
+static void enable_board_wakeup_source(void)
+{
+ /* T2 interrupt line (keypad) */
+ omap_mux_init_signal("sys_nirq",
+ OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 57,
+ .reset_gpio_port[1] = 61,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
+/*
+ * SDP3430 V2 Board CS organization
+ * Different from SDP3430 V1. Now 4 switches used to specify CS
+ *
+ * See also the Switch S8 settings in the comments.
+ */
+static char chip_sel_3430[][GPMC_CS_NUM] = {
+ {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */
+ {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */
+ {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */
+};
+
+static struct mtd_partition sdp_nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "Bootloader-NOR",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "Params-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "Kernel-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "Filesystem-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct mtd_partition sdp_onenand_partitions[] = {
+ {
+ .name = "X-Loader-OneNAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot Environment-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16 * (64 * 2048),
+ },
+ {
+ .name = "File System-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition sdp_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 6 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 40 * (64 * 2048),
+ },
+ {
+ .name = "File System - NAND",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */
+ },
+};
+
+static struct flash_partitions sdp_flash_partitions[] = {
+ {
+ .parts = sdp_nor_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nor_partitions),
+ },
+ {
+ .parts = sdp_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_onenand_partitions),
+ },
+ {
+ .parts = sdp_nand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nand_partitions),
+ },
+};
+
+static void __init omap_3430sdp_init(void)
+{
+ int gpio_pendown;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_board_config = sdp3430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+ omap3430_i2c_init();
+ omap_display_init(&sdp3430_dss_data);
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+ gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2;
+ else
+ gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
+ omap_ads7846_init(1, gpio_pendown, 310, NULL);
+ omap_serial_init();
+ omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
+ usb_musb_init(NULL);
+ board_smc91x_init();
+ board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
+ sdp3430_display_init();
+ enable_board_wakeup_source();
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
+ /* Maintainer: Syed Khasim - Texas Instruments Inc */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap_3430sdp_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
new file mode 100644
index 00000000000..6ef350d1ae4
--- /dev/null
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/mtd/nand.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include <plat/board.h>
+#include <plat/gpmc-smc91x.h>
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "sdram-hynix-h8mbx00u0mer-0em.h"
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 3,
+ .flags = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+ board_smc91x_data.gpio_irq = 158;
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif /* defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) */
+
+static void enable_board_wakeup_source(void)
+{
+ /* T2 interrupt line (keypad) */
+ omap_mux_init_signal("sys_nirq",
+ OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 126,
+ .reset_gpio_port[1] = 61,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static struct omap_board_config_kernel sdp_config[] __initdata = {
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+/*
+ * SDP3630 CS organization
+ * See also the Switch S8 settings in the comments.
+ */
+static char chip_sel_sdp[][GPMC_CS_NUM] = {
+ {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */
+ {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */
+ {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */
+};
+
+static struct mtd_partition sdp_nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "Bootloader-NOR",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "Params-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "Kernel-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "Filesystem-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct mtd_partition sdp_onenand_partitions[] = {
+ {
+ .name = "X-Loader-OneNAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot Environment-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16 * (64 * 2048),
+ },
+ {
+ .name = "File System-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition sdp_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 6 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 40 * (64 * 2048),
+ },
+ {
+ .name = "File System - NAND",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */
+ },
+};
+
+static struct flash_partitions sdp_flash_partitions[] = {
+ {
+ .parts = sdp_nor_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nor_partitions),
+ },
+ {
+ .parts = sdp_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_onenand_partitions),
+ },
+ {
+ .parts = sdp_nand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nand_partitions),
+ },
+};
+
+static void __init omap_sdp_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+ omap_board_config = sdp_config;
+ omap_board_config_size = ARRAY_SIZE(sdp_config);
+ zoom_peripherals_init();
+ omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
+ zoom_display_init();
+ board_smc91x_init();
+ board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
+ enable_board_wakeup_source();
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap_sdp_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
new file mode 100644
index 00000000000..4e9071589bf
--- /dev/null
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -0,0 +1,940 @@
+/*
+ * Board support file for OMAP4430 SDP.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Based on mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/twl.h>
+#include <linux/gpio_keys.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/leds.h>
+#include <linux/leds_pwm.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/usb.h>
+#include <plat/mmc.h>
+#include <plat/omap4-keypad.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-nokia-dsi.h>
+#include <video/omap-panel-picodlp.h>
+#include <linux/wl12xx.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#define ETH_KS8851_IRQ 34
+#define ETH_KS8851_POWER_ON 48
+#define ETH_KS8851_QUART 138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
+#define OMAP4_SFH7741_ENABLE_GPIO 188
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
+#define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */
+#define DLP_POWER_ON_GPIO 40
+
+#define GPIO_WIFI_PMENA 54
+#define GPIO_WIFI_IRQ 53
+
+static const int sdp4430_keymap[] = {
+ KEY(0, 0, KEY_E),
+ KEY(0, 1, KEY_R),
+ KEY(0, 2, KEY_T),
+ KEY(0, 3, KEY_HOME),
+ KEY(0, 4, KEY_F5),
+ KEY(0, 5, KEY_UNKNOWN),
+ KEY(0, 6, KEY_I),
+ KEY(0, 7, KEY_LEFTSHIFT),
+
+ KEY(1, 0, KEY_D),
+ KEY(1, 1, KEY_F),
+ KEY(1, 2, KEY_G),
+ KEY(1, 3, KEY_SEND),
+ KEY(1, 4, KEY_F6),
+ KEY(1, 5, KEY_UNKNOWN),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_ENTER),
+
+ KEY(2, 0, KEY_X),
+ KEY(2, 1, KEY_C),
+ KEY(2, 2, KEY_V),
+ KEY(2, 3, KEY_END),
+ KEY(2, 4, KEY_F7),
+ KEY(2, 5, KEY_UNKNOWN),
+ KEY(2, 6, KEY_DOT),
+ KEY(2, 7, KEY_CAPSLOCK),
+
+ KEY(3, 0, KEY_Z),
+ KEY(3, 1, KEY_KPPLUS),
+ KEY(3, 2, KEY_B),
+ KEY(3, 3, KEY_F1),
+ KEY(3, 4, KEY_F8),
+ KEY(3, 5, KEY_UNKNOWN),
+ KEY(3, 6, KEY_O),
+ KEY(3, 7, KEY_SPACE),
+
+ KEY(4, 0, KEY_W),
+ KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_U),
+ KEY(4, 3, KEY_F2),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(4, 5, KEY_UNKNOWN),
+ KEY(4, 6, KEY_L),
+ KEY(4, 7, KEY_LEFT),
+
+ KEY(5, 0, KEY_S),
+ KEY(5, 1, KEY_H),
+ KEY(5, 2, KEY_J),
+ KEY(5, 3, KEY_F3),
+ KEY(5, 4, KEY_F9),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ KEY(5, 6, KEY_M),
+ KEY(5, 7, KEY_RIGHT),
+
+ KEY(6, 0, KEY_Q),
+ KEY(6, 1, KEY_A),
+ KEY(6, 2, KEY_N),
+ KEY(6, 3, KEY_BACK),
+ KEY(6, 4, KEY_BACKSPACE),
+ KEY(6, 5, KEY_UNKNOWN),
+ KEY(6, 6, KEY_P),
+ KEY(6, 7, KEY_UP),
+
+ KEY(7, 0, KEY_PROG1),
+ KEY(7, 1, KEY_PROG2),
+ KEY(7, 2, KEY_PROG3),
+ KEY(7, 3, KEY_PROG4),
+ KEY(7, 4, KEY_F4),
+ KEY(7, 5, KEY_UNKNOWN),
+ KEY(7, 6, KEY_OK),
+ KEY(7, 7, KEY_DOWN),
+};
+static struct omap_device_pad keypad_pads[] = {
+ { .name = "kpd_col1.kpd_col1",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "kpd_col1.kpd_col1",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "kpd_col2.kpd_col2",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "kpd_col3.kpd_col3",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "kpd_col4.kpd_col4",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "kpd_col5.kpd_col5",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "gpmc_a23.kpd_col7",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "gpmc_a22.kpd_col6",
+ .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
+ },
+ { .name = "kpd_row0.kpd_row0",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "kpd_row1.kpd_row1",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "kpd_row2.kpd_row2",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "kpd_row3.kpd_row3",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "kpd_row4.kpd_row4",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "kpd_row5.kpd_row5",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "gpmc_a18.kpd_row6",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+ { .name = "gpmc_a19.kpd_row7",
+ .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
+ OMAP_MUX_MODE1 | OMAP_INPUT_EN,
+ },
+};
+
+static struct matrix_keymap_data sdp4430_keymap_data = {
+ .keymap = sdp4430_keymap,
+ .keymap_size = ARRAY_SIZE(sdp4430_keymap),
+};
+
+static struct omap4_keypad_platform_data sdp4430_keypad_data = {
+ .keymap_data = &sdp4430_keymap_data,
+ .rows = 8,
+ .cols = 8,
+};
+
+static struct omap_board_data keypad_data = {
+ .id = 1,
+ .pads = keypad_pads,
+ .pads_cnt = ARRAY_SIZE(keypad_pads),
+};
+
+static struct gpio_led sdp4430_gpio_leds[] = {
+ {
+ .name = "omap4:green:debug0",
+ .gpio = 61,
+ },
+ {
+ .name = "omap4:green:debug1",
+ .gpio = 30,
+ },
+ {
+ .name = "omap4:green:debug2",
+ .gpio = 7,
+ },
+ {
+ .name = "omap4:green:debug3",
+ .gpio = 8,
+ },
+ {
+ .name = "omap4:green:debug4",
+ .gpio = 50,
+ },
+ {
+ .name = "omap4:blue:user",
+ .gpio = 169,
+ },
+ {
+ .name = "omap4:red:user",
+ .gpio = 170,
+ },
+ {
+ .name = "omap4:green:user",
+ .gpio = 139,
+ },
+
+};
+
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+ {
+ .desc = "Proximity Sensor",
+ .type = EV_SW,
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+ .active_low = 0,
+ }
+};
+
+static struct gpio_led_platform_data sdp4430_led_data = {
+ .leds = sdp4430_gpio_leds,
+ .num_leds = ARRAY_SIZE(sdp4430_gpio_leds),
+};
+
+static struct led_pwm sdp4430_pwm_leds[] = {
+ {
+ .name = "omap4:green:chrg",
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .pwm_period_ns = 7812500,
+ },
+};
+
+static struct led_pwm_platform_data sdp4430_pwm_data = {
+ .num_leds = ARRAY_SIZE(sdp4430_pwm_leds),
+ .leds = sdp4430_pwm_leds,
+};
+
+static struct platform_device sdp4430_leds_pwm = {
+ .name = "leds_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_pwm_data,
+ },
+};
+
+static int omap_prox_activate(struct device *dev)
+{
+ gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+ return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+ gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+ .buttons = sdp4430_gpio_keys,
+ .nbuttons = ARRAY_SIZE(sdp4430_gpio_keys),
+ .enable = omap_prox_activate,
+ .disable = omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_gpio_keys_data,
+ },
+};
+
+static struct platform_device sdp4430_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_led_data,
+ },
+};
+static struct spi_board_info sdp4430_spi_board_info[] __initdata = {
+ {
+ .modalias = "ks8851",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 24000000,
+ .irq = ETH_KS8851_IRQ,
+ },
+};
+
+static struct gpio sdp4430_eth_gpios[] __initdata = {
+ { ETH_KS8851_POWER_ON, GPIOF_OUT_INIT_HIGH, "eth_power" },
+ { ETH_KS8851_QUART, GPIOF_OUT_INIT_HIGH, "quart" },
+ { ETH_KS8851_IRQ, GPIOF_IN, "eth_irq" },
+};
+
+static int __init omap_ethernet_init(void)
+{
+ int status;
+
+ /* Request of GPIO lines */
+ status = gpio_request_array(sdp4430_eth_gpios,
+ ARRAY_SIZE(sdp4430_eth_gpios));
+ if (status)
+ pr_err("Cannot request ETH GPIOs\n");
+
+ return status;
+}
+
+static struct regulator_consumer_supply sdp4430_vbat_supply[] = {
+ REGULATOR_SUPPLY("vddvibl", "twl6040-vibra"),
+ REGULATOR_SUPPLY("vddvibr", "twl6040-vibra"),
+};
+
+static struct regulator_init_data sdp4430_vbat_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp4430_vbat_supply),
+ .consumer_supplies = sdp4430_vbat_supply,
+};
+
+static struct fixed_voltage_config sdp4430_vbat_pdata = {
+ .supply_name = "VBAT",
+ .microvolts = 3750000,
+ .init_data = &sdp4430_vbat_data,
+ .gpio = -EINVAL,
+};
+
+static struct platform_device sdp4430_vbat = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_vbat_pdata,
+ },
+};
+
+static struct platform_device sdp4430_dmic_codec = {
+ .name = "dmic-codec",
+ .id = -1,
+};
+
+static struct platform_device *sdp4430_devices[] __initdata = {
+ &sdp4430_gpio_keys_device,
+ &sdp4430_leds_gpio,
+ &sdp4430_leds_pwm,
+ &sdp4430_vbat,
+ &sdp4430_dmic_codec,
+};
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_UTMI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .nonremovable = true,
+ .ocr_mask = MMC_VDD_29_30,
+ .no_off_init = true,
+ },
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {
+ .mmc = 5,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .pm_caps = MMC_PM_KEEP_POWER,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .ocr_mask = MMC_VDD_165_195,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply sdp4430_vaux_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+static struct regulator_consumer_supply omap4_sdp4430_vmmc5_supply = {
+ .supply = "vmmc",
+ .dev_name = "omap_hsmmc.4",
+};
+
+static struct regulator_init_data sdp4430_vmmc5 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap4_sdp4430_vmmc5_supply,
+};
+
+static struct fixed_voltage_config sdp4430_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = GPIO_WIFI_PMENA,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &sdp4430_vmmc5,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &sdp4430_vwlan,
+ },
+};
+
+static int omap4_twl6030_hsmmc_late_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_mmc_platform_data *pdata = dev->platform_data;
+
+ /* Setting MMC1 Card detect Irq */
+ if (pdev->id == 0) {
+ ret = twl6030_mmc_card_detect_config();
+ if (ret)
+ pr_err("Failed configuring MMC1 card detect\n");
+ pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
+ MMCDETECT_INTR_OFFSET;
+ pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+ }
+ return ret;
+}
+
+static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
+{
+ struct omap_mmc_platform_data *pdata;
+
+ /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+ if (!dev) {
+ pr_err("Failed %s\n", __func__);
+ return;
+ }
+ pdata = dev->platform_data;
+ pdata->init = omap4_twl6030_hsmmc_late_init;
+}
+
+static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ struct omap2_hsmmc_info *c;
+
+ omap2_hsmmc_init(controllers);
+ for (c = controllers; c->mmc; c++)
+ omap4_twl6030_hsmmc_set_late_init(c->dev);
+
+ return 0;
+}
+
+static struct regulator_init_data sdp4430_vaux1 = {
+ .constraints = {
+ .min_uV = 1000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp4430_vaux_supply),
+ .consumer_supplies = sdp4430_vaux_supply,
+};
+
+static struct regulator_init_data sdp4430_vusim = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2900000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct twl4030_codec_data twl6040_codec = {
+ /* single-step ramp for headset and handsfree */
+ .hs_left_step = 0x0f,
+ .hs_right_step = 0x0f,
+ .hf_left_step = 0x1d,
+ .hf_right_step = 0x1d,
+};
+
+static struct twl4030_vibra_data twl6040_vibra = {
+ .vibldrv_res = 8,
+ .vibrdrv_res = 3,
+ .viblmotor_res = 10,
+ .vibrmotor_res = 10,
+ .vddvibl_uV = 0, /* fixed volt supply - VBAT */
+ .vddvibr_uV = 0, /* fixed volt supply - VBAT */
+};
+
+static struct twl4030_audio_data twl6040_audio = {
+ .codec = &twl6040_codec,
+ .vibra = &twl6040_vibra,
+ .audpwron_gpio = 127,
+ .naudint_irq = OMAP44XX_IRQ_SYS_2N,
+ .irq_base = TWL6040_CODEC_IRQ_BASE,
+};
+
+static struct twl4030_platform_data sdp4430_twldata = {
+ .audio = &twl6040_audio,
+ /* Regulators */
+ .vusim = &sdp4430_vusim,
+ .vaux1 = &sdp4430_vaux1,
+};
+
+static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tmp105", 0x48),
+ },
+ {
+ I2C_BOARD_INFO("bh1780", 0x29),
+ },
+};
+static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("hmc5843", 0x1e),
+ },
+};
+static int __init omap4_i2c_init(void)
+{
+ omap4_pmic_get_config(&sdp4430_twldata, TWL_COMMON_PDATA_USB,
+ TWL_COMMON_REGULATOR_VDAC |
+ TWL_COMMON_REGULATOR_VAUX2 |
+ TWL_COMMON_REGULATOR_VAUX3 |
+ TWL_COMMON_REGULATOR_VMMC |
+ TWL_COMMON_REGULATOR_VPP |
+ TWL_COMMON_REGULATOR_VANA |
+ TWL_COMMON_REGULATOR_VCXIO |
+ TWL_COMMON_REGULATOR_VUSB |
+ TWL_COMMON_REGULATOR_CLK32KG);
+ omap4_pmic_init("twl6030", &sdp4430_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
+ ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
+ omap_register_i2c_bus(4, 400, sdp4430_i2c_4_boardinfo,
+ ARRAY_SIZE(sdp4430_i2c_4_boardinfo));
+ return 0;
+}
+
+static void __init omap_sfh7741prox_init(void)
+{
+ int error;
+
+ error = gpio_request_one(OMAP4_SFH7741_ENABLE_GPIO,
+ GPIOF_OUT_INIT_LOW, "sfh7741");
+ if (error < 0)
+ pr_err("%s:failed to request GPIO %d, error %d\n",
+ __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+}
+
+static struct gpio sdp4430_hdmi_gpios[] = {
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
+ { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
+};
+
+static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+ int status;
+
+ status = gpio_request_array(sdp4430_hdmi_gpios,
+ ARRAY_SIZE(sdp4430_hdmi_gpios));
+ if (status)
+ pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
+
+ return status;
+}
+
+static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+ gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
+}
+
+static struct nokia_dsi_panel_data dsi1_panel = {
+ .name = "taal",
+ .reset_gpio = 102,
+ .use_ext_te = false,
+ .ext_te_gpio = 101,
+ .esd_interval = 0,
+};
+
+static struct omap_dss_device sdp4430_lcd_device = {
+ .name = "lcd",
+ .driver_name = "taal",
+ .type = OMAP_DISPLAY_TYPE_DSI,
+ .data = &dsi1_panel,
+ .phy.dsi = {
+ .clk_lane = 1,
+ .clk_pol = 0,
+ .data1_lane = 2,
+ .data1_pol = 0,
+ .data2_lane = 3,
+ .data2_pol = 0,
+
+ .module = 0,
+ },
+
+ .clocks = {
+ .dispc = {
+ .channel = {
+ /* Logic Clock = 172.8 MHz */
+ .lck_div = 1,
+ /* Pixel Clock = 34.56 MHz */
+ .pck_div = 5,
+ .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
+ },
+ .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
+ },
+
+ .dsi = {
+ .regn = 16, /* Fint = 2.4 MHz */
+ .regm = 180, /* DDR Clock = 216 MHz */
+ .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
+ .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
+
+ .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
+ .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
+ },
+ },
+ .channel = OMAP_DSS_CHANNEL_LCD,
+};
+
+static struct nokia_dsi_panel_data dsi2_panel = {
+ .name = "taal",
+ .reset_gpio = 104,
+ .use_ext_te = false,
+ .ext_te_gpio = 103,
+ .esd_interval = 0,
+};
+
+static struct omap_dss_device sdp4430_lcd2_device = {
+ .name = "lcd2",
+ .driver_name = "taal",
+ .type = OMAP_DISPLAY_TYPE_DSI,
+ .data = &dsi2_panel,
+ .phy.dsi = {
+ .clk_lane = 1,
+ .clk_pol = 0,
+ .data1_lane = 2,
+ .data1_pol = 0,
+ .data2_lane = 3,
+ .data2_pol = 0,
+
+ .module = 1,
+ },
+
+ .clocks = {
+ .dispc = {
+ .channel = {
+ /* Logic Clock = 172.8 MHz */
+ .lck_div = 1,
+ /* Pixel Clock = 34.56 MHz */
+ .pck_div = 5,
+ .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
+ },
+ .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
+ },
+
+ .dsi = {
+ .regn = 16, /* Fint = 2.4 MHz */
+ .regm = 180, /* DDR Clock = 216 MHz */
+ .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
+ .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
+
+ .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
+ .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
+ },
+ },
+ .channel = OMAP_DSS_CHANNEL_LCD2,
+};
+
+static void sdp4430_lcd_init(void)
+{
+ int r;
+
+ r = gpio_request_one(dsi1_panel.reset_gpio, GPIOF_DIR_OUT,
+ "lcd1_reset_gpio");
+ if (r)
+ pr_err("%s: Could not get lcd1_reset_gpio\n", __func__);
+
+ r = gpio_request_one(dsi2_panel.reset_gpio, GPIOF_DIR_OUT,
+ "lcd2_reset_gpio");
+ if (r)
+ pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
+}
+
+static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
+static struct omap_dss_device sdp4430_hdmi_device = {
+ .name = "hdmi",
+ .driver_name = "hdmi_panel",
+ .type = OMAP_DISPLAY_TYPE_HDMI,
+ .platform_enable = sdp4430_panel_enable_hdmi,
+ .platform_disable = sdp4430_panel_disable_hdmi,
+ .channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &sdp4430_hdmi_data,
+};
+
+static struct picodlp_panel_data sdp4430_picodlp_pdata = {
+ .picodlp_adapter_id = 2,
+ .emu_done_gpio = 44,
+ .pwrgood_gpio = 45,
+};
+
+static void sdp4430_picodlp_init(void)
+{
+ int r;
+ const struct gpio picodlp_gpios[] = {
+ {DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
+ "DLP POWER ON"},
+ {sdp4430_picodlp_pdata.emu_done_gpio, GPIOF_IN,
+ "DLP EMU DONE"},
+ {sdp4430_picodlp_pdata.pwrgood_gpio, GPIOF_OUT_INIT_LOW,
+ "DLP PWRGOOD"},
+ };
+
+ r = gpio_request_array(picodlp_gpios, ARRAY_SIZE(picodlp_gpios));
+ if (r)
+ pr_err("Cannot request PicoDLP GPIOs, error %d\n", r);
+}
+
+static int sdp4430_panel_enable_picodlp(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(DISPLAY_SEL_GPIO, 0);
+ gpio_set_value(DLP_POWER_ON_GPIO, 1);
+
+ return 0;
+}
+
+static void sdp4430_panel_disable_picodlp(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(DLP_POWER_ON_GPIO, 0);
+ gpio_set_value(DISPLAY_SEL_GPIO, 1);
+}
+
+static struct omap_dss_device sdp4430_picodlp_device = {
+ .name = "picodlp",
+ .driver_name = "picodlp_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 24,
+ .channel = OMAP_DSS_CHANNEL_LCD2,
+ .platform_enable = sdp4430_panel_enable_picodlp,
+ .platform_disable = sdp4430_panel_disable_picodlp,
+ .data = &sdp4430_picodlp_pdata,
+};
+
+static struct omap_dss_device *sdp4430_dss_devices[] = {
+ &sdp4430_lcd_device,
+ &sdp4430_lcd2_device,
+ &sdp4430_hdmi_device,
+ &sdp4430_picodlp_device,
+};
+
+static struct omap_dss_board_info sdp4430_dss_data = {
+ .num_devices = ARRAY_SIZE(sdp4430_dss_devices),
+ .devices = sdp4430_dss_devices,
+ .default_device = &sdp4430_lcd_device,
+};
+
+static void __init omap_4430sdp_display_init(void)
+{
+ int r;
+
+ /* Enable LCD2 by default (instead of Pico DLP) */
+ r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH,
+ "display_sel");
+ if (r)
+ pr_err("%s: Could not get display_sel GPIO\n", __func__);
+
+ sdp4430_lcd_init();
+ sdp4430_picodlp_init();
+ omap_display_init(&sdp4430_dss_data);
+ /*
+ * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
+ * later have external pull up on the HDMI I2C lines
+ */
+ if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2)
+ omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
+ else
+ omap_hdmi_init(0);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+#else
+#define board_mux NULL
+ #endif
+
+static void __init omap4_sdp4430_wifi_mux_init(void)
+{
+ omap_mux_init_gpio(GPIO_WIFI_IRQ, OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_WAKEUPENABLE);
+ omap_mux_init_gpio(GPIO_WIFI_PMENA, OMAP_PIN_OUTPUT);
+
+ omap_mux_init_signal("sdmmc5_cmd.sdmmc5_cmd",
+ OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc5_clk.sdmmc5_clk",
+ OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc5_dat0.sdmmc5_dat0",
+ OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc5_dat1.sdmmc5_dat1",
+ OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc5_dat2.sdmmc5_dat2",
+ OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc5_dat3.sdmmc5_dat3",
+ OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
+
+}
+
+static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ),
+ .board_ref_clock = WL12XX_REFCLOCK_26,
+ .board_tcxo_clock = WL12XX_TCXOCLOCK_26,
+};
+
+static void __init omap4_sdp4430_wifi_init(void)
+{
+ int ret;
+
+ omap4_sdp4430_wifi_mux_init();
+ ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
+ if (ret)
+ pr_err("Error setting wl12xx data: %d\n", ret);
+ ret = platform_device_register(&omap_vwlan_device);
+ if (ret)
+ pr_err("Error registering wl12xx device: %d\n", ret);
+}
+
+static void __init omap_4430sdp_init(void)
+{
+ int status;
+ int package = OMAP_PACKAGE_CBS;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ package = OMAP_PACKAGE_CBL;
+ omap4_mux_init(board_mux, NULL, package);
+
+ omap4_i2c_init();
+ omap_sfh7741prox_init();
+ platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ omap4_sdp4430_wifi_init();
+ omap4_twl6030_hsmmc_init(mmc);
+
+ usb_musb_init(&musb_board_data);
+
+ status = omap_ethernet_init();
+ if (status) {
+ pr_err("Ethernet initialization failed: %d\n", status);
+ } else {
+ sdp4430_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ);
+ spi_register_board_info(sdp4430_spi_board_info,
+ ARRAY_SIZE(sdp4430_spi_board_info));
+ }
+
+ status = omap4_keyboard_init(&sdp4430_keypad_data, &keypad_data);
+ if (status)
+ pr_err("Keypad initialization failed: %d\n", status);
+
+ omap_4430sdp_display_init();
+}
+
+MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
+ /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
+ .init_irq = gic_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = omap_4430sdp_init,
+ .timer = &omap4_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
new file mode 100644
index 00000000000..c3851e8de28
--- /dev/null
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -0,0 +1,105 @@
+/*
+ * Support for AM3517/05 Craneboard
+ * http://www.mistralsolutions.com/products/craneboard.php
+ *
+ * Copyright (C) 2010 Mistral Solutions Pvt Ltd. <www.mistralsolutions.com>
+ * Author: R.Srinath <srinath@mistralsolutions.com>
+ *
+ * Based on mach-omap2/board-am3517evm.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "control.h"
+
+#define GPIO_USB_POWER 35
+#define GPIO_USB_NRESET 38
+
+
+/* Board initialization */
+static struct omap_board_config_kernel am3517_crane_config[] __initdata = {
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct usbhs_omap_board_data usbhs_bdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = GPIO_USB_NRESET,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void __init am3517_crane_init(void)
+{
+ int ret;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+
+ omap_board_config = am3517_crane_config;
+ omap_board_config_size = ARRAY_SIZE(am3517_crane_config);
+
+ /* Configure GPIO for EHCI port */
+ if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) {
+ pr_err("Can not configure mux for GPIO_USB_NRESET %d\n",
+ GPIO_USB_NRESET);
+ return;
+ }
+
+ if (omap_mux_init_gpio(GPIO_USB_POWER, OMAP_PIN_OUTPUT)) {
+ pr_err("Can not configure mux for GPIO_USB_POWER %d\n",
+ GPIO_USB_POWER);
+ return;
+ }
+
+ ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH,
+ "usb_ehci_enable");
+ if (ret < 0) {
+ pr_err("Can not request GPIO %d\n", GPIO_USB_POWER);
+ return;
+ }
+
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = am35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = am3517_crane_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
new file mode 100644
index 00000000000..4b1cfe32e6b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -0,0 +1,520 @@
+/*
+ * linux/arch/arm/mach-omap2/board-am3517evm.c
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ * Author: Ranjith Lohithakshan <ranjithl@ti.com>
+ *
+ * Based on mach-omap2/board-omap3evm.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/can/platform/ti_hecc.h>
+#include <linux/davinci_emac.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <mach/am35xx.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
+
+#include "mux.h"
+#include "control.h"
+#include "hsmmc.h"
+
+#define AM35XX_EVM_MDIO_FREQUENCY (1000000)
+
+static struct mdio_platform_data am3517_evm_mdio_pdata = {
+ .bus_freq = AM35XX_EVM_MDIO_FREQUENCY,
+};
+
+static struct resource am3517_mdio_resources[] = {
+ {
+ .start = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET,
+ .end = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET +
+ SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device am3517_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(am3517_mdio_resources),
+ .resource = am3517_mdio_resources,
+ .dev.platform_data = &am3517_evm_mdio_pdata,
+};
+
+static struct emac_platform_data am3517_evm_emac_pdata = {
+ .rmii_en = 1,
+};
+
+static struct resource am3517_emac_resources[] = {
+ {
+ .start = AM35XX_IPSS_EMAC_BASE,
+ .end = AM35XX_IPSS_EMAC_BASE + 0x2FFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
+ .end = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
+ .end = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
+ .end = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
+ .end = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device am3517_emac_device = {
+ .name = "davinci_emac",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(am3517_emac_resources),
+ .resource = am3517_emac_resources,
+};
+
+static void am3517_enable_ethernet_int(void)
+{
+ u32 regval;
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
+ AM35XX_CPGMAC_C0_TX_PULSE_CLR |
+ AM35XX_CPGMAC_C0_MISC_PULSE_CLR |
+ AM35XX_CPGMAC_C0_RX_THRESH_CLR);
+ omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static void am3517_disable_ethernet_int(void)
+{
+ u32 regval;
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
+ AM35XX_CPGMAC_C0_TX_PULSE_CLR);
+ omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
+{
+ unsigned int regval;
+
+ pdata->ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET;
+ pdata->ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET;
+ pdata->ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET;
+ pdata->ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE;
+ pdata->version = EMAC_VERSION_2;
+ pdata->hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR;
+ pdata->interrupt_enable = am3517_enable_ethernet_int;
+ pdata->interrupt_disable = am3517_disable_ethernet_int;
+ am3517_emac_device.dev.platform_data = pdata;
+ platform_device_register(&am3517_emac_device);
+ platform_device_register(&am3517_mdio_device);
+ clk_add_alias(NULL, dev_name(&am3517_mdio_device.dev),
+ NULL, &am3517_emac_device.dev);
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+ regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
+ omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+
+ return ;
+}
+
+
+
+#define LCD_PANEL_PWR 176
+#define LCD_PANEL_BKLIGHT_PWR 182
+#define LCD_PANEL_PWM 181
+
+static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("s35390a", 0x30),
+ },
+};
+
+/*
+ * RTC - S35390A
+ */
+#define GPIO_RTCS35390A_IRQ 55
+
+static void __init am3517_evm_rtc_init(void)
+{
+ int r;
+
+ omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP);
+
+ r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "rtcs35390a-irq");
+ if (r < 0) {
+ printk(KERN_WARNING "failed to request GPIO#%d\n",
+ GPIO_RTCS35390A_IRQ);
+ return;
+ }
+
+ am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ);
+}
+
+/*
+ * I2C GPIO Expander - TCA6416
+ */
+
+/* Mounted on Base-Board */
+static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+};
+static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1A),
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &am3517evm_gpio_expander_info_0,
+ },
+};
+
+/* Mounted on UI Card */
+static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = {
+ .gpio_base = OMAP_MAX_GPIO_LINES + 16,
+};
+static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = {
+ .gpio_base = OMAP_MAX_GPIO_LINES + 32,
+};
+static struct i2c_board_info __initdata am3517evm_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tca6416", 0x20),
+ .platform_data = &am3517evm_ui_gpio_expander_info_1,
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &am3517evm_ui_gpio_expander_info_2,
+ },
+};
+
+static int __init am3517_evm_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 400, NULL, 0);
+ omap_register_i2c_bus(2, 400, am3517evm_i2c2_boardinfo,
+ ARRAY_SIZE(am3517evm_i2c2_boardinfo));
+ omap_register_i2c_bus(3, 400, am3517evm_i2c3_boardinfo,
+ ARRAY_SIZE(am3517evm_i2c3_boardinfo));
+
+ return 0;
+}
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
+ defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
+static struct gpio am3517_evm_dss_gpios[] __initdata = {
+ /* GPIO 182 = LCD Backlight Power */
+ { LCD_PANEL_BKLIGHT_PWR, GPIOF_OUT_INIT_HIGH, "lcd_backlight_pwr" },
+ /* GPIO 181 = LCD Panel PWM */
+ { LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd bl enable" },
+ /* GPIO 176 = LCD Panel Power enable pin */
+ { LCD_PANEL_PWR, GPIOF_OUT_INIT_HIGH, "dvi enable" },
+};
+
+static void __init am3517_evm_display_init(void)
+{
+ int r;
+
+ omap_mux_init_gpio(LCD_PANEL_PWR, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(LCD_PANEL_BKLIGHT_PWR, OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_gpio(LCD_PANEL_PWM, OMAP_PIN_INPUT_PULLDOWN);
+
+ r = gpio_request_array(am3517_evm_dss_gpios,
+ ARRAY_SIZE(am3517_evm_dss_gpios));
+ if (r) {
+ printk(KERN_ERR "failed to get DSS panel control GPIOs\n");
+ return;
+ }
+
+ printk(KERN_INFO "Display initialized successfully\n");
+}
+#else
+static void __init am3517_evm_display_init(void) {}
+#endif
+
+static int am3517_evm_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(LCD_PANEL_PWR, 1);
+ lcd_enabled = 1;
+
+ return 0;
+}
+
+static void am3517_evm_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(LCD_PANEL_PWR, 0);
+ lcd_enabled = 0;
+}
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "sharp_lq",
+ .platform_enable = am3517_evm_panel_enable_lcd,
+ .platform_disable = am3517_evm_panel_disable_lcd,
+};
+
+static struct omap_dss_device am3517_evm_lcd_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 16,
+};
+
+static int am3517_evm_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void am3517_evm_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device am3517_evm_tv_device = {
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .name = "tv",
+ .driver_name = "venc",
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = am3517_evm_panel_enable_tv,
+ .platform_disable = am3517_evm_panel_disable_tv,
+};
+
+static int am3517_evm_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = am3517_evm_panel_enable_dvi,
+ .platform_disable = am3517_evm_panel_disable_dvi,
+};
+
+static struct omap_dss_device am3517_evm_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *am3517_evm_dss_devices[] = {
+ &am3517_evm_lcd_device,
+ &am3517_evm_tv_device,
+ &am3517_evm_dvi_device,
+};
+
+static struct omap_dss_board_info am3517_evm_dss_data = {
+ .num_devices = ARRAY_SIZE(am3517_evm_dss_devices),
+ .devices = am3517_evm_dss_devices,
+ .default_device = &am3517_evm_lcd_device,
+};
+
+/*
+ * Board initialization
+ */
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 500,
+ .set_phy_power = am35x_musb_phy_power,
+ .clear_irq = am35x_musb_clear_irq,
+ .set_mode = am35x_set_mode,
+ .reset = am35x_musb_reset,
+};
+
+static __init void am3517_evm_musb_init(void)
+{
+ u32 devconf2;
+
+ /*
+ * Set up USB clock/mode in the DEVCONF2 register.
+ */
+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+ /* USB2.0 PHY reference clock is 13 MHz */
+ devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE);
+ devconf2 |= CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN
+ | CONF2_DATPOL;
+
+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+
+ usb_musb_init(&musb_board_data);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
+ defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+#else
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+#endif
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 57,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* USB OTG DRVVBUS offset = 0x212 */
+ OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+
+static struct resource am3517_hecc_resources[] = {
+ {
+ .start = AM35XX_IPSS_HECC_BASE,
+ .end = AM35XX_IPSS_HECC_BASE + 0x3FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_HECC0_IRQ,
+ .end = INT_35XX_HECC0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device am3517_hecc_device = {
+ .name = "ti_hecc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(am3517_hecc_resources),
+ .resource = am3517_hecc_resources,
+};
+
+static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
+ .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
+ .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
+ .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
+ .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
+ .int_line = AM35XX_HECC_INT_LINE,
+ .version = AM35XX_HECC_VERSION,
+};
+
+static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata)
+{
+ am3517_hecc_device.dev.platform_data = pdata;
+ platform_device_register(&am3517_hecc_device);
+}
+
+static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = 127,
+ .gpio_wp = 126,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = 128,
+ .gpio_wp = 129,
+ },
+ {} /* Terminator */
+};
+
+
+static void __init am3517_evm_init(void)
+{
+ omap_board_config = am3517_evm_config;
+ omap_board_config_size = ARRAY_SIZE(am3517_evm_config);
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ am3517_evm_i2c_init();
+ omap_display_init(&am3517_evm_dss_data);
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+
+ /* Configure GPIO for EHCI port */
+ omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
+ usbhs_init(&usbhs_bdata);
+ am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
+ /* DSS */
+ am3517_evm_display_init();
+
+ /* RTC - S35390A */
+ am3517_evm_rtc_init();
+
+ i2c_register_board_info(1, am3517evm_i2c1_boardinfo,
+ ARRAY_SIZE(am3517evm_i2c1_boardinfo));
+ /*Ethernet*/
+ am3517_evm_ethernet_init(&am3517_evm_emac_pdata);
+
+ /* MUSB */
+ am3517_evm_musb_init();
+
+ /* MMC init function */
+ omap2_hsmmc_init(mmc);
+}
+
+MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = am35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = am3517_evm_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
new file mode 100644
index 00000000000..ac773829941
--- /dev/null
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/arm/mach-omap2/board-apollon.c
+ *
+ * Copyright (C) 2005,2006 Samsung Electronics
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Modified from mach-omap/omap2/board-h4.c
+ *
+ * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
+ * the bootloader passes the board-specific data to the kernel.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/smc91x.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <plat/led.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include "mux.h"
+#include "control.h"
+
+/* LED & Switch macros */
+#define LED0_GPIO13 13
+#define LED1_GPIO14 14
+#define LED2_GPIO15 15
+#define SW_ENTER_GPIO16 16
+#define SW_UP_GPIO17 17
+#define SW_DOWN_GPIO58 58
+
+#define APOLLON_FLASH_CS 0
+#define APOLLON_ETH_CS 1
+#define APOLLON_ETHR_GPIO_IRQ 74
+
+static struct mtd_partition apollon_partitions[] = {
+ {
+ .name = "X-Loader + U-Boot",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16M,
+ },
+ {
+ .name = "filesystem00",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_32M,
+ },
+ {
+ .name = "filesystem01",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct onenand_platform_data apollon_flash_data = {
+ .parts = apollon_partitions,
+ .nr_parts = ARRAY_SIZE(apollon_partitions),
+};
+
+static struct resource apollon_flash_resource[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device apollon_onenand_device = {
+ .name = "onenand-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &apollon_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(apollon_flash_resource),
+ .resource = apollon_flash_resource,
+};
+
+static void __init apollon_flash_init(void)
+{
+ unsigned long base;
+
+ if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
+ printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
+ return;
+ }
+ apollon_flash_resource[0].start = base;
+ apollon_flash_resource[0].end = base + SZ_128K - 1;
+}
+
+static struct smc91x_platdata appolon_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource apollon_smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
+ .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device apollon_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .dev = {
+ .platform_data = &appolon_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(apollon_smc91x_resources),
+ .resource = apollon_smc91x_resources,
+};
+
+static struct omap_led_config apollon_led_config[] = {
+ {
+ .cdev = {
+ .name = "apollon:led0",
+ },
+ .gpio = LED0_GPIO13,
+ },
+ {
+ .cdev = {
+ .name = "apollon:led1",
+ },
+ .gpio = LED1_GPIO14,
+ },
+ {
+ .cdev = {
+ .name = "apollon:led2",
+ },
+ .gpio = LED2_GPIO15,
+ },
+};
+
+static struct omap_led_platform_data apollon_led_data = {
+ .nr_leds = ARRAY_SIZE(apollon_led_config),
+ .leds = apollon_led_config,
+};
+
+static struct platform_device apollon_led_device = {
+ .name = "omap-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &apollon_led_data,
+ },
+};
+
+static struct platform_device *apollon_devices[] __initdata = {
+ &apollon_onenand_device,
+ &apollon_smc91x_device,
+ &apollon_led_device,
+};
+
+static inline void __init apollon_init_smc91x(void)
+{
+ unsigned long base;
+
+ unsigned int rate;
+ struct clk *gpmc_fck;
+ int eth_cs;
+ int err;
+
+ gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
+ if (IS_ERR(gpmc_fck)) {
+ WARN_ON(1);
+ return;
+ }
+
+ clk_enable(gpmc_fck);
+ rate = clk_get_rate(gpmc_fck);
+
+ eth_cs = APOLLON_ETH_CS;
+
+ /* Make sure CS1 timings are correct */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
+
+ if (rate >= 160000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else if (rate >= 130000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else {/* rate = 100000000 */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
+ }
+
+ if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
+ goto out;
+ }
+ apollon_smc91x_resources[0].start = base + 0x300;
+ apollon_smc91x_resources[0].end = base + 0x30f;
+ udelay(100);
+
+ omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);
+ err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");
+ if (err) {
+ printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+ APOLLON_ETHR_GPIO_IRQ);
+ gpmc_cs_free(APOLLON_ETH_CS);
+ }
+out:
+ clk_disable(gpmc_fck);
+ clk_put(gpmc_fck);
+}
+
+static struct omap_usb_config apollon_usb_config __initdata = {
+ .register_dev = 1,
+ .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
+
+ .pins[0] = 6,
+};
+
+static struct panel_generic_dpi_data apollon_panel_data = {
+ .name = "apollon",
+};
+
+static struct omap_dss_device apollon_lcd_device = {
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 18,
+ .data = &apollon_panel_data,
+};
+
+static struct omap_dss_device *apollon_dss_devices[] = {
+ &apollon_lcd_device,
+};
+
+static struct omap_dss_board_info apollon_dss_data = {
+ .num_devices = ARRAY_SIZE(apollon_dss_devices),
+ .devices = apollon_dss_devices,
+ .default_device = &apollon_lcd_device,
+};
+
+static struct gpio apollon_gpio_leds[] __initdata = {
+ { LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
+ { LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6 */
+ { LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4 */
+};
+
+static void __init apollon_led_init(void)
+{
+ omap_mux_init_signal("vlynq_clk.gpio_13", 0);
+ omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
+ omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
+
+ gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));
+}
+
+static void __init apollon_usb_init(void)
+{
+ /* USB device */
+ /* DEVICE_SUSPEND */
+ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
+ gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");
+ omap2_usbfs_init(&apollon_usb_config);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap_apollon_init(void)
+{
+ u32 v;
+
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+
+ apollon_init_smc91x();
+ apollon_led_init();
+ apollon_flash_init();
+ apollon_usb_init();
+
+ /* REVISIT: where's the correct place */
+ omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);
+
+ /* LCD PWR_EN */
+ omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
+
+ /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
+ v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ v |= (1 << 24);
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on
+ * if not needed.
+ */
+ platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ omap_display_init(&apollon_dss_data);
+}
+
+MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
+ /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = omap_apollon_init,
+ .timer = &omap2_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
new file mode 100644
index 00000000000..d73316ed420
--- /dev/null
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -0,0 +1,687 @@
+/*
+ * CompuLab CM-T35/CM-T3730 modules support
+ *
+ * Copyright (C) 2009-2011 CompuLab, Ltd.
+ * Authors: Mike Rapoport <mike@compulab.co.il>
+ * Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/at24.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/nand.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
+#include <plat/mcspi.h>
+
+#include <mach/hardware.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define CM_T35_GPIO_PENDOWN 57
+#define SB_T35_USB_HUB_RESET_GPIO 167
+
+#define CM_T35_SMSC911X_CS 5
+#define CM_T35_SMSC911X_GPIO 163
+#define SB_T35_SMSC911X_CS 4
+#define SB_T35_SMSC911X_GPIO 65
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = {
+ .id = 0,
+ .cs = CM_T35_SMSC911X_CS,
+ .gpio_irq = CM_T35_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = {
+ .id = 1,
+ .cs = SB_T35_SMSC911X_CS,
+ .gpio_irq = SB_T35_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static void __init cm_t35_init_ethernet(void)
+{
+ gpmc_smsc911x_init(&cm_t35_smsc911x_cfg);
+ gpmc_smsc911x_init(&sb_t35_smsc911x_cfg);
+}
+#else
+static inline void __init cm_t35_init_ethernet(void) { return; }
+#endif
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led cm_t35_leds[] = {
+ [0] = {
+ .gpio = 186,
+ .name = "cm-t35:green",
+ .default_trigger = "heartbeat",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data cm_t35_led_pdata = {
+ .num_leds = ARRAY_SIZE(cm_t35_leds),
+ .leds = cm_t35_leds,
+};
+
+static struct platform_device cm_t35_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t35_led_pdata,
+ },
+};
+
+static void __init cm_t35_init_led(void)
+{
+ platform_device_register(&cm_t35_led_device);
+}
+#else
+static inline void cm_t35_init_led(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+static struct mtd_partition cm_t35_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data cm_t35_nand_data = {
+ .parts = cm_t35_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_t35_nand_partitions),
+ .cs = 0,
+};
+
+static void __init cm_t35_init_nand(void)
+{
+ if (gpmc_nand_init(&cm_t35_nand_data) < 0)
+ pr_err("CM-T35: Unable to register NAND device\n");
+}
+#else
+static inline void cm_t35_init_nand(void) {}
+#endif
+
+#define CM_T35_LCD_EN_GPIO 157
+#define CM_T35_LCD_BL_GPIO 58
+#define CM_T35_DVI_EN_GPIO 54
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static int cm_t35_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
+ gpio_set_value(CM_T35_LCD_BL_GPIO, 1);
+
+ lcd_enabled = 1;
+
+ return 0;
+}
+
+static void cm_t35_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ lcd_enabled = 0;
+
+ gpio_set_value(CM_T35_LCD_BL_GPIO, 0);
+ gpio_set_value(CM_T35_LCD_EN_GPIO, 0);
+}
+
+static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(CM_T35_DVI_EN_GPIO, 0);
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void cm_t35_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(CM_T35_DVI_EN_GPIO, 1);
+ dvi_enabled = 0;
+}
+
+static int cm_t35_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void cm_t35_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "toppoly_tdo35s",
+ .platform_enable = cm_t35_panel_enable_lcd,
+ .platform_disable = cm_t35_panel_disable_lcd,
+};
+
+static struct omap_dss_device cm_t35_lcd_device = {
+ .name = "lcd",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 18,
+};
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = cm_t35_panel_enable_dvi,
+ .platform_disable = cm_t35_panel_disable_dvi,
+};
+
+static struct omap_dss_device cm_t35_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device cm_t35_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = cm_t35_panel_enable_tv,
+ .platform_disable = cm_t35_panel_disable_tv,
+};
+
+static struct omap_dss_device *cm_t35_dss_devices[] = {
+ &cm_t35_lcd_device,
+ &cm_t35_dvi_device,
+ &cm_t35_tv_device,
+};
+
+static struct omap_dss_board_info cm_t35_dss_data = {
+ .num_devices = ARRAY_SIZE(cm_t35_dss_devices),
+ .devices = cm_t35_dss_devices,
+ .default_device = &cm_t35_dvi_device,
+};
+
+static struct omap2_mcspi_device_config tdo24m_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct tdo24m_platform_data tdo24m_config = {
+ .model = TDO35S,
+};
+
+static struct spi_board_info cm_t35_lcd_spi_board_info[] __initdata = {
+ {
+ .modalias = "tdo24m",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 1000000,
+ .controller_data = &tdo24m_mcspi_config,
+ .platform_data = &tdo24m_config,
+ },
+};
+
+static struct gpio cm_t35_dss_gpios[] __initdata = {
+ { CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW, "lcd enable" },
+ { CM_T35_LCD_BL_GPIO, GPIOF_OUT_INIT_LOW, "lcd bl enable" },
+ { CM_T35_DVI_EN_GPIO, GPIOF_OUT_INIT_HIGH, "dvi enable" },
+};
+
+static void __init cm_t35_init_display(void)
+{
+ int err;
+
+ spi_register_board_info(cm_t35_lcd_spi_board_info,
+ ARRAY_SIZE(cm_t35_lcd_spi_board_info));
+
+ err = gpio_request_array(cm_t35_dss_gpios,
+ ARRAY_SIZE(cm_t35_dss_gpios));
+ if (err) {
+ pr_err("CM-T35: failed to request DSS control GPIOs\n");
+ return;
+ }
+
+ gpio_export(CM_T35_LCD_EN_GPIO, 0);
+ gpio_export(CM_T35_LCD_BL_GPIO, 0);
+ gpio_export(CM_T35_DVI_EN_GPIO, 0);
+
+ msleep(50);
+ gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
+
+ err = omap_display_init(&cm_t35_dss_data);
+ if (err) {
+ pr_err("CM-T35: failed to register DSS device\n");
+ gpio_free_array(cm_t35_dss_gpios, ARRAY_SIZE(cm_t35_dss_gpios));
+ }
+}
+
+static struct regulator_consumer_supply cm_t35_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply cm_t35_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply cm_t35_vio_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data cm_t35_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cm_t35_vmmc1_supply),
+ .consumer_supplies = cm_t35_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data cm_t35_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cm_t35_vsim_supply),
+ .consumer_supplies = cm_t35_vsim_supply,
+};
+
+static struct regulator_init_data cm_t35_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cm_t35_vio_supplies),
+ .consumer_supplies = cm_t35_vio_supplies,
+};
+
+static uint32_t cm_t35_keymap[] = {
+ KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT),
+ KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN),
+ KEY(2, 0, KEY_RIGHT), KEY(2, 1, KEY_C), KEY(2, 2, KEY_D),
+};
+
+static struct matrix_keymap_data cm_t35_keymap_data = {
+ .keymap = cm_t35_keymap,
+ .keymap_size = ARRAY_SIZE(cm_t35_keymap),
+};
+
+static struct twl4030_keypad_data cm_t35_kp_data = {
+ .keymap_data = &cm_t35_keymap_data,
+ .rows = 3,
+ .cols = 3,
+ .rep = 1,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .transceiver = 1,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .ocr_mask = 0x00100000, /* 3.3V */
+ },
+ {} /* Terminator */
+};
+
+static struct usbhs_omap_board_data usbhs_bdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6,
+ .reset_gpio_port[1] = OMAP_MAX_GPIO_LINES + 7,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void __init cm_t35_init_usbh(void)
+{
+ int err;
+
+ err = gpio_request_one(SB_T35_USB_HUB_RESET_GPIO,
+ GPIOF_OUT_INIT_LOW, "usb hub rst");
+ if (err) {
+ pr_err("SB-T35: usb hub rst gpio request failed: %d\n", err);
+ } else {
+ udelay(10);
+ gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1);
+ msleep(1);
+ }
+
+ usbhs_init(&usbhs_bdata);
+}
+
+static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
+ unsigned ngpio)
+{
+ int wlan_rst = gpio + 2;
+
+ if (gpio_request_one(wlan_rst, GPIOF_OUT_INIT_HIGH, "WLAN RST") == 0) {
+ gpio_export(wlan_rst, 0);
+ udelay(10);
+ gpio_set_value_cansleep(wlan_rst, 0);
+ udelay(10);
+ gpio_set_value_cansleep(wlan_rst, 1);
+ } else {
+ pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
+ }
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = cm_t35_twl_gpio_setup,
+};
+
+static struct twl4030_platform_data cm_t35_twldata = {
+ /* platform_data for children goes here */
+ .keypad = &cm_t35_kp_data,
+ .gpio = &cm_t35_gpio_data,
+ .vmmc1 = &cm_t35_vmmc1,
+ .vsim = &cm_t35_vsim,
+ .vio = &cm_t35_vio,
+};
+
+static void __init cm_t35_init_i2c(void)
+{
+ omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB,
+ TWL_COMMON_REGULATOR_VDAC |
+ TWL_COMMON_PDATA_AUDIO);
+
+ omap3_pmic_init("tps65930", &cm_t35_twldata);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* nCS and IRQ for CM-T35 ethernet */
+ OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0),
+ OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+ /* nCS and IRQ for SB-T35 ethernet */
+ OMAP3_MUX(GPMC_NCS4, OMAP_MUX_MODE0),
+ OMAP3_MUX(GPMC_WAIT3, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+ /* PENDOWN GPIO */
+ OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* mUSB */
+ OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* MMC 2 */
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+
+ /* McSPI 1 */
+ OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+
+ /* McSPI 4 */
+ OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP),
+
+ /* McBSP 2 */
+ OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* serial ports */
+ OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* common DSS */
+ OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* display controls */
+ OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* TPS IRQ */
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
+ OMAP_PIN_INPUT_PULLUP),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static void __init cm_t3x_common_dss_mux_init(int mux_mode)
+{
+ omap_mux_init_signal("dss_data18", mux_mode);
+ omap_mux_init_signal("dss_data19", mux_mode);
+ omap_mux_init_signal("dss_data20", mux_mode);
+ omap_mux_init_signal("dss_data21", mux_mode);
+ omap_mux_init_signal("dss_data22", mux_mode);
+ omap_mux_init_signal("dss_data23", mux_mode);
+}
+
+static void __init cm_t35_init_mux(void)
+{
+ int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT;
+
+ omap_mux_init_signal("dss_data0.dss_data0", mux_mode);
+ omap_mux_init_signal("dss_data1.dss_data1", mux_mode);
+ omap_mux_init_signal("dss_data2.dss_data2", mux_mode);
+ omap_mux_init_signal("dss_data3.dss_data3", mux_mode);
+ omap_mux_init_signal("dss_data4.dss_data4", mux_mode);
+ omap_mux_init_signal("dss_data5.dss_data5", mux_mode);
+ cm_t3x_common_dss_mux_init(mux_mode);
+}
+
+static void __init cm_t3730_init_mux(void)
+{
+ int mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT;
+
+ omap_mux_init_signal("sys_boot0", mux_mode);
+ omap_mux_init_signal("sys_boot1", mux_mode);
+ omap_mux_init_signal("sys_boot3", mux_mode);
+ omap_mux_init_signal("sys_boot4", mux_mode);
+ omap_mux_init_signal("sys_boot5", mux_mode);
+ omap_mux_init_signal("sys_boot6", mux_mode);
+ cm_t3x_common_dss_mux_init(mux_mode);
+}
+#else
+static inline void cm_t35_init_mux(void) {}
+static inline void cm_t3730_init_mux(void) {}
+#endif
+
+static struct omap_board_config_kernel cm_t35_config[] __initdata = {
+};
+
+static void __init cm_t3x_common_init(void)
+{
+ omap_board_config = cm_t35_config;
+ omap_board_config_size = ARRAY_SIZE(cm_t35_config);
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ cm_t35_init_i2c();
+ omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
+ cm_t35_init_ethernet();
+ cm_t35_init_led();
+ cm_t35_init_display();
+
+ usb_musb_init(NULL);
+ cm_t35_init_usbh();
+}
+
+static void __init cm_t35_init(void)
+{
+ cm_t3x_common_init();
+ cm_t35_init_mux();
+ cm_t35_init_nand();
+}
+
+static void __init cm_t3730_init(void)
+{
+ cm_t3x_common_init();
+ cm_t3730_init_mux();
+}
+
+MACHINE_START(CM_T35, "Compulab CM-T35")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = cm_t35_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(CM_T3730, "Compulab CM-T3730")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = cm_t3730_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
new file mode 100644
index 00000000000..f36d694d215
--- /dev/null
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -0,0 +1,306 @@
+/*
+ * linux/arch/arm/mach-omap2/board-cm-t3517.c
+ *
+ * Support for the CompuLab CM-T3517 modules
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Author: Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/rtc-v3020.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/can/platform/ti_hecc.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/usb.h>
+#include <plat/nand.h>
+#include <plat/gpmc.h>
+
+#include <mach/am35xx.h>
+
+#include "mux.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cm_t3517_leds[] = {
+ [0] = {
+ .gpio = 186,
+ .name = "cm-t3517:green",
+ .default_trigger = "heartbeat",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data cm_t3517_led_pdata = {
+ .num_leds = ARRAY_SIZE(cm_t3517_leds),
+ .leds = cm_t3517_leds,
+};
+
+static struct platform_device cm_t3517_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t3517_led_pdata,
+ },
+};
+
+static void __init cm_t3517_init_leds(void)
+{
+ platform_device_register(&cm_t3517_led_device);
+}
+#else
+static inline void cm_t3517_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE)
+static struct resource cm_t3517_hecc_resources[] = {
+ {
+ .start = AM35XX_IPSS_HECC_BASE,
+ .end = AM35XX_IPSS_HECC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_HECC0_IRQ,
+ .end = INT_35XX_HECC0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ti_hecc_platform_data cm_t3517_hecc_pdata = {
+ .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
+ .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
+ .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
+ .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
+ .int_line = AM35XX_HECC_INT_LINE,
+ .version = AM35XX_HECC_VERSION,
+};
+
+static struct platform_device cm_t3517_hecc_device = {
+ .name = "ti_hecc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(cm_t3517_hecc_resources),
+ .resource = cm_t3517_hecc_resources,
+ .dev = {
+ .platform_data = &cm_t3517_hecc_pdata,
+ },
+};
+
+static void cm_t3517_init_hecc(void)
+{
+ platform_device_register(&cm_t3517_hecc_device);
+}
+#else
+static inline void cm_t3517_init_hecc(void) {}
+#endif
+
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
+#define RTC_IO_GPIO (153)
+#define RTC_WR_GPIO (154)
+#define RTC_RD_GPIO (53)
+#define RTC_CS_GPIO (163)
+#define RTC_CS_EN_GPIO (160)
+
+struct v3020_platform_data cm_t3517_v3020_pdata = {
+ .use_gpio = 1,
+ .gpio_cs = RTC_CS_GPIO,
+ .gpio_wr = RTC_WR_GPIO,
+ .gpio_rd = RTC_RD_GPIO,
+ .gpio_io = RTC_IO_GPIO,
+};
+
+static struct platform_device cm_t3517_rtc_device = {
+ .name = "v3020",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t3517_v3020_pdata,
+ }
+};
+
+static void __init cm_t3517_init_rtc(void)
+{
+ int err;
+
+ err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH,
+ "rtc cs en");
+ if (err) {
+ pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
+ return;
+ }
+
+ platform_device_register(&cm_t3517_rtc_device);
+}
+#else
+static inline void cm_t3517_init_rtc(void) {}
+#endif
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+#define HSUSB1_RESET_GPIO (146)
+#define HSUSB2_RESET_GPIO (147)
+#define USB_HUB_RESET_GPIO (152)
+
+static struct usbhs_omap_board_data cm_t3517_ehci_pdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = HSUSB1_RESET_GPIO,
+ .reset_gpio_port[1] = HSUSB2_RESET_GPIO,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static int __init cm_t3517_init_usbh(void)
+{
+ int err;
+
+ err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW,
+ "usb hub rst");
+ if (err) {
+ pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err);
+ } else {
+ udelay(10);
+ gpio_set_value(USB_HUB_RESET_GPIO, 1);
+ msleep(1);
+ }
+
+ usbhs_init(&cm_t3517_ehci_pdata);
+
+ return 0;
+}
+#else
+static inline int cm_t3517_init_usbh(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+static struct mtd_partition cm_t3517_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data cm_t3517_nand_data = {
+ .parts = cm_t3517_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_t3517_nand_partitions),
+ .cs = 0,
+};
+
+static void __init cm_t3517_init_nand(void)
+{
+ if (gpmc_nand_init(&cm_t3517_nand_data) < 0)
+ pr_err("CM-T3517: NAND initialization failed\n");
+}
+#else
+static inline void cm_t3517_init_nand(void) {}
+#endif
+
+static struct omap_board_config_kernel cm_t3517_config[] __initdata = {
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* GPIO186 - Green LED */
+ OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* RTC GPIOs: */
+ /* IO - GPIO153 */
+ OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* WR# - GPIO154 */
+ OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* RD# - GPIO53 */
+ OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* CS# - GPIO163 */
+ OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* CS EN - GPIO160 */
+ OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* HSUSB1 RESET */
+ OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* HSUSB2 RESET */
+ OMAP3_MUX(UART2_RX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* CM-T3517 USB HUB nRESET */
+ OMAP3_MUX(MCBSP4_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init cm_t3517_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ omap_board_config = cm_t3517_config;
+ omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
+ cm_t3517_init_leds();
+ cm_t3517_init_nand();
+ cm_t3517_init_rtc();
+ cm_t3517_init_usbh();
+ cm_t3517_init_hecc();
+}
+
+MACHINE_START(CM_T3517, "Compulab CM-T3517")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = am35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = cm_t3517_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
new file mode 100644
index 00000000000..e873063f4fd
--- /dev/null
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -0,0 +1,667 @@
+/*
+ * board-devkit8000.c - TimLL Devkit8000
+ *
+ * Copyright (C) 2009 Kim Botherway
+ * Copyright (C) 2010 Thomas Weber
+ *
+ * Modified from mach-omap2/board-omap3beagle.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <mach/id.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
+
+#include <plat/mcspi.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/dm9000.h>
+#include <linux/interrupt.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OMAP_DM9000_GPIO_IRQ 25
+#define OMAP3_DEVKIT_TS_GPIO 27
+
+static struct mtd_partition devkit8000_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {} /* Terminator */
+};
+
+static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void devkit8000_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 0);
+}
+
+static int devkit8000_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void devkit8000_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 0);
+}
+
+static struct regulator_consumer_supply devkit8000_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply devkit8000_vio_supply[] = {
+ REGULATOR_SUPPLY("vcc", "spi2.0"),
+};
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "innolux_at070tn83",
+ .platform_enable = devkit8000_panel_enable_lcd,
+ .platform_disable = devkit8000_panel_disable_lcd,
+};
+
+static struct omap_dss_device devkit8000_lcd_device = {
+ .name = "lcd",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = devkit8000_panel_enable_dvi,
+ .platform_disable = devkit8000_panel_disable_dvi,
+};
+
+static struct omap_dss_device devkit8000_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device devkit8000_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+
+static struct omap_dss_device *devkit8000_dss_devices[] = {
+ &devkit8000_lcd_device,
+ &devkit8000_dvi_device,
+ &devkit8000_tv_device,
+};
+
+static struct omap_dss_board_info devkit8000_dss_data = {
+ .num_devices = ARRAY_SIZE(devkit8000_dss_devices),
+ .devices = devkit8000_dss_devices,
+ .default_device = &devkit8000_lcd_device,
+};
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_1),
+ KEY(1, 0, KEY_2),
+ KEY(2, 0, KEY_3),
+ KEY(0, 1, KEY_4),
+ KEY(1, 1, KEY_5),
+ KEY(2, 1, KEY_6),
+ KEY(3, 1, KEY_F5),
+ KEY(0, 2, KEY_7),
+ KEY(1, 2, KEY_8),
+ KEY(2, 2, KEY_9),
+ KEY(3, 2, KEY_F6),
+ KEY(0, 3, KEY_F7),
+ KEY(1, 3, KEY_0),
+ KEY(2, 3, KEY_F8),
+ PERSISTENT_KEY(4, 5),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ 0
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data devkit8000_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 6,
+ .cols = 6,
+ .rep = 1,
+};
+
+static struct gpio_led gpio_leds[];
+
+static int devkit8000_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
+ devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0;
+ ret = gpio_request_one(devkit8000_lcd_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "LCD_PWREN");
+ if (ret < 0) {
+ devkit8000_lcd_device.reset_gpio = -EINVAL;
+ printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n");
+ }
+
+ /* gpio + 7 is "DVI_PD" (out, active low) */
+ devkit8000_dvi_device.reset_gpio = gpio + 7;
+ ret = gpio_request_one(devkit8000_dvi_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "DVI PowerDown");
+ if (ret < 0) {
+ devkit8000_dvi_device.reset_gpio = -EINVAL;
+ printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n");
+ }
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pulldowns = BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13)
+ | BIT(15) | BIT(16) | BIT(17),
+ .setup = devkit8000_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data devkit8000_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(devkit8000_vmmc1_supply),
+ .consumer_supplies = devkit8000_vmmc1_supply,
+};
+
+/* VPLL1 for digital video outputs */
+static struct regulator_init_data devkit8000_vpll1 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies),
+ .consumer_supplies = devkit8000_vpll1_supplies,
+};
+
+/* VAUX4 for ads7846 and nubs */
+static struct regulator_init_data devkit8000_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(devkit8000_vio_supply),
+ .consumer_supplies = devkit8000_vio_supply,
+};
+
+static struct twl4030_platform_data devkit8000_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &devkit8000_gpio_data,
+ .vmmc1 = &devkit8000_vmmc1,
+ .vpll1 = &devkit8000_vpll1,
+ .vio = &devkit8000_vio,
+ .keypad = &devkit8000_kp_data,
+};
+
+static int __init devkit8000_i2c_init(void)
+{
+ omap3_pmic_get_config(&devkit8000_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC);
+ omap3_pmic_init("tps65930", &devkit8000_twldata);
+ /* Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .gpio = 186,
+ .active_low = true,
+ },
+ {
+ .name = "led2",
+ .default_trigger = "mmc0",
+ .gpio = 163,
+ .active_low = true,
+ },
+ {
+ .name = "ledB",
+ .default_trigger = "none",
+ .gpio = 153,
+ .active_low = true,
+ },
+ {
+ .name = "led3",
+ .default_trigger = "none",
+ .gpio = 164,
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 26,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+#define OMAP_DM9000_BASE 0x2c000000
+
+static struct resource omap_dm9000_resources[] = {
+ [0] = {
+ .start = OMAP_DM9000_BASE,
+ .end = (OMAP_DM9000_BASE + 0x4 - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (OMAP_DM9000_BASE + 0x400),
+ .end = (OMAP_DM9000_BASE + 0x400 + 0x4 - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = OMAP_GPIO_IRQ(OMAP_DM9000_GPIO_IRQ),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct dm9000_plat_data omap_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device omap_dm9000_dev = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap_dm9000_resources),
+ .resource = omap_dm9000_resources,
+ .dev = {
+ .platform_data = &omap_dm9000_platdata,
+ },
+};
+
+static void __init omap_dm9000_init(void)
+{
+ unsigned char *eth_addr = omap_dm9000_platdata.dev_addr;
+ struct omap_die_id odi;
+ int ret;
+
+ ret = gpio_request_one(OMAP_DM9000_GPIO_IRQ, GPIOF_IN, "dm9000 irq");
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n",
+ OMAP_DM9000_GPIO_IRQ);
+ return;
+ }
+
+ /* init the mac address using DIE id */
+ omap_get_die_id(&odi);
+
+ eth_addr[0] = 0x02; /* locally administered */
+ eth_addr[1] = odi.id_1 & 0xff;
+ eth_addr[2] = (odi.id_0 & 0xff000000) >> 24;
+ eth_addr[3] = (odi.id_0 & 0x00ff0000) >> 16;
+ eth_addr[4] = (odi.id_0 & 0x0000ff00) >> 8;
+ eth_addr[5] = (odi.id_0 & 0x000000ff);
+}
+
+static struct platform_device *devkit8000_devices[] __initdata = {
+ &leds_gpio,
+ &keys_gpio,
+ &omap_dm9000_dev,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* nCS and IRQ for Devkit8000 ethernet */
+ OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE0),
+ OMAP3_MUX(ETK_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+ /* McSPI 2*/
+ OMAP3_MUX(MCSPI2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI2_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCSPI2_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI2_CS0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCSPI2_CS1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* PENDOWN GPIO */
+ OMAP3_MUX(ETK_D13, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* mUSB */
+ OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* USB 1 */
+ OMAP3_MUX(ETK_CTL, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(ETK_D8, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D9, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D0, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D7, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+
+ /* MMC 1 */
+ OMAP3_MUX(SDMMC1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* McBSP 2 */
+ OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* I2C 1 */
+ OMAP3_MUX(I2C1_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C1_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* I2C 2 */
+ OMAP3_MUX(I2C2_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* I2C 3 */
+ OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* I2C 4 */
+ OMAP3_MUX(I2C4_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C4_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* serial ports */
+ OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* DSS */
+ OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* expansion port */
+ /* McSPI 1 */
+ OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP3_MUX(MCSPI1_CS3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+
+ /* HDQ */
+ OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* McSPI4 */
+ OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP),
+
+ /* MMC 2 */
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+
+ /* I2C3 */
+ OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* TPS IRQ */
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
+ OMAP_PIN_INPUT_PULLUP),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init devkit8000_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+
+ omap_dm9000_init();
+
+ devkit8000_i2c_init();
+ platform_add_devices(devkit8000_devices,
+ ARRAY_SIZE(devkit8000_devices));
+
+ omap_display_init(&devkit8000_dss_data);
+
+ omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL);
+
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
+ ARRAY_SIZE(devkit8000_nand_partitions));
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = devkit8000_init,
+ .timer = &omap3_secure_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
new file mode 100644
index 00000000000..30a6f527510
--- /dev/null
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -0,0 +1,247 @@
+/*
+ * board-flash.c
+ * Modified from mach-omap2/board-3430sdp-flash.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Vimal Singh <vimalsingh@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <plat/irqs.h>
+
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/onenand.h>
+#include <plat/tc.h>
+
+#include "board-flash.h"
+
+#define REG_FPGA_REV 0x10
+#define REG_FPGA_DIP_SWITCH_INPUT2 0x60
+#define MAX_SUPPORTED_GPMC_CONFIG 3
+
+#define DEBUG_BASE 0x08000000 /* debug board */
+
+/* various memory sizes */
+#define FLASH_SIZE_SDPV1 SZ_64M /* NOR flash (64 Meg aligned) */
+#define FLASH_SIZE_SDPV2 SZ_128M /* NOR flash (256 Meg aligned) */
+
+static struct physmap_flash_data board_nor_data = {
+ .width = 2,
+};
+
+static struct resource board_nor_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device board_nor_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &board_nor_data,
+ },
+ .num_resources = 1,
+ .resource = &board_nor_resource,
+};
+
+static void
+__init board_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
+{
+ int err;
+
+ board_nor_data.parts = nor_parts;
+ board_nor_data.nr_parts = nr_parts;
+
+ /* Configure start address and size of NOR device */
+ if (omap_rev() >= OMAP3430_REV_ES1_0) {
+ err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1,
+ (unsigned long *)&board_nor_resource.start);
+ board_nor_resource.end = board_nor_resource.start
+ + FLASH_SIZE_SDPV2 - 1;
+ } else {
+ err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1,
+ (unsigned long *)&board_nor_resource.start);
+ board_nor_resource.end = board_nor_resource.start
+ + FLASH_SIZE_SDPV1 - 1;
+ }
+ if (err < 0) {
+ pr_err("NOR: Can't request GPMC CS\n");
+ return;
+ }
+ if (platform_device_register(&board_nor_device) < 0)
+ pr_err("Unable to register NOR device\n");
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+static struct omap_onenand_platform_data board_onenand_data = {
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static void
+__init board_onenand_init(struct mtd_partition *onenand_parts,
+ u8 nr_parts, u8 cs)
+{
+ board_onenand_data.cs = cs;
+ board_onenand_data.parts = onenand_parts;
+ board_onenand_data.nr_parts = nr_parts;
+
+ gpmc_onenand_init(&board_onenand_data);
+}
+#else
+static void
+__init board_onenand_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
+{
+}
+#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+
+/* Note that all values in this struct are in nanoseconds */
+static struct gpmc_timings nand_timings = {
+
+ .sync_clk = 0,
+
+ .cs_on = 0,
+ .cs_rd_off = 36,
+ .cs_wr_off = 36,
+
+ .adv_on = 6,
+ .adv_rd_off = 24,
+ .adv_wr_off = 36,
+
+ .we_off = 30,
+ .oe_off = 48,
+
+ .access = 54,
+ .rd_cycle = 72,
+ .wr_cycle = 72,
+
+ .wr_access = 30,
+ .wr_data_mux_bus = 0,
+};
+
+static struct omap_nand_platform_data board_nand_data = {
+ .gpmc_t = &nand_timings,
+};
+
+void
+__init board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type)
+{
+ board_nand_data.cs = cs;
+ board_nand_data.parts = nand_parts;
+ board_nand_data.nr_parts = nr_parts;
+ board_nand_data.devsize = nand_type;
+
+ board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+ board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
+ gpmc_nand_init(&board_nand_data);
+}
+#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
+
+/**
+ * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get
+ * the various cs values.
+ */
+static u8 get_gpmc0_type(void)
+{
+ u8 cs = 0;
+ void __iomem *fpga_map_addr;
+
+ fpga_map_addr = ioremap(DEBUG_BASE, 4096);
+ if (!fpga_map_addr)
+ return -ENOMEM;
+
+ if (!(__raw_readw(fpga_map_addr + REG_FPGA_REV)))
+ /* we dont have an DEBUG FPGA??? */
+ /* Depend on #defines!! default to strata boot return param */
+ goto unmap;
+
+ /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */
+ cs = __raw_readw(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf;
+
+ /* ES2.0 SDP's onwards 4 dip switches are provided for CS */
+ if (omap_rev() >= OMAP3430_REV_ES1_0)
+ /* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */
+ cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) |
+ ((cs & 2) << 1) | ((cs & 1) << 3);
+ else
+ /* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */
+ cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2);
+unmap:
+ iounmap(fpga_map_addr);
+ return cs;
+}
+
+/**
+ * board_flash_init - Identify devices connected to GPMC and register.
+ *
+ * @return - void.
+ */
+void board_flash_init(struct flash_partitions partition_info[],
+ char chip_sel_board[][GPMC_CS_NUM], int nand_type)
+{
+ u8 cs = 0;
+ u8 norcs = GPMC_CS_NUM + 1;
+ u8 nandcs = GPMC_CS_NUM + 1;
+ u8 onenandcs = GPMC_CS_NUM + 1;
+ u8 idx;
+ unsigned char *config_sel = NULL;
+
+ /* REVISIT: Is this return correct idx for 2430 SDP?
+ * for which cs configuration matches for 2430 SDP?
+ */
+ idx = get_gpmc0_type();
+ if (idx >= MAX_SUPPORTED_GPMC_CONFIG) {
+ pr_err("%s: Invalid chip select: %d\n", __func__, cs);
+ return;
+ }
+ config_sel = (unsigned char *)(chip_sel_board[idx]);
+
+ while (cs < GPMC_CS_NUM) {
+ switch (config_sel[cs]) {
+ case PDC_NOR:
+ if (norcs > GPMC_CS_NUM)
+ norcs = cs;
+ break;
+ case PDC_NAND:
+ if (nandcs > GPMC_CS_NUM)
+ nandcs = cs;
+ break;
+ case PDC_ONENAND:
+ if (onenandcs > GPMC_CS_NUM)
+ onenandcs = cs;
+ break;
+ };
+ cs++;
+ }
+
+ if (norcs > GPMC_CS_NUM)
+ pr_err("NOR: Unable to find configuration in GPMC\n");
+ else
+ board_nor_init(partition_info[0].parts,
+ partition_info[0].nr_parts, norcs);
+
+ if (onenandcs > GPMC_CS_NUM)
+ pr_err("OneNAND: Unable to find configuration in GPMC\n");
+ else
+ board_onenand_init(partition_info[1].parts,
+ partition_info[1].nr_parts, onenandcs);
+
+ if (nandcs > GPMC_CS_NUM)
+ pr_err("NAND: Unable to find configuration in GPMC\n");
+ else
+ board_nand_init(partition_info[2].parts,
+ partition_info[2].nr_parts, nandcs, nand_type);
+}
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
new file mode 100644
index 00000000000..d25503a9841
--- /dev/null
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -0,0 +1,49 @@
+/*
+ * board-sdp.h
+ *
+ * Information structures for SDP-specific board config data
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <plat/gpmc.h>
+
+#define PDC_NOR 1
+#define PDC_NAND 2
+#define PDC_ONENAND 3
+#define DBG_MPDB 4
+
+struct flash_partitions {
+ struct mtd_partition *parts;
+ int nr_parts;
+};
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+extern void board_flash_init(struct flash_partitions [],
+ char chip_sel[][GPMC_CS_NUM], int nand_type);
+#else
+static inline void board_flash_init(struct flash_partitions part[],
+ char chip_sel[][GPMC_CS_NUM], int nand_type)
+{
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+extern void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type);
+#else
+static inline void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type)
+{
+}
+#endif
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
new file mode 100644
index 00000000000..ad497620539
--- /dev/null
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Modified from the original mach-omap/omap2/board-generic.c did by Paul
+ * to support the OMAP2+ device tree boards with an unique board file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/irqdomain.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/arch.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include "common-board-devices.h"
+
+/*
+ * XXX: Still needed to boot until the i2c & twl driver is adapted to
+ * device-tree
+ */
+#ifdef CONFIG_ARCH_OMAP4
+static struct twl4030_platform_data sdp4430_twldata = {
+ .irq_base = TWL6030_IRQ_BASE,
+ .irq_end = TWL6030_IRQ_END,
+};
+
+static void __init omap4_i2c_init(void)
+{
+ omap4_pmic_init("twl6030", &sdp4430_twldata);
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct twl4030_platform_data beagle_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+};
+
+static void __init omap3_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &beagle_twldata);
+}
+#endif
+
+static struct of_device_id omap_dt_match_table[] __initdata = {
+ { .compatible = "simple-bus", },
+ { .compatible = "ti,omap-infra", },
+ { }
+};
+
+static struct of_device_id intc_match[] __initdata = {
+ { .compatible = "ti,omap3-intc", },
+ { .compatible = "arm,cortex-a9-gic", },
+ { }
+};
+
+static void __init omap_generic_init(void)
+{
+ struct device_node *node = of_find_matching_node(NULL, intc_match);
+ if (node)
+ irq_domain_add_simple(node, 0);
+
+ omap_sdrc_init(NULL, NULL);
+
+ of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
+}
+
+#ifdef CONFIG_ARCH_OMAP4
+static void __init omap4_init(void)
+{
+ omap4_i2c_init();
+ omap_generic_init();
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static void __init omap3_init(void)
+{
+ omap3_i2c_init();
+ omap_generic_init();
+}
+#endif
+
+#if defined(CONFIG_SOC_OMAP2420)
+static const char *omap242x_boards_compat[] __initdata = {
+ "ti,omap2420",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap2_timer,
+ .dt_compat = omap242x_boards_compat,
+ .restart = omap_prcm_restart,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_SOC_OMAP2430)
+static const char *omap243x_boards_compat[] __initdata = {
+ "ti,omap2430",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap243x_map_io,
+ .init_early = omap2430_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap2_timer,
+ .dt_compat = omap243x_boards_compat,
+ .restart = omap_prcm_restart,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+static const char *omap3_boards_compat[] __initdata = {
+ "ti,omap3",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3_init,
+ .timer = &omap3_timer,
+ .dt_compat = omap3_boards_compat,
+ .restart = omap_prcm_restart,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4)
+static const char *omap4_boards_compat[] __initdata = {
+ "ti,omap4",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
+ .init_irq = gic_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = omap4_init,
+ .timer = &omap4_timer,
+ .dt_compat = omap4_boards_compat,
+ .restart = omap_prcm_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
new file mode 100644
index 00000000000..54af800d143
--- /dev/null
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -0,0 +1,403 @@
+/*
+ * linux/arch/arm/mach-omap2/board-h4.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/input.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/input/matrix_keypad.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/usb.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/menelaus.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include "mux.h"
+#include "control.h"
+
+#define H4_FLASH_CS 0
+#define H4_SMC91X_CS 1
+
+#define H4_ETHR_GPIO_IRQ 92
+
+#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
+static const uint32_t board_matrix_keys[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_A),
+ KEY(3, 0, KEY_B),
+ KEY(4, 0, KEY_C),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(2, 1, KEY_E),
+ KEY(3, 1, KEY_F),
+ KEY(4, 1, KEY_G),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(3, 2, KEY_K),
+ KEY(4, 2, KEY_3),
+ KEY(0, 3, KEY_M),
+ KEY(1, 3, KEY_N),
+ KEY(2, 3, KEY_O),
+ KEY(3, 3, KEY_P),
+ KEY(4, 3, KEY_Q),
+ KEY(0, 4, KEY_R),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_T),
+ KEY(3, 4, KEY_U),
+ KEY(4, 4, KEY_ENTER),
+ KEY(0, 5, KEY_V),
+ KEY(1, 5, KEY_W),
+ KEY(2, 5, KEY_L),
+ KEY(3, 5, KEY_S),
+ KEY(4, 5, KEY_ENTER),
+};
+
+static const struct matrix_keymap_data board_keymap_data = {
+ .keymap = board_matrix_keys,
+ .keymap_size = ARRAY_SIZE(board_matrix_keys),
+};
+
+static unsigned int board_keypad_row_gpios[] = {
+ 88, 89, 124, 11, 6, 96
+};
+
+static unsigned int board_keypad_col_gpios[] = {
+ 90, 91, 100, 36, 12, 97, 98
+};
+
+static struct matrix_keypad_platform_data board_keypad_platform_data = {
+ .keymap_data = &board_keymap_data,
+ .row_gpios = board_keypad_row_gpios,
+ .num_row_gpios = ARRAY_SIZE(board_keypad_row_gpios),
+ .col_gpios = board_keypad_col_gpios,
+ .num_col_gpios = ARRAY_SIZE(board_keypad_col_gpios),
+ .active_low = 1,
+
+ .debounce_ms = 20,
+ .col_scan_delay_us = 5,
+};
+
+static struct platform_device board_keyboard = {
+ .name = "matrix-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &board_keypad_platform_data,
+ },
+};
+static void __init board_mkp_init(void)
+{
+ omap_mux_init_gpio(88, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_gpio(89, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_gpio(124, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
+ if (omap_has_menelaus()) {
+ omap_mux_init_signal("sdrc_a14.gpio0",
+ OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
+ omap_mux_init_signal("gpio_98", 0);
+ board_keypad_row_gpios[5] = 0;
+ board_keypad_col_gpios[2] = 15;
+ board_keypad_col_gpios[6] = 18;
+ } else {
+ omap_mux_init_signal("gpio_96", OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("gpio_100", 0);
+ omap_mux_init_signal("gpio_98", 0);
+ }
+ omap_mux_init_signal("gpio_90", 0);
+ omap_mux_init_signal("gpio_91", 0);
+ omap_mux_init_signal("gpio_36", 0);
+ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
+ omap_mux_init_signal("gpio_97", 0);
+
+ platform_device_register(&board_keyboard);
+}
+#else
+static inline void board_mkp_init(void)
+{
+}
+#endif
+
+static struct mtd_partition h4_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data h4_flash_data = {
+ .width = 2,
+ .parts = h4_partitions,
+ .nr_parts = ARRAY_SIZE(h4_partitions),
+};
+
+static struct resource h4_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device h4_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &h4_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &h4_flash_resource,
+};
+
+static struct platform_device *h4_devices[] __initdata = {
+ &h4_flash_device,
+};
+
+static struct panel_generic_dpi_data h4_panel_data = {
+ .name = "h4",
+};
+
+static struct omap_dss_device h4_lcd_device = {
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 16,
+ .data = &h4_panel_data,
+};
+
+static struct omap_dss_device *h4_dss_devices[] = {
+ &h4_lcd_device,
+};
+
+static struct omap_dss_board_info h4_dss_data = {
+ .num_devices = ARRAY_SIZE(h4_dss_devices),
+ .devices = h4_dss_devices,
+ .default_device = &h4_lcd_device,
+};
+
+/* 2420 Sysboot setup (2430 is different) */
+static u32 get_sysboot_value(void)
+{
+ return (omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
+ (OMAP2_SYSBOOT_5_MASK | OMAP2_SYSBOOT_4_MASK |
+ OMAP2_SYSBOOT_3_MASK | OMAP2_SYSBOOT_2_MASK |
+ OMAP2_SYSBOOT_1_MASK | OMAP2_SYSBOOT_0_MASK));
+}
+
+/* H4-2420's always used muxed mode, H4-2422's always use non-muxed
+ *
+ * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423
+ * correctly. The macro needs to look at production_id not just hawkeye.
+ */
+static u32 is_gpmc_muxed(void)
+{
+ u32 mux;
+ mux = get_sysboot_value();
+ if ((mux & 0xF) == 0xd)
+ return 1; /* NAND config (could be either) */
+ if (mux & 0x2) /* if mux'ed */
+ return 1;
+ else
+ return 0;
+}
+
+static inline void __init h4_init_debug(void)
+{
+ int eth_cs;
+ unsigned long cs_mem_base;
+ unsigned int muxed, rate;
+ struct clk *gpmc_fck;
+
+ eth_cs = H4_SMC91X_CS;
+
+ gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
+ if (IS_ERR(gpmc_fck)) {
+ WARN_ON(1);
+ return;
+ }
+
+ clk_enable(gpmc_fck);
+ rate = clk_get_rate(gpmc_fck);
+ clk_disable(gpmc_fck);
+ clk_put(gpmc_fck);
+
+ if (is_gpmc_muxed())
+ muxed = 0x200;
+ else
+ muxed = 0;
+
+ /* Make sure CS1 timings are correct */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1,
+ 0x00011000 | muxed);
+
+ if (rate >= 160000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else if (rate >= 130000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else {/* rate = 100000000 */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
+ }
+
+ if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+ goto out;
+ }
+
+ udelay(100);
+
+ omap_mux_init_gpio(92, 0);
+ if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ) < 0)
+ gpmc_cs_free(eth_cs);
+
+out:
+ clk_disable(gpmc_fck);
+ clk_put(gpmc_fck);
+}
+
+static void __init h4_init_flash(void)
+{
+ unsigned long base;
+
+ if (gpmc_cs_request(H4_FLASH_CS, SZ_64M, &base) < 0) {
+ printk("Can't request GPMC CS for flash\n");
+ return;
+ }
+ h4_flash_resource.start = base;
+ h4_flash_resource.end = base + SZ_64M - 1;
+}
+
+static struct omap_usb_config h4_usb_config __initdata = {
+ /* S1.10 OFF -- usb "download port"
+ * usb0 switched to Mini-B port and isp1105 transceiver;
+ * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging
+ */
+ .register_dev = 1,
+ .pins[0] = 3,
+/* .hmc_mode = 0x14,*/ /* 0:dev 1:host 2:disable */
+ .hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */
+};
+
+static struct at24_platform_data m24c01 = {
+ .byte_len = SZ_1K / 8,
+ .page_size = 16,
+};
+
+static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ .irq = OMAP_GPIO_IRQ(125),
+ },
+ { /* EEPROM on mainboard */
+ I2C_BOARD_INFO("24c01", 0x52),
+ .platform_data = &m24c01,
+ },
+ { /* EEPROM on cpu card */
+ I2C_BOARD_INFO("24c01", 0x57),
+ .platform_data = &m24c01,
+ },
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap_h4_init(void)
+{
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on
+ * if not needed.
+ */
+
+ board_mkp_init();
+ i2c_register_board_info(1, h4_i2c_board_info,
+ ARRAY_SIZE(h4_i2c_board_info));
+
+ platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
+ omap2_usbfs_init(&h4_usb_config);
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ h4_init_flash();
+
+ omap_display_init(&h4_dss_data);
+}
+
+MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
+ /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = omap_h4_init,
+ .timer = &omap2_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
new file mode 100644
index 00000000000..a59ace0ed56
--- /dev/null
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2009 Integration Software and Electronic Engineering.
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-dvi.h>
+#include <plat/onenand.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "sdram-numonyx-m65kxxxxam.h"
+#include "common-board-devices.h"
+
+#define IGEP2_SMSC911X_CS 5
+#define IGEP2_SMSC911X_GPIO 176
+#define IGEP2_GPIO_USBH_NRESET 24
+#define IGEP2_GPIO_LED0_GREEN 26
+#define IGEP2_GPIO_LED0_RED 27
+#define IGEP2_GPIO_LED1_RED 28
+#define IGEP2_GPIO_DVI_PUP 170
+
+#define IGEP2_RB_GPIO_WIFI_NPD 94
+#define IGEP2_RB_GPIO_WIFI_NRESET 95
+#define IGEP2_RB_GPIO_BT_NRESET 137
+#define IGEP2_RC_GPIO_WIFI_NPD 138
+#define IGEP2_RC_GPIO_WIFI_NRESET 139
+#define IGEP2_RC_GPIO_BT_NRESET 137
+
+#define IGEP3_GPIO_LED0_GREEN 54
+#define IGEP3_GPIO_LED0_RED 53
+#define IGEP3_GPIO_LED1_RED 16
+#define IGEP3_GPIO_USBH_NRESET 183
+
+/*
+ * IGEP2 Hardware Revision Table
+ *
+ * --------------------------------------------------------------------------
+ * | Id. | Hw Rev. | HW0 (28) | WIFI_NPD | WIFI_NRESET | BT_NRESET |
+ * --------------------------------------------------------------------------
+ * | 0 | B | high | gpio94 | gpio95 | - |
+ * | 0 | B/C (B-compatible) | high | gpio94 | gpio95 | gpio137 |
+ * | 1 | C | low | gpio138 | gpio139 | gpio137 |
+ * --------------------------------------------------------------------------
+ */
+
+#define IGEP2_BOARD_HWREV_B 0
+#define IGEP2_BOARD_HWREV_C 1
+#define IGEP3_BOARD_HWREV 2
+
+static u8 hwrev;
+
+static void __init igep2_get_revision(void)
+{
+ u8 ret;
+
+ if (machine_is_igep0030()) {
+ hwrev = IGEP3_BOARD_HWREV;
+ return;
+ }
+
+ omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT);
+
+ if (gpio_request_one(IGEP2_GPIO_LED1_RED, GPIOF_IN, "GPIO_HW0_REV")) {
+ pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n");
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ return;
+ }
+
+ ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
+ if (ret == 0) {
+ pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_C;
+ } else if (ret == 1) {
+ pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_B;
+ } else {
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ hwrev = -1;
+ }
+
+ gpio_free(IGEP2_GPIO_LED1_RED);
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+#define ONENAND_MAP 0x20000000
+
+/* NAND04GR4E1A ( x2 Flash built-in COMBO POP MEMORY )
+ * Since the device is equipped with two DataRAMs, and two-plane NAND
+ * Flash memory array, these two component enables simultaneous program
+ * of 4KiB. Plane1 has only even blocks such as block0, block2, block4
+ * while Plane2 has only odd blocks such as block1, block3, block5.
+ * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
+ */
+
+static struct mtd_partition igep_onenand_partitions[] = {
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 2 * (64*(2*2048))
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 6 * (64*(2*2048)),
+ },
+ {
+ .name = "Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64*(2*2048)),
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 12 * (64*(2*2048)),
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data igep_onenand_data = {
+ .parts = igep_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(igep_onenand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device igep_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep_onenand_data,
+ },
+};
+
+static void __init igep_flash_init(void)
+{
+ u8 cs = 0;
+ u8 onenandcs = GPMC_CS_NUM + 1;
+
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ u32 ret;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /* Check if NAND/oneNAND is configured */
+ if ((ret & 0xC00) == 0x800)
+ /* NAND found */
+ pr_err("IGEP: Unsupported NAND found\n");
+ else {
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+ /* ONENAND found */
+ onenandcs = cs;
+ }
+ }
+
+ if (onenandcs > GPMC_CS_NUM) {
+ pr_err("IGEP: Unable to find configuration in GPMC\n");
+ return;
+ }
+
+ igep_onenand_data.cs = onenandcs;
+
+ if (platform_device_register(&igep_onenand_device) < 0)
+ pr_err("IGEP: Unable to register OneNAND device\n");
+}
+
+#else
+static void __init igep_flash_init(void) {}
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = IGEP2_SMSC911X_CS,
+ .gpio_irq = IGEP2_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static inline void __init igep2_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+#else
+static inline void __init igep2_init_smsc911x(void) { }
+#endif
+
+static struct regulator_consumer_supply igep_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data igep_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(igep_vmmc1_supply),
+ .consumer_supplies = igep_vmmc1_supply,
+};
+
+static struct regulator_consumer_supply igep_vio_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"),
+};
+
+static struct regulator_init_data igep_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(igep_vio_supply),
+ .consumer_supplies = igep_vio_supply,
+};
+
+static struct regulator_consumer_supply igep_vmmc2_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+static struct regulator_init_data igep_vmmc2 = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(igep_vmmc2_supply),
+ .consumer_supplies = igep_vmmc2_supply,
+};
+
+static struct fixed_voltage_config igep_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .enabled_at_boot = 1,
+ .init_data = &igep_vmmc2,
+};
+
+static struct platform_device igep_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &igep_vwlan,
+ },
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+#endif
+ {} /* Terminator */
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep_gpio_leds[] = {
+ [0] = {
+ .name = "gpio-led:red:d0",
+ .default_trigger = "default-off"
+ },
+ [1] = {
+ .name = "gpio-led:green:d0",
+ .default_trigger = "default-off",
+ },
+ [2] = {
+ .name = "gpio-led:red:d1",
+ .default_trigger = "default-off",
+ },
+ [3] = {
+ .name = "gpio-led:green:d1",
+ .default_trigger = "heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data igep_led_pdata = {
+ .leds = igep_gpio_leds,
+ .num_leds = ARRAY_SIZE(igep_gpio_leds),
+};
+
+static struct platform_device igep_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep_led_pdata,
+ },
+};
+
+static void __init igep_leds_init(void)
+{
+ if (machine_is_igep0020()) {
+ igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
+ } else {
+ igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
+ }
+
+ platform_device_register(&igep_led_device);
+}
+
+#else
+static struct gpio igep_gpio_leds[] __initdata = {
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d0" },
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:green:d0" },
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d1" },
+};
+
+static inline void igep_leds_init(void)
+{
+ int i;
+
+ if (machine_is_igep0020()) {
+ igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
+ } else {
+ igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
+ }
+
+ if (gpio_request_array(igep_gpio_leds, ARRAY_SIZE(igep_gpio_leds))) {
+ pr_warning("IGEP v2: Could not obtain leds gpios\n");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(igep_gpio_leds); i++)
+ gpio_export(igep_gpio_leds[i].gpio, 0);
+}
+#endif
+
+static struct gpio igep2_twl_gpios[] = {
+ { -EINVAL, GPIOF_IN, "GPIO_EHCI_NOC" },
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "GPIO_USBH_CPEN" },
+};
+
+static int igep_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+ ret = gpio_request_one(gpio + TWL4030_GPIO_MAX + 1, GPIOF_OUT_INIT_HIGH,
+ "gpio-led:green:d1");
+ if (ret == 0)
+ gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
+ else
+ pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n");
+#else
+ igep_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
+
+ if (machine_is_igep0030())
+ return 0;
+
+ /*
+ * REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ igep2_twl_gpios[0].gpio = gpio + 1;
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */
+ igep2_twl_gpios[1].gpio = gpio + TWL4030_GPIO_MAX;
+
+ ret = gpio_request_array(igep2_twl_gpios, ARRAY_SIZE(igep2_twl_gpios));
+ if (ret < 0)
+ pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
+
+ return 0;
+};
+
+static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = igep_twl_gpio_setup,
+};
+
+static int igep2_enable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1);
+
+ return 0;
+}
+
+static void igep2_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0);
+}
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = igep2_enable_dvi,
+ .platform_disable = igep2_disable_dvi,
+ .i2c_bus_num = 3,
+};
+
+static struct omap_dss_device igep2_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *igep2_dss_devices[] = {
+ &igep2_dvi_device
+};
+
+static struct omap_dss_board_info igep2_dss_data = {
+ .num_devices = ARRAY_SIZE(igep2_dss_devices),
+ .devices = igep2_dss_devices,
+ .default_device = &igep2_dvi_device,
+};
+
+static void __init igep2_display_init(void)
+{
+ int err = gpio_request_one(IGEP2_GPIO_DVI_PUP, GPIOF_OUT_INIT_HIGH,
+ "GPIO_DVI_PUP");
+ if (err)
+ pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
+}
+
+static struct platform_device *igep_devices[] __initdata = {
+ &igep_vwlan_device,
+};
+
+static int igep2_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_A),
+ KEY(0, 3, KEY_B),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_F),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_K),
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data igep2_keymap_data = {
+ .keymap = igep2_keymap,
+ .keymap_size = ARRAY_SIZE(igep2_keymap),
+};
+
+static struct twl4030_keypad_data igep2_keypad_pdata = {
+ .keymap_data = &igep2_keymap_data,
+ .rows = 4,
+ .cols = 4,
+ .rep = 1,
+};
+
+static struct twl4030_platform_data igep_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &igep_twl4030_gpio_pdata,
+ .vmmc1 = &igep_vmmc1,
+ .vio = &igep_vio,
+};
+
+static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static void __init igep_i2c_init(void)
+{
+ int ret;
+
+ omap3_pmic_get_config(&igep_twldata, TWL_COMMON_PDATA_USB, 0);
+
+ if (machine_is_igep0020()) {
+ /*
+ * Bus 3 is attached to the DVI port where devices like the
+ * pico DLP projector don't work reliably with 400kHz
+ */
+ ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
+ ARRAY_SIZE(igep2_i2c3_boardinfo));
+ if (ret)
+ pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
+
+ igep_twldata.keypad = &igep2_keypad_pdata;
+ /* Get common pmic data */
+ omap3_pmic_get_config(&igep_twldata, TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VPLL2);
+ igep_twldata.vpll2->constraints.apply_uV = true;
+ igep_twldata.vpll2->constraints.name = "VDVI";
+ }
+
+ omap3_pmic_init("twl4030", &igep_twldata);
+}
+
+static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+static struct gpio igep_wlan_bt_gpios[] __initdata = {
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NPD" },
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NRESET" },
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_BT_NRESET" },
+};
+
+static void __init igep_wlan_bt_init(void)
+{
+ int err;
+
+ /* GPIO's for WLAN-BT combo depends on hardware revision */
+ if (hwrev == IGEP2_BOARD_HWREV_B) {
+ igep_wlan_bt_gpios[0].gpio = IGEP2_RB_GPIO_WIFI_NPD;
+ igep_wlan_bt_gpios[1].gpio = IGEP2_RB_GPIO_WIFI_NRESET;
+ igep_wlan_bt_gpios[2].gpio = IGEP2_RB_GPIO_BT_NRESET;
+ } else if (hwrev == IGEP2_BOARD_HWREV_C || machine_is_igep0030()) {
+ igep_wlan_bt_gpios[0].gpio = IGEP2_RC_GPIO_WIFI_NPD;
+ igep_wlan_bt_gpios[1].gpio = IGEP2_RC_GPIO_WIFI_NRESET;
+ igep_wlan_bt_gpios[2].gpio = IGEP2_RC_GPIO_BT_NRESET;
+ } else
+ return;
+
+ err = gpio_request_array(igep_wlan_bt_gpios,
+ ARRAY_SIZE(igep_wlan_bt_gpios));
+ if (err) {
+ pr_warning("IGEP2: Could not obtain WIFI/BT gpios\n");
+ return;
+ }
+
+ gpio_export(igep_wlan_bt_gpios[0].gpio, 0);
+ gpio_export(igep_wlan_bt_gpios[1].gpio, 0);
+ gpio_export(igep_wlan_bt_gpios[2].gpio, 0);
+
+ gpio_set_value(igep_wlan_bt_gpios[1].gpio, 0);
+ udelay(10);
+ gpio_set_value(igep_wlan_bt_gpios[1].gpio, 1);
+
+}
+#else
+static inline void __init igep_wlan_bt_init(void) { }
+#endif
+
+static void __init igep_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ /* Get IGEP2 hardware revision */
+ igep2_get_revision();
+ /* Register I2C busses and drivers */
+ igep_i2c_init();
+ platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
+ omap_serial_init();
+ omap_sdrc_init(m65kxxxxam_sdrc_params,
+ m65kxxxxam_sdrc_params);
+ usb_musb_init(NULL);
+
+ igep_flash_init();
+ igep_leds_init();
+
+ /*
+ * WLAN-BT combo module from MuRata which has a Marvell WLAN
+ * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
+ */
+ igep_wlan_bt_init();
+
+ if (machine_is_igep0020()) {
+ omap_display_init(&igep2_dss_data);
+ igep2_display_init();
+ igep2_init_smsc911x();
+ usbhs_init(&igep2_usbhs_bdata);
+ } else {
+ usbhs_init(&igep3_usbhs_bdata);
+ }
+}
+
+MACHINE_START(IGEP0020, "IGEP v2 board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = igep_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(IGEP0030, "IGEP OMAP3 module")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = igep_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
new file mode 100644
index 00000000000..2d2a61f7dcb
--- /dev/null
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -0,0 +1,441 @@
+/*
+ * linux/arch/arm/mach-omap2/board-ldp.c
+ *
+ * Copyright (C) 2008 Texas Instruments Inc.
+ * Nishant Kamat <nskamat@ti.com>
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio_keys.h>
+#include <linux/workqueue.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/mmc/host.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+#include <mach/board-zoom.h>
+
+#include <asm/delay.h>
+#include <plat/usb.h>
+#include <plat/gpmc-smsc911x.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "hsmmc.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#define LDP_SMSC911X_CS 1
+#define LDP_SMSC911X_GPIO 152
+#define DEBUG_BASE 0x08000000
+#define LDP_ETHR_START DEBUG_BASE
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_1),
+ KEY(1, 0, KEY_2),
+ KEY(2, 0, KEY_3),
+ KEY(0, 1, KEY_4),
+ KEY(1, 1, KEY_5),
+ KEY(2, 1, KEY_6),
+ KEY(3, 1, KEY_F5),
+ KEY(0, 2, KEY_7),
+ KEY(1, 2, KEY_8),
+ KEY(2, 2, KEY_9),
+ KEY(3, 2, KEY_F6),
+ KEY(0, 3, KEY_F7),
+ KEY(1, 3, KEY_0),
+ KEY(2, 3, KEY_F8),
+ PERSISTENT_KEY(4, 5),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ 0
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data ldp_kp_twl4030_data = {
+ .keymap_data = &board_map_data,
+ .rows = 6,
+ .cols = 6,
+ .rep = 1,
+};
+
+static struct gpio_keys_button ldp_gpio_keys_buttons[] = {
+ [0] = {
+ .code = KEY_ENTER,
+ .gpio = 101,
+ .desc = "enter sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [1] = {
+ .code = KEY_F1,
+ .gpio = 102,
+ .desc = "func 1",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [2] = {
+ .code = KEY_F2,
+ .gpio = 103,
+ .desc = "func 2",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [3] = {
+ .code = KEY_F3,
+ .gpio = 104,
+ .desc = "func 3",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [4] = {
+ .code = KEY_F4,
+ .gpio = 105,
+ .desc = "func 4",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [5] = {
+ .code = KEY_LEFT,
+ .gpio = 106,
+ .desc = "left sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [6] = {
+ .code = KEY_RIGHT,
+ .gpio = 107,
+ .desc = "right sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [7] = {
+ .code = KEY_UP,
+ .gpio = 108,
+ .desc = "up sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [8] = {
+ .code = KEY_DOWN,
+ .gpio = 109,
+ .desc = "down sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+};
+
+static struct gpio_keys_platform_data ldp_gpio_keys = {
+ .buttons = ldp_gpio_keys_buttons,
+ .nbuttons = ARRAY_SIZE(ldp_gpio_keys_buttons),
+ .rep = 1,
+};
+
+static struct platform_device ldp_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &ldp_gpio_keys,
+ },
+};
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = LDP_SMSC911X_CS,
+ .gpio_irq = LDP_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static inline void __init ldp_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+/* LCD */
+
+static int ldp_backlight_gpio;
+static int ldp_lcd_enable_gpio;
+
+#define LCD_PANEL_RESET_GPIO 55
+#define LCD_PANEL_QVGA_GPIO 56
+
+static int ldp_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(ldp_lcd_enable_gpio))
+ gpio_direction_output(ldp_lcd_enable_gpio, 1);
+ if (gpio_is_valid(ldp_backlight_gpio))
+ gpio_direction_output(ldp_backlight_gpio, 1);
+
+ return 0;
+}
+
+static void ldp_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(ldp_lcd_enable_gpio))
+ gpio_direction_output(ldp_lcd_enable_gpio, 0);
+ if (gpio_is_valid(ldp_backlight_gpio))
+ gpio_direction_output(ldp_backlight_gpio, 0);
+}
+
+static struct panel_generic_dpi_data ldp_panel_data = {
+ .name = "nec_nl2432dr22-11b",
+ .platform_enable = ldp_panel_enable_lcd,
+ .platform_disable = ldp_panel_disable_lcd,
+};
+
+static struct omap_dss_device ldp_lcd_device = {
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 18,
+ .data = &ldp_panel_data,
+};
+
+static struct omap_dss_device *ldp_dss_devices[] = {
+ &ldp_lcd_device,
+};
+
+static struct omap_dss_board_info ldp_dss_data = {
+ .num_devices = ARRAY_SIZE(ldp_dss_devices),
+ .devices = ldp_dss_devices,
+ .default_device = &ldp_lcd_device,
+};
+
+static void __init ldp_display_init(void)
+{
+ int r;
+
+ static struct gpio gpios[] __initdata = {
+ {LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"},
+ {LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"},
+ };
+
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r) {
+ pr_err("Cannot request LCD GPIOs, error %d\n", r);
+ return;
+ }
+
+ omap_display_init(&ldp_dss_data);
+}
+
+static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
+{
+ int r;
+
+ struct gpio gpios[] = {
+ {gpio + 7 , GPIOF_OUT_INIT_LOW, "LCD ENABLE"},
+ {gpio + 15, GPIOF_OUT_INIT_LOW, "LCD BACKLIGHT"},
+ };
+
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r) {
+ pr_err("Cannot request LCD GPIOs, error %d\n", r);
+ ldp_backlight_gpio = -EINVAL;
+ ldp_lcd_enable_gpio = -EINVAL;
+ return r;
+ }
+
+ ldp_backlight_gpio = gpio + 15;
+ ldp_lcd_enable_gpio = gpio + 7;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data ldp_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = ldp_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply ldp_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data ldp_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldp_vmmc1_supply),
+ .consumer_supplies = ldp_vmmc1_supply,
+};
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply ldp_vaux1_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+/* VAUX1 */
+static struct regulator_init_data ldp_vaux1 = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldp_vaux1_supplies),
+ .consumer_supplies = ldp_vaux1_supplies,
+};
+
+static struct regulator_consumer_supply ldp_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_init_data ldp_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldp_vpll2_supplies),
+ .consumer_supplies = ldp_vpll2_supplies,
+};
+
+static struct twl4030_platform_data ldp_twldata = {
+ /* platform_data for children goes here */
+ .vmmc1 = &ldp_vmmc1,
+ .vaux1 = &ldp_vaux1,
+ .vpll2 = &ldp_vpll2,
+ .gpio = &ldp_gpio_data,
+ .keypad = &ldp_kp_twl4030_data,
+};
+
+static int __init omap_i2c_init(void)
+{
+ omap3_pmic_get_config(&ldp_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC, 0);
+ omap3_pmic_init("twl4030", &ldp_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static struct platform_device *ldp_devices[] __initdata = {
+ &ldp_gpio_keys_device,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct mtd_partition ldp_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048), /* 512KB, 0x80000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 2 * (64 * 2048), /* 256KB, 0x40000 */
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/
+ .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */
+ },
+ {
+ .name = "File System - NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */
+ .size = MTDPART_SIZ_FULL, /* 96MB, 0x6000000 */
+ },
+
+};
+
+static void __init omap_ldp_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ ldp_init_smsc911x();
+ omap_i2c_init();
+ platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
+ omap_ads7846_init(1, 54, 310, NULL);
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ usb_musb_init(NULL);
+ board_nand_init(ldp_nand_partitions,
+ ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
+
+ omap2_hsmmc_init(mmc);
+ ldp_display_init();
+}
+
+MACHINE_START(OMAP_LDP, "OMAP LDP board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap_ldp_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
new file mode 100644
index 00000000000..67226271760
--- /dev/null
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -0,0 +1,724 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n8x0.c
+ *
+ * Copyright (C) 2005-2009 Nokia Corporation
+ * Author: Juha Yrjola <juha.yrjola@nokia.com>
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/musb.h>
+#include <sound/tlv320aic3x.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/menelaus.h>
+#include <mach/irqs.h>
+#include <plat/mcspi.h>
+#include <plat/onenand.h>
+#include <plat/mmc.h>
+#include <plat/serial.h>
+
+#include "mux.h"
+
+static int slot1_cover_open;
+static int slot2_cover_open;
+static struct device *mmc_device;
+
+#define TUSB6010_ASYNC_CS 1
+#define TUSB6010_SYNC_CS 4
+#define TUSB6010_GPIO_INT 58
+#define TUSB6010_GPIO_ENABLE 0
+#define TUSB6010_DMACHAN 0x3f
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+/*
+ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+ * provide then PGOOD signal to TUSB6010 which will release it from reset.
+ */
+static int tusb_set_power(int state)
+{
+ int i, retval = 0;
+
+ if (state) {
+ gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
+ msleep(1);
+
+ /* Wait until TUSB6010 pulls INT pin down */
+ i = 100;
+ while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
+ msleep(1);
+ i--;
+ }
+
+ if (!i) {
+ printk(KERN_ERR "tusb: powerup failed\n");
+ retval = -ENODEV;
+ }
+ } else {
+ gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
+ msleep(10);
+ }
+
+ return retval;
+}
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+static struct musb_hdrc_platform_data tusb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+ .mode = MUSB_PERIPHERAL,
+#else /* defined(CONFIG_USB_MUSB_HOST) */
+ .mode = MUSB_HOST,
+#endif
+ .set_power = tusb_set_power,
+ .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */
+ .power = 100, /* Max 100 mA VBUS for host mode */
+ .config = &musb_config,
+};
+
+static void __init n8x0_usb_init(void)
+{
+ int ret = 0;
+ static char announce[] __initdata = KERN_INFO "TUSB 6010\n";
+
+ /* PM companion chip power control pin */
+ ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW,
+ "TUSB6010 enable");
+ if (ret != 0) {
+ printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+ TUSB6010_GPIO_ENABLE);
+ return;
+ }
+ tusb_set_power(0);
+
+ ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+ TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
+ TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
+ if (ret != 0)
+ goto err;
+
+ printk(announce);
+
+ return;
+
+err:
+ gpio_free(TUSB6010_GPIO_ENABLE);
+}
+#else
+
+static void __init n8x0_usb_init(void) {}
+
+#endif /*CONFIG_USB_MUSB_TUSB6010 */
+
+
+static struct omap2_mcspi_device_config p54spi_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct spi_board_info n800_spi_board_info[] __initdata = {
+ {
+ .modalias = "p54spi",
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 48000000,
+ .controller_data = &p54spi_mcspi_config,
+ },
+};
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+static struct mtd_partition onenand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x20000,
+ .mask_flags = MTD_WRITEABLE, /* Force read-only */
+ },
+ {
+ .name = "config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x60000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x200000,
+ },
+ {
+ .name = "initfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x400000,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .cs = 0,
+ .gpio_irq = 26,
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .flags = ONENAND_SYNC_READ,
+ }
+};
+#endif
+
+#if defined(CONFIG_MENELAUS) && \
+ (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE))
+
+/*
+ * On both N800 and N810, only the first of the two MMC controllers is in use.
+ * The two MMC slots are multiplexed via Menelaus companion chip over I2C.
+ * On N800, both slots are powered via Menelaus. On N810, only one of the
+ * slots is powered via Menelaus. The N810 EMMC is powered via GPIO.
+ *
+ * VMMC slot 1 on both N800 and N810
+ * VDCDC3_APE and VMCS2_APE slot 2 on N800
+ * GPIO23 and GPIO9 slot 2 EMMC on N810
+ *
+ */
+#define N8X0_SLOT_SWITCH_GPIO 96
+#define N810_EMMC_VSD_GPIO 23
+#define N810_EMMC_VIO_GPIO 9
+
+static int n8x0_mmc_switch_slot(struct device *dev, int slot)
+{
+#ifdef CONFIG_MMC_DEBUG
+ dev_dbg(dev, "Choose slot %d\n", slot + 1);
+#endif
+ gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot);
+ return 0;
+}
+
+static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ int mV;
+
+#ifdef CONFIG_MMC_DEBUG
+ dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
+ power_on ? "on" : "off", vdd);
+#endif
+ if (slot == 0) {
+ if (!power_on)
+ return menelaus_set_vmmc(0);
+ switch (1 << vdd) {
+ case MMC_VDD_33_34:
+ case MMC_VDD_32_33:
+ case MMC_VDD_31_32:
+ mV = 3100;
+ break;
+ case MMC_VDD_30_31:
+ mV = 3000;
+ break;
+ case MMC_VDD_28_29:
+ mV = 2800;
+ break;
+ case MMC_VDD_165_195:
+ mV = 1850;
+ break;
+ default:
+ BUG();
+ }
+ return menelaus_set_vmmc(mV);
+ } else {
+ if (!power_on)
+ return menelaus_set_vdcdc(3, 0);
+ switch (1 << vdd) {
+ case MMC_VDD_33_34:
+ case MMC_VDD_32_33:
+ mV = 3300;
+ break;
+ case MMC_VDD_30_31:
+ case MMC_VDD_29_30:
+ mV = 3000;
+ break;
+ case MMC_VDD_28_29:
+ case MMC_VDD_27_28:
+ mV = 2800;
+ break;
+ case MMC_VDD_24_25:
+ case MMC_VDD_23_24:
+ mV = 2400;
+ break;
+ case MMC_VDD_22_23:
+ case MMC_VDD_21_22:
+ mV = 2200;
+ break;
+ case MMC_VDD_20_21:
+ mV = 2000;
+ break;
+ case MMC_VDD_165_195:
+ mV = 1800;
+ break;
+ default:
+ BUG();
+ }
+ return menelaus_set_vdcdc(3, mV);
+ }
+ return 0;
+}
+
+static void n810_set_power_emmc(struct device *dev,
+ int power_on)
+{
+ dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off");
+
+ if (power_on) {
+ gpio_set_value(N810_EMMC_VSD_GPIO, 1);
+ msleep(1);
+ gpio_set_value(N810_EMMC_VIO_GPIO, 1);
+ msleep(1);
+ } else {
+ gpio_set_value(N810_EMMC_VIO_GPIO, 0);
+ msleep(50);
+ gpio_set_value(N810_EMMC_VSD_GPIO, 0);
+ msleep(50);
+ }
+}
+
+static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (machine_is_nokia_n800() || slot == 0)
+ return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd);
+
+ n810_set_power_emmc(dev, power_on);
+
+ return 0;
+}
+
+static int n8x0_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
+{
+ int r;
+
+ dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
+ bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
+ BUG_ON(slot != 0 && slot != 1);
+ slot++;
+ switch (bus_mode) {
+ case MMC_BUSMODE_OPENDRAIN:
+ r = menelaus_set_mmc_opendrain(slot, 1);
+ break;
+ case MMC_BUSMODE_PUSHPULL:
+ r = menelaus_set_mmc_opendrain(slot, 0);
+ break;
+ default:
+ BUG();
+ }
+ if (r != 0 && printk_ratelimit())
+ dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
+ slot);
+ return r;
+}
+
+static int n8x0_mmc_get_cover_state(struct device *dev, int slot)
+{
+ slot++;
+ BUG_ON(slot != 1 && slot != 2);
+ if (slot == 1)
+ return slot1_cover_open;
+ else
+ return slot2_cover_open;
+}
+
+static void n8x0_mmc_callback(void *data, u8 card_mask)
+{
+ int bit, *openp, index;
+
+ if (machine_is_nokia_n800()) {
+ bit = 1 << 1;
+ openp = &slot2_cover_open;
+ index = 1;
+ } else {
+ bit = 1;
+ openp = &slot1_cover_open;
+ index = 0;
+ }
+
+ if (card_mask & bit)
+ *openp = 1;
+ else
+ *openp = 0;
+
+#ifdef CONFIG_MMC_OMAP
+ omap_mmc_notify_cover_event(mmc_device, index, *openp);
+#else
+ pr_warn("MMC: notify cover event not available\n");
+#endif
+}
+
+static int n8x0_mmc_late_init(struct device *dev)
+{
+ int r, bit, *openp;
+ int vs2sel;
+
+ mmc_device = dev;
+
+ r = menelaus_set_slot_sel(1);
+ if (r < 0)
+ return r;
+
+ if (machine_is_nokia_n800())
+ vs2sel = 0;
+ else
+ vs2sel = 2;
+
+ r = menelaus_set_mmc_slot(2, 0, vs2sel, 1);
+ if (r < 0)
+ return r;
+
+ n8x0_mmc_set_power(dev, 0, MMC_POWER_ON, 16); /* MMC_VDD_28_29 */
+ n8x0_mmc_set_power(dev, 1, MMC_POWER_ON, 16);
+
+ r = menelaus_set_mmc_slot(1, 1, 0, 1);
+ if (r < 0)
+ return r;
+ r = menelaus_set_mmc_slot(2, 1, vs2sel, 1);
+ if (r < 0)
+ return r;
+
+ r = menelaus_get_slot_pin_states();
+ if (r < 0)
+ return r;
+
+ if (machine_is_nokia_n800()) {
+ bit = 1 << 1;
+ openp = &slot2_cover_open;
+ } else {
+ bit = 1;
+ openp = &slot1_cover_open;
+ slot2_cover_open = 0;
+ }
+
+ /* All slot pin bits seem to be inversed until first switch change */
+ if (r == 0xf || r == (0xf & ~bit))
+ r = ~r;
+
+ if (r & bit)
+ *openp = 1;
+ else
+ *openp = 0;
+
+ r = menelaus_register_mmc_callback(n8x0_mmc_callback, NULL);
+
+ return r;
+}
+
+static void n8x0_mmc_shutdown(struct device *dev)
+{
+ int vs2sel;
+
+ if (machine_is_nokia_n800())
+ vs2sel = 0;
+ else
+ vs2sel = 2;
+
+ menelaus_set_mmc_slot(1, 0, 0, 0);
+ menelaus_set_mmc_slot(2, 0, vs2sel, 0);
+}
+
+static void n8x0_mmc_cleanup(struct device *dev)
+{
+ menelaus_unregister_mmc_callback();
+
+ gpio_free(N8X0_SLOT_SWITCH_GPIO);
+
+ if (machine_is_nokia_n810()) {
+ gpio_free(N810_EMMC_VSD_GPIO);
+ gpio_free(N810_EMMC_VIO_GPIO);
+ }
+}
+
+/*
+ * MMC controller1 has two slots that are multiplexed via I2C.
+ * MMC controller2 is not in use.
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 2,
+ .switch_slot = n8x0_mmc_switch_slot,
+ .init = n8x0_mmc_late_init,
+ .cleanup = n8x0_mmc_cleanup,
+ .shutdown = n8x0_mmc_shutdown,
+ .max_freq = 24000000,
+ .dma_mask = 0xffffffff,
+ .slots[0] = {
+ .wires = 4,
+ .set_power = n8x0_mmc_set_power,
+ .set_bus_mode = n8x0_mmc_set_bus_mode,
+ .get_cover_state = n8x0_mmc_get_cover_state,
+ .ocr_mask = MMC_VDD_165_195 | MMC_VDD_30_31 |
+ MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "internal",
+ },
+ .slots[1] = {
+ .set_power = n8x0_mmc_set_power,
+ .set_bus_mode = n8x0_mmc_set_bus_mode,
+ .get_cover_state = n8x0_mmc_get_cover_state,
+ .ocr_mask = MMC_VDD_165_195 | MMC_VDD_20_21 |
+ MMC_VDD_21_22 | MMC_VDD_22_23 |
+ MMC_VDD_23_24 | MMC_VDD_24_25 |
+ MMC_VDD_27_28 | MMC_VDD_28_29 |
+ MMC_VDD_29_30 | MMC_VDD_30_31 |
+ MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "external",
+ },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
+
+static struct gpio n810_emmc_gpios[] __initdata = {
+ { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" },
+ { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" },
+};
+
+static void __init n8x0_mmc_init(void)
+{
+ int err;
+
+ if (machine_is_nokia_n810()) {
+ mmc1_data.slots[0].name = "external";
+
+ /*
+ * Some Samsung Movinand chips do not like open-ended
+ * multi-block reads and fall to braind-dead state
+ * while doing so. Reducing the number of blocks in
+ * the transfer or delays in clock disable do not help
+ */
+ mmc1_data.slots[1].name = "internal";
+ mmc1_data.slots[1].ban_openended = 1;
+ }
+
+ err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW,
+ "MMC slot switch");
+ if (err)
+ return;
+
+ if (machine_is_nokia_n810()) {
+ err = gpio_request_array(n810_emmc_gpios,
+ ARRAY_SIZE(n810_emmc_gpios));
+ if (err) {
+ gpio_free(N8X0_SLOT_SWITCH_GPIO);
+ return;
+ }
+ }
+
+ mmc_data[0] = &mmc1_data;
+ omap242x_init_mmc(mmc_data);
+}
+#else
+
+void __init n8x0_mmc_init(void)
+{
+}
+#endif /* CONFIG_MMC_OMAP */
+
+#ifdef CONFIG_MENELAUS
+
+static int n8x0_auto_sleep_regulators(void)
+{
+ u32 val;
+ int ret;
+
+ val = EN_VPLL_SLEEP | EN_VMMC_SLEEP \
+ | EN_VAUX_SLEEP | EN_VIO_SLEEP \
+ | EN_VMEM_SLEEP | EN_DC3_SLEEP \
+ | EN_VC_SLEEP | EN_DC2_SLEEP;
+
+ ret = menelaus_set_regulator_sleep(1, val);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not set regulators to sleep on "
+ "menelaus: %u\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int n8x0_auto_voltage_scale(void)
+{
+ int ret;
+
+ ret = menelaus_set_vcore_hw(1400, 1050);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not set VCORE voltage on "
+ "menelaus: %u\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+ int ret;
+
+ ret = n8x0_auto_voltage_scale();
+ if (ret < 0)
+ return ret;
+ ret = n8x0_auto_sleep_regulators();
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+#else
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
+ .late_init = n8x0_menelaus_late_init,
+};
+
+static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] __initdata = {
+ {
+ I2C_BOARD_INFO("menelaus", 0x72),
+ .irq = INT_24XX_SYS_NIRQ,
+ .platform_data = &n8x0_menelaus_platform_data,
+ },
+};
+
+static struct aic3x_pdata n810_aic33_data __initdata = {
+ .gpio_reset = 118,
+};
+
+static struct i2c_board_info n810_i2c_board_info_2[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ .platform_data = &n810_aic33_data,
+ },
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* I2S codec port pins for McBSP block */
+ OMAP2420_MUX(EAC_AC_SCLK, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_FS, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_DIN, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_DOUT, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+ {
+ .name = "uart3_rx_irrx.uart3_rx_irrx",
+ .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+ .enable = OMAP_MUX_MODE0,
+ .idle = OMAP_MUX_MODE3 /* Mux as GPIO for idle */
+ },
+};
+
+static inline void board_serial_init(void)
+{
+ struct omap_board_data bdata;
+
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+
+ bdata.id = 0;
+ omap_serial_init_port(&bdata, NULL);
+
+ bdata.id = 1;
+ omap_serial_init_port(&bdata, NULL);
+
+ bdata.id = 2;
+ bdata.pads = serial2_pads;
+ bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
+ omap_serial_init_port(&bdata, NULL);
+}
+
+#else
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init();
+}
+
+#endif
+
+static void __init n8x0_init_machine(void)
+{
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+ /* FIXME: add n810 spi devices */
+ spi_register_board_info(n800_spi_board_info,
+ ARRAY_SIZE(n800_spi_board_info));
+ omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
+ ARRAY_SIZE(n8x0_i2c_board_info_1));
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ if (machine_is_nokia_n810())
+ i2c_register_board_info(2, n810_i2c_board_info_2,
+ ARRAY_SIZE(n810_i2c_board_info_2));
+ board_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ gpmc_onenand_init(board_onenand_data);
+ n8x0_mmc_init();
+ n8x0_usb_init();
+}
+
+MACHINE_START(NOKIA_N800, "Nokia N800")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = n8x0_init_machine,
+ .timer = &omap2_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810, "Nokia N810")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = n8x0_init_machine,
+ .timer = &omap2_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .handle_irq = omap2_intc_handle_irq,
+ .init_machine = n8x0_init_machine,
+ .timer = &omap2_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
new file mode 100644
index 00000000000..7ffcd2839e7
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -0,0 +1,566 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3beagle.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/opp.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <video/omapdss.h>
+#include <video/omap-panel-dvi.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <plat/omap_device.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "pm.h"
+#include "common-board-devices.h"
+
+/*
+ * OMAP3 Beagle revision
+ * Run time detection of Beagle revision is done by reading GPIO.
+ * GPIO ID -
+ * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
+ * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
+ * C4 = GPIO173, GPIO172, GPIO171: 1 0 1
+ * XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
+ */
+enum {
+ OMAP3BEAGLE_BOARD_UNKN = 0,
+ OMAP3BEAGLE_BOARD_AXBX,
+ OMAP3BEAGLE_BOARD_C1_3,
+ OMAP3BEAGLE_BOARD_C4,
+ OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
+};
+
+static u8 omap3_beagle_version;
+
+/*
+ * Board-specific configuration
+ * Defaults to BeagleBoard-xMC
+ */
+static struct {
+ int mmc1_gpio_wp;
+ int usb_pwr_level;
+ int reset_gpio;
+ int usr_button_gpio;
+} beagle_config = {
+ .mmc1_gpio_wp = -EINVAL,
+ .usb_pwr_level = GPIOF_OUT_INIT_LOW,
+ .reset_gpio = 129,
+ .usr_button_gpio = 4,
+};
+
+static struct gpio omap3_beagle_rev_gpios[] __initdata = {
+ { 171, GPIOF_IN, "rev_id_0" },
+ { 172, GPIOF_IN, "rev_id_1" },
+ { 173, GPIOF_IN, "rev_id_2" },
+};
+
+static void __init omap3_beagle_init_rev(void)
+{
+ int ret;
+ u16 beagle_rev = 0;
+
+ omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
+
+ ret = gpio_request_array(omap3_beagle_rev_gpios,
+ ARRAY_SIZE(omap3_beagle_rev_gpios));
+ if (ret < 0) {
+ printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ return;
+ }
+
+ beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
+ | (gpio_get_value(173) << 2);
+
+ gpio_free_array(omap3_beagle_rev_gpios,
+ ARRAY_SIZE(omap3_beagle_rev_gpios));
+
+ switch (beagle_rev) {
+ case 7:
+ printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
+ beagle_config.mmc1_gpio_wp = 29;
+ beagle_config.reset_gpio = 170;
+ beagle_config.usr_button_gpio = 7;
+ break;
+ case 6:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
+ beagle_config.mmc1_gpio_wp = 23;
+ beagle_config.reset_gpio = 170;
+ beagle_config.usr_button_gpio = 7;
+ break;
+ case 5:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
+ beagle_config.mmc1_gpio_wp = 23;
+ beagle_config.reset_gpio = 170;
+ beagle_config.usr_button_gpio = 7;
+ break;
+ case 0:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ beagle_config.usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
+ default:
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ }
+}
+
+static struct mtd_partition omap3beagle_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+/* DSS */
+
+static int beagle_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 1);
+
+ return 0;
+}
+
+static void beagle_disable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = beagle_enable_dvi,
+ .platform_disable = beagle_disable_dvi,
+ .i2c_bus_num = 3,
+};
+
+static struct omap_dss_device beagle_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = -EINVAL,
+};
+
+static struct omap_dss_device beagle_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static struct omap_dss_device *beagle_dss_devices[] = {
+ &beagle_dvi_device,
+ &beagle_tv_device,
+};
+
+static struct omap_dss_board_info beagle_dss_data = {
+ .num_devices = ARRAY_SIZE(beagle_dss_devices),
+ .devices = beagle_dss_devices,
+ .default_device = &beagle_dvi_device,
+};
+
+static void __init beagle_display_init(void)
+{
+ int r;
+
+ r = gpio_request_one(beagle_dvi_device.reset_gpio, GPIOF_OUT_INIT_LOW,
+ "DVI reset");
+ if (r < 0)
+ printk(KERN_ERR "Unable to get DVI reset GPIO\n");
+}
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply beagle_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply beagle_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct gpio_led gpio_leds[];
+
+static int beagle_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int r;
+
+ if (beagle_config.mmc1_gpio_wp != -EINVAL)
+ omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
+ mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /*
+ * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
+ * high / others active low)
+ * DVI reset GPIO is different between beagle revisions
+ */
+ /* Valid for all -xM revisions */
+ if (cpu_is_omap3630()) {
+ /*
+ * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 2 control varies depending on the board rev as below:
+ * P7/P8 revisions(prototype): Camera EN
+ * A2+ revisions (production): LDO (DVI, serial, led blocks)
+ */
+ r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW,
+ "nDVI_PWR_EN");
+ if (r)
+ pr_err("%s: unable to configure nDVI_PWR_EN\n",
+ __func__);
+ r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
+ "DVI_LDO_EN");
+ if (r)
+ pr_err("%s: unable to configure DVI_LDO_EN\n",
+ __func__);
+ } else {
+ /*
+ * REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
+ pr_err("%s: unable to configure EHCI_nOC\n", __func__);
+ }
+ beagle_dvi_device.reset_gpio = beagle_config.reset_gpio;
+
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level,
+ "nEN_USB_PWR");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data beagle_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+ | BIT(15) | BIT(16) | BIT(17),
+ .setup = beagle_twl_gpio_setup,
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data beagle_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(beagle_vmmc1_supply),
+ .consumer_supplies = beagle_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data beagle_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(beagle_vsim_supply),
+ .consumer_supplies = beagle_vsim_supply,
+};
+
+static struct twl4030_platform_data beagle_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &beagle_gpio_data,
+ .vmmc1 = &beagle_vmmc1,
+ .vsim = &beagle_vsim,
+};
+
+static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static int __init omap3_beagle_i2c_init(void)
+{
+ omap3_pmic_get_config(&beagle_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
+ TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ beagle_twldata.vpll2->constraints.name = "VDVI";
+
+ omap3_pmic_init("twl4030", &beagle_twldata);
+ /* Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz */
+ omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
+ return 0;
+}
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "beagleboard::usr0",
+ .default_trigger = "heartbeat",
+ .gpio = 150,
+ },
+ {
+ .name = "beagleboard::usr1",
+ .default_trigger = "mmc0",
+ .gpio = 149,
+ },
+ {
+ .name = "beagleboard::pmu_stat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ /* Dynamically assigned depending on board */
+ .gpio = -EINVAL,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+static struct platform_device madc_hwmon = {
+ .name = "twl4030_madc_hwmon",
+ .id = -1,
+};
+
+static struct platform_device *omap3_beagle_devices[] __initdata = {
+ &leds_gpio,
+ &keys_gpio,
+ &madc_hwmon,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 147,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init beagle_opp_init(void)
+{
+ int r = 0;
+
+ /* Initialize the omap3 opp table */
+ if (omap3_opp_init()) {
+ pr_err("%s: opp default init failed\n", __func__);
+ return;
+ }
+
+ /* Custom OPP enabled for all xM versions */
+ if (cpu_is_omap3630()) {
+ struct device *mpu_dev, *iva_dev;
+
+ mpu_dev = omap_device_get_by_hwmod_name("mpu");
+ iva_dev = omap_device_get_by_hwmod_name("iva");
+
+ if (!mpu_dev || !iva_dev) {
+ pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
+ __func__, mpu_dev, iva_dev);
+ return;
+ }
+ /* Enable MPU 1GHz and lower opps */
+ r = opp_enable(mpu_dev, 800000000);
+ /* TODO: MPU 1GHz needs SR and ABB */
+
+ /* Enable IVA 800MHz and lower opps */
+ r |= opp_enable(iva_dev, 660000000);
+ /* TODO: DSP 800MHz needs SR and ABB */
+ if (r) {
+ pr_err("%s: failed to enable higher opp %d\n",
+ __func__, r);
+ /*
+ * Cleanup - disable the higher freqs - we dont care
+ * about the results
+ */
+ opp_disable(mpu_dev, 800000000);
+ opp_disable(iva_dev, 660000000);
+ }
+ }
+ return;
+}
+
+static void __init omap3_beagle_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3_beagle_init_rev();
+ omap3_beagle_i2c_init();
+
+ gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
+
+ platform_add_devices(omap3_beagle_devices,
+ ARRAY_SIZE(omap3_beagle_devices));
+ omap_display_init(&beagle_dss_data);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+
+ omap_mux_init_gpio(170, OMAP_PIN_INPUT);
+ /* REVISIT leave DVI powered down until it's needed ... */
+ gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
+
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
+ ARRAY_SIZE(omap3beagle_nand_partitions));
+
+ /* Ensure msecure is mux'd to be able to set the RTC. */
+ omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+ beagle_display_init();
+ beagle_opp_init();
+}
+
+MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
+ /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3_beagle_init,
+ .timer = &omap3_secure_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
new file mode 100644
index 00000000000..c877236a844
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -0,0 +1,697 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3evm.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/leds.h>
+#include <linux/interrupt.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/i2c/twl.h>
+#include <linux/usb/otg.h>
+#include <linux/smsc911x.h>
+
+#include <linux/wl12xx.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
+#include <linux/export.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/usb.h>
+#include "common.h"
+#include <plat/mcspi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-dvi.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OMAP3_EVM_TS_GPIO 175
+#define OMAP3_EVM_EHCI_VBUS 22
+#define OMAP3_EVM_EHCI_SELECT 61
+
+#define OMAP3EVM_ETHR_START 0x2c000000
+#define OMAP3EVM_ETHR_SIZE 1024
+#define OMAP3EVM_ETHR_ID_REV 0x50
+#define OMAP3EVM_ETHR_GPIO_IRQ 176
+#define OMAP3EVM_SMSC911X_CS 5
+/*
+ * Eth Reset signal
+ * 64 = Generation 1 (<=RevD)
+ * 7 = Generation 2 (>=RevE)
+ */
+#define OMAP3EVM_GEN1_ETHR_GPIO_RST 64
+#define OMAP3EVM_GEN2_ETHR_GPIO_RST 7
+
+static u8 omap3_evm_version;
+
+u8 get_omap3_evm_rev(void)
+{
+ return omap3_evm_version;
+}
+EXPORT_SYMBOL(get_omap3_evm_rev);
+
+static void __init omap3_evm_get_revision(void)
+{
+ void __iomem *ioaddr;
+ unsigned int smsc_id;
+
+ /* Ethernet PHY ID is stored at ID_REV register */
+ ioaddr = ioremap_nocache(OMAP3EVM_ETHR_START, SZ_1K);
+ if (!ioaddr)
+ return;
+ smsc_id = readl(ioaddr + OMAP3EVM_ETHR_ID_REV) & 0xFFFF0000;
+ iounmap(ioaddr);
+
+ switch (smsc_id) {
+ /*SMSC9115 chipset*/
+ case 0x01150000:
+ omap3_evm_version = OMAP3EVM_BOARD_GEN_1;
+ break;
+ /*SMSC 9220 chipset*/
+ case 0x92200000:
+ default:
+ omap3_evm_version = OMAP3EVM_BOARD_GEN_2;
+ }
+}
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = OMAP3EVM_SMSC911X_CS,
+ .gpio_irq = OMAP3EVM_ETHR_GPIO_IRQ,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static inline void __init omap3evm_init_smsc911x(void)
+{
+ struct clk *l3ck;
+ unsigned int rate;
+
+ l3ck = clk_get(NULL, "l3_ck");
+ if (IS_ERR(l3ck))
+ rate = 100000000;
+ else
+ rate = clk_get_rate(l3ck);
+
+ /* Configure ethernet controller reset gpio */
+ if (cpu_is_omap3430()) {
+ if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1)
+ smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST;
+ else
+ smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST;
+ }
+
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+#else
+static inline void __init omap3evm_init_smsc911x(void) { return; }
+#endif
+
+/*
+ * OMAP3EVM LCD Panel control signals
+ */
+#define OMAP3EVM_LCD_PANEL_LR 2
+#define OMAP3EVM_LCD_PANEL_UD 3
+#define OMAP3EVM_LCD_PANEL_INI 152
+#define OMAP3EVM_LCD_PANEL_ENVDD 153
+#define OMAP3EVM_LCD_PANEL_QVGA 154
+#define OMAP3EVM_LCD_PANEL_RESB 155
+#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 210
+#define OMAP3EVM_DVI_PANEL_EN_GPIO 199
+
+static struct gpio omap3_evm_dss_gpios[] __initdata = {
+ { OMAP3EVM_LCD_PANEL_RESB, GPIOF_OUT_INIT_HIGH, "lcd_panel_resb" },
+ { OMAP3EVM_LCD_PANEL_INI, GPIOF_OUT_INIT_HIGH, "lcd_panel_ini" },
+ { OMAP3EVM_LCD_PANEL_QVGA, GPIOF_OUT_INIT_LOW, "lcd_panel_qvga" },
+ { OMAP3EVM_LCD_PANEL_LR, GPIOF_OUT_INIT_HIGH, "lcd_panel_lr" },
+ { OMAP3EVM_LCD_PANEL_UD, GPIOF_OUT_INIT_HIGH, "lcd_panel_ud" },
+ { OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW, "lcd_panel_envdd" },
+};
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_evm_display_init(void)
+{
+ int r;
+
+ r = gpio_request_array(omap3_evm_dss_gpios,
+ ARRAY_SIZE(omap3_evm_dss_gpios));
+ if (r)
+ printk(KERN_ERR "failed to get lcd_panel_* gpios\n");
+}
+
+static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+ else
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1);
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+ else
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+
+ lcd_enabled = 0;
+}
+
+static struct omap_dss_device omap3_evm_lcd_device = {
+ .name = "lcd",
+ .driver_name = "sharp_ls_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 18,
+ .platform_enable = omap3_evm_enable_lcd,
+ .platform_disable = omap3_evm_disable_lcd,
+};
+
+static int omap3_evm_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void omap3_evm_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device omap3_evm_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = omap3_evm_enable_tv,
+ .platform_disable = omap3_evm_disable_tv,
+};
+
+static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 1);
+
+ dvi_enabled = 1;
+ return 0;
+}
+
+static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 0);
+
+ dvi_enabled = 0;
+}
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = omap3_evm_enable_dvi,
+ .platform_disable = omap3_evm_disable_dvi,
+};
+
+static struct omap_dss_device omap3_evm_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *omap3_evm_dss_devices[] = {
+ &omap3_evm_lcd_device,
+ &omap3_evm_tv_device,
+ &omap3_evm_dvi_device,
+};
+
+static struct omap_dss_board_info omap3_evm_dss_data = {
+ .num_devices = ARRAY_SIZE(omap3_evm_dss_devices),
+ .devices = omap3_evm_dss_devices,
+ .default_device = &omap3_evm_lcd_device,
+};
+
+static struct regulator_consumer_supply omap3evm_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply omap3evm_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3evm_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3evm_vmmc1_supply),
+ .consumer_supplies = omap3evm_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data omap3evm_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3evm_vsim_supply),
+ .consumer_supplies = omap3evm_vsim_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 63,
+ },
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ {
+ .name = "wl1271",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+#endif
+ {} /* Terminator */
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "omap3evm::ledb",
+ /* normally not visible (board underside) */
+ .default_trigger = "default-on",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+
+static int omap3evm_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int r, lcd_bl_en;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ omap_mux_init_gpio(63, OMAP_PIN_INPUT);
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /*
+ * Most GPIOs are for USB OTG. Some are mostly sent to
+ * the P2 connector; notably LEDA for the LCD backlight.
+ */
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
+ lcd_bl_en = get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2 ?
+ GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ r = gpio_request_one(gpio + TWL4030_GPIO_MAX, lcd_bl_en, "EN_LCD_BKL");
+ if (r)
+ printk(KERN_ERR "failed to get/set lcd_bkl gpio\n");
+
+ /* gpio + 7 == DVI Enable */
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+ gpio_leds[0].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ platform_device_register(&leds_gpio);
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = omap3evm_twl_gpio_setup,
+};
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_DOWN),
+ KEY(0, 2, KEY_ENTER),
+ KEY(0, 3, KEY_M),
+
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_I),
+ KEY(1, 3, KEY_N),
+
+ KEY(2, 0, KEY_A),
+ KEY(2, 1, KEY_E),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_O),
+
+ KEY(3, 0, KEY_B),
+ KEY(3, 1, KEY_F),
+ KEY(3, 2, KEY_K),
+ KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data omap3evm_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 4,
+ .cols = 4,
+ .rep = 1,
+};
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply omap3evm_vio_supply[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+/* VIO for ads7846 */
+static struct regulator_init_data omap3evm_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3evm_vio_supply),
+ .consumer_supplies = omap3evm_vio_supply,
+};
+
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+
+#define OMAP3EVM_WLAN_PMENA_GPIO (150)
+#define OMAP3EVM_WLAN_IRQ_GPIO (149)
+
+static struct regulator_consumer_supply omap3evm_vmmc2_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+/* VMMC2 for driving the WL12xx module */
+static struct regulator_init_data omap3evm_vmmc2 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3evm_vmmc2_supply),
+ .consumer_supplies = omap3evm_vmmc2_supply,
+};
+
+static struct fixed_voltage_config omap3evm_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.80V */
+ .gpio = OMAP3EVM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &omap3evm_vmmc2,
+};
+
+static struct platform_device omap3evm_wlan_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap3evm_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO),
+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
+};
+#endif
+
+static struct twl4030_platform_data omap3evm_twldata = {
+ /* platform_data for children goes here */
+ .keypad = &omap3evm_kp_data,
+ .gpio = &omap3evm_gpio_data,
+ .vio = &omap3evm_vio,
+ .vmmc1 = &omap3evm_vmmc1,
+ .vsim = &omap3evm_vsim,
+};
+
+static int __init omap3_evm_i2c_init(void)
+{
+ omap3_pmic_get_config(&omap3evm_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
+ TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ omap3evm_twldata.vdac->constraints.apply_uV = true;
+ omap3evm_twldata.vpll2->constraints.apply_uV = true;
+
+ omap3_pmic_init("twl4030", &omap3evm_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
+};
+
+static struct usbhs_omap_board_data usbhs_bdata __initdata = {
+
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ /* PHY reset GPIO will be runtime programmed based on EVM version */
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux omap35x_board_mux[] __initdata = {
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_board_mux omap36x_board_mux[] __initdata = {
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ /* AM/DM37x EVM: DSS data bus muxed with sys_boot */
+ OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT0, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT1, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT3, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap35x_board_mux NULL
+#define omap36x_board_mux NULL
+#endif
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+static struct gpio omap3_evm_ehci_gpios[] __initdata = {
+ { OMAP3_EVM_EHCI_VBUS, GPIOF_OUT_INIT_HIGH, "enable EHCI VBUS" },
+ { OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW, "select EHCI port" },
+};
+
+static void __init omap3_evm_wl12xx_init(void)
+{
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ int ret;
+
+ /* WL12xx WLAN Init */
+ ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
+ if (ret)
+ pr_err("error setting wl12xx data: %d\n", ret);
+ ret = platform_device_register(&omap3evm_wlan_regulator);
+ if (ret)
+ pr_err("error registering wl12xx device: %d\n", ret);
+#endif
+}
+
+static void __init omap3_evm_init(void)
+{
+ omap3_evm_get_revision();
+
+ if (cpu_is_omap3630())
+ omap3_mux_init(omap36x_board_mux, OMAP_PACKAGE_CBB);
+ else
+ omap3_mux_init(omap35x_board_mux, OMAP_PACKAGE_CBB);
+
+ omap_board_config = omap3_evm_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
+
+ omap3_evm_i2c_init();
+
+ omap_display_init(&omap3_evm_dss_data);
+
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
+
+ /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
+ usb_nop_xceiv_register();
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
+ /* enable EHCI VBUS using GPIO22 */
+ omap_mux_init_gpio(OMAP3_EVM_EHCI_VBUS, OMAP_PIN_INPUT_PULLUP);
+ /* Select EHCI port on main board */
+ omap_mux_init_gpio(OMAP3_EVM_EHCI_SELECT,
+ OMAP_PIN_INPUT_PULLUP);
+ gpio_request_array(omap3_evm_ehci_gpios,
+ ARRAY_SIZE(omap3_evm_ehci_gpios));
+
+ /* setup EHCI phy reset config */
+ omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
+ usbhs_bdata.reset_gpio_port[1] = 21;
+
+ /* EVM REV >= E can supply 500mA with EXTVBUS programming */
+ musb_board_data.power = 500;
+ musb_board_data.extvbus = 1;
+ } else {
+ /* setup EHCI phy reset on MDC */
+ omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
+ usbhs_bdata.reset_gpio_port[1] = 135;
+ }
+ usb_musb_init(&musb_board_data);
+ usbhs_init(&usbhs_bdata);
+ omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
+ omap3evm_init_smsc911x();
+ omap3_evm_display_init();
+ omap3_evm_wl12xx_init();
+}
+
+MACHINE_START(OMAP3EVM, "OMAP3 EVM")
+ /* Maintainer: Syed Mohammed Khasim - Texas Instruments */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3_evm_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
new file mode 100644
index 00000000000..4198dd017d8
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -0,0 +1,226 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3logic.c
+ *
+ * Copyright (C) 2010 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Copyright (C) 2010 Logic Product Development, Inc.
+ * Peter Barada <peter.barada@logicpd.com>
+ *
+ * Modified from Beagle, EVM, and RX51
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <linux/regulator/machine.h>
+
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#include <plat/mux.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc-smsc911x.h>
+#include <plat/gpmc.h>
+#include <plat/sdrc.h>
+
+#define OMAP3LOGIC_SMSC911X_CS 1
+
+#define OMAP3530_LV_SOM_MMC_GPIO_CD 110
+#define OMAP3530_LV_SOM_MMC_GPIO_WP 126
+#define OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ 152
+
+#define OMAP3_TORPEDO_MMC_GPIO_CD 127
+#define OMAP3_TORPEDO_SMSC911X_GPIO_IRQ 129
+
+static struct regulator_consumer_supply omap3logic_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3logic_vmmc1 = {
+ .constraints = {
+ .name = "VMMC1",
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3logic_vmmc1_supply),
+ .consumer_supplies = omap3logic_vmmc1_supply,
+};
+
+static struct twl4030_gpio_platform_data omap3logic_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8)
+ | BIT(13) | BIT(15) | BIT(16) | BIT(17),
+};
+
+static struct twl4030_platform_data omap3logic_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &omap3logic_gpio_data,
+ .vmmc1 = &omap3logic_vmmc1,
+};
+
+static int __init omap3logic_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &omap3logic_twldata);
+ return 0;
+}
+
+static struct omap2_hsmmc_info __initdata board_mmc_info[] = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static void __init board_mmc_init(void)
+{
+ if (machine_is_omap3530_lv_som()) {
+ /* OMAP3530 LV SOM board */
+ board_mmc_info[0].gpio_cd = OMAP3530_LV_SOM_MMC_GPIO_CD;
+ board_mmc_info[0].gpio_wp = OMAP3530_LV_SOM_MMC_GPIO_WP;
+ omap_mux_init_signal("gpio_110", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("gpio_126", OMAP_PIN_OUTPUT);
+ } else if (machine_is_omap3_torpedo()) {
+ /* OMAP3 Torpedo board */
+ board_mmc_info[0].gpio_cd = OMAP3_TORPEDO_MMC_GPIO_CD;
+ omap_mux_init_signal("gpio_127", OMAP_PIN_OUTPUT);
+ } else {
+ /* unsupported board */
+ printk(KERN_ERR "%s(): unknown machine type\n", __func__);
+ return;
+ }
+
+ omap2_hsmmc_init(board_mmc_info);
+}
+
+static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
+ .cs = OMAP3LOGIC_SMSC911X_CS,
+ .gpio_irq = -EINVAL,
+ .gpio_reset = -EINVAL,
+};
+
+/* TODO/FIXME (comment by Peter Barada, LogicPD):
+ * Fix the PBIAS voltage for Torpedo MMC1 pins that
+ * are used for other needs (IRQs, etc). */
+static void omap3torpedo_fix_pbias_voltage(void)
+{
+ u16 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+ u32 reg;
+
+ if (machine_is_omap3_torpedo())
+ {
+ /* Set the bias for the pin */
+ reg = omap_ctrl_readl(control_pbias_offset);
+
+ reg &= ~OMAP343X_PBIASLITEPWRDNZ1;
+ omap_ctrl_writel(reg, control_pbias_offset);
+
+ /* 100ms delay required for PBIAS configuration */
+ msleep(100);
+
+ reg |= OMAP343X_PBIASLITEVMODE1;
+ reg |= OMAP343X_PBIASLITEPWRDNZ1;
+ omap_ctrl_writel(reg | 0x300, control_pbias_offset);
+ }
+}
+
+static inline void __init board_smsc911x_init(void)
+{
+ if (machine_is_omap3530_lv_som()) {
+ /* OMAP3530 LV SOM board */
+ board_smsc911x_data.gpio_irq =
+ OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ;
+ omap_mux_init_signal("gpio_152", OMAP_PIN_INPUT);
+ } else if (machine_is_omap3_torpedo()) {
+ /* OMAP3 Torpedo board */
+ board_smsc911x_data.gpio_irq = OMAP3_TORPEDO_SMSC911X_GPIO_IRQ;
+ omap_mux_init_signal("gpio_129", OMAP_PIN_INPUT);
+ } else {
+ /* unsupported board */
+ printk(KERN_ERR "%s(): unknown machine type\n", __func__);
+ return;
+ }
+
+ gpmc_smsc911x_init(&board_smsc911x_data);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap3logic_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3torpedo_fix_pbias_voltage();
+ omap3logic_i2c_init();
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ board_mmc_init();
+ board_smsc911x_init();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
+ .atag_offset = 0x100,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3logic_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
+ .atag_offset = 0x100,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3logic_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
new file mode 100644
index 00000000000..1644b73017f
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -0,0 +1,613 @@
+/*
+ * board-omap3pandora.c (Pandora Handheld Console)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/wl12xx.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/regulator/fixed.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <mach/hardware.h>
+#include <plat/mcspi.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <plat/nand.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define PANDORA_WIFI_IRQ_GPIO 21
+#define PANDORA_WIFI_NRESET_GPIO 23
+#define OMAP3_PANDORA_TS_GPIO 94
+
+static struct mtd_partition omap3pandora_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 15 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "uboot-env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 80 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data pandora_nand_data = {
+ .cs = 0,
+ .devsize = NAND_BUSWIDTH_16,
+ .xfer_type = NAND_OMAP_PREFETCH_DMA,
+ .parts = omap3pandora_nand_partitions,
+ .nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions),
+};
+
+static struct gpio_led pandora_gpio_leds[] = {
+ {
+ .name = "pandora::sd1",
+ .default_trigger = "mmc0",
+ .gpio = 128,
+ }, {
+ .name = "pandora::sd2",
+ .default_trigger = "mmc1",
+ .gpio = 129,
+ }, {
+ .name = "pandora::bluetooth",
+ .gpio = 158,
+ }, {
+ .name = "pandora::wifi",
+ .gpio = 159,
+ },
+};
+
+static struct gpio_led_platform_data pandora_gpio_led_data = {
+ .leds = pandora_gpio_leds,
+ .num_leds = ARRAY_SIZE(pandora_gpio_leds),
+};
+
+static struct platform_device pandora_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &pandora_gpio_led_data,
+ },
+};
+
+#define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \
+{ \
+ .gpio = gpio_num, \
+ .type = ev_type, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .debounce_interval = 4, \
+ .desc = "btn " descr, \
+}
+
+#define GPIO_BUTTON_LOW(gpio_num, event_code, description) \
+ GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description)
+
+static struct gpio_keys_button pandora_gpio_keys[] = {
+ GPIO_BUTTON_LOW(110, KEY_UP, "up"),
+ GPIO_BUTTON_LOW(103, KEY_DOWN, "down"),
+ GPIO_BUTTON_LOW(96, KEY_LEFT, "left"),
+ GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"),
+ GPIO_BUTTON_LOW(109, KEY_PAGEUP, "game 1"),
+ GPIO_BUTTON_LOW(111, KEY_END, "game 2"),
+ GPIO_BUTTON_LOW(106, KEY_PAGEDOWN, "game 3"),
+ GPIO_BUTTON_LOW(101, KEY_HOME, "game 4"),
+ GPIO_BUTTON_LOW(102, KEY_RIGHTSHIFT, "l"),
+ GPIO_BUTTON_LOW(97, KEY_KPPLUS, "l2"),
+ GPIO_BUTTON_LOW(105, KEY_RIGHTCTRL, "r"),
+ GPIO_BUTTON_LOW(107, KEY_KPMINUS, "r2"),
+ GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"),
+ GPIO_BUTTON_LOW(99, KEY_MENU, "menu"),
+ GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"),
+ GPIO_BUTTON(100, EV_KEY, KEY_LEFTALT, 0, "alt"),
+ GPIO_BUTTON(108, EV_SW, SW_LID, 1, "lid"),
+};
+
+static struct gpio_keys_platform_data pandora_gpio_key_info = {
+ .buttons = pandora_gpio_keys,
+ .nbuttons = ARRAY_SIZE(pandora_gpio_keys),
+};
+
+static struct platform_device pandora_keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &pandora_gpio_key_info,
+ },
+};
+
+static const uint32_t board_keymap[] = {
+ /* row, col, code */
+ KEY(0, 0, KEY_9),
+ KEY(0, 1, KEY_8),
+ KEY(0, 2, KEY_I),
+ KEY(0, 3, KEY_J),
+ KEY(0, 4, KEY_N),
+ KEY(0, 5, KEY_M),
+ KEY(1, 0, KEY_0),
+ KEY(1, 1, KEY_7),
+ KEY(1, 2, KEY_U),
+ KEY(1, 3, KEY_H),
+ KEY(1, 4, KEY_B),
+ KEY(1, 5, KEY_SPACE),
+ KEY(2, 0, KEY_BACKSPACE),
+ KEY(2, 1, KEY_6),
+ KEY(2, 2, KEY_Y),
+ KEY(2, 3, KEY_G),
+ KEY(2, 4, KEY_V),
+ KEY(2, 5, KEY_FN),
+ KEY(3, 0, KEY_O),
+ KEY(3, 1, KEY_5),
+ KEY(3, 2, KEY_T),
+ KEY(3, 3, KEY_F),
+ KEY(3, 4, KEY_C),
+ KEY(4, 0, KEY_P),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_R),
+ KEY(4, 3, KEY_D),
+ KEY(4, 4, KEY_X),
+ KEY(5, 0, KEY_K),
+ KEY(5, 1, KEY_3),
+ KEY(5, 2, KEY_E),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_Z),
+ KEY(6, 0, KEY_L),
+ KEY(6, 1, KEY_2),
+ KEY(6, 2, KEY_W),
+ KEY(6, 3, KEY_A),
+ KEY(6, 4, KEY_DOT),
+ KEY(7, 0, KEY_ENTER),
+ KEY(7, 1, KEY_1),
+ KEY(7, 2, KEY_Q),
+ KEY(7, 3, KEY_LEFTSHIFT),
+ KEY(7, 4, KEY_COMMA),
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data pandora_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 8,
+ .cols = 6,
+ .rep = 1,
+};
+
+static struct omap_dss_device pandora_lcd_device = {
+ .name = "lcd",
+ .driver_name = "tpo_td043mtea1_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = 157,
+};
+
+static struct omap_dss_device pandora_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static struct omap_dss_device *pandora_dss_devices[] = {
+ &pandora_lcd_device,
+ &pandora_tv_device,
+};
+
+static struct omap_dss_board_info pandora_dss_data = {
+ .num_devices = ARRAY_SIZE(pandora_dss_devices),
+ .devices = pandora_dss_devices,
+ .default_device = &pandora_lcd_device,
+};
+
+static void pandora_wl1251_init_card(struct mmc_card *card)
+{
+ /*
+ * We have TI wl1251 attached to MMC3. Pass this information to
+ * SDIO core because it can't be probed by normal methods.
+ */
+ card->quirks |= MMC_QUIRK_NONSTD_SDIO;
+ card->cccr.wide_bus = 1;
+ card->cis.vendor = 0x104c;
+ card->cis.device = 0x9066;
+ card->cis.blksize = 512;
+ card->cis.max_dtr = 20000000;
+}
+
+static struct omap2_hsmmc_info omap3pandora_mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 126,
+ .ext_clock = 0,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 127,
+ .ext_clock = 1,
+ .transceiver = true,
+ },
+ {
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .init_card = pandora_wl1251_init_card,
+ },
+ {} /* Terminator */
+};
+
+static int omap3pandora_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret, gpio_32khz;
+
+ /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
+ omap3pandora_mmc[0].gpio_cd = gpio + 0;
+ omap3pandora_mmc[1].gpio_cd = gpio + 1;
+ omap2_hsmmc_init(omap3pandora_mmc);
+
+ /* gpio + 13 drives 32kHz buffer for wifi module */
+ gpio_32khz = gpio + 13;
+ ret = gpio_request_one(gpio_32khz, GPIOF_OUT_INIT_HIGH, "wifi 32kHz");
+ if (ret < 0) {
+ pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = omap3pandora_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply pandora_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply pandora_vmmc2_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1")
+};
+
+static struct regulator_consumer_supply pandora_vmmc3_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"),
+};
+
+static struct regulator_consumer_supply pandora_vdds_supplies[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+};
+
+static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {
+ REGULATOR_SUPPLY("vcc", "display0"),
+};
+
+static struct regulator_consumer_supply pandora_usb_phy_supply[] = {
+ REGULATOR_SUPPLY("hsusb0", "ehci-omap.0"),
+};
+
+/* ads7846 on SPI and 2 nub controllers on I2C */
+static struct regulator_consumer_supply pandora_vaux4_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+ REGULATOR_SUPPLY("vcc", "3-0066"),
+ REGULATOR_SUPPLY("vcc", "3-0067"),
+};
+
+static struct regulator_consumer_supply pandora_adac_supply[] = {
+ REGULATOR_SUPPLY("vcc", "soc-audio"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data pandora_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc1_supply),
+ .consumer_supplies = pandora_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */
+static struct regulator_init_data pandora_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc2_supply),
+ .consumer_supplies = pandora_vmmc2_supply,
+};
+
+/* VAUX1 for LCD */
+static struct regulator_init_data pandora_vaux1 = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vcc_lcd_supply),
+ .consumer_supplies = pandora_vcc_lcd_supply,
+};
+
+/* VAUX2 for USB host PHY */
+static struct regulator_init_data pandora_vaux2 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_usb_phy_supply),
+ .consumer_supplies = pandora_usb_phy_supply,
+};
+
+/* VAUX4 for ads7846 and nubs */
+static struct regulator_init_data pandora_vaux4 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vaux4_supplies),
+ .consumer_supplies = pandora_vaux4_supplies,
+};
+
+/* VSIM for audio DAC */
+static struct regulator_init_data pandora_vsim = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_adac_supply),
+ .consumer_supplies = pandora_adac_supply,
+};
+
+/* Fixed regulator internal to Wifi module */
+static struct regulator_init_data pandora_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc3_supply),
+ .consumer_supplies = pandora_vmmc3_supply,
+};
+
+static struct fixed_voltage_config pandora_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = PANDORA_WIFI_NRESET_GPIO,
+ .startup_delay = 50000, /* 50ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &pandora_vmmc3,
+};
+
+static struct platform_device pandora_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &pandora_vwlan,
+ },
+};
+
+static struct twl4030_bci_platform_data pandora_bci_data;
+
+static struct twl4030_platform_data omap3pandora_twldata = {
+ .gpio = &omap3pandora_gpio_data,
+ .vmmc1 = &pandora_vmmc1,
+ .vmmc2 = &pandora_vmmc2,
+ .vaux1 = &pandora_vaux1,
+ .vaux2 = &pandora_vaux2,
+ .vaux4 = &pandora_vaux4,
+ .vsim = &pandora_vsim,
+ .keypad = &pandora_kp_data,
+ .bci = &pandora_bci_data,
+};
+
+static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("bq27500", 0x55),
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
+static int __init omap3pandora_i2c_init(void)
+{
+ omap3_pmic_get_config(&omap3pandora_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ omap3pandora_twldata.vdac->constraints.apply_uV = true;
+
+ omap3pandora_twldata.vpll2->constraints.apply_uV = true;
+ omap3pandora_twldata.vpll2->num_consumer_supplies =
+ ARRAY_SIZE(pandora_vdds_supplies);
+ omap3pandora_twldata.vpll2->consumer_supplies = pandora_vdds_supplies;
+
+ omap3_pmic_init("tps65950", &omap3pandora_twldata);
+ /* i2c2 pins are not connected */
+ omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo,
+ ARRAY_SIZE(omap3pandora_i2c3_boardinfo));
+ return 0;
+}
+
+static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
+ {
+ .modalias = "tpo_td043mtea1_panel_spi",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 375000,
+ .platform_data = &pandora_lcd_device,
+ }
+};
+
+static void __init pandora_wl1251_init(void)
+{
+ struct wl12xx_platform_data pandora_wl1251_pdata;
+ int ret;
+
+ memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+
+ ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
+ if (ret < 0)
+ goto fail;
+
+ pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
+ if (pandora_wl1251_pdata.irq < 0)
+ goto fail_irq;
+
+ pandora_wl1251_pdata.use_eeprom = true;
+ ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+ if (ret < 0)
+ goto fail_irq;
+
+ return;
+
+fail_irq:
+ gpio_free(PANDORA_WIFI_IRQ_GPIO);
+fail:
+ printk(KERN_ERR "wl1251 board initialisation failed\n");
+}
+
+static struct platform_device *omap3pandora_devices[] __initdata = {
+ &pandora_leds_gpio,
+ &pandora_keys_gpio,
+ &pandora_vwlan_device,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 16,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap3pandora_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3pandora_i2c_init();
+ pandora_wl1251_init();
+ platform_add_devices(omap3pandora_devices,
+ ARRAY_SIZE(omap3pandora_devices));
+ omap_display_init(&pandora_dss_data);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ spi_register_board_info(omap3pandora_spi_board_info,
+ ARRAY_SIZE(omap3pandora_spi_board_info));
+ omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
+ usbhs_init(&usbhs_bdata);
+ usb_musb_init(NULL);
+ gpmc_nand_init(&pandora_nand_data);
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3pandora_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
new file mode 100644
index 00000000000..cb089a46f62
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -0,0 +1,461 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3evm.c
+ *
+ * Copyright (C) 2008 Guangzhou EMA-Tech
+ *
+ * Modified from mach-omap2/board-omap3evm.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
+
+#include <plat/mcspi.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c/at24.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <plat/gpmc-smsc911x.h>
+
+#define OMAP3STALKER_ETHR_START 0x2c000000
+#define OMAP3STALKER_ETHR_SIZE 1024
+#define OMAP3STALKER_ETHR_GPIO_IRQ 19
+#define OMAP3STALKER_SMC911X_CS 5
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = OMAP3STALKER_SMC911X_CS,
+ .gpio_irq = OMAP3STALKER_ETHR_GPIO_IRQ,
+ .gpio_reset = -EINVAL,
+ .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
+};
+
+static inline void __init omap3stalker_init_eth(void)
+{
+ struct clk *l3ck;
+ unsigned int rate;
+
+ l3ck = clk_get(NULL, "l3_ck");
+ if (IS_ERR(l3ck))
+ rate = 100000000;
+ else
+ rate = clk_get_rate(l3ck);
+
+ omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP);
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+#else
+static inline void __init omap3stalker_init_eth(void)
+{
+ return;
+}
+#endif
+
+/*
+ * OMAP3 DSS control signals
+ */
+
+#define DSS_ENABLE_GPIO 199
+#define LCD_PANEL_BKLIGHT_GPIO 210
+#define ENABLE_VPLL2_DEV_GRP 0xE0
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_stalker_display_init(void)
+{
+ return;
+}
+
+static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void omap3_stalker_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device omap3_stalker_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+#if defined(CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO)
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+#elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE)
+ .u.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+#endif
+ .platform_enable = omap3_stalker_enable_tv,
+ .platform_disable = omap3_stalker_disable_tv,
+};
+
+static int omap3_stalker_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(DSS_ENABLE_GPIO, 1);
+ dvi_enabled = 1;
+ return 0;
+}
+
+static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(DSS_ENABLE_GPIO, 0);
+ dvi_enabled = 0;
+}
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = omap3_stalker_enable_dvi,
+ .platform_disable = omap3_stalker_disable_dvi,
+};
+
+static struct omap_dss_device omap3_stalker_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *omap3_stalker_dss_devices[] = {
+ &omap3_stalker_tv_device,
+ &omap3_stalker_dvi_device,
+};
+
+static struct omap_dss_board_info omap3_stalker_dss_data = {
+ .num_devices = ARRAY_SIZE(omap3_stalker_dss_devices),
+ .devices = omap3_stalker_dss_devices,
+ .default_device = &omap3_stalker_dvi_device,
+};
+
+static struct regulator_consumer_supply omap3stalker_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply omap3stalker_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3stalker_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3stalker_vmmc1_supply),
+ .consumer_supplies = omap3stalker_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data omap3stalker_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3stalker_vsim_supply),
+ .consumer_supplies = omap3stalker_vsim_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 23,
+ },
+ {} /* Terminator */
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 18,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "stalker:D8:usr0",
+ .default_trigger = "default-on",
+ .gpio = 126,
+ },
+ {
+ .name = "stalker:D9:usr1",
+ .default_trigger = "default-on",
+ .gpio = 127,
+ },
+ {
+ .name = "stalker:D3:mmc0",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ .default_trigger = "mmc0",
+ },
+ {
+ .name = "stalker:D4:heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ .default_trigger = "heartbeat",
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static int
+omap3stalker_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /*
+ * Most GPIOs are for USB OTG. Some are mostly sent to
+ * the P2 connector; notably LEDA for the LCD backlight.
+ */
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
+ "EN_LCD_BKL");
+
+ /* gpio + 7 == DVI Enable */
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+ /* GPIO + 13 == ledsync (out, heartbeat) */
+ gpio_leds[3].gpio = gpio + 13;
+
+ platform_device_register(&leds_gpio);
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3stalker_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = omap3stalker_twl_gpio_setup,
+};
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_DOWN),
+ KEY(0, 2, KEY_ENTER),
+ KEY(0, 3, KEY_M),
+
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_I),
+ KEY(1, 3, KEY_N),
+
+ KEY(2, 0, KEY_A),
+ KEY(2, 1, KEY_E),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_O),
+
+ KEY(3, 0, KEY_B),
+ KEY(3, 1, KEY_F),
+ KEY(3, 2, KEY_K),
+ KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data omap3stalker_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 4,
+ .cols = 4,
+ .rep = 1,
+};
+
+static struct twl4030_platform_data omap3stalker_twldata = {
+ /* platform_data for children goes here */
+ .keypad = &omap3stalker_kp_data,
+ .gpio = &omap3stalker_gpio_data,
+ .vmmc1 = &omap3stalker_vmmc1,
+ .vsim = &omap3stalker_vsim,
+};
+
+static struct at24_platform_data fram_info = {
+ .byte_len = (64 * 1024) / 8,
+ .page_size = 8192,
+ .flags = AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO,
+};
+
+static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = {
+ {
+ I2C_BOARD_INFO("24c64", 0x50),
+ .flags = I2C_CLIENT_WAKE,
+ .platform_data = &fram_info,
+ },
+};
+
+static int __init omap3_stalker_i2c_init(void)
+{
+ omap3_pmic_get_config(&omap3stalker_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
+ TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ omap3stalker_twldata.vdac->constraints.apply_uV = true;
+ omap3stalker_twldata.vpll2->constraints.apply_uV = true;
+ omap3stalker_twldata.vpll2->constraints.name = "VDVI";
+
+ omap3_pmic_init("twl4030", &omap3stalker_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3,
+ ARRAY_SIZE(omap3stalker_i2c_boardinfo3));
+ return 0;
+}
+
+#define OMAP3_STALKER_TS_GPIO 175
+
+static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
+};
+
+static struct platform_device *omap3_stalker_devices[] __initdata = {
+ &keys_gpio,
+};
+
+static struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 21,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+ {.reg_offset = OMAP_MUX_TERMINATOR},
+};
+#endif
+
+static void __init omap3_stalker_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_board_config = omap3_stalker_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
+
+ omap3_stalker_i2c_init();
+
+ platform_add_devices(omap3_stalker_devices,
+ ARRAY_SIZE(omap3_stalker_devices));
+
+ omap_display_init(&omap3_stalker_dss_data);
+
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
+
+ omap_mux_init_gpio(21, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP);
+
+ omap3stalker_init_eth();
+ omap3_stalker_display_init();
+/* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(SBC3530, "OMAP3 STALKER")
+ /* Maintainer: Jason Lam -lzg@ema-tech.com */
+ .atag_offset = 0x100,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3_stalker_init,
+ .timer = &omap3_secure_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
new file mode 100644
index 00000000000..a0b851aafcc
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -0,0 +1,388 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3touchbook.c
+ *
+ * Copyright (C) 2009 Always Innovating
+ *
+ * Modified from mach-omap2/board-omap3beagleboard.c
+ *
+ * Initial code: Grégoire Gentil, Tim Yamin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#include <linux/spi/ads7846.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#include <asm/setup.h>
+
+#define OMAP3_AC_GPIO 136
+#define OMAP3_TS_GPIO 162
+#define TB_BL_PWM_TIMER 9
+#define TB_KILL_POWER_GPIO 168
+
+static unsigned long touchbook_revision;
+
+static struct mtd_partition omap3touchbook_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply touchbook_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply touchbook_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct gpio_led gpio_leds[];
+
+static int touchbook_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+ omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+ mmc[0].gpio_wp = 23;
+ } else {
+ omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+ }
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC");
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
+ "nEN_USB_PWR");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data touchbook_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+ | BIT(15) | BIT(16) | BIT(17),
+ .setup = touchbook_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply touchbook_vdac_supply[] = {
+{
+ .supply = "vdac",
+},
+};
+
+static struct regulator_consumer_supply touchbook_vdvi_supply[] = {
+{
+ .supply = "vdvi",
+},
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data touchbook_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(touchbook_vmmc1_supply),
+ .consumer_supplies = touchbook_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data touchbook_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(touchbook_vsim_supply),
+ .consumer_supplies = touchbook_vsim_supply,
+};
+
+static struct twl4030_platform_data touchbook_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &touchbook_gpio_data,
+ .vmmc1 = &touchbook_vmmc1,
+ .vsim = &touchbook_vsim,
+};
+
+static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("bq27200", 0x55),
+ },
+};
+
+static int __init omap3_touchbook_i2c_init(void)
+{
+ /* Standard TouchBook bus */
+ omap3_pmic_get_config(&touchbook_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ touchbook_twldata.vdac->num_consumer_supplies =
+ ARRAY_SIZE(touchbook_vdac_supply);
+ touchbook_twldata.vdac->consumer_supplies = touchbook_vdac_supply;
+
+ touchbook_twldata.vpll2->constraints.name = "VDVI";
+ touchbook_twldata.vpll2->num_consumer_supplies =
+ ARRAY_SIZE(touchbook_vdvi_supply);
+ touchbook_twldata.vpll2->consumer_supplies = touchbook_vdvi_supply;
+
+ omap3_pmic_init("twl4030", &touchbook_twldata);
+ /* Additional TouchBook bus */
+ omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo,
+ ARRAY_SIZE(touchBook_i2c_boardinfo));
+
+ return 0;
+}
+
+static struct ads7846_platform_data ads7846_pdata = {
+ .x_min = 100,
+ .y_min = 265,
+ .x_max = 3950,
+ .y_max = 3750,
+ .x_plate_ohms = 40,
+ .pressure_max = 255,
+ .debounce_max = 10,
+ .debounce_tol = 5,
+ .debounce_rep = 1,
+ .gpio_pendown = OMAP3_TS_GPIO,
+ .keep_vref_on = 1,
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "touchbook::usr0",
+ .default_trigger = "heartbeat",
+ .gpio = 150,
+ },
+ {
+ .name = "touchbook::usr1",
+ .default_trigger = "mmc0",
+ .gpio = 149,
+ },
+ {
+ .name = "touchbook::pmu_stat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 7,
+ .desc = "user",
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_POWER,
+ .gpio = 183,
+ .desc = "power",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct platform_device *omap3_touchbook_devices[] __initdata = {
+ &leds_gpio,
+ &keys_gpio,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 147,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void omap3_touchbook_poweroff(void)
+{
+ int pwr_off = TB_KILL_POWER_GPIO;
+
+ if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0)
+ printk(KERN_ERR "Unable to get kill power GPIO\n");
+}
+
+static int __init early_touchbook_revision(char *p)
+{
+ if (!p)
+ return 0;
+
+ return strict_strtoul(p, 10, &touchbook_revision);
+}
+early_param("tbr", early_touchbook_revision);
+
+static void __init omap3_touchbook_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ pm_power_off = omap3_touchbook_poweroff;
+
+ omap3_touchbook_i2c_init();
+ platform_add_devices(omap3_touchbook_devices,
+ ARRAY_SIZE(omap3_touchbook_devices));
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+
+ omap_mux_init_gpio(170, OMAP_PIN_INPUT);
+ /* REVISIT leave DVI powered down until it's needed ... */
+ gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
+
+ /* Touchscreen and accelerometer */
+ omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions,
+ ARRAY_SIZE(omap3touchbook_nand_partitions));
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
+ /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap3_touchbook_init,
+ .timer = &omap3_secure_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
new file mode 100644
index 00000000000..28fc271f703
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -0,0 +1,523 @@
+/*
+ * Board support file for OMAP4430 based PandaBoard.
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * Author: David Anders <x0132446@ti.com>
+ *
+ * Based on mach-omap2/board-4430sdp.c
+ *
+ * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Based on mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <video/omapdss.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <plat/usb.h>
+#include <plat/mmc.h>
+#include <video/omap-panel-dvi.h>
+
+#include "hsmmc.h"
+#include "control.h"
+#include "mux.h"
+#include "common-board-devices.h"
+
+#define GPIO_HUB_POWER 1
+#define GPIO_HUB_NRESET 62
+#define GPIO_WIFI_PMENA 43
+#define GPIO_WIFI_IRQ 53
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
+
+/* wl127x BT, FM, GPS connectivity chip */
+static int wl1271_gpios[] = {46, -1, -1};
+static struct platform_device wl1271_device = {
+ .name = "kim",
+ .id = -1,
+ .dev = {
+ .platform_data = &wl1271_gpios,
+ },
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "pandaboard::status1",
+ .default_trigger = "heartbeat",
+ .gpio = 7,
+ },
+ {
+ .name = "pandaboard::status2",
+ .default_trigger = "mmc0",
+ .gpio = 8,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct platform_device *panda_devices[] __initdata = {
+ &leds_gpio,
+ &wl1271_device,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .phy_reset = false,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static struct gpio panda_ehci_gpios[] __initdata = {
+ { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" },
+ { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" },
+};
+
+static void __init omap4_ehci_init(void)
+{
+ int ret;
+ struct clk *phy_ref_clk;
+
+ /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
+ phy_ref_clk = clk_get(NULL, "auxclk3_ck");
+ if (IS_ERR(phy_ref_clk)) {
+ pr_err("Cannot request auxclk3\n");
+ return;
+ }
+ clk_set_rate(phy_ref_clk, 19200000);
+ clk_enable(phy_ref_clk);
+
+ /* disable the power to the usb hub prior to init and reset phy+hub */
+ ret = gpio_request_array(panda_ehci_gpios,
+ ARRAY_SIZE(panda_ehci_gpios));
+ if (ret) {
+ pr_err("Unable to initialize EHCI power/reset\n");
+ return;
+ }
+
+ gpio_export(GPIO_HUB_POWER, 0);
+ gpio_export(GPIO_HUB_NRESET, 0);
+ gpio_set_value(GPIO_HUB_NRESET, 1);
+
+ usbhs_init(&usbhs_bdata);
+
+ /* enable power to hub */
+ gpio_set_value(GPIO_HUB_POWER, 1);
+}
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_UTMI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ },
+ {
+ .name = "wl1271",
+ .mmc = 5,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .ocr_mask = MMC_VDD_165_195,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply omap4_panda_vmmc5_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.4"),
+};
+
+static struct regulator_init_data panda_vmmc5 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_panda_vmmc5_supply),
+ .consumer_supplies = omap4_panda_vmmc5_supply,
+};
+
+static struct fixed_voltage_config panda_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = GPIO_WIFI_PMENA,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &panda_vmmc5,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &panda_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ),
+ /* PANDA ref clock is 38.4 MHz */
+ .board_ref_clock = 2,
+};
+
+static int omap4_twl6030_hsmmc_late_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_mmc_platform_data *pdata = dev->platform_data;
+
+ if (!pdata) {
+ dev_err(dev, "%s: NULL platform data\n", __func__);
+ return -EINVAL;
+ }
+ /* Setting MMC1 Card detect Irq */
+ if (pdev->id == 0) {
+ ret = twl6030_mmc_card_detect_config();
+ if (ret)
+ dev_err(dev, "%s: Error card detect config(%d)\n",
+ __func__, ret);
+ else
+ pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+ }
+ return ret;
+}
+
+static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
+{
+ struct omap_mmc_platform_data *pdata;
+
+ /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+ if (!dev) {
+ pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
+ return;
+ }
+ pdata = dev->platform_data;
+
+ pdata->init = omap4_twl6030_hsmmc_late_init;
+}
+
+static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ struct omap2_hsmmc_info *c;
+
+ omap2_hsmmc_init(controllers);
+ for (c = controllers; c->mmc; c++)
+ omap4_twl6030_hsmmc_set_late_init(c->dev);
+
+ return 0;
+}
+
+/* Panda board uses the common PMIC configuration */
+static struct twl4030_platform_data omap4_panda_twldata;
+
+/*
+ * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
+ * is connected as I2C slave device, and can be accessed at address 0x50
+ */
+static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static int __init omap4_panda_i2c_init(void)
+{
+ omap4_pmic_get_config(&omap4_panda_twldata, TWL_COMMON_PDATA_USB,
+ TWL_COMMON_REGULATOR_VDAC |
+ TWL_COMMON_REGULATOR_VAUX2 |
+ TWL_COMMON_REGULATOR_VAUX3 |
+ TWL_COMMON_REGULATOR_VMMC |
+ TWL_COMMON_REGULATOR_VPP |
+ TWL_COMMON_REGULATOR_VANA |
+ TWL_COMMON_REGULATOR_VCXIO |
+ TWL_COMMON_REGULATOR_VUSB |
+ TWL_COMMON_REGULATOR_CLK32KG);
+ omap4_pmic_init("twl6030", &omap4_panda_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ /*
+ * Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz
+ */
+ omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
+ ARRAY_SIZE(panda_i2c_eeprom));
+ omap_register_i2c_bus(4, 400, NULL, 0);
+ return 0;
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 53 */
+ OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ /* WLAN POWER ENABLE - GPIO 43 */
+ OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC5 CMD */
+ OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC5 CLK */
+ OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC5 DAT[0-3] */
+ OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ /* gpio 0 - TFP410 PD */
+ OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
+ /* dispc2_data23 */
+ OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data22 */
+ OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data21 */
+ OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data20 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data19 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data18 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data15 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data14 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data13 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data12 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data11 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data10 */
+ OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data9 */
+ OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data16 */
+ OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data17 */
+ OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_hsync */
+ OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_pclk */
+ OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_vsync */
+ OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_de */
+ OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data8 */
+ OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data7 */
+ OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data6 */
+ OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data5 */
+ OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data4 */
+ OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data3 */
+ OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data2 */
+ OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data1 */
+ OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data0 */
+ OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+#else
+#define board_mux NULL
+#endif
+
+/* Display DVI */
+#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
+
+static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+/* Using generic display panel */
+static struct panel_dvi_platform_data omap4_dvi_panel = {
+ .platform_enable = omap4_panda_enable_dvi,
+ .platform_disable = omap4_panda_disable_dvi,
+ .i2c_bus_num = 3,
+};
+
+struct omap_dss_device omap4_panda_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "dvi",
+ .data = &omap4_dvi_panel,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
+ .channel = OMAP_DSS_CHANNEL_LCD2,
+};
+
+int __init omap4_panda_dvi_init(void)
+{
+ int r;
+
+ /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
+ r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "DVI PD");
+ if (r)
+ pr_err("Failed to get DVI powerdown GPIO\n");
+
+ return r;
+}
+
+static struct gpio panda_hdmi_gpios[] = {
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
+ { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
+};
+
+static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+ int status;
+
+ status = gpio_request_array(panda_hdmi_gpios,
+ ARRAY_SIZE(panda_hdmi_gpios));
+ if (status)
+ pr_err("Cannot request HDMI GPIOs\n");
+
+ return status;
+}
+
+static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+ gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
+}
+
+static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
+static struct omap_dss_device omap4_panda_hdmi_device = {
+ .name = "hdmi",
+ .driver_name = "hdmi_panel",
+ .type = OMAP_DISPLAY_TYPE_HDMI,
+ .platform_enable = omap4_panda_panel_enable_hdmi,
+ .platform_disable = omap4_panda_panel_disable_hdmi,
+ .channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &omap4_panda_hdmi_data,
+};
+
+static struct omap_dss_device *omap4_panda_dss_devices[] = {
+ &omap4_panda_dvi_device,
+ &omap4_panda_hdmi_device,
+};
+
+static struct omap_dss_board_info omap4_panda_dss_data = {
+ .num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
+ .devices = omap4_panda_dss_devices,
+ .default_device = &omap4_panda_dvi_device,
+};
+
+void omap4_panda_display_init(void)
+{
+ int r;
+
+ r = omap4_panda_dvi_init();
+ if (r)
+ pr_err("error initializing panda DVI\n");
+
+ omap_display_init(&omap4_panda_dss_data);
+
+ /*
+ * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
+ * later have external pull up on the HDMI I2C lines
+ */
+ if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2)
+ omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
+ else
+ omap_hdmi_init(0);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+}
+
+static void __init omap4_panda_init(void)
+{
+ int package = OMAP_PACKAGE_CBS;
+ int ret;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ package = OMAP_PACKAGE_CBL;
+ omap4_mux_init(board_mux, NULL, package);
+
+ ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
+ if (ret)
+ pr_err("error setting wl12xx data: %d\n", ret);
+
+ omap4_panda_i2c_init();
+ platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
+ platform_device_register(&omap_vwlan_device);
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ omap4_twl6030_hsmmc_init(mmc);
+ omap4_ehci_init();
+ usb_musb_init(&musb_board_data);
+ omap4_panda_display_init();
+}
+
+MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
+ /* Maintainer: David Anders - Texas Instruments Inc */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
+ .init_irq = gic_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = omap4_panda_init,
+ .timer = &omap4_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
new file mode 100644
index 00000000000..52c0cef7716
--- /dev/null
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -0,0 +1,569 @@
+/*
+ * board-overo.c (Gumstix Overo)
+ *
+ * Initial code: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include "common.h"
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
+#include <plat/gpmc.h>
+#include <mach/hardware.h>
+#include <plat/nand.h>
+#include <plat/mcspi.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OVERO_GPIO_BT_XGATE 15
+#define OVERO_GPIO_W2W_NRESET 16
+#define OVERO_GPIO_PENDOWN 114
+#define OVERO_GPIO_BT_NRESET 164
+#define OVERO_GPIO_USBH_CPEN 168
+#define OVERO_GPIO_USBH_NRESET 183
+
+#define OVERO_SMSC911X_CS 5
+#define OVERO_SMSC911X_GPIO 176
+#define OVERO_SMSC911X2_CS 4
+#define OVERO_SMSC911X2_GPIO 65
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+/* fixed regulator for ads7846 */
+static struct regulator_consumer_supply ads7846_supply[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+static struct regulator_init_data vads7846_regulator = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ads7846_supply),
+ .consumer_supplies = ads7846_supply,
+};
+
+static struct fixed_voltage_config vads7846 = {
+ .supply_name = "vads7846",
+ .microvolts = 3300000, /* 3.3V */
+ .gpio = -EINVAL,
+ .startup_delay = 0,
+ .init_data = &vads7846_regulator,
+};
+
+static struct platform_device vads7846_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &vads7846,
+ },
+};
+
+static void __init overo_ads7846_init(void)
+{
+ omap_ads7846_init(1, OVERO_GPIO_PENDOWN, 0, NULL);
+ platform_device_register(&vads7846_device);
+}
+
+#else
+static inline void __init overo_ads7846_init(void) { return; }
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .id = 0,
+ .cs = OVERO_SMSC911X_CS,
+ .gpio_irq = OVERO_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct omap_smsc911x_platform_data smsc911x2_cfg = {
+ .id = 1,
+ .cs = OVERO_SMSC911X2_CS,
+ .gpio_irq = OVERO_SMSC911X2_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static void __init overo_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&smsc911x_cfg);
+ gpmc_smsc911x_init(&smsc911x2_cfg);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
+/* DSS */
+static int lcd_enabled;
+static int dvi_enabled;
+
+#define OVERO_GPIO_LCD_EN 144
+#define OVERO_GPIO_LCD_BL 145
+
+static struct gpio overo_dss_gpios[] __initdata = {
+ { OVERO_GPIO_LCD_EN, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_EN" },
+ { OVERO_GPIO_LCD_BL, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_BL" },
+};
+
+static void __init overo_display_init(void)
+{
+ if (gpio_request_array(overo_dss_gpios, ARRAY_SIZE(overo_dss_gpios))) {
+ printk(KERN_ERR "could not obtain DSS control GPIOs\n");
+ return;
+ }
+
+ gpio_export(OVERO_GPIO_LCD_EN, 0);
+ gpio_export(OVERO_GPIO_LCD_BL, 0);
+}
+
+static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static struct panel_dvi_platform_data dvi_panel = {
+ .platform_enable = overo_panel_enable_dvi,
+ .platform_disable = overo_panel_disable_dvi,
+ .i2c_bus_num = 3,
+};
+
+static struct omap_dss_device overo_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "dvi",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device overo_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(OVERO_GPIO_LCD_EN, 1);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 1);
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(OVERO_GPIO_LCD_EN, 0);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 0);
+ lcd_enabled = 0;
+}
+
+static struct panel_generic_dpi_data lcd43_panel = {
+ .name = "samsung_lte430wq_f0c",
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+
+static struct omap_dss_device overo_lcd43_device = {
+ .name = "lcd43",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd43_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+static struct omap_dss_device overo_lcd35_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd35",
+ .driver_name = "lgphilips_lb035q02_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+#endif
+
+static struct omap_dss_device *overo_dss_devices[] = {
+ &overo_dvi_device,
+ &overo_tv_device,
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ &overo_lcd35_device,
+#endif
+ &overo_lcd43_device,
+};
+
+static struct omap_dss_board_info overo_dss_data = {
+ .num_devices = ARRAY_SIZE(overo_dss_devices),
+ .devices = overo_dss_devices,
+ .default_device = &overo_dvi_device,
+};
+
+static struct mtd_partition overo_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 14 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x240000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .transceiver = true,
+ .ocr_mask = 0x00100000, /* 3.3V */
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply overo_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "overo:red:gpio21",
+ .default_trigger = "heartbeat",
+ .gpio = 21,
+ .active_low = true,
+ },
+ {
+ .name = "overo:blue:gpio22",
+ .default_trigger = "none",
+ .gpio = 22,
+ .active_low = true,
+ },
+ {
+ .name = "overo:blue:COM",
+ .default_trigger = "mmc0",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_leds_pdata = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device gpio_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_leds_pdata,
+ },
+};
+
+static void __init overo_init_led(void)
+{
+ platform_device_register(&gpio_leds_device);
+}
+
+#else
+static inline void __init overo_init_led(void) { return; }
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_0,
+ .gpio = 23,
+ .desc = "button0",
+ .wakeup = 1,
+ },
+ {
+ .code = BTN_1,
+ .gpio = 14,
+ .desc = "button1",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_keys_pdata = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_keys_pdata,
+ },
+};
+
+static void __init overo_init_keys(void)
+{
+ platform_device_register(&gpio_keys_device);
+}
+
+#else
+static inline void __init overo_init_keys(void) { return; }
+#endif
+
+static int overo_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ omap2_hsmmc_init(mmc);
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data overo_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = overo_twl_gpio_setup,
+};
+
+static struct regulator_init_data overo_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(overo_vmmc1_supply),
+ .consumer_supplies = overo_vmmc1_supply,
+};
+
+static struct twl4030_platform_data overo_twldata = {
+ .gpio = &overo_gpio_data,
+ .vmmc1 = &overo_vmmc1,
+};
+
+static int __init overo_i2c_init(void)
+{
+ omap3_pmic_get_config(&overo_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ overo_twldata.vpll2->constraints.name = "VDVI";
+
+ omap3_pmic_init("tps65950", &overo_twldata);
+ /* i2c2 pins are used for gpio */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct spi_board_info overo_spi_board_info[] __initdata = {
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ {
+ .modalias = "lgphilips_lb035q02_panel-spi",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 500000,
+ .mode = SPI_MODE_3,
+ },
+#endif
+};
+
+static int __init overo_spi_init(void)
+{
+ overo_ads7846_init();
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+ return 0;
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct gpio overo_bt_gpios[] __initdata = {
+ { OVERO_GPIO_BT_XGATE, GPIOF_OUT_INIT_LOW, "lcd enable" },
+ { OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" },
+};
+
+static void __init overo_init(void)
+{
+ int ret;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ overo_i2c_init();
+ omap_display_init(&overo_dss_data);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ omap_nand_flash_init(0, overo_nand_partitions,
+ ARRAY_SIZE(overo_nand_partitions));
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ overo_spi_init();
+ overo_init_smsc911x();
+ overo_display_init();
+ overo_init_led();
+ overo_init_keys();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+ ret = gpio_request_one(OVERO_GPIO_W2W_NRESET, GPIOF_OUT_INIT_HIGH,
+ "OVERO_GPIO_W2W_NRESET");
+ if (ret == 0) {
+ gpio_export(OVERO_GPIO_W2W_NRESET, 0);
+ gpio_set_value(OVERO_GPIO_W2W_NRESET, 0);
+ udelay(10);
+ gpio_set_value(OVERO_GPIO_W2W_NRESET, 1);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_W2W_NRESET\n");
+ }
+
+ ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios));
+ if (ret) {
+ pr_err("%s: could not obtain BT gpios\n", __func__);
+ } else {
+ gpio_export(OVERO_GPIO_BT_XGATE, 0);
+ gpio_export(OVERO_GPIO_BT_NRESET, 0);
+ gpio_set_value(OVERO_GPIO_BT_NRESET, 0);
+ mdelay(6);
+ gpio_set_value(OVERO_GPIO_BT_NRESET, 1);
+ }
+
+ ret = gpio_request_one(OVERO_GPIO_USBH_CPEN, GPIOF_OUT_INIT_HIGH,
+ "OVERO_GPIO_USBH_CPEN");
+ if (ret == 0)
+ gpio_export(OVERO_GPIO_USBH_CPEN, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_USBH_CPEN\n");
+}
+
+MACHINE_START(OVERO, "Gumstix Overo")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = overo_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
new file mode 100644
index 00000000000..8678b386c6a
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -0,0 +1,156 @@
+/*
+ * Board support file for Nokia RM-680.
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/i2c/twl.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/i2c.h>
+#include <plat/mmc.h>
+#include <plat/usb.h>
+#include <plat/gpmc.h>
+#include "common.h"
+#include <plat/onenand.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "sdram-nokia.h"
+#include "common-board-devices.h"
+
+static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+/* Fixed regulator for internal eMMC */
+static struct regulator_init_data rm680_vemmc = {
+ .constraints = {
+ .name = "rm680_vemmc",
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS
+ | REGULATOR_CHANGE_MODE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rm680_vemmc_consumers),
+ .consumer_supplies = rm680_vemmc_consumers,
+};
+
+static struct fixed_voltage_config rm680_vemmc_config = {
+ .supply_name = "VEMMC",
+ .microvolts = 2900000,
+ .gpio = 157,
+ .startup_delay = 150,
+ .enable_high = 1,
+ .init_data = &rm680_vemmc,
+};
+
+static struct platform_device rm680_vemmc_device = {
+ .name = "reg-fixed-voltage",
+ .dev = {
+ .platform_data = &rm680_vemmc_config,
+ },
+};
+
+static struct platform_device *rm680_peripherals_devices[] __initdata = {
+ &rm680_vemmc_device,
+};
+
+/* TWL */
+static struct twl4030_gpio_platform_data rm680_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pullups = BIT(0),
+ .pulldowns = BIT(1) | BIT(2) | BIT(8) | BIT(15),
+};
+
+static struct twl4030_platform_data rm680_twl_data = {
+ .gpio = &rm680_gpio_data,
+ /* add rest of the children here */
+};
+
+static void __init rm680_i2c_init(void)
+{
+ omap3_pmic_get_config(&rm680_twl_data, TWL_COMMON_PDATA_USB, 0);
+ omap_pmic_init(1, 2900, "twl5031", INT_34XX_SYS_NIRQ, &rm680_twl_data);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .gpio_irq = 65,
+ .flags = ONENAND_SYNC_READWRITE,
+ }
+};
+#endif
+
+/* eMMC */
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ { /* Terminator */ }
+};
+
+static void __init rm680_peripherals_init(void)
+{
+ platform_add_devices(rm680_peripherals_devices,
+ ARRAY_SIZE(rm680_peripherals_devices));
+ rm680_i2c_init();
+ gpmc_onenand_init(board_onenand_data);
+ omap2_hsmmc_init(mmc);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init rm680_init(void)
+{
+ struct omap_sdrc_params *sdrc_params;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+
+ sdrc_params = nokia_get_sdram_timings();
+ omap_sdrc_init(sdrc_params, sdrc_params);
+
+ usb_musb_init(NULL);
+ rm680_peripherals_init();
+}
+
+MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = rm680_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
new file mode 100644
index 00000000000..acb4e77b39e
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -0,0 +1,1152 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-peripherals.c
+ *
+ * Copyright (C) 2008-2009 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/wl12xx.h>
+#include <linux/spi/tsc2005.h>
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/mmc/host.h>
+#include <linux/power/isp1704_charger.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/onenand.h>
+#include <plat/gpmc-smc91x.h>
+
+#include <mach/board-rx51.h>
+
+#include <sound/tlv320aic3x.h>
+#include <sound/tpa6130a2-plat.h>
+#include <media/radio-si4713.h>
+#include <media/si4713.h>
+#include <linux/leds-lp5523.h>
+
+#include <../drivers/staging/iio/light/tsl2563.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define SYSTEM_REV_B_USES_VAUX3 0x1699
+#define SYSTEM_REV_S_USES_VAUX3 0x8
+
+#define RX51_WL1251_POWER_GPIO 87
+#define RX51_WL1251_IRQ_GPIO 42
+#define RX51_FMTX_RESET_GPIO 163
+#define RX51_FMTX_IRQ 53
+#define RX51_LP5523_CHIP_EN_GPIO 41
+
+#define RX51_USB_TRANSCEIVER_RST_GPIO 67
+
+#define RX51_TSC2005_RESET_GPIO 104
+#define RX51_TSC2005_IRQ_GPIO 100
+
+/* list all spi devices here */
+enum {
+ RX51_SPI_WL1251,
+ RX51_SPI_MIPID, /* LCD panel */
+ RX51_SPI_TSC2005, /* Touch Controller */
+};
+
+static struct wl12xx_platform_data wl1251_pdata;
+static struct tsc2005_platform_data tsc2005_pdata;
+
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+static struct tsl2563_platform_data rx51_tsl2563_platform_data = {
+ .cover_comp_gain = 16,
+};
+#endif
+
+#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE)
+static struct lp5523_led_config rx51_lp5523_led_config[] = {
+ {
+ .chan_nr = 0,
+ .led_current = 50,
+ }, {
+ .chan_nr = 1,
+ .led_current = 50,
+ }, {
+ .chan_nr = 2,
+ .led_current = 50,
+ }, {
+ .chan_nr = 3,
+ .led_current = 50,
+ }, {
+ .chan_nr = 4,
+ .led_current = 50,
+ }, {
+ .chan_nr = 5,
+ .led_current = 50,
+ }, {
+ .chan_nr = 6,
+ .led_current = 50,
+ }, {
+ .chan_nr = 7,
+ .led_current = 50,
+ }, {
+ .chan_nr = 8,
+ .led_current = 50,
+ }
+};
+
+static int rx51_lp5523_setup(void)
+{
+ return gpio_request_one(RX51_LP5523_CHIP_EN_GPIO, GPIOF_DIR_OUT,
+ "lp5523_enable");
+}
+
+static void rx51_lp5523_release(void)
+{
+ gpio_free(RX51_LP5523_CHIP_EN_GPIO);
+}
+
+static void rx51_lp5523_enable(bool state)
+{
+ gpio_set_value(RX51_LP5523_CHIP_EN_GPIO, !!state);
+}
+
+static struct lp5523_platform_data rx51_lp5523_platform_data = {
+ .led_config = rx51_lp5523_led_config,
+ .num_channels = ARRAY_SIZE(rx51_lp5523_led_config),
+ .clock_mode = LP5523_CLOCK_AUTO,
+ .setup_resources = rx51_lp5523_setup,
+ .release_resources = rx51_lp5523_release,
+ .enable = rx51_lp5523_enable,
+};
+#endif
+
+static struct omap2_mcspi_device_config wl1251_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct omap2_mcspi_device_config mipid_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
+ [RX51_SPI_WL1251] = {
+ .modalias = "wl1251",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 48000000,
+ .mode = SPI_MODE_3,
+ .controller_data = &wl1251_mcspi_config,
+ .platform_data = &wl1251_pdata,
+ },
+ [RX51_SPI_MIPID] = {
+ .modalias = "acx565akm",
+ .bus_num = 1,
+ .chip_select = 2,
+ .max_speed_hz = 6000000,
+ .controller_data = &mipid_mcspi_config,
+ },
+ [RX51_SPI_TSC2005] = {
+ .modalias = "tsc2005",
+ .bus_num = 1,
+ .chip_select = 0,
+ .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),
+ .max_speed_hz = 6000000,
+ .controller_data = &tsc2005_mcspi_config,
+ .platform_data = &tsc2005_pdata,
+ },
+};
+
+static void rx51_charger_set_power(bool on)
+{
+ gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on);
+}
+
+static struct isp1704_charger_data rx51_charger_data = {
+ .set_power = rx51_charger_set_power,
+};
+
+static struct platform_device rx51_charger_device = {
+ .name = "isp1704_charger",
+ .dev = {
+ .platform_data = &rx51_charger_data,
+ },
+};
+
+static void __init rx51_charger_init(void)
+{
+ WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO,
+ GPIOF_OUT_INIT_HIGH, "isp1704_reset"));
+
+ platform_device_register(&rx51_charger_device);
+}
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+
+#define RX51_GPIO_CAMERA_LENS_COVER 110
+#define RX51_GPIO_CAMERA_FOCUS 68
+#define RX51_GPIO_CAMERA_CAPTURE 69
+#define RX51_GPIO_KEYPAD_SLIDE 71
+#define RX51_GPIO_LOCK_BUTTON 113
+#define RX51_GPIO_PROXIMITY 89
+
+#define RX51_GPIO_DEBOUNCE_TIMEOUT 10
+
+static struct gpio_keys_button rx51_gpio_keys[] = {
+ {
+ .desc = "Camera Lens Cover",
+ .type = EV_SW,
+ .code = SW_CAMERA_LENS_COVER,
+ .gpio = RX51_GPIO_CAMERA_LENS_COVER,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Camera Focus",
+ .type = EV_KEY,
+ .code = KEY_CAMERA_FOCUS,
+ .gpio = RX51_GPIO_CAMERA_FOCUS,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Camera Capture",
+ .type = EV_KEY,
+ .code = KEY_CAMERA,
+ .gpio = RX51_GPIO_CAMERA_CAPTURE,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Lock Button",
+ .type = EV_KEY,
+ .code = KEY_SCREENLOCK,
+ .gpio = RX51_GPIO_LOCK_BUTTON,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Keypad Slide",
+ .type = EV_SW,
+ .code = SW_KEYPAD_SLIDE,
+ .gpio = RX51_GPIO_KEYPAD_SLIDE,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Proximity Sensor",
+ .type = EV_SW,
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = RX51_GPIO_PROXIMITY,
+ .active_low = 0,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }
+};
+
+static struct gpio_keys_platform_data rx51_gpio_keys_data = {
+ .buttons = rx51_gpio_keys,
+ .nbuttons = ARRAY_SIZE(rx51_gpio_keys),
+};
+
+static struct platform_device rx51_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_gpio_keys_data,
+ },
+};
+
+static void __init rx51_add_gpio_keys(void)
+{
+ platform_device_register(&rx51_gpio_keys_device);
+}
+#else
+static void __init rx51_add_gpio_keys(void)
+{
+}
+#endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */
+
+static uint32_t board_keymap[] = {
+ /*
+ * Note that KEY(x, 8, KEY_XXX) entries represent "entrire row
+ * connected to the ground" matrix state.
+ */
+ KEY(0, 0, KEY_Q),
+ KEY(0, 1, KEY_O),
+ KEY(0, 2, KEY_P),
+ KEY(0, 3, KEY_COMMA),
+ KEY(0, 4, KEY_BACKSPACE),
+ KEY(0, 6, KEY_A),
+ KEY(0, 7, KEY_S),
+
+ KEY(1, 0, KEY_W),
+ KEY(1, 1, KEY_D),
+ KEY(1, 2, KEY_F),
+ KEY(1, 3, KEY_G),
+ KEY(1, 4, KEY_H),
+ KEY(1, 5, KEY_J),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_L),
+
+ KEY(2, 0, KEY_E),
+ KEY(2, 1, KEY_DOT),
+ KEY(2, 2, KEY_UP),
+ KEY(2, 3, KEY_ENTER),
+ KEY(2, 5, KEY_Z),
+ KEY(2, 6, KEY_X),
+ KEY(2, 7, KEY_C),
+ KEY(2, 8, KEY_F9),
+
+ KEY(3, 0, KEY_R),
+ KEY(3, 1, KEY_V),
+ KEY(3, 2, KEY_B),
+ KEY(3, 3, KEY_N),
+ KEY(3, 4, KEY_M),
+ KEY(3, 5, KEY_SPACE),
+ KEY(3, 6, KEY_SPACE),
+ KEY(3, 7, KEY_LEFT),
+
+ KEY(4, 0, KEY_T),
+ KEY(4, 1, KEY_DOWN),
+ KEY(4, 2, KEY_RIGHT),
+ KEY(4, 4, KEY_LEFTCTRL),
+ KEY(4, 5, KEY_RIGHTALT),
+ KEY(4, 6, KEY_LEFTSHIFT),
+ KEY(4, 8, KEY_F10),
+
+ KEY(5, 0, KEY_Y),
+ KEY(5, 8, KEY_F11),
+
+ KEY(6, 0, KEY_U),
+
+ KEY(7, 0, KEY_I),
+ KEY(7, 1, KEY_F7),
+ KEY(7, 2, KEY_F8),
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data rx51_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 8,
+ .cols = 8,
+ .rep = 1,
+};
+
+/* Enable input logic and pull all lines up when eMMC is on. */
+static struct omap_board_mux rx51_mmc2_on_mux[] = {
+ OMAP3_MUX(SDMMC2_CMD, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/* Disable input logic and pull all lines down when eMMC is off. */
+static struct omap_board_mux rx51_mmc2_off_mux[] = {
+ OMAP3_MUX(SDMMC2_CMD, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_mux_partition *partition;
+
+/*
+ * Current flows to eMMC when eMMC is off and the data lines are pulled up,
+ * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
+ */
+static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
+{
+ if (power_on)
+ omap_mux_write_array(partition, rx51_mmc2_on_mux);
+ else
+ omap_mux_write_array(partition, rx51_mmc2_off_mux);
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .cover_only = true,
+ .gpio_cd = 160,
+ .gpio_wp = -EINVAL,
+ .power_saving = true,
+ },
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ /* See also rx51_mmc2_remux */
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .nonremovable = true,
+ .power_saving = true,
+ .remux = rx51_mmc2_remux,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply rx51_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply rx51_vaux2_supply[] = {
+ REGULATOR_SUPPLY("vdds_csib", "omap3isp"),
+};
+
+static struct regulator_consumer_supply rx51_vaux3_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+static struct regulator_consumer_supply rx51_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"),
+};
+
+static struct regulator_consumer_supply rx51_vmmc2_supplies[] = {
+ /* tlv320aic3x analog supplies */
+ REGULATOR_SUPPLY("AVDD", "2-0018"),
+ REGULATOR_SUPPLY("DRVDD", "2-0018"),
+ REGULATOR_SUPPLY("AVDD", "2-0019"),
+ REGULATOR_SUPPLY("DRVDD", "2-0019"),
+ /* tpa6130a2 */
+ REGULATOR_SUPPLY("Vdd", "2-0060"),
+ /* Keep vmmc as last item. It is not iterated for newer boards */
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+static struct regulator_consumer_supply rx51_vio_supplies[] = {
+ /* tlv320aic3x digital supplies */
+ REGULATOR_SUPPLY("IOVDD", "2-0018"),
+ REGULATOR_SUPPLY("DVDD", "2-0018"),
+ REGULATOR_SUPPLY("IOVDD", "2-0019"),
+ REGULATOR_SUPPLY("DVDD", "2-0019"),
+ /* Si4713 IO supply */
+ REGULATOR_SUPPLY("vio", "2-0063"),
+};
+
+static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ /* Si4713 supply */
+ REGULATOR_SUPPLY("vdd", "2-0063"),
+};
+
+static struct regulator_init_data rx51_vaux1 = {
+ .constraints = {
+ .name = "V28",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .always_on = true, /* due battery cover sensor */
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vaux1_consumers),
+ .consumer_supplies = rx51_vaux1_consumers,
+};
+
+static struct regulator_init_data rx51_vaux2 = {
+ .constraints = {
+ .name = "VCSI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vaux2_supply),
+ .consumer_supplies = rx51_vaux2_supply,
+};
+
+/* VAUX3 - adds more power to VIO_18 rail */
+static struct regulator_init_data rx51_vaux3_cam = {
+ .constraints = {
+ .name = "VCAM_DIG_18",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vaux3_mmc = {
+ .constraints = {
+ .name = "VMMC2_30",
+ .min_uV = 2800000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vaux3_supply),
+ .consumer_supplies = rx51_vaux3_supply,
+};
+
+static struct regulator_init_data rx51_vaux4 = {
+ .constraints = {
+ .name = "VCAM_ANA_28",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vmmc1_supply),
+ .consumer_supplies = rx51_vmmc1_supply,
+};
+
+static struct regulator_init_data rx51_vmmc2 = {
+ .constraints = {
+ .name = "V28_A",
+ .min_uV = 2800000,
+ .max_uV = 3000000,
+ .always_on = true, /* due VIO leak to AIC34 VDDs */
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vmmc2_supplies),
+ .consumer_supplies = rx51_vmmc2_supplies,
+};
+
+static struct regulator_init_data rx51_vpll1 = {
+ .constraints = {
+ .name = "VPLL",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vpll2 = {
+ .constraints = {
+ .name = "VSDI_CSI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vsim = {
+ .constraints = {
+ .name = "VMMC2_IO_18",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vsim_supply),
+ .consumer_supplies = rx51_vsim_supply,
+};
+
+static struct regulator_init_data rx51_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vio_supplies),
+ .consumer_supplies = rx51_vio_supplies,
+};
+
+static struct regulator_init_data rx51_vintana1 = {
+ .constraints = {
+ .name = "VINTANA1",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vintana2 = {
+ .constraints = {
+ .name = "VINTANA2",
+ .min_uV = 2750000,
+ .max_uV = 2750000,
+ .apply_uV = true,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vintdig = {
+ .constraints = {
+ .name = "VINTDIG",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
+ .gpio_reset = RX51_FMTX_RESET_GPIO,
+};
+
+static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
+ I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
+ .platform_data = &rx51_si4713_i2c_data,
+};
+
+static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
+ .i2c_bus = 2,
+ .subdev_board_info = &rx51_si4713_board_info,
+};
+
+static struct platform_device rx51_si4713_dev = {
+ .name = "radio-si4713",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_si4713_data,
+ },
+};
+
+static __init void rx51_init_si4713(void)
+{
+ int err;
+
+ err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
+ if (err) {
+ printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
+ return;
+ }
+ rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
+ platform_device_register(&rx51_si4713_dev);
+}
+
+static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
+{
+ /* FIXME this gpio setup is just a placeholder for now */
+ gpio_request_one(gpio + 6, GPIOF_OUT_INIT_LOW, "backlight_pwm");
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "speaker_en");
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data rx51_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(0) | BIT(1) | BIT(2) | BIT(3)
+ | BIT(4) | BIT(5)
+ | BIT(8) | BIT(9) | BIT(10) | BIT(11)
+ | BIT(12) | BIT(13) | BIT(14) | BIT(15)
+ | BIT(16) | BIT(17) ,
+ .setup = rx51_twlgpio_setup,
+};
+
+static struct twl4030_ins sleep_on_seq[] __initdata = {
+/*
+ * Turn off everything
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_SLEEP), 2},
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+ .script = sleep_on_seq,
+ .size = ARRAY_SIZE(sleep_on_seq),
+ .flags = TWL4030_SLEEP_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+/*
+ * Reenable everything
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+ .script = wakeup_seq,
+ .size = ARRAY_SIZE(wakeup_seq),
+ .flags = TWL4030_WAKEUP12_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_p3_seq[] __initdata = {
+/*
+ * Reenable everything
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_p3_script __initdata = {
+ .script = wakeup_p3_seq,
+ .size = ARRAY_SIZE(wakeup_p3_seq),
+ .flags = TWL4030_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_ins wrst_seq[] __initdata = {
+/*
+ * Reset twl4030.
+ * Reset VDD1 regulator.
+ * Reset VDD2 regulator.
+ * Reset VPLL1 regulator.
+ * Enable sysclk output.
+ * Reenable twl4030.
+ */
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 0, 1, RES_STATE_ACTIVE),
+ 0x13},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 3, RES_STATE_OFF), 0x13},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x13},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x13},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x35},
+ {MSG_SINGULAR(DEV_GRP_P3, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wrst_script __initdata = {
+ .script = wrst_seq,
+ .size = ARRAY_SIZE(wrst_seq),
+ .flags = TWL4030_WRST_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+ /* wakeup12 script should be loaded before sleep script, otherwise a
+ board might hit retention before loading of wakeup script is
+ completed. This can cause boot failures depending on timing issues.
+ */
+ &wakeup_script,
+ &sleep_on_script,
+ &wakeup_p3_script,
+ &wrst_script,
+};
+
+static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
+ { .resource = RES_VDD1, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+ .remap_sleep = RES_STATE_OFF
+ },
+ { .resource = RES_VDD2, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+ .remap_sleep = RES_STATE_OFF
+ },
+ { .resource = RES_VPLL1, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+ .remap_sleep = RES_STATE_OFF
+ },
+ { .resource = RES_VPLL2, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX1, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX2, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX3, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX4, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VMMC1, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VMMC2, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VDAC, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VSIM, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VIO, .devgroup = DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1 , .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_REGEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_32KCLKOUT, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_RESET, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_MAIN_REF, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { 0, 0},
+};
+
+static struct twl4030_power_data rx51_t2scripts_data __initdata = {
+ .scripts = twl4030_scripts,
+ .num = ARRAY_SIZE(twl4030_scripts),
+ .resource_config = twl4030_rconfig,
+};
+
+struct twl4030_vibra_data rx51_vibra_data __initdata = {
+ .coexist = 0,
+};
+
+struct twl4030_audio_data rx51_audio_data __initdata = {
+ .audio_mclk = 26000000,
+ .vibra = &rx51_vibra_data,
+};
+
+static struct twl4030_platform_data rx51_twldata __initdata = {
+ /* platform_data for children goes here */
+ .gpio = &rx51_gpio_data,
+ .keypad = &rx51_kp_data,
+ .power = &rx51_t2scripts_data,
+ .audio = &rx51_audio_data,
+
+ .vaux1 = &rx51_vaux1,
+ .vaux2 = &rx51_vaux2,
+ .vaux4 = &rx51_vaux4,
+ .vmmc1 = &rx51_vmmc1,
+ .vpll1 = &rx51_vpll1,
+ .vpll2 = &rx51_vpll2,
+ .vsim = &rx51_vsim,
+ .vintana1 = &rx51_vintana1,
+ .vintana2 = &rx51_vintana2,
+ .vintdig = &rx51_vintdig,
+ .vio = &rx51_vio,
+};
+
+static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = {
+ .power_gpio = 98,
+};
+
+/* Audio setup data */
+static struct aic3x_setup_data rx51_aic34_setup = {
+ .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
+ .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
+};
+
+static struct aic3x_pdata rx51_aic3x_data = {
+ .setup = &rx51_aic34_setup,
+ .gpio_reset = 60,
+};
+
+static struct aic3x_pdata rx51_aic3x_data2 = {
+ .gpio_reset = 60,
+};
+
+static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ .platform_data = &rx51_aic3x_data,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x19),
+ .platform_data = &rx51_aic3x_data2,
+ },
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+ {
+ I2C_BOARD_INFO("tsl2563", 0x29),
+ .platform_data = &rx51_tsl2563_platform_data,
+ },
+#endif
+#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE)
+ {
+ I2C_BOARD_INFO("lp5523", 0x32),
+ .platform_data = &rx51_lp5523_platform_data,
+ },
+#endif
+ {
+ I2C_BOARD_INFO("bq27200", 0x55),
+ },
+ {
+ I2C_BOARD_INFO("tpa6130a2", 0x60),
+ .platform_data = &rx51_tpa6130a2_data,
+ }
+};
+
+static int __init rx51_i2c_init(void)
+{
+ if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
+ system_rev >= SYSTEM_REV_B_USES_VAUX3) {
+ rx51_twldata.vaux3 = &rx51_vaux3_mmc;
+ /* Only older boards use VMMC2 for internal MMC */
+ rx51_vmmc2.num_consumer_supplies--;
+ } else {
+ rx51_twldata.vaux3 = &rx51_vaux3_cam;
+ }
+ rx51_twldata.vmmc2 = &rx51_vmmc2;
+ omap3_pmic_get_config(&rx51_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC,
+ TWL_COMMON_REGULATOR_VDAC);
+
+ rx51_twldata.vdac->constraints.apply_uV = true;
+ rx51_twldata.vdac->constraints.name = "VDAC";
+
+ omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata);
+ omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
+ ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+static struct mtd_partition onenand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x20000,
+ .mask_flags = MTD_WRITEABLE, /* Force read-only */
+ },
+ {
+ .name = "config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x60000,
+ },
+ {
+ .name = "log",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x40000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x200000,
+ },
+ {
+ .name = "initfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x200000,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .cs = 0,
+ .gpio_irq = 65,
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .flags = ONENAND_SYNC_READWRITE,
+ }
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 1,
+ .gpio_irq = 54,
+ .gpio_pwrdwn = 86,
+ .gpio_reset = 164,
+ .flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+ omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_gpio(86, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(164, OMAP_PIN_OUTPUT);
+
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif
+
+static void rx51_wl1251_set_power(bool enable)
+{
+ gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
+}
+
+static struct gpio rx51_wl1251_gpios[] __initdata = {
+ { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" },
+ { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" },
+};
+
+static void __init rx51_init_wl1251(void)
+{
+ int irq, ret;
+
+ ret = gpio_request_array(rx51_wl1251_gpios,
+ ARRAY_SIZE(rx51_wl1251_gpios));
+ if (ret < 0)
+ goto error;
+
+ irq = gpio_to_irq(RX51_WL1251_IRQ_GPIO);
+ if (irq < 0)
+ goto err_irq;
+
+ wl1251_pdata.set_power = rx51_wl1251_set_power;
+ rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
+
+ return;
+
+err_irq:
+ gpio_free(RX51_WL1251_IRQ_GPIO);
+ gpio_free(RX51_WL1251_POWER_GPIO);
+error:
+ printk(KERN_ERR "wl1251 board initialisation failed\n");
+ wl1251_pdata.set_power = NULL;
+
+ /*
+ * Now rx51_peripherals_spi_board_info[1].irq is zero and
+ * set_power is null, and wl1251_probe() will fail.
+ */
+}
+
+static struct tsc2005_platform_data tsc2005_pdata = {
+ .ts_pressure_max = 2048,
+ .ts_pressure_fudge = 2,
+ .ts_x_max = 4096,
+ .ts_x_fudge = 4,
+ .ts_y_max = 4096,
+ .ts_y_fudge = 7,
+ .ts_x_plate_ohm = 280,
+ .esd_timeout_ms = 8000,
+};
+
+static void rx51_tsc2005_set_reset(bool enable)
+{
+ gpio_set_value(RX51_TSC2005_RESET_GPIO, enable);
+}
+
+static void __init rx51_init_tsc2005(void)
+{
+ int r;
+
+ r = gpio_request_one(RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ");
+ if (r < 0) {
+ printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 IRQ");
+ rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = 0;
+ }
+
+ r = gpio_request_one(RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
+ "tsc2005 reset");
+ if (r >= 0) {
+ tsc2005_pdata.set_reset = rx51_tsc2005_set_reset;
+ } else {
+ printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 reset");
+ tsc2005_pdata.esd_timeout_ms = 0;
+ }
+}
+
+void __init rx51_peripherals_init(void)
+{
+ rx51_i2c_init();
+ regulator_has_full_constraints();
+ gpmc_onenand_init(board_onenand_data);
+ board_smc91x_init();
+ rx51_add_gpio_keys();
+ rx51_init_wl1251();
+ rx51_init_tsc2005();
+ rx51_init_si4713();
+ spi_register_board_info(rx51_peripherals_spi_board_info,
+ ARRAY_SIZE(rx51_peripherals_spi_board_info));
+
+ partition = omap_mux_get("core");
+ if (partition)
+ omap2_hsmmc_init(mmc);
+
+ rx51_charger_init();
+}
+
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
new file mode 100644
index 00000000000..2c1289bd5e6
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-video.c
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/mm.h>
+#include <asm/mach-types.h>
+#include <video/omapdss.h>
+#include <plat/vram.h>
+#include <plat/mcspi.h>
+
+#include <mach/board-rx51.h>
+
+#include "mux.h"
+
+#define RX51_LCD_RESET_GPIO 90
+
+#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+
+static int rx51_lcd_enable(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void rx51_lcd_disable(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+static struct omap_dss_device rx51_lcd_device = {
+ .name = "lcd",
+ .driver_name = "panel-acx565akm",
+ .type = OMAP_DISPLAY_TYPE_SDI,
+ .phy.sdi.datapairs = 2,
+ .reset_gpio = RX51_LCD_RESET_GPIO,
+ .platform_enable = rx51_lcd_enable,
+ .platform_disable = rx51_lcd_disable,
+};
+
+static struct omap_dss_device rx51_tv_device = {
+ .name = "tv",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .driver_name = "venc",
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+};
+
+static struct omap_dss_device *rx51_dss_devices[] = {
+ &rx51_lcd_device,
+ &rx51_tv_device,
+};
+
+static struct omap_dss_board_info rx51_dss_board_info = {
+ .num_devices = ARRAY_SIZE(rx51_dss_devices),
+ .devices = rx51_dss_devices,
+ .default_device = &rx51_lcd_device,
+};
+
+static int __init rx51_video_init(void)
+{
+ if (!machine_is_nokia_rx51())
+ return 0;
+
+ if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) {
+ pr_err("%s cannot configure MUX for LCD RESET\n", __func__);
+ return 0;
+ }
+
+ if (gpio_request_one(RX51_LCD_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
+ "LCD ACX565AKM reset")) {
+ pr_err("%s failed to get LCD Reset GPIO\n", __func__);
+ return 0;
+ }
+
+ omap_display_init(&rx51_dss_board_info);
+ return 0;
+}
+
+subsys_initcall(rx51_video_init);
+
+void __init rx51_video_mem_init(void)
+{
+ /*
+ * GFX 864x480x32bpp
+ * VID1/2 1280x720x32bpp double buffered
+ */
+ omap_vram_set_sdram_vram(PAGE_ALIGN(864 * 480 * 4) +
+ 2 * PAGE_ALIGN(1280 * 720 * 4 * 2), 0);
+}
+
+#else
+void __init rx51_video_mem_init(void) { }
+#endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
new file mode 100644
index 00000000000..27f01f051df
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -0,0 +1,134 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51.c
+ *
+ * Copyright (C) 2007, 2008 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "pm.h"
+#include "sdram-nokia.h"
+
+#define RX51_GPIO_SLEEP_IND 162
+
+extern void rx51_video_mem_init(void);
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "sleep_ind",
+ .gpio = RX51_GPIO_SLEEP_IND,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+/*
+ * cpuidle C-states definition override from the default values.
+ * The 'exit_latency' field is the sum of sleep and wake-up latencies.
+ */
+static struct cpuidle_params rx51_cpuidle_params[] = {
+ /* C1 */
+ {110 + 162, 5 , 1},
+ /* C2 */
+ {106 + 180, 309, 1},
+ /* C3 */
+ {107 + 410, 46057, 0},
+ /* C4 */
+ {121 + 3374, 46057, 0},
+ /* C5 */
+ {855 + 1146, 46057, 1},
+ /* C6 */
+ {7580 + 4134, 484329, 0},
+ /* C7 */
+ {7505 + 15274, 484329, 1},
+};
+
+extern void __init rx51_peripherals_init(void);
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_PERIPHERAL,
+ .power = 0,
+};
+
+static void __init rx51_init(void)
+{
+ struct omap_sdrc_params *sdrc_params;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3_pm_init_cpuidle(rx51_cpuidle_params);
+ omap_serial_init();
+
+ sdrc_params = nokia_get_sdram_timings();
+ omap_sdrc_init(sdrc_params, sdrc_params);
+
+ usb_musb_init(&musb_board_data);
+ rx51_peripherals_init();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+ platform_device_register(&leds_gpio);
+}
+
+static void __init rx51_reserve(void)
+{
+ rx51_video_mem_init();
+ omap_reserve();
+}
+
+MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
+ /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
+ .atag_offset = 0x100,
+ .reserve = rx51_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = rx51_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
new file mode 100644
index 00000000000..ab9a7a9e9d6
--- /dev/null
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -0,0 +1,67 @@
+/*
+ * Code for TI8168/TI8148 EVM.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/irqs.h>
+#include <plat/board.h>
+#include "common.h"
+#include <plat/usb.h>
+
+static struct omap_musb_board_data musb_board_data = {
+ .set_phy_power = ti81xx_musb_phy_power,
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 500,
+};
+
+static struct omap_board_config_kernel ti81xx_evm_config[] __initdata = {
+};
+
+static void __init ti81xx_evm_init(void)
+{
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ omap_board_config = ti81xx_evm_config;
+ omap_board_config_size = ARRAY_SIZE(ti81xx_evm_config);
+ usb_musb_init(&musb_board_data);
+}
+
+MACHINE_START(TI8168EVM, "ti8168evm")
+ /* Maintainer: Texas Instruments */
+ .atag_offset = 0x100,
+ .map_io = ti81xx_map_io,
+ .init_early = ti81xx_init_early,
+ .init_irq = ti81xx_init_irq,
+ .timer = &omap3_timer,
+ .init_machine = ti81xx_evm_init,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(TI8148EVM, "ti8148evm")
+ /* Maintainer: Texas Instruments */
+ .atag_offset = 0x100,
+ .map_io = ti81xx_map_io,
+ .init_early = ti81xx_init_early,
+ .init_irq = ti81xx_init_irq,
+ .timer = &omap3_timer,
+ .init_machine = ti81xx_evm_init,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
new file mode 100644
index 00000000000..369c2eb7715
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ * Mikkel Christensen <mlc@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+
+#include <plat/gpmc.h>
+#include <plat/gpmc-smsc911x.h>
+
+#include <mach/board-zoom.h>
+
+#define ZOOM_SMSC911X_CS 7
+#define ZOOM_SMSC911X_GPIO 158
+#define ZOOM_QUADUART_CS 3
+#define ZOOM_QUADUART_GPIO 102
+#define ZOOM_QUADUART_RST_GPIO 152
+#define QUART_CLK 1843200
+#define DEBUG_BASE 0x08000000
+#define ZOOM_ETHR_START DEBUG_BASE
+
+static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = {
+ .cs = ZOOM_SMSC911X_CS,
+ .gpio_irq = ZOOM_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static inline void __init zoom_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&zoom_smsc911x_cfg);
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = ZOOM_UART_BASE,
+ .irq = OMAP_GPIO_IRQ(102),
+ .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ,
+ .irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = QUART_CLK,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device zoom_debugboard_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static inline void __init zoom_init_quaduart(void)
+{
+ int quart_cs;
+ unsigned long cs_mem_base;
+ int quart_gpio = 0;
+
+ if (gpio_request_one(ZOOM_QUADUART_RST_GPIO,
+ GPIOF_OUT_INIT_LOW,
+ "TL16CP754C GPIO") < 0) {
+ pr_err("Failed to request GPIO%d for TL16CP754C\n",
+ ZOOM_QUADUART_RST_GPIO);
+ return;
+ }
+
+ quart_cs = ZOOM_QUADUART_CS;
+
+ if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem"
+ "for Quad UART(TL16CP754C)\n");
+ return;
+ }
+
+ quart_gpio = ZOOM_QUADUART_GPIO;
+
+ if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0)
+ printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
+ quart_gpio);
+}
+
+static inline int omap_zoom_debugboard_detect(void)
+{
+ int debug_board_detect = 0;
+ int ret = 1;
+
+ debug_board_detect = ZOOM_SMSC911X_GPIO;
+
+ if (gpio_request_one(debug_board_detect, GPIOF_IN,
+ "Zoom debug board detect") < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for Zoom debug"
+ "board detect\n", debug_board_detect);
+ return 0;
+ }
+
+ if (!gpio_get_value(debug_board_detect)) {
+ ret = 0;
+ }
+ gpio_free(debug_board_detect);
+ return ret;
+}
+
+static struct platform_device *zoom_devices[] __initdata = {
+ &zoom_debugboard_serial_device,
+};
+
+int __init zoom_debugboard_init(void)
+{
+ if (!omap_zoom_debugboard_detect())
+ return 0;
+
+ zoom_init_smsc911x();
+ zoom_init_quaduart();
+ return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
+}
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c
new file mode 100644
index 00000000000..d4683ba5f72
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-display.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 Texas Instruments Inc.
+ *
+ * Modified from mach-omap2/board-zoom-peripherals.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/spi/spi.h>
+#include <plat/mcspi.h>
+#include <video/omapdss.h>
+
+#define LCD_PANEL_RESET_GPIO_PROD 96
+#define LCD_PANEL_RESET_GPIO_PILOT 55
+#define LCD_PANEL_QVGA_GPIO 56
+
+static struct gpio zoom_lcd_gpios[] __initdata = {
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "lcd reset" },
+ { LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "lcd qvga" },
+};
+
+static void __init zoom_lcd_panel_init(void)
+{
+ zoom_lcd_gpios[0].gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
+ LCD_PANEL_RESET_GPIO_PROD :
+ LCD_PANEL_RESET_GPIO_PILOT;
+
+ if (gpio_request_array(zoom_lcd_gpios, ARRAY_SIZE(zoom_lcd_gpios)))
+ pr_err("%s: Failed to get LCD GPIOs.\n", __func__);
+}
+
+static int zoom_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+}
+
+/*
+ * PWMA/B register offsets (TWL4030_MODULE_PWMA)
+ */
+#define TWL_INTBR_PMBR1 0xD
+#define TWL_INTBR_GPBR1 0xC
+#define TWL_LED_PWMON 0x0
+#define TWL_LED_PWMOFF 0x1
+
+static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
+{
+ unsigned char c;
+ u8 mux_pwm, enb_pwm;
+
+ if (level > 100)
+ return -1;
+
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &mux_pwm, TWL_INTBR_PMBR1);
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &enb_pwm, TWL_INTBR_GPBR1);
+
+ if (level == 0) {
+ /* disable pwm1 output and clock */
+ enb_pwm = enb_pwm & 0xF5;
+ /* change pwm1 pin to gpio pin */
+ mux_pwm = mux_pwm & 0xCF;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ enb_pwm, TWL_INTBR_GPBR1);
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ mux_pwm, TWL_INTBR_PMBR1);
+ return 0;
+ }
+
+ if (!((enb_pwm & 0xA) && (mux_pwm & 0x30))) {
+ /* change gpio pin to pwm1 pin */
+ mux_pwm = mux_pwm | 0x30;
+ /* enable pwm1 output and clock*/
+ enb_pwm = enb_pwm | 0x0A;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ mux_pwm, TWL_INTBR_PMBR1);
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ enb_pwm, TWL_INTBR_GPBR1);
+ }
+
+ c = ((50 * (100 - level)) / 100) + 1;
+ twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF);
+ twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON);
+
+ return 0;
+}
+
+static struct omap_dss_device zoom_lcd_device = {
+ .name = "lcd",
+ .driver_name = "NEC_8048_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 24,
+ .platform_enable = zoom_panel_enable_lcd,
+ .platform_disable = zoom_panel_disable_lcd,
+ .max_backlight_level = 100,
+ .set_backlight = zoom_set_bl_intensity,
+};
+
+static struct omap_dss_device *zoom_dss_devices[] = {
+ &zoom_lcd_device,
+};
+
+static struct omap_dss_board_info zoom_dss_data = {
+ .num_devices = ARRAY_SIZE(zoom_dss_devices),
+ .devices = zoom_dss_devices,
+ .default_device = &zoom_lcd_device,
+};
+
+static struct omap2_mcspi_device_config dss_lcd_mcspi_config = {
+ .turbo_mode = 1,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info nec_8048_spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "nec_8048_spi",
+ .bus_num = 1,
+ .chip_select = 2,
+ .max_speed_hz = 375000,
+ .controller_data = &dss_lcd_mcspi_config,
+ },
+};
+
+void __init zoom_display_init(void)
+{
+ omap_display_init(&zoom_dss_data);
+ spi_register_board_info(nec_8048_spi_board_info,
+ ARRAY_SIZE(nec_8048_spi_board_info));
+ zoom_lcd_panel_init();
+}
+
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
new file mode 100644
index 00000000000..c126461836a
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ *
+ * Modified from mach-omap2/board-zoom2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OMAP_ZOOM_WLAN_PMENA_GPIO (101)
+#define OMAP_ZOOM_WLAN_IRQ_GPIO (162)
+
+#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
+
+/* Zoom2 has Qwerty keyboard*/
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_E),
+ KEY(0, 1, KEY_R),
+ KEY(0, 2, KEY_T),
+ KEY(0, 3, KEY_HOME),
+ KEY(0, 6, KEY_I),
+ KEY(0, 7, KEY_LEFTSHIFT),
+ KEY(1, 0, KEY_D),
+ KEY(1, 1, KEY_F),
+ KEY(1, 2, KEY_G),
+ KEY(1, 3, KEY_SEND),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_ENTER),
+ KEY(2, 0, KEY_X),
+ KEY(2, 1, KEY_C),
+ KEY(2, 2, KEY_V),
+ KEY(2, 3, KEY_END),
+ KEY(2, 6, KEY_DOT),
+ KEY(2, 7, KEY_CAPSLOCK),
+ KEY(3, 0, KEY_Z),
+ KEY(3, 1, KEY_KPPLUS),
+ KEY(3, 2, KEY_B),
+ KEY(3, 3, KEY_F1),
+ KEY(3, 6, KEY_O),
+ KEY(3, 7, KEY_SPACE),
+ KEY(4, 0, KEY_W),
+ KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_U),
+ KEY(4, 3, KEY_F2),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(4, 6, KEY_L),
+ KEY(4, 7, KEY_LEFT),
+ KEY(5, 0, KEY_S),
+ KEY(5, 1, KEY_H),
+ KEY(5, 2, KEY_J),
+ KEY(5, 3, KEY_F3),
+ KEY(5, 4, KEY_UNKNOWN),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ KEY(5, 6, KEY_M),
+ KEY(5, 7, KEY_RIGHT),
+ KEY(6, 0, KEY_Q),
+ KEY(6, 1, KEY_A),
+ KEY(6, 2, KEY_N),
+ KEY(6, 3, KEY_BACKSPACE),
+ KEY(6, 6, KEY_P),
+ KEY(6, 7, KEY_UP),
+ KEY(7, 0, KEY_PROG1), /*MACRO 1 <User defined> */
+ KEY(7, 1, KEY_PROG2), /*MACRO 2 <User defined> */
+ KEY(7, 2, KEY_PROG3), /*MACRO 3 <User defined> */
+ KEY(7, 3, KEY_PROG4), /*MACRO 4 <User defined> */
+ KEY(7, 6, KEY_SELECT),
+ KEY(7, 7, KEY_DOWN)
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data zoom_kp_twl4030_data = {
+ .keymap_data = &board_map_data,
+ .rows = 8,
+ .cols = 8,
+ .rep = 1,
+};
+
+static struct regulator_consumer_supply zoom_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply zoom_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply zoom_vmmc2_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+static struct regulator_consumer_supply zoom_vmmc3_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"),
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data zoom_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(zoom_vmmc1_supply),
+ .consumer_supplies = zoom_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data zoom_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 1850000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(zoom_vmmc2_supply),
+ .consumer_supplies = zoom_vmmc2_supply,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data zoom_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(zoom_vsim_supply),
+ .consumer_supplies = zoom_vsim_supply,
+};
+
+static struct regulator_init_data zoom_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(zoom_vmmc3_supply),
+ .consumer_supplies = zoom_vmmc3_supply,
+};
+
+static struct fixed_voltage_config zoom_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &zoom_vmmc3,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &zoom_vwlan,
+ },
+};
+
+static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
+ /* ZOOM ref clock is 26 MHz */
+ .board_ref_clock = 1,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .power_saving = true,
+ },
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .nonremovable = true,
+ .power_saving = true,
+ },
+ {
+ .name = "wl1271",
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+};
+
+static int zoom_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
+ "lcd enable");
+ if (ret)
+ pr_err("Failed to get LCD_PANEL_ENABLE_GPIO (gpio%d).\n",
+ LCD_PANEL_ENABLE_GPIO);
+
+ return ret;
+}
+
+/* EXTMUTE callback function */
+static void zoom2_set_hs_extmute(int mute)
+{
+ gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
+}
+
+static struct twl4030_gpio_platform_data zoom_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = zoom_twl_gpio_setup,
+};
+
+static struct twl4030_platform_data zoom_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &zoom_gpio_data,
+ .keypad = &zoom_kp_twl4030_data,
+ .vmmc1 = &zoom_vmmc1,
+ .vmmc2 = &zoom_vmmc2,
+ .vsim = &zoom_vsim,
+};
+
+static int __init omap_i2c_init(void)
+{
+ omap3_pmic_get_config(&zoom_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_BCI |
+ TWL_COMMON_PDATA_MADC | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ if (machine_is_omap_zoom2()) {
+ struct twl4030_codec_data *codec_data;
+ codec_data = zoom_twldata.audio->codec;
+
+ codec_data->ramp_delay_value = 3; /* 161 ms */
+ codec_data->hs_extmute = 1;
+ codec_data->set_hs_extmute = zoom2_set_hs_extmute;
+ }
+ omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static void enable_board_wakeup_source(void)
+{
+ /* T2 interrupt line (keypad) */
+ omap_mux_init_signal("sys_nirq",
+ OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+void __init zoom_peripherals_init(void)
+{
+ int ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
+
+ if (ret)
+ pr_err("error setting wl12xx data: %d\n", ret);
+
+ omap_i2c_init();
+ platform_device_register(&omap_vwlan_device);
+ usb_musb_init(NULL);
+ enable_board_wakeup_source();
+ omap_serial_init();
+}
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
new file mode 100644
index 00000000000..5c20bcc57f2
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2009-2010 Texas Instruments Inc.
+ * Mikkel Christensen <mlc@ti.com>
+ * Felipe Balbi <balbi@ti.com>
+ *
+ * Modified from mach-omap2/board-ldp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/mtd/nand.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include <plat/board.h>
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "sdram-hynix-h8mbx00u0mer-0em.h"
+
+#define ZOOM3_EHCI_RESET_GPIO 64
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 162 */
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* WLAN POWER ENABLE - GPIO 101 */
+ OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC3 CMD */
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 CLK */
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 DAT[0-3] */
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct mtd_partition zoom_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048), /* 512KB, 0x80000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 2 * (64 * 2048), /* 256KB, 0x40000 */
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/
+ .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */
+ },
+ {
+ .name = "system",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */
+ .size = 3328 * (64 * 2048), /* 416M, 0x1A000000 */
+ },
+ {
+ .name = "userdata",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C000000*/
+ .size = 256 * (64 * 2048), /* 32M, 0x2000000 */
+ },
+ {
+ .name = "cache",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E000000*/
+ .size = 256 * (64 * 2048), /* 32M, 0x2000000 */
+ },
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static void __init omap_zoom_init(void)
+{
+ if (machine_is_omap_zoom2()) {
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ } else if (machine_is_omap_zoom3()) {
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+ omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT);
+ usbhs_init(&usbhs_bdata);
+ }
+
+ board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions),
+ ZOOM_NAND_CS, NAND_BUSWIDTH_16);
+ zoom_debugboard_init();
+ zoom_peripherals_init();
+
+ if (machine_is_omap_zoom2())
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ else if (machine_is_omap_zoom3())
+ omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
+
+ zoom_display_init();
+}
+
+MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap_zoom_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
+
+MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_irq = omap3_init_irq,
+ .handle_irq = omap3_intc_handle_irq,
+ .init_machine = omap_zoom_init,
+ .timer = &omap3_timer,
+ .restart = omap_prcm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
new file mode 100644
index 00000000000..b19a1f7234a
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -0,0 +1,146 @@
+/*
+ * OMAP2xxx APLL clock control functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
+#define EN_APLL_STOPPED 0
+#define EN_APLL_LOCKED 3
+
+/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
+#define APLLS_CLKIN_19_2MHZ 0
+#define APLLS_CLKIN_13MHZ 2
+#define APLLS_CLKIN_12MHZ 3
+
+void __iomem *cm_idlest_pll;
+
+/* Private functions */
+
+/* Enable an APLL if off */
+static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
+{
+ u32 cval, apll_mask;
+
+ apll_mask = EN_APLL_LOCKED << clk->enable_bit;
+
+ cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+ if ((cval & apll_mask) == apll_mask)
+ return 0; /* apll already enabled */
+
+ cval &= ~apll_mask;
+ cval |= apll_mask;
+ omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+
+ omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
+ OMAP24XX_CM_IDLEST_VAL, clk->name);
+
+ /*
+ * REVISIT: Should we return an error code if omap2_wait_clock_ready()
+ * fails?
+ */
+ return 0;
+}
+
+static int omap2_clk_apll96_enable(struct clk *clk)
+{
+ return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);
+}
+
+static int omap2_clk_apll54_enable(struct clk *clk)
+{
+ return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
+}
+
+static void _apll96_allow_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll96_auto_low_power_stop();
+}
+
+static void _apll96_deny_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll96_disable_autoidle();
+}
+
+static void _apll54_allow_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll54_auto_low_power_stop();
+}
+
+static void _apll54_deny_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll54_disable_autoidle();
+}
+
+/* Stop APLL */
+static void omap2_clk_apll_disable(struct clk *clk)
+{
+ u32 cval;
+
+ cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
+ omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+}
+
+/* Public data */
+
+const struct clkops clkops_apll96 = {
+ .enable = omap2_clk_apll96_enable,
+ .disable = omap2_clk_apll_disable,
+ .allow_idle = _apll96_allow_idle,
+ .deny_idle = _apll96_deny_idle,
+};
+
+const struct clkops clkops_apll54 = {
+ .enable = omap2_clk_apll54_enable,
+ .disable = omap2_clk_apll_disable,
+ .allow_idle = _apll54_allow_idle,
+ .deny_idle = _apll54_deny_idle,
+};
+
+/* Public functions */
+
+u32 omap2xxx_get_apll_clkin(void)
+{
+ u32 aplls, srate = 0;
+
+ aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+ aplls &= OMAP24XX_APLLS_CLKIN_MASK;
+ aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
+
+ if (aplls == APLLS_CLKIN_19_2MHZ)
+ srate = 19200000;
+ else if (aplls == APLLS_CLKIN_13MHZ)
+ srate = 13000000;
+ else if (aplls == APLLS_CLKIN_12MHZ)
+ srate = 12000000;
+
+ return srate;
+}
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
new file mode 100644
index 00000000000..1502a7bc20b
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP2-specific DPLL control functions
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/**
+ * _allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control. The DPLL will enter low-power
+ * stop when its downstream clocks are gated. No return value.
+ * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
+ * instead. Add some mechanism to optionally enter this mode.
+ */
+static void _allow_idle(struct clk *clk)
+{
+ if (!clk || !clk->dpll_data)
+ return;
+
+ omap2xxx_cm_set_dpll_auto_low_power_stop();
+}
+
+/**
+ * _deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control. No return value.
+ */
+static void _deny_idle(struct clk *clk)
+{
+ if (!clk || !clk->dpll_data)
+ return;
+
+ omap2xxx_cm_set_dpll_disable_autoidle();
+}
+
+
+/* Public data */
+
+const struct clkops clkops_omap2xxx_dpll_ops = {
+ .allow_idle = _allow_idle,
+ .deny_idle = _deny_idle,
+};
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
new file mode 100644
index 00000000000..4ae43922208
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -0,0 +1,173 @@
+/*
+ * DPLL + CORE_CLK composite clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX The DPLL and CORE clocks should be split into two separate clock
+ * types.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
+
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
+ *
+ * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
+ * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
+ * (the latter is unusual). This currently should be called with
+ * struct clk *dpll_ck, which is a composite clock of dpll_ck and
+ * core_ck.
+ */
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
+{
+ long long core_clk;
+ u32 v;
+
+ core_clk = omap2_get_dpll_rate(clk);
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if (v == CORE_CLK_SRC_32K)
+ core_clk = 32768;
+ else
+ core_clk *= v;
+
+ return core_clk;
+}
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+static long omap2_dpllcore_round_rate(unsigned long target_rate)
+{
+ u32 high, low, core_clk_src;
+
+ core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
+ high = curr_prcm_set->dpll_speed * 2;
+ low = curr_prcm_set->dpll_speed;
+ } else { /* DPLL clockout x 2 */
+ high = curr_prcm_set->dpll_speed;
+ low = curr_prcm_set->dpll_speed / 2;
+ }
+
+#ifdef DOWN_VARIABLE_DPLL
+ if (target_rate > high)
+ return high;
+ else
+ return target_rate;
+#else
+ if (target_rate > low)
+ return high;
+ else
+ return low;
+#endif
+
+}
+
+unsigned long omap2_dpllcore_recalc(struct clk *clk)
+{
+ return omap2xxx_clk_get_core_rate(clk);
+}
+
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+{
+ u32 cur_rate, low, mult, div, valid_rate, done_rate;
+ u32 bypass = 0;
+ struct prcm_config tmpset;
+ const struct dpll_data *dd;
+
+ cur_rate = omap2xxx_clk_get_core_rate(dclk);
+ mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if ((rate == (cur_rate / 2)) && (mult == 2)) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+ } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+ } else if (rate != cur_rate) {
+ valid_rate = omap2_dpllcore_round_rate(rate);
+ if (valid_rate != rate)
+ return -EINVAL;
+
+ if (mult == 1)
+ low = curr_prcm_set->dpll_speed;
+ else
+ low = curr_prcm_set->dpll_speed / 2;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
+ tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
+ dd->div1_mask);
+ div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+ tmpset.cm_clksel2_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
+ if (rate > low) {
+ tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
+ mult = ((rate / 2) / 1000000);
+ done_rate = CORE_CLK_SRC_DPLL_X2;
+ } else {
+ tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
+ mult = (rate / 1000000);
+ done_rate = CORE_CLK_SRC_DPLL;
+ }
+ tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
+ tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
+
+ /* Worst case */
+ tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
+
+ if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
+ bypass = 1;
+
+ /* For omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+ /* Force dll lock mode */
+ omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+ bypass);
+
+ /* Errata: ret dll entry state */
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
+ }
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c
new file mode 100644
index 00000000000..c3460928b5e
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_osc.c
@@ -0,0 +1,76 @@
+/*
+ * OMAP2xxx osc_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * XXX This does not actually enable the osc_ck, since the osc_ck must
+ * be running for this function to be called. Instead, this function
+ * is used to disable an autoidle mode on the osc_ck. The existing
+ * clk_enable/clk_disable()-based usecounting for osc_ck should be
+ * replaced with autoidle-based usecounting.
+ */
+static int omap2_enable_osc_ck(struct clk *clk)
+{
+ u32 pcc;
+
+ pcc = __raw_readl(prcm_clksrc_ctrl);
+
+ __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+
+ return 0;
+}
+
+/*
+ * XXX This does not actually disable the osc_ck, since doing so would
+ * immediately halt the system. Instead, this function is used to
+ * enable an autoidle mode on the osc_ck. The existing
+ * clk_enable/clk_disable()-based usecounting for osc_ck should be
+ * replaced with autoidle-based usecounting.
+ */
+static void omap2_disable_osc_ck(struct clk *clk)
+{
+ u32 pcc;
+
+ pcc = __raw_readl(prcm_clksrc_ctrl);
+
+ __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+}
+
+const struct clkops clkops_oscck = {
+ .enable = omap2_enable_osc_ck,
+ .disable = omap2_disable_osc_ck,
+};
+
+unsigned long omap2_osc_clk_recalc(struct clk *clk)
+{
+ return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
+}
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c
new file mode 100644
index 00000000000..8693cfdac49
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_sys.c
@@ -0,0 +1,50 @@
+/*
+ * OMAP2xxx sys_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+void __iomem *prcm_clksrc_ctrl;
+
+u32 omap2xxx_get_sysclkdiv(void)
+{
+ u32 div;
+
+ div = __raw_readl(prcm_clksrc_ctrl);
+ div &= OMAP_SYSCLKDIV_MASK;
+ div >>= OMAP_SYSCLKDIV_SHIFT;
+
+ return div;
+}
+
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
+{
+ return clk->parent->rate / omap2xxx_get_sysclkdiv();
+}
+
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
new file mode 100644
index 00000000000..39f9d5a58d0
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -0,0 +1,246 @@
+/*
+ * OMAP2xxx DVFS virtual clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX Some of this code should be replaceable by the upcoming OPP layer
+ * code. However, some notion of "rate set" is probably still necessary
+ * for OMAP2xxx at least. Rate sets should be generalized so they can be
+ * used for any OMAP chip, not just OMAP2xxx. In particular, Richard Woodruff
+ * has in the past expressed a preference to use rate sets for OPP changes,
+ * rather than dynamically recalculating the clock tree, so if someone wants
+ * this badly enough to write the code to handle it, we should support it
+ * as an option.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+const struct prcm_config *curr_prcm_set;
+const struct prcm_config *rate_table;
+
+/**
+ * omap2_table_mpu_recalc - just return the MPU speed
+ * @clk: virt_prcm_set struct clk
+ *
+ * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
+ */
+unsigned long omap2_table_mpu_recalc(struct clk *clk)
+{
+ return curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+ const struct prcm_config *ptr;
+ long highest_rate;
+
+ highest_rate = -EINVAL;
+
+ for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+ if (!(ptr->flags & cpu_mask))
+ continue;
+ if (ptr->xtal_speed != sclk->rate)
+ continue;
+
+ highest_rate = ptr->mpu_speed;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->mpu_speed <= rate)
+ break;
+ }
+ return highest_rate;
+}
+
+/* Sets basic clocks based on the specified rate */
+int omap2_select_table_rate(struct clk *clk, unsigned long rate)
+{
+ u32 cur_rate, done_rate, bypass = 0, tmp;
+ const struct prcm_config *prcm;
+ unsigned long found_speed = 0;
+ unsigned long flags;
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+
+ if (prcm->xtal_speed != sclk->rate)
+ continue;
+
+ if (prcm->mpu_speed <= rate) {
+ found_speed = prcm->mpu_speed;
+ break;
+ }
+ }
+
+ if (!found_speed) {
+ printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+ rate / 1000000);
+ return -EINVAL;
+ }
+
+ curr_prcm_set = prcm;
+ cur_rate = omap2xxx_clk_get_core_rate(dclk);
+
+ if (prcm->dpll_speed == cur_rate / 2) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+ } else if (prcm->dpll_speed == cur_rate * 2) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+ } else if (prcm->dpll_speed != cur_rate) {
+ local_irq_save(flags);
+
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ bypass = 1;
+
+ if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
+ CORE_CLK_SRC_DPLL_X2)
+ done_rate = CORE_CLK_SRC_DPLL_X2;
+ else
+ done_rate = CORE_CLK_SRC_DPLL;
+
+ /* MPU divider */
+ omap2_cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
+
+ /* dsp + iva1 div(2420), iva2.1(2430) */
+ omap2_cm_write_mod_reg(prcm->cm_clksel_dsp,
+ OMAP24XX_DSP_MOD, CM_CLKSEL);
+
+ omap2_cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
+
+ /* Major subsystem dividers */
+ tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
+ omap2_cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+ CM_CLKSEL1);
+
+ if (cpu_is_omap2430())
+ omap2_cm_write_mod_reg(prcm->cm_clksel_mdm,
+ OMAP2430_MDM_MOD, CM_CLKSEL);
+
+ /* x2 to enter omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+ omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+ bypass);
+
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
+
+ local_irq_restore(flags);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Walk PRCM rate table and fillout cpufreq freq_table
+ * XXX This should be replaced by an OPP layer in the near future
+ */
+static struct cpufreq_frequency_table *freq_table;
+
+void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ const struct prcm_config *prcm;
+ int i = 0;
+ int tbl_sz = 0;
+
+ if (!cpu_is_omap24xx())
+ return;
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sclk->rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ tbl_sz++;
+ }
+
+ /*
+ * XXX Ensure that we're doing what CPUFreq expects for this error
+ * case and the following one
+ */
+ if (tbl_sz == 0) {
+ pr_warning("%s: no matching entries in rate_table\n",
+ __func__);
+ return;
+ }
+
+ /* Include the CPUFREQ_TABLE_END terminator entry */
+ tbl_sz++;
+
+ freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
+ GFP_ATOMIC);
+ if (!freq_table) {
+ pr_err("%s: could not kzalloc frequency table\n", __func__);
+ return;
+ }
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sclk->rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = prcm->mpu_speed / 1000;
+ i++;
+ }
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ *table = &freq_table[0];
+}
+
+void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ if (!cpu_is_omap24xx())
+ return;
+
+ kfree(freq_table);
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
new file mode 100644
index 00000000000..d6e34dd9e7e
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -0,0 +1,122 @@
+/*
+ * OMAP34xx M2 divider clock code
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni Högander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "sdrc.h"
+
+#define CYCLES_PER_MHZ 1000000
+
+/*
+ * CORE DPLL (DPLL3) M2 divider rate programming functions
+ *
+ * These call into SRAM code to do the actual CM writes, since the SDRAM
+ * is clocked from DPLL3.
+ */
+
+/**
+ * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Program the DPLL M2 divider with the rounded target rate. Returns
+ * -EINVAL upon error, or 0 upon success.
+ */
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div = 0;
+ u32 unlock_dll = 0;
+ u32 c;
+ unsigned long validrate, sdrcrate, _mpurate;
+ struct omap_sdrc_params *sdrc_cs0;
+ struct omap_sdrc_params *sdrc_cs1;
+ int ret;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ sdrcrate = sdrc_ick_p->rate;
+ if (rate > clk->rate)
+ sdrcrate <<= ((rate / clk->rate) >> 1);
+ else
+ sdrcrate >>= ((clk->rate / rate) >> 1);
+
+ ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
+ if (ret)
+ return -EINVAL;
+
+ if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
+ pr_debug("clock: will unlock SDRC DLL\n");
+ unlock_dll = 1;
+ }
+
+ /*
+ * XXX This only needs to be done when the CPU frequency changes
+ */
+ _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
+ c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
+ c += 1; /* for safety */
+ c *= SDRC_MPURATE_LOOPS;
+ c >>= SDRC_MPURATE_SCALE;
+ if (c == 0)
+ c = 1;
+
+ pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+ validrate);
+ pr_debug("clock: SDRC CS0 timing params used:"
+ " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
+ if (sdrc_cs1)
+ pr_debug("clock: SDRC CS1 timing params used: "
+ " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+ sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+ sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+
+ if (sdrc_cs1)
+ omap3_configure_core_dpll(
+ new_div, unlock_dll, c, rate > clk->rate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+ sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+ else
+ omap3_configure_core_dpll(
+ new_div, unlock_dll, c, rate > clk->rate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ 0, 0, 0, 0);
+ clk->rate = rate;
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
new file mode 100644
index 00000000000..e25364de028
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -0,0 +1,509 @@
+/*
+ * clkt_clksel.c - OMAP2/3/4 clksel clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * clksel clocks are clocks that do not have a fixed parent, or that
+ * can divide their parent's rate, or possibly both at the same time, based
+ * on the contents of a hardware register bitfield.
+ *
+ * All of the various mux and divider settings can be encoded into
+ * struct clksel* data structures, and then these can be autogenerated
+ * from some hardware database for each new chip generation. This
+ * should avoid the need to write, review, and validate a lot of new
+ * clock code for each new chip, since it can be exported from the SoC
+ * design flow. This is now done on OMAP4.
+ *
+ * The fusion of mux and divider clocks is a software creation. In
+ * hardware reality, the multiplexer (parent selection) and the
+ * divider exist separately. XXX At some point these clksel clocks
+ * should be split into "divider" clocks and "mux" clocks to better
+ * match the hardware.
+ *
+ * (The name "clksel" comes from the name of the corresponding
+ * register field in the OMAP2/3 family of SoCs.)
+ *
+ * XXX Currently these clocks are only used in the OMAP2/3/4 code, but
+ * many of the OMAP1 clocks should be convertible to use this
+ * mechanism.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+
+/* Private functions */
+
+/**
+ * _get_clksel_by_parent() - return clksel struct for a given clk & parent
+ * @clk: OMAP struct clk ptr to inspect
+ * @src_clk: OMAP struct clk ptr of the parent clk to search for
+ *
+ * Scan the struct clksel array associated with the clock to find
+ * the element associated with the supplied parent clock address.
+ * Returns a pointer to the struct clksel on success or NULL on error.
+ */
+static const struct clksel *_get_clksel_by_parent(struct clk *clk,
+ struct clk *src_clk)
+{
+ const struct clksel *clks;
+
+ for (clks = clk->clksel; clks->parent; clks++)
+ if (clks->parent == src_clk)
+ break; /* Found the requested parent */
+
+ if (!clks->parent) {
+ /* This indicates a data problem */
+ WARN(1, "clock: Could not find parent clock %s in clksel array "
+ "of clock %s\n", src_clk->name, clk->name);
+ return NULL;
+ }
+
+ return clks;
+}
+
+/**
+ * _get_div_and_fieldval() - find the new clksel divisor and field value to use
+ * @src_clk: planned new parent struct clk *
+ * @clk: struct clk * that is being reparented
+ * @field_val: pointer to a u32 to contain the register data for the divisor
+ *
+ * Given an intended new parent struct clk * @src_clk, and the struct
+ * clk * @clk to the clock that is being reparented, find the
+ * appropriate rate divisor for the new clock (returned as the return
+ * value), and the corresponding register bitfield data to program to
+ * reach that divisor (returned in the u32 pointed to by @field_val).
+ * Returns 0 on error, or returns the newly-selected divisor upon
+ * success (in this latter case, the corresponding register bitfield
+ * value is passed back in the variable pointed to by @field_val)
+ */
+static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
+ u32 *field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr, *max_clkr = NULL;
+ u8 max_div = 0;
+
+ clks = _get_clksel_by_parent(clk, src_clk);
+ if (!clks)
+ return 0;
+
+ /*
+ * Find the highest divisor (e.g., the one resulting in the
+ * lowest rate) to use as the default. This should avoid
+ * clock rates that are too high for the device. XXX A better
+ * solution here would be to try to determine if there is a
+ * divisor matching the original clock rate before the parent
+ * switch, and if it cannot be found, to fall back to the
+ * highest divisor.
+ */
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->div > max_div) {
+ max_div = clkr->div;
+ max_clkr = clkr;
+ }
+ }
+
+ if (max_div == 0) {
+ /* This indicates an error in the clksel data */
+ WARN(1, "clock: Could not find divisor for clock %s parent %s"
+ "\n", clk->name, src_clk->parent->name);
+ return 0;
+ }
+
+ *field_val = max_clkr->val;
+
+ return max_div;
+}
+
+/**
+ * _write_clksel_reg() - program a clock's clksel register in hardware
+ * @clk: struct clk * to program
+ * @v: clksel bitfield value to program (with LSB at bit 0)
+ *
+ * Shift the clksel register bitfield value @v to its appropriate
+ * location in the clksel register and write it in. This function
+ * will ensure that the write to the clksel_reg reaches its
+ * destination before returning -- important since PRM and CM register
+ * accesses can be quite slow compared to ARM cycles -- but does not
+ * take into account any time the hardware might take to switch the
+ * clock source.
+ */
+static void _write_clksel_reg(struct clk *clk, u32 field_val)
+{
+ u32 v;
+
+ v = __raw_readl(clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ __raw_writel(v, clk->clksel_reg);
+
+ v = __raw_readl(clk->clksel_reg); /* OCP barrier */
+}
+
+/**
+ * _clksel_to_divisor() - turn clksel field value into integer divider
+ * @clk: OMAP struct clk to use
+ * @field_val: register field value to find
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a register field
+ * value to search for, find the corresponding clock divisor. The register
+ * field value should be pre-masked and shifted down so the LSB is at bit 0
+ * before calling. Returns 0 on error or returns the actual integer divisor
+ * upon success.
+ */
+static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ clks = _get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return 0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->val == field_val)
+ break;
+ }
+
+ if (!clkr->div) {
+ /* This indicates a data error */
+ WARN(1, "clock: Could not find fieldval %d for clock %s parent "
+ "%s\n", field_val, clk->name, clk->parent->name);
+ return 0;
+ }
+
+ return clkr->div;
+}
+
+/**
+ * _divisor_to_clksel() - turn clksel integer divisor into a field value
+ * @clk: OMAP struct clk to use
+ * @div: integer divisor to search for
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a clock
+ * divisor, find the corresponding register field value. Returns the
+ * register field value _before_ left-shifting (i.e., LSB is at bit
+ * 0); or returns 0xFFFFFFFF (~0) upon error.
+ */
+static u32 _divisor_to_clksel(struct clk *clk, u32 div)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ /* should never happen */
+ WARN_ON(div == 0);
+
+ clks = _get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return ~0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->div == div)
+ break;
+ }
+
+ if (!clkr->div) {
+ pr_err("clock: Could not find divisor %d for clock %s parent "
+ "%s\n", div, clk->name, clk->parent->name);
+ return ~0;
+ }
+
+ return clkr->val;
+}
+
+/**
+ * _read_divisor() - get current divisor applied to parent clock (from hdwr)
+ * @clk: OMAP struct clk to use.
+ *
+ * Read the current divisor register value for @clk that is programmed
+ * into the hardware, convert it into the actual divisor value, and
+ * return it; or return 0 on error.
+ */
+static u32 _read_divisor(struct clk *clk)
+{
+ u32 v;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return 0;
+
+ v = __raw_readl(clk->clksel_reg);
+ v &= clk->clksel_mask;
+ v >>= __ffs(clk->clksel_mask);
+
+ return _clksel_to_divisor(clk, v);
+}
+
+/* Public functions */
+
+/**
+ * omap2_clksel_round_rate_div() - find divisor for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ * @new_div: ptr to where we should store the divisor
+ *
+ * Finds 'best' divider value in an array based on the source and target
+ * rates. The divider array must be sorted with smallest divider first.
+ * This function is also used by the DPLL3 M2 divider code.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+ u32 *new_div)
+{
+ unsigned long test_rate;
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 last_div = 0;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return ~0;
+
+ pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
+ clk->name, target_rate);
+
+ *new_div = 1;
+
+ clks = _get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return ~0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ /* Sanity check */
+ if (clkr->div <= last_div)
+ pr_err("clock: clksel_rate table not sorted "
+ "for clock %s", clk->name);
+
+ last_div = clkr->div;
+
+ test_rate = clk->parent->rate / clkr->div;
+
+ if (test_rate <= target_rate)
+ break; /* found it */
+ }
+
+ if (!clkr->div) {
+ pr_err("clock: Could not find divisor for target "
+ "rate %ld for clock %s parent %s\n", target_rate,
+ clk->name, clk->parent->name);
+ return ~0;
+ }
+
+ *new_div = clkr->div;
+
+ pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+ (clk->parent->rate / clkr->div));
+
+ return clk->parent->rate / clkr->div;
+}
+
+/*
+ * Clocktype interface functions to the OMAP clock code
+ * (i.e., those used in struct clk field function pointers, etc.)
+ */
+
+/**
+ * omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Given a pointer @clk to a source-selectable struct clk, read the
+ * hardware register and determine what its parent is currently set
+ * to. Update @clk's .parent field with the appropriate clk ptr. No
+ * return value.
+ */
+void omap2_init_clksel_parent(struct clk *clk)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 r, found = 0;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return;
+
+ r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+ r >>= __ffs(clk->clksel_mask);
+
+ for (clks = clk->clksel; clks->parent && !found; clks++) {
+ for (clkr = clks->rates; clkr->div && !found; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->val == r) {
+ if (clk->parent != clks->parent) {
+ pr_debug("clock: inited %s parent "
+ "to %s (was %s)\n",
+ clk->name, clks->parent->name,
+ ((clk->parent) ?
+ clk->parent->name : "NULL"));
+ clk_reparent(clk, clks->parent);
+ };
+ found = 1;
+ }
+ }
+ }
+
+ /* This indicates a data error */
+ WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
+ clk->name, r);
+
+ return;
+}
+
+/**
+ * omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field
+ * @clk: struct clk *
+ *
+ * This function is intended to be called only by the clock framework.
+ * Each clksel clock should have its struct clk .recalc field set to this
+ * function. Returns the clock's current rate, based on its parent's rate
+ * and its current divisor setting in the hardware.
+ */
+unsigned long omap2_clksel_recalc(struct clk *clk)
+{
+ unsigned long rate;
+ u32 div = 0;
+
+ div = _read_divisor(clk);
+ if (div == 0)
+ return clk->rate;
+
+ rate = clk->parent->rate / div;
+
+ pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name,
+ rate, div);
+
+ return rate;
+}
+
+/**
+ * omap2_clksel_round_rate() - find rounded rate for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ *
+ * This function is intended to be called only by the clock framework.
+ * Finds best target rate based on the source clock and possible dividers.
+ * rates. The divider array must be sorted with smallest divider first.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ u32 new_div;
+
+ return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
+}
+
+/**
+ * omap2_clksel_set_rate() - program clock rate in hardware
+ * @clk: struct clk * to program rate
+ * @rate: target rate to program
+ *
+ * This function is intended to be called only by the clock framework.
+ * Program @clk's rate to @rate in the hardware. The clock can be
+ * either enabled or disabled when this happens, although if the clock
+ * is enabled, some downstream devices may glitch or behave
+ * unpredictably when the clock rate is changed - this depends on the
+ * hardware. This function does not currently check the usecount of
+ * the clock, so if multiple drivers are using the clock, and the rate
+ * is changed, they will all be affected without any notification.
+ * Returns -EINVAL upon error, or 0 upon success.
+ */
+int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 field_val, validrate, new_div = 0;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ field_val = _divisor_to_clksel(clk, new_div);
+ if (field_val == ~0)
+ return -EINVAL;
+
+ _write_clksel_reg(clk, field_val);
+
+ clk->rate = clk->parent->rate / new_div;
+
+ pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate);
+
+ return 0;
+}
+
+/*
+ * Clksel parent setting function - not passed in struct clk function
+ * pointer - instead, the OMAP clock code currently assumes that any
+ * parent-setting clock is a clksel clock, and calls
+ * omap2_clksel_set_parent() by default
+ */
+
+/**
+ * omap2_clksel_set_parent() - change a clock's parent clock
+ * @clk: struct clk * of the child clock
+ * @new_parent: struct clk * of the new parent clock
+ *
+ * This function is intended to be called only by the clock framework.
+ * Change the parent clock of clock @clk to @new_parent. This is
+ * intended to be used while @clk is disabled. This function does not
+ * currently check the usecount of the clock, so if multiple drivers
+ * are using the clock, and the parent is changed, they will all be
+ * affected without any notification. Returns -EINVAL upon error, or
+ * 0 upon success.
+ */
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
+{
+ u32 field_val = 0;
+ u32 parent_div;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return -EINVAL;
+
+ parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
+ if (!parent_div)
+ return -EINVAL;
+
+ _write_clksel_reg(clk, field_val);
+
+ clk_reparent(clk, new_parent);
+
+ /* CLKSEL clocks follow their parents' rates, divided by a divisor */
+ clk->rate = new_parent->rate;
+
+ if (parent_div > 0)
+ clk->rate /= parent_div;
+
+ pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
+ clk->name, clk->parent->name, clk->rate);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
new file mode 100644
index 00000000000..e069a9be93d
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -0,0 +1,359 @@
+/*
+ * OMAP2/3/4 DPLL clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/div64.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* DPLL rate rounding: minimum DPLL multiplier, divider values */
+#define DPLL_MIN_MULTIPLIER 2
+#define DPLL_MIN_DIVIDER 1
+
+/* Possible error results from _dpll_test_mult */
+#define DPLL_MULT_UNDERFLOW -1
+
+/*
+ * Scale factor to mitigate roundoff errors in DPLL rate rounding.
+ * The higher the scale factor, the greater the risk of arithmetic overflow,
+ * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
+ * must be a power of DPLL_SCALE_BASE.
+ */
+#define DPLL_SCALE_FACTOR 64
+#define DPLL_SCALE_BASE 2
+#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
+ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
+
+/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
+#define OMAP3430_DPLL_FINT_BAND1_MIN 750000
+#define OMAP3430_DPLL_FINT_BAND1_MAX 2100000
+#define OMAP3430_DPLL_FINT_BAND2_MIN 7500000
+#define OMAP3430_DPLL_FINT_BAND2_MAX 21000000
+
+/*
+ * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
+ * From device data manual section 4.3 "DPLL and DLL Specifications".
+ */
+#define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000
+#define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000
+#define OMAP3PLUS_DPLL_FINT_MIN 32000
+#define OMAP3PLUS_DPLL_FINT_MAX 52000000
+
+/* _dpll_test_fint() return codes */
+#define DPLL_FINT_UNDERFLOW -1
+#define DPLL_FINT_INVALID -2
+
+/* Private functions */
+
+/*
+ * _dpll_test_fint - test whether an Fint value is valid for the DPLL
+ * @clk: DPLL struct clk to test
+ * @n: divider value (N) to test
+ *
+ * Tests whether a particular divider @n will result in a valid DPLL
+ * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
+ * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
+ * (assuming that it is counting N upwards), or -2 if the enclosing loop
+ * should skip to the next iteration (again assuming N is increasing).
+ */
+static int _dpll_test_fint(struct clk *clk, u8 n)
+{
+ struct dpll_data *dd;
+ long fint, fint_min, fint_max;
+ int ret = 0;
+
+ dd = clk->dpll_data;
+
+ /* DPLL divider must result in a valid jitter correction val */
+ fint = clk->parent->rate / n;
+
+ if (cpu_is_omap24xx()) {
+ /* Should not be called for OMAP2, so warn if it is called */
+ WARN(1, "No fint limits available for OMAP2!\n");
+ return DPLL_FINT_INVALID;
+ } else if (cpu_is_omap3430()) {
+ fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
+ fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
+ } else if (dd->flags & DPLL_J_TYPE) {
+ fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN;
+ fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;
+ } else {
+ fint_min = OMAP3PLUS_DPLL_FINT_MIN;
+ fint_max = OMAP3PLUS_DPLL_FINT_MAX;
+ }
+
+ if (fint < fint_min) {
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "lowering max_divider\n", n);
+ dd->max_divider = n;
+ ret = DPLL_FINT_UNDERFLOW;
+ } else if (fint > fint_max) {
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "boosting min_divider\n", n);
+ dd->min_divider = n;
+ ret = DPLL_FINT_INVALID;
+ } else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX &&
+ fint < OMAP3430_DPLL_FINT_BAND2_MIN) {
+ pr_debug("rejecting n=%d due to Fint failure\n", n);
+ ret = DPLL_FINT_INVALID;
+ }
+
+ return ret;
+}
+
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+ unsigned int m, unsigned int n)
+{
+ unsigned long long num;
+
+ num = (unsigned long long)parent_rate * m;
+ do_div(num, n);
+ return num;
+}
+
+/*
+ * _dpll_test_mult - test a DPLL multiplier value
+ * @m: pointer to the DPLL m (multiplier) value under test
+ * @n: current DPLL n (divider) value under test
+ * @new_rate: pointer to storage for the resulting rounded rate
+ * @target_rate: the desired DPLL rate
+ * @parent_rate: the DPLL's parent clock rate
+ *
+ * This code tests a DPLL multiplier value, ensuring that the
+ * resulting rate will not be higher than the target_rate, and that
+ * the multiplier value itself is valid for the DPLL. Initially, the
+ * integer pointed to by the m argument should be prescaled by
+ * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
+ * a non-scaled m upon return. This non-scaled m will result in a
+ * new_rate as close as possible to target_rate (but not greater than
+ * target_rate) given the current (parent_rate, n, prescaled m)
+ * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
+ * non-scaled m attempted to underflow, which can allow the calling
+ * function to bail out early; or 0 upon success.
+ */
+static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
+ unsigned long target_rate,
+ unsigned long parent_rate)
+{
+ int r = 0, carry = 0;
+
+ /* Unscale m and round if necessary */
+ if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
+ carry = 1;
+ *m = (*m / DPLL_SCALE_FACTOR) + carry;
+
+ /*
+ * The new rate must be <= the target rate to avoid programming
+ * a rate that is impossible for the hardware to handle
+ */
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+ if (*new_rate > target_rate) {
+ (*m)--;
+ *new_rate = 0;
+ }
+
+ /* Guard against m underflow */
+ if (*m < DPLL_MIN_MULTIPLIER) {
+ *m = DPLL_MIN_MULTIPLIER;
+ *new_rate = 0;
+ r = DPLL_MULT_UNDERFLOW;
+ }
+
+ if (*new_rate == 0)
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+
+ return r;
+}
+
+/* Public functions */
+
+void omap2_init_dpll_parent(struct clk *clk)
+{
+ u32 v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return;
+
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ /* Reparent the struct clk in case the dpll is in bypass */
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ } else if (cpu_is_omap44xx()) {
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ }
+ return;
+}
+
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values. When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
+u32 omap2_get_dpll_rate(struct clk *clk)
+{
+ long long dpll_clk;
+ u32 dpll_mult, dpll_div, v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return 0;
+
+ /* Return bypass rate if DPLL is bypassed */
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap44xx()) {
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
+ return dd->clk_bypass->rate;
+ }
+
+ v = __raw_readl(dd->mult_div1_reg);
+ dpll_mult = v & dd->mult_mask;
+ dpll_mult >>= __ffs(dd->mult_mask);
+ dpll_div = v & dd->div1_mask;
+ dpll_div >>= __ffs(dd->div1_mask);
+
+ dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
+ do_div(dpll_clk, dpll_div + 1);
+
+ return dpll_clk;
+}
+
+/* DPLL rate rounding code */
+
+/**
+ * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
+ * @clk: struct clk * for a DPLL
+ * @target_rate: desired DPLL clock rate
+ *
+ * Given a DPLL and a desired target rate, round the target rate to a
+ * possible, programmable rate for this DPLL. Attempts to select the
+ * minimum possible n. Stores the computed (m, n) in the DPLL's
+ * dpll_data structure so set_rate() will not need to call this
+ * (expensive) function again. Returns ~0 if the target rate cannot
+ * be rounded, or the rounded rate upon success.
+ */
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ int m, n, r, scaled_max_m;
+ unsigned long scaled_rt_rp;
+ unsigned long new_rate = 0;
+ struct dpll_data *dd;
+
+ if (!clk || !clk->dpll_data)
+ return ~0;
+
+ dd = clk->dpll_data;
+
+ pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
+ clk->name, target_rate);
+
+ scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+ scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
+
+ dd->last_rounded_rate = 0;
+
+ for (n = dd->min_divider; n <= dd->max_divider; n++) {
+
+ /* Is the (input clk, divider) pair valid for the DPLL? */
+ r = _dpll_test_fint(clk, n);
+ if (r == DPLL_FINT_UNDERFLOW)
+ break;
+ else if (r == DPLL_FINT_INVALID)
+ continue;
+
+ /* Compute the scaled DPLL multiplier, based on the divider */
+ m = scaled_rt_rp * n;
+
+ /*
+ * Since we're counting n up, a m overflow means we
+ * can bail out completely (since as n increases in
+ * the next iteration, there's no way that m can
+ * increase beyond the current m)
+ */
+ if (m > scaled_max_m)
+ break;
+
+ r = _dpll_test_mult(&m, n, &new_rate, target_rate,
+ dd->clk_ref->rate);
+
+ /* m can't be set low enough for this n - try with a larger n */
+ if (r == DPLL_MULT_UNDERFLOW)
+ continue;
+
+ pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
+ clk->name, m, n, new_rate);
+
+ if (target_rate == new_rate) {
+ dd->last_rounded_m = m;
+ dd->last_rounded_n = n;
+ dd->last_rounded_rate = target_rate;
+ break;
+ }
+ }
+
+ if (target_rate != new_rate) {
+ pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,
+ target_rate);
+ return ~0;
+ }
+
+ return target_rate;
+}
+
diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c
new file mode 100644
index 00000000000..3d43fba2542
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_iclk.c
@@ -0,0 +1,82 @@
+/*
+ * OMAP2/3 interface clock control
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/* XXX */
+void omap2_clkt_iclk_allow_idle(struct clk *clk)
+{
+ u32 v, r;
+
+ r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+ v = __raw_readl((__force void __iomem *)r);
+ v |= (1 << clk->enable_bit);
+ __raw_writel(v, (__force void __iomem *)r);
+}
+
+/* XXX */
+void omap2_clkt_iclk_deny_idle(struct clk *clk)
+{
+ u32 v, r;
+
+ r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+ v = __raw_readl((__force void __iomem *)r);
+ v &= ~(1 << clk->enable_bit);
+ __raw_writel(v, (__force void __iomem *)r);
+}
+
+/* Public data */
+
+const struct clkops clkops_omap2_iclk_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_iclk_dflt = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_iclk_idle_only = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_mdmclk_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
new file mode 100644
index 00000000000..f57ed5baecc
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.c
@@ -0,0 +1,545 @@
+/*
+ * linux/arch/arm/mach-omap2/clock.c
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <trace/events/power.h>
+
+#include <asm/cpu.h>
+#include <plat/clock.h>
+#include "clockdomain.h"
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+u16 cpu_mask;
+
+/*
+ * clkdm_control: if true, then when a clock is enabled in the
+ * hardware, its clockdomain will first be enabled; and when a clock
+ * is disabled in the hardware, its clockdomain will be disabled
+ * afterwards.
+ */
+static bool clkdm_control = true;
+
+/*
+ * OMAP2+ specific clock functions
+ */
+
+/* Private functions */
+
+/**
+ * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
+ * @clk: struct clk * belonging to the module
+ *
+ * If the necessary clocks for the OMAP hardware IP block that
+ * corresponds to clock @clk are enabled, then wait for the module to
+ * indicate readiness (i.e., to leave IDLE). This code does not
+ * belong in the clock code and will be moved in the medium term to
+ * module-dependent code. No return value.
+ */
+static void _omap2_module_wait_ready(struct clk *clk)
+{
+ void __iomem *companion_reg, *idlest_reg;
+ u8 other_bit, idlest_bit, idlest_val;
+
+ /* Not all modules have multiple clocks that their IDLEST depends on */
+ if (clk->ops->find_companion) {
+ clk->ops->find_companion(clk, &companion_reg, &other_bit);
+ if (!(__raw_readl(companion_reg) & (1 << other_bit)))
+ return;
+ }
+
+ clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
+
+ omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
+ clk->name);
+}
+
+/* Public functions */
+
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk. Intended to be
+ * called during clk_register(). No return value.
+ */
+void omap2_init_clk_clkdm(struct clk *clk)
+{
+ struct clockdomain *clkdm;
+
+ if (!clk->clkdm_name)
+ return;
+
+ clkdm = clkdm_lookup(clk->clkdm_name);
+ if (clkdm) {
+ pr_debug("clock: associated clk %s to clkdm %s\n",
+ clk->name, clk->clkdm_name);
+ clk->clkdm = clkdm;
+ } else {
+ pr_debug("clock: could not associate clk %s to "
+ "clkdm %s\n", clk->name, clk->clkdm_name);
+ }
+}
+
+/**
+ * omap2_clk_disable_clkdm_control - disable clkdm control on clk enable/disable
+ *
+ * Prevent the OMAP clock code from calling into the clockdomain code
+ * when a hardware clock in that clockdomain is enabled or disabled.
+ * Intended to be called at init time from omap*_clk_init(). No
+ * return value.
+ */
+void __init omap2_clk_disable_clkdm_control(void)
+{
+ clkdm_control = false;
+}
+
+/**
+ * omap2_clk_dflt_find_companion - find companion clock to @clk
+ * @clk: struct clk * to find the companion clock of
+ * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
+ * @other_bit: u8 ** to return the companion clock bit shift in
+ *
+ * Note: We don't need special code here for INVERT_ENABLE for the
+ * time being since INVERT_ENABLE only applies to clocks enabled by
+ * CM_CLKEN_PLL
+ *
+ * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's
+ * just a matter of XORing the bits.
+ *
+ * Some clocks don't have companion clocks. For example, modules with
+ * only an interface clock (such as MAILBOXES) don't have a companion
+ * clock. Right now, this code relies on the hardware exporting a bit
+ * in the correct companion register that indicates that the
+ * nonexistent 'companion clock' is active. Future patches will
+ * associate this type of code with per-module data structures to
+ * avoid this issue, and remove the casts. No return value.
+ */
+void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+ u8 *other_bit)
+{
+ u32 r;
+
+ /*
+ * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
+ * it's just a matter of XORing the bits.
+ */
+ r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN));
+
+ *other_reg = (__force void __iomem *)r;
+ *other_bit = clk->enable_bit;
+}
+
+/**
+ * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
+ * @clk: struct clk * to find IDLEST info for
+ * @idlest_reg: void __iomem ** to return the CM_IDLEST va in
+ * @idlest_bit: u8 * to return the CM_IDLEST bit shift in
+ * @idlest_val: u8 * to return the idle status indicator
+ *
+ * Return the CM_IDLEST register address and bit shift corresponding
+ * to the module that "owns" this clock. This default code assumes
+ * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that
+ * the IDLEST register address ID corresponds to the CM_*CLKEN
+ * register address ID (e.g., that CM_FCLKEN2 corresponds to
+ * CM_IDLEST2). This is not true for all modules. No return value.
+ */
+void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+ u8 *idlest_bit, u8 *idlest_val)
+{
+ u32 r;
+
+ r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+ *idlest_reg = (__force void __iomem *)r;
+ *idlest_bit = clk->enable_bit;
+
+ /*
+ * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
+ * 34xx reverses this, just to keep us on our toes
+ * AM35xx uses both, depending on the module.
+ */
+ if (cpu_is_omap24xx())
+ *idlest_val = OMAP24XX_CM_IDLEST_VAL;
+ else if (cpu_is_omap34xx())
+ *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+ else
+ BUG();
+
+}
+
+int omap2_dflt_clk_enable(struct clk *clk)
+{
+ u32 v;
+
+ if (unlikely(clk->enable_reg == NULL)) {
+ pr_err("clock.c: Enable for %s without enable code\n",
+ clk->name);
+ return 0; /* REVISIT: -EINVAL */
+ }
+
+ v = __raw_readl(clk->enable_reg);
+ if (clk->flags & INVERT_ENABLE)
+ v &= ~(1 << clk->enable_bit);
+ else
+ v |= (1 << clk->enable_bit);
+ __raw_writel(v, clk->enable_reg);
+ v = __raw_readl(clk->enable_reg); /* OCP barrier */
+
+ if (clk->ops->find_idlest)
+ _omap2_module_wait_ready(clk);
+
+ return 0;
+}
+
+void omap2_dflt_clk_disable(struct clk *clk)
+{
+ u32 v;
+
+ if (!clk->enable_reg) {
+ /*
+ * 'Independent' here refers to a clock which is not
+ * controlled by its parent.
+ */
+ printk(KERN_ERR "clock: clk_disable called on independent "
+ "clock %s which has no enable_reg\n", clk->name);
+ return;
+ }
+
+ v = __raw_readl(clk->enable_reg);
+ if (clk->flags & INVERT_ENABLE)
+ v |= (1 << clk->enable_bit);
+ else
+ v &= ~(1 << clk->enable_bit);
+ __raw_writel(v, clk->enable_reg);
+ /* No OCP barrier needed here since it is a disable operation */
+}
+
+const struct clkops clkops_omap2_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+};
+
+const struct clkops clkops_omap2_dflt = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+};
+
+/**
+ * omap2_clk_disable - disable a clock, if the system is not using it
+ * @clk: struct clk * to disable
+ *
+ * Decrements the usecount on struct clk @clk. If there are no users
+ * left, call the clkops-specific clock disable function to disable it
+ * in hardware. If the clock is part of a clockdomain (which they all
+ * should be), request that the clockdomain be disabled. (It too has
+ * a usecount, and so will not be disabled in the hardware until it no
+ * longer has any users.) If the clock has a parent clock (most of
+ * them do), then call ourselves, recursing on the parent clock. This
+ * can cause an entire branch of the clock tree to be powered off by
+ * simply disabling one clock. Intended to be called with the clockfw_lock
+ * spinlock held. No return value.
+ */
+void omap2_clk_disable(struct clk *clk)
+{
+ if (clk->usecount == 0) {
+ WARN(1, "clock: %s: omap2_clk_disable() called, but usecount "
+ "already 0?", clk->name);
+ return;
+ }
+
+ pr_debug("clock: %s: decrementing usecount\n", clk->name);
+
+ clk->usecount--;
+
+ if (clk->usecount > 0)
+ return;
+
+ pr_debug("clock: %s: disabling in hardware\n", clk->name);
+
+ if (clk->ops && clk->ops->disable) {
+ trace_clock_disable(clk->name, 0, smp_processor_id());
+ clk->ops->disable(clk);
+ }
+
+ if (clkdm_control && clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, clk);
+
+ if (clk->parent)
+ omap2_clk_disable(clk->parent);
+}
+
+/**
+ * omap2_clk_enable - request that the system enable a clock
+ * @clk: struct clk * to enable
+ *
+ * Increments the usecount on struct clk @clk. If there were no users
+ * previously, then recurse up the clock tree, enabling all of the
+ * clock's parents and all of the parent clockdomains, and finally,
+ * enabling @clk's clockdomain, and @clk itself. Intended to be
+ * called with the clockfw_lock spinlock held. Returns 0 upon success
+ * or a negative error code upon failure.
+ */
+int omap2_clk_enable(struct clk *clk)
+{
+ int ret;
+
+ pr_debug("clock: %s: incrementing usecount\n", clk->name);
+
+ clk->usecount++;
+
+ if (clk->usecount > 1)
+ return 0;
+
+ pr_debug("clock: %s: enabling in hardware\n", clk->name);
+
+ if (clk->parent) {
+ ret = omap2_clk_enable(clk->parent);
+ if (ret) {
+ WARN(1, "clock: %s: could not enable parent %s: %d\n",
+ clk->name, clk->parent->name, ret);
+ goto oce_err1;
+ }
+ }
+
+ if (clkdm_control && clk->clkdm) {
+ ret = clkdm_clk_enable(clk->clkdm, clk);
+ if (ret) {
+ WARN(1, "clock: %s: could not enable clockdomain %s: "
+ "%d\n", clk->name, clk->clkdm->name, ret);
+ goto oce_err2;
+ }
+ }
+
+ if (clk->ops && clk->ops->enable) {
+ trace_clock_enable(clk->name, 1, smp_processor_id());
+ ret = clk->ops->enable(clk);
+ if (ret) {
+ WARN(1, "clock: %s: could not enable: %d\n",
+ clk->name, ret);
+ goto oce_err3;
+ }
+ }
+
+ return 0;
+
+oce_err3:
+ if (clkdm_control && clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, clk);
+oce_err2:
+ if (clk->parent)
+ omap2_clk_disable(clk->parent);
+oce_err1:
+ clk->usecount--;
+
+ return ret;
+}
+
+/* Given a clock and a rate apply a clock specific rounding function */
+long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->round_rate)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+
+/* Set the clock rate for a clock source */
+int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);
+
+ /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
+ if (clk->set_rate) {
+ trace_clock_set_rate(clk->name, rate, smp_processor_id());
+ ret = clk->set_rate(clk, rate);
+ }
+
+ return ret;
+}
+
+int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
+{
+ if (!clk->clksel)
+ return -EINVAL;
+
+ if (clk->parent == new_parent)
+ return 0;
+
+ return omap2_clksel_set_parent(clk, new_parent);
+}
+
+/* OMAP3/4 non-CORE DPLL clkops */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+
+const struct clkops clkops_omap3_noncore_dpll_ops = {
+ .enable = omap3_noncore_dpll_enable,
+ .disable = omap3_noncore_dpll_disable,
+ .allow_idle = omap3_dpll_allow_idle,
+ .deny_idle = omap3_dpll_deny_idle,
+};
+
+const struct clkops clkops_omap3_core_dpll_ops = {
+ .allow_idle = omap3_dpll_allow_idle,
+ .deny_idle = omap3_dpll_deny_idle,
+};
+
+#endif
+
+/*
+ * OMAP2+ clock reset and init functions
+ */
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+void omap2_clk_disable_unused(struct clk *clk)
+{
+ u32 regval32, v;
+
+ v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
+
+ regval32 = __raw_readl(clk->enable_reg);
+ if ((regval32 & (1 << clk->enable_bit)) == v)
+ return;
+
+ pr_debug("Disabling unused clock \"%s\"\n", clk->name);
+ if (cpu_is_omap34xx()) {
+ omap2_clk_enable(clk);
+ omap2_clk_disable(clk);
+ } else {
+ clk->ops->disable(clk);
+ }
+ if (clk->clkdm != NULL)
+ pwrdm_clkdm_state_switch(clk->clkdm);
+}
+#endif
+
+/**
+ * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
+ * @mpurate_ck_name: clk name of the clock to change rate
+ *
+ * Change the ARM MPU clock rate to the rate specified on the command
+ * line, if one was specified. @mpurate_ck_name should be
+ * "virt_prcm_set" on OMAP2xxx and "dpll1_ck" on OMAP34xx/OMAP36xx.
+ * XXX Does not handle voltage scaling - on OMAP2xxx this is currently
+ * handled by the virt_prcm_set clock, but this should be handled by
+ * the OPP layer. XXX This is intended to be handled by the OPP layer
+ * code in the near future and should be removed from the clock code.
+ * Returns -EINVAL if 'mpurate' is zero or if clk_set_rate() rejects
+ * the rate, -ENOENT if the struct clk referred to by @mpurate_ck_name
+ * cannot be found, or 0 upon success.
+ */
+int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name)
+{
+ struct clk *mpurate_ck;
+ int r;
+
+ if (!mpurate)
+ return -EINVAL;
+
+ mpurate_ck = clk_get(NULL, mpurate_ck_name);
+ if (WARN(IS_ERR(mpurate_ck), "Failed to get %s.\n", mpurate_ck_name))
+ return -ENOENT;
+
+ r = clk_set_rate(mpurate_ck, mpurate);
+ if (IS_ERR_VALUE(r)) {
+ WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",
+ mpurate_ck->name, mpurate, r);
+ clk_put(mpurate_ck);
+ return -EINVAL;
+ }
+
+ calibrate_delay();
+ recalculate_root_clocks();
+
+ clk_put(mpurate_ck);
+
+ return 0;
+}
+
+/**
+ * omap2_clk_print_new_rates - print summary of current clock tree rates
+ * @hfclkin_ck_name: clk name for the off-chip HF oscillator
+ * @core_ck_name: clk name for the on-chip CORE_CLK
+ * @mpu_ck_name: clk name for the ARM MPU clock
+ *
+ * Prints a short message to the console with the HFCLKIN oscillator
+ * rate, the rate of the CORE clock, and the rate of the ARM MPU clock.
+ * Called by the boot-time MPU rate switching code. XXX This is intended
+ * to be handled by the OPP layer code in the near future and should be
+ * removed from the clock code. No return value.
+ */
+void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,
+ const char *core_ck_name,
+ const char *mpu_ck_name)
+{
+ struct clk *hfclkin_ck, *core_ck, *mpu_ck;
+ unsigned long hfclkin_rate;
+
+ mpu_ck = clk_get(NULL, mpu_ck_name);
+ if (WARN(IS_ERR(mpu_ck), "clock: failed to get %s.\n", mpu_ck_name))
+ return;
+
+ core_ck = clk_get(NULL, core_ck_name);
+ if (WARN(IS_ERR(core_ck), "clock: failed to get %s.\n", core_ck_name))
+ return;
+
+ hfclkin_ck = clk_get(NULL, hfclkin_ck_name);
+ if (WARN(IS_ERR(hfclkin_ck), "Failed to get %s.\n", hfclkin_ck_name))
+ return;
+
+ hfclkin_rate = clk_get_rate(hfclkin_ck);
+
+ pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
+ "%ld.%01ld/%ld/%ld MHz\n",
+ (hfclkin_rate / 1000000),
+ ((hfclkin_rate / 100000) % 10),
+ (clk_get_rate(core_ck) / 1000000),
+ (clk_get_rate(mpu_ck) / 1000000));
+}
+
+/* Common data */
+
+struct clk_functions omap2_clk_functions = {
+ .clk_enable = omap2_clk_enable,
+ .clk_disable = omap2_clk_disable,
+ .clk_round_rate = omap2_clk_round_rate,
+ .clk_set_rate = omap2_clk_set_rate,
+ .clk_set_parent = omap2_clk_set_parent,
+ .clk_disable_unused = omap2_clk_disable_unused,
+#ifdef CONFIG_CPU_FREQ
+ /* These will be removed when the OPP code is integrated */
+ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
+ .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
+#endif
+};
+
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
new file mode 100644
index 00000000000..b8c2a686481
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.h
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-omap2/clock.h
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_H
+
+#include <linux/kernel.h>
+
+#include <plat/clock.h>
+
+/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
+#define CORE_CLK_SRC_32K 0x0
+#define CORE_CLK_SRC_DPLL 0x1
+#define CORE_CLK_SRC_DPLL_X2 0x2
+
+/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP2XXX_EN_DPLL_LPBYPASS 0x1
+#define OMAP2XXX_EN_DPLL_FRBYPASS 0x2
+#define OMAP2XXX_EN_DPLL_LOCKED 0x3
+
+/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP3XXX_EN_DPLL_LPBYPASS 0x5
+#define OMAP3XXX_EN_DPLL_FRBYPASS 0x6
+#define OMAP3XXX_EN_DPLL_LOCKED 0x7
+
+/* OMAP4xxx CM_CLKMODE_DPLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP4XXX_EN_DPLL_MNBYPASS 0x4
+#define OMAP4XXX_EN_DPLL_LPBYPASS 0x5
+#define OMAP4XXX_EN_DPLL_FRBYPASS 0x6
+#define OMAP4XXX_EN_DPLL_LOCKED 0x7
+
+/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
+#define DPLL_LOW_POWER_STOP 0x1
+#define DPLL_LOW_POWER_BYPASS 0x5
+#define DPLL_LOCKED 0x7
+
+/* DPLL Type and DCO Selection Flags */
+#define DPLL_J_TYPE 0x1
+
+int omap2_clk_enable(struct clk *clk);
+void omap2_clk_disable(struct clk *clk);
+long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
+int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
+int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
+unsigned long omap3_dpll_recalc(struct clk *clk);
+unsigned long omap3_clkoutx2_recalc(struct clk *clk);
+void omap3_dpll_allow_idle(struct clk *clk);
+void omap3_dpll_deny_idle(struct clk *clk);
+u32 omap3_dpll_autoidle_read(struct clk *clk);
+int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
+int omap3_noncore_dpll_enable(struct clk *clk);
+void omap3_noncore_dpll_disable(struct clk *clk);
+int omap4_dpllmx_gatectrl_read(struct clk *clk);
+void omap4_dpllmx_allow_gatectrl(struct clk *clk);
+void omap4_dpllmx_deny_gatectrl(struct clk *clk);
+long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate);
+unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk);
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+void omap2_clk_disable_unused(struct clk *clk);
+#else
+#define omap2_clk_disable_unused NULL
+#endif
+
+void omap2_init_clk_clkdm(struct clk *clk);
+void __init omap2_clk_disable_clkdm_control(void);
+
+/* clkt_clksel.c public functions */
+u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+ u32 *new_div);
+void omap2_init_clksel_parent(struct clk *clk);
+unsigned long omap2_clksel_recalc(struct clk *clk);
+long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
+int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
+
+/* clkt_iclk.c public functions */
+extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
+extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
+
+u32 omap2_get_dpll_rate(struct clk *clk);
+void omap2_init_dpll_parent(struct clk *clk);
+
+int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
+
+
+#ifdef CONFIG_ARCH_OMAP2
+void omap2xxx_clk_prepare_for_reboot(void);
+#else
+static inline void omap2xxx_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+void omap3_clk_prepare_for_reboot(void);
+#else
+static inline void omap3_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void omap4_clk_prepare_for_reboot(void);
+#else
+static inline void omap4_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+int omap2_dflt_clk_enable(struct clk *clk);
+void omap2_dflt_clk_disable(struct clk *clk);
+void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+ u8 *other_bit);
+void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+ u8 *idlest_bit, u8 *idlest_val);
+int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
+void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
+ const char *core_ck_name,
+ const char *mpu_ck_name);
+
+extern u16 cpu_mask;
+
+extern const struct clkops clkops_omap2_dflt_wait;
+extern const struct clkops clkops_dummy;
+extern const struct clkops clkops_omap2_dflt;
+
+extern struct clk_functions omap2_clk_functions;
+extern struct clk *vclk, *sclk;
+
+extern const struct clksel_rate gpt_32k_rates[];
+extern const struct clksel_rate gpt_sys_rates[];
+extern const struct clksel_rate gfx_l3_rates[];
+extern const struct clksel_rate dsp_ick_rates[];
+
+#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
+extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#else
+#define omap2_clk_init_cpufreq_table 0
+#define omap2_clk_exit_cpufreq_table 0
+#endif
+
+extern const struct clkops clkops_omap2_iclk_dflt_wait;
+extern const struct clkops clkops_omap2_iclk_dflt;
+extern const struct clkops clkops_omap2_iclk_idle_only;
+extern const struct clkops clkops_omap2_mdmclk_dflt_wait;
+extern const struct clkops clkops_omap2xxx_dpll_ops;
+extern const struct clkops clkops_omap3_noncore_dpll_ops;
+extern const struct clkops clkops_omap3_core_dpll_ops;
+extern const struct clkops clkops_omap4_dpllmx_ops;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
new file mode 100644
index 00000000000..61ad3855f10
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -0,0 +1,2006 @@
+/*
+ * OMAP2420 clock data
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "control.h"
+
+#define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
+
+/*
+ * 2420 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ * many cases the parent is selectable. The set parent calls will
+ * also switch sources.
+ *
+ * Several sources are given initial rates which may be wrong, this will
+ * be fixed up in the init func.
+ *
+ * Things are broadly separated below by clock domains. It is
+ * noteworthy that most peripherals have dependencies on multiple clock
+ * domains. Many get their interface clocks from the L4 domain, but get
+ * functional clocks from fixed sources or other core domain derived
+ * clocks.
+ */
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+ .name = "func_32k_ck",
+ .ops = &clkops_null,
+ .rate = 32768,
+ .clkdm_name = "wkup_clkdm",
+};
+
+static struct clk secure_32k_ck = {
+ .name = "secure_32k_ck",
+ .ops = &clkops_null,
+ .rate = 32768,
+ .clkdm_name = "wkup_clkdm",
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
+ .name = "osc_ck",
+ .ops = &clkops_oscck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_osc_clk_recalc,
+};
+
+/* Without modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
+ .name = "sys_ck", /* ~ ref_clk also */
+ .ops = &clkops_null,
+ .parent = &osc_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2xxx_sys_clk_recalc,
+};
+
+static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
+ .name = "alt_ck",
+ .ops = &clkops_null,
+ .rate = 54000000,
+ .clkdm_name = "wkup_clkdm",
+};
+
+/* Optional external clock input for McBSP CLKS */
+static struct clk mcbsp_clks = {
+ .name = "mcbsp_clks",
+ .ops = &clkops_null,
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+/* REVISIT: Rate changes on dpll_ck trigger a full set change. ...
+ * deal with this
+ */
+
+static struct dpll_data dpll_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .mult_mask = OMAP24XX_DPLL_MULT_MASK,
+ .div1_mask = OMAP24XX_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP24XX_EN_DPLL_MASK,
+ .max_multiplier = 1023,
+ .min_divider = 1,
+ .max_divider = 16,
+};
+
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
+static struct clk dpll_ck = {
+ .name = "dpll_ck",
+ .ops = &clkops_omap2xxx_dpll_ops,
+ .parent = &sys_ck, /* Can be func_32k also */
+ .dpll_data = &dpll_dd,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_dpllcore_recalc,
+ .set_rate = &omap2_reprogram_dpllcore,
+};
+
+static struct clk apll96_ck = {
+ .name = "apll96_ck",
+ .ops = &clkops_apll96,
+ .parent = &sys_ck,
+ .rate = 96000000,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT,
+};
+
+static struct clk apll54_ck = {
+ .name = "apll54_ck",
+ .ops = &clkops_apll54,
+ .parent = &sys_ck,
+ .rate = 54000000,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT,
+};
+
+/*
+ * PRCM digital base sources
+ */
+
+/* func_54m_ck */
+
+static const struct clksel_rate func_54m_apll54_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_54m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel func_54m_clksel[] = {
+ { .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
+ { .parent = &alt_ck, .rates = func_54m_alt_rates, },
+ { .parent = NULL },
+};
+
+static struct clk func_54m_ck = {
+ .name = "func_54m_ck",
+ .ops = &clkops_null,
+ .parent = &apll54_ck, /* can also be alt_clk */
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_54M_SOURCE_MASK,
+ .clksel = func_54m_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+ .name = "core_ck",
+ .ops = &clkops_null,
+ .parent = &dpll_ck, /* can also be 32k */
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk func_96m_ck = {
+ .name = "func_96m_ck",
+ .ops = &clkops_null,
+ .parent = &apll96_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* func_48m_ck */
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+ { .div = 2, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel func_48m_clksel[] = {
+ { .parent = &apll96_ck, .rates = func_48m_apll96_rates },
+ { .parent = &alt_ck, .rates = func_48m_alt_rates },
+ { .parent = NULL }
+};
+
+static struct clk func_48m_ck = {
+ .name = "func_48m_ck",
+ .ops = &clkops_null,
+ .parent = &apll96_ck, /* 96M or Alt */
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_48M_SOURCE_MASK,
+ .clksel = func_48m_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk func_12m_ck = {
+ .name = "func_12m_ck",
+ .ops = &clkops_null,
+ .parent = &func_48m_ck,
+ .fixed_div = 4,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+ .name = "ck_wdt1_osc",
+ .ops = &clkops_null, /* RMK: missing? */
+ .parent = &osc_ck,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The common_clkout* clksel_rate structs are common to
+ * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
+ * sys_clkout2_* are 2420-only, so the
+ * clksel_rate flags fields are inaccurate for those clocks. This is
+ * harmless since access to those clocks are gated by the struct clk
+ * flags fields, which mark them as 2420-only.
+ */
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+ { .parent = &core_ck, .rates = common_clkout_src_core_rates },
+ { .parent = &sys_ck, .rates = common_clkout_src_sys_rates },
+ { .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+ { .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+ { .parent = NULL }
+};
+
+static struct clk sys_clkout_src = {
+ .name = "sys_clkout_src",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .enable_bit = OMAP24XX_CLKOUT_EN_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP24XX_CLKOUT_SOURCE_MASK,
+ .clksel = common_clkout_src_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate common_clkout_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 16, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel sys_clkout_clksel[] = {
+ { .parent = &sys_clkout_src, .rates = common_clkout_rates },
+ { .parent = NULL }
+};
+
+static struct clk sys_clkout = {
+ .name = "sys_clkout",
+ .ops = &clkops_null,
+ .parent = &sys_clkout_src,
+ .clkdm_name = "wkup_clkdm",
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP24XX_CLKOUT_DIV_MASK,
+ .clksel = sys_clkout_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2_src = {
+ .name = "sys_clkout2_src",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .enable_bit = OMAP2420_CLKOUT2_EN_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP2420_CLKOUT2_SOURCE_MASK,
+ .clksel = common_clkout_src_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+ { .parent = &sys_clkout2_src, .rates = common_clkout_rates },
+ { .parent = NULL }
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2 = {
+ .name = "sys_clkout2",
+ .ops = &clkops_null,
+ .parent = &sys_clkout2_src,
+ .clkdm_name = "wkup_clkdm",
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP2420_CLKOUT2_DIV_MASK,
+ .clksel = sys_clkout2_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk emul_ck = {
+ .name = "emul_ck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2420_PRCM_CLKEMUL_CTRL,
+ .enable_bit = OMAP24XX_EMULATION_EN_SHIFT,
+ .recalc = &followparent_recalc,
+
+};
+
+/*
+ * MPU clock domain
+ * Clocks:
+ * MPU_FCLK, MPU_ICLK
+ * INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static const struct clksel_rate mpu_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_242X },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 0 },
+};
+
+static const struct clksel mpu_clksel[] = {
+ { .parent = &core_ck, .rates = mpu_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk mpu_ck = { /* Control cpu */
+ .name = "mpu_ck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .clkdm_name = "mpu_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_MPU_MASK,
+ .clksel = mpu_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2420-UMA+IVA1) clock domain
+ * Clocks:
+ * 2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
+ *
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static const struct clksel_rate dsp_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 12, .val = 12, .flags = RATE_IN_242X },
+ { .div = 0 },
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+ { .parent = &core_ck, .rates = dsp_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk dsp_fck = {
+ .name = "dsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "dsp_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_MASK,
+ .clksel = dsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel dsp_ick_clksel[] = {
+ { .parent = &dsp_fck, .rates = dsp_ick_rates },
+ { .parent = NULL }
+};
+
+static struct clk dsp_ick = {
+ .name = "dsp_ick", /* apparently ipi and isp */
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &dsp_fck,
+ .clkdm_name = "dsp_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP2420_EN_DSP_IPI_SHIFT, /* for ipi */
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
+ .clksel = dsp_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
+ * the C54x, but which is contained in the DSP powerdomain. Does not
+ * exist on later OMAPs.
+ */
+static struct clk iva1_ifck = {
+ .name = "iva1_ifck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "iva1_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP2420_EN_IVA_COP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP2420_CLKSEL_IVA_MASK,
+ .clksel = dsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* IVA1 mpu/int/i/f clocks are /2 of parent */
+static struct clk iva1_mpu_int_ifck = {
+ .name = "iva1_mpu_int_ifck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &iva1_ifck,
+ .clkdm_name = "iva1_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP2420_EN_IVA_MPU_SHIFT,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ * CAM, HS-USB.
+ * F-CLOCK
+ * SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static const struct clksel_rate core_l3_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_242X },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 12, .val = 12, .flags = RATE_IN_242X },
+ { .div = 16, .val = 16, .flags = RATE_IN_242X },
+ { .div = 0 }
+};
+
+static const struct clksel core_l3_clksel[] = {
+ { .parent = &core_ck, .rates = core_l3_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
+ .name = "core_l3_ck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L3_MASK,
+ .clksel = core_l3_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* usb_l4_ick */
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+ { .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+ { .parent = NULL },
+};
+
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
+static struct clk usb_l4_ick = { /* FS-USB interface clock */
+ .name = "usb_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_USB_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_USB_MASK,
+ .clksel = usb_l4_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks. Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+ { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+ { .parent = NULL }
+};
+
+static struct clk l4_ck = { /* used both as an ick and fck */
+ .name = "l4_ck",
+ .ops = &clkops_null,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L4_MASK,
+ .clksel = l4_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+ { .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk ssi_ssr_sst_fck = {
+ .name = "ssi_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_SSI_MASK,
+ .clksel = ssi_ssr_sst_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+ .name = "ssi_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+
+/*
+ * GFX clock domain
+ * Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+
+/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
+static const struct clksel gfx_fck_clksel[] = {
+ { .parent = &core_l3_ck, .rates = gfx_l3_rates },
+ { .parent = NULL },
+};
+
+static struct clk gfx_3d_fck = {
+ .name = "gfx_3d_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .par