diff options
author | Anton Arapov <anton@redhat.com> | 2012-04-16 10:05:28 +0200 |
---|---|---|
committer | Anton Arapov <anton@redhat.com> | 2012-04-16 10:05:28 +0200 |
commit | b4b6116a13633898cf868f2f103c96a90c4c20f8 (patch) | |
tree | 93d1b7e2cfcdf473d8d4ff3ad141fa864f8491f6 /arch/arm/mach-pxa | |
parent | edd4be777c953e5faafc80d091d3084b4343f5d3 (diff) | |
download | kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.gz kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.xz kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.zip |
fedora kernel: d9aad82f3319f3cfd1aebc01234254ef0c37ad84v3.3.2-1
Signed-off-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'arch/arm/mach-pxa')
198 files changed, 49666 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig new file mode 100644 index 00000000000..61d3c72ded8 --- /dev/null +++ b/arch/arm/mach-pxa/Kconfig @@ -0,0 +1,719 @@ +if ARCH_PXA + +menu "Intel PXA2xx/PXA3xx Implementations" + +config ARCH_PXA_V7 + bool "ARMv7 (PXA95x) based systems" + +if ARCH_PXA_V7 +comment "Marvell Dev Platforms (sorted by hardware release time)" +config MACH_TAVOREVB3 + bool "PXA95x Development Platform (aka TavorEVB III)" + select CPU_PXA955 + +config MACH_SAARB + bool "PXA955 Handheld Platform (aka SAARB)" + select CPU_PXA955 +endif + +config PXA_V7_MACH_AUTO + def_bool y + depends on ARCH_PXA_V7 + depends on !MACH_SAARB + select MACH_TAVOREVB3 + +if !ARCH_PXA_V7 +comment "Intel/Marvell Dev Platforms (sorted by hardware release time)" + +config ARCH_LUBBOCK + bool "Intel DBPXA250 Development Platform (aka Lubbock)" + select PXA25x + select SA1111 + +config MACH_MAINSTONE + bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)" + select PXA27x + select HAVE_PWM + +config MACH_ZYLONITE + bool + select PXA3xx + select HAVE_PWM + +config MACH_ZYLONITE300 + bool "PXA3xx Development Platform (aka Zylonite) PXA300/310" + select CPU_PXA300 + select CPU_PXA310 + select MACH_ZYLONITE + +config MACH_ZYLONITE320 + bool "PXA3xx Development Platform (aka Zylonite) PXA320" + select CPU_PXA320 + select MACH_ZYLONITE + +config MACH_LITTLETON + bool "PXA3xx Form Factor Platform (aka Littleton)" + select PXA3xx + select CPU_PXA300 + select CPU_PXA310 + +config MACH_TAVOREVB + bool "PXA930 Evaluation Board (aka TavorEVB)" + select PXA3xx + select CPU_PXA930 + +config MACH_SAAR + bool "PXA930 Handheld Platform (aka SAAR)" + select PXA3xx + select CPU_PXA930 + +comment "Third Party Dev Platforms (sorted by vendor name)" + +config ARCH_PXA_IDP + bool "Accelent Xscale IDP" + select PXA25x + +config ARCH_VIPER + bool "Arcom/Eurotech VIPER SBC" + select PXA25x + select ISA + select I2C_GPIO + select HAVE_PWM + select PXA_HAVE_ISA_IRQS + select ARCOM_PCMCIA + +config MACH_ARCOM_ZEUS + bool "Arcom/Eurotech ZEUS SBC" + select PXA27x + select ISA + select PXA_HAVE_ISA_IRQS + select ARCOM_PCMCIA + +config MACH_BALLOON3 + bool "Balloon 3 board" + select PXA27x + select IWMMXT + +config MACH_CSB726 + bool "Enable Cogent CSB726 System On a Module" + select PXA27x + select IWMMXT + help + Say Y here if you intend to run this kernel on a Cogent + CSB726 System On Module. + +config CSB726_CSB701 + bool "Enable support for CSB701 baseboard" + depends on MACH_CSB726 + +config MACH_ARMCORE + bool "CompuLab CM-X255/CM-X270 modules" + select PXA27x + select IWMMXT + select PXA25x + select MIGHT_HAVE_PCI + +config MACH_EM_X270 + bool "CompuLab EM-x270 platform" + select PXA27x + +config MACH_EXEDA + bool "CompuLab eXeda platform" + select PXA27x + +config MACH_CM_X300 + bool "CompuLab CM-X300 modules" + select PXA3xx + select CPU_PXA300 + select CPU_PXA310 + select HAVE_PWM + +config MACH_CAPC7117 + bool "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM" + select CPU_PXA320 + select PXA3xx + +config ARCH_GUMSTIX + bool "Gumstix XScale 255 boards" + select PXA25x + help + Say Y here if you intend to run this kernel on + Basix, Connex, ws-200ax, ws-400ax systems + +choice + prompt "Gumstix Carrier/Expansion Board" + depends on ARCH_GUMSTIX + +config GUMSTIX_AM200EPD + bool "Enable AM200EPD board support" + +config GUMSTIX_AM300EPD + bool "Enable AM300EPD board support" + +endchoice + +config MACH_INTELMOTE2 + bool "Intel Mote 2 Platform" + select PXA27x + select IWMMXT + +config MACH_STARGATE2 + bool "Intel Stargate 2 Platform" + select PXA27x + select IWMMXT + +config MACH_XCEP + bool "Iskratel Electronics XCEP" + select PXA25x + select MTD + select MTD_PHYSMAP + select MTD_CFI_INTELEXT + select MTD_CFI + select MTD_CHAR + select SMC91X + help + PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash. + Tuned for usage in Libera instruments for particle accelerators. + +config TRIZEPS_PXA + bool "PXA based Keith und Koep Trizeps DIMM-Modules" + +config MACH_TRIZEPS4 + bool "Keith und Koep Trizeps4 DIMM-Module" + depends on TRIZEPS_PXA + select TRIZEPS_PCMCIA + select PXA27x + +config MACH_TRIZEPS4WL + bool "Keith und Koep Trizeps4-WL DIMM-Module" + depends on TRIZEPS_PXA + select TRIZEPS_PCMCIA + select PXA27x + +choice + prompt "Select base board for Trizeps module" + depends on TRIZEPS_PXA + +config MACH_TRIZEPS_CONXS + bool "ConXS Eval Board" + +config MACH_TRIZEPS_UCONXS + bool "uConXS Eval Board" + +config MACH_TRIZEPS_ANY + bool "another Board" + +endchoice + +config ARCOM_PCMCIA + bool + help + Generic option for Arcom Viper/Zeus PCMCIA + +config TRIZEPS_PCMCIA + bool + help + Enable PCMCIA support for Trizeps modules + +config MACH_LOGICPD_PXA270 + bool "LogicPD PXA270 Card Engine Development Platform" + select PXA27x + select HAVE_PWM + +config MACH_PCM027 + bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" + select PXA27x + select IWMMXT + +config MACH_PCM990_BASEBOARD + bool "PHYTEC PCM-990 development board" + select HAVE_PWM + depends on MACH_PCM027 + +choice + prompt "display on pcm990" + depends on MACH_PCM990_BASEBOARD + +config PCM990_DISPLAY_SHARP + bool "sharp lq084v1dg21 stn display" + +config PCM990_DISPLAY_NEC + bool "nec nl6448bc20_18d tft display" + +config PCM990_DISPLAY_NONE + bool "no display" + +endchoice + +config MACH_COLIBRI + bool "Toradex Colibri PXA270" + select PXA27x + +config MACH_COLIBRI_PXA270_INCOME + bool "Income s.r.o. PXA270 SBC" + depends on MACH_COLIBRI + select PXA27x + select HAVE_PWM + +config MACH_COLIBRI300 + bool "Toradex Colibri PXA300/310" + select PXA3xx + select CPU_PXA300 + select CPU_PXA310 + +config MACH_COLIBRI320 + bool "Toradex Colibri PXA320" + select PXA3xx + select CPU_PXA320 + +config MACH_COLIBRI_EVALBOARD + bool "Toradex Colibri Evaluation Carrier Board support" + depends on MACH_COLIBRI || MACH_COLIBRI300 || MACH_COLIBRI320 + +config MACH_VPAC270 + bool "Voipac PXA270" + select PXA27x + select HAVE_PATA_PLATFORM + help + PXA270 based Single Board Computer. + +comment "End-user Products (sorted by vendor name)" + +config MACH_H4700 + bool "HP iPAQ hx4700" + select PXA27x + select IWMMXT + select HAVE_PWM + +config MACH_H5000 + bool "HP iPAQ h5000" + select PXA25x + +config MACH_HIMALAYA + bool "HTC Himalaya Support" + select CPU_PXA26x + +config MACH_MAGICIAN + bool "Enable HTC Magician Support" + select PXA27x + select IWMMXT + select HAVE_PWM + +config MACH_MIOA701 + bool "Mitac Mio A701 Support" + select PXA27x + select IWMMXT + select HAVE_PWM + select GPIO_SYSFS + help + Say Y here if you intend to run this kernel on a + MIO A701. Currently there is only basic support + for this PDA. + +config PXA_EZX + bool "Motorola EZX Platform" + select PXA27x + select IWMMXT + select HAVE_PWM + +config MACH_EZX_A780 + bool "Motorola EZX A780" + default y + depends on PXA_EZX + +config MACH_EZX_E680 + bool "Motorola EZX E680" + default y + depends on PXA_EZX + +config MACH_EZX_A1200 + bool "Motorola EZX A1200" + default y + depends on PXA_EZX + +config MACH_EZX_A910 + bool "Motorola EZX A910" + default y + depends on PXA_EZX + +config MACH_EZX_E6 + bool "Motorola EZX E6" + default y + depends on PXA_EZX + +config MACH_EZX_E2 + bool "Motorola EZX E2" + default y + depends on PXA_EZX + +config MACH_MP900C + bool "Nec Mobilepro 900/c" + select PXA25x + +config ARCH_PXA_PALM + bool "PXA based Palm PDAs" + select HAVE_PWM + +config MACH_PALM27X + bool + +config MACH_PALMTE2 + bool "Palm Tungsten|E2" + default y + depends on ARCH_PXA_PALM + select PXA25x + help + Say Y here if you intend to run this kernel on a Palm Tungsten|E2 + handheld computer. + +config MACH_PALMTC + bool "Palm Tungsten|C" + default y + depends on ARCH_PXA_PALM + select PXA25x + help + Say Y here if you intend to run this kernel on a Palm Tungsten|C + handheld computer. + +config MACH_PALMT5 + bool "Palm Tungsten|T5" + default y + depends on ARCH_PXA_PALM + select PXA27x + select IWMMXT + select MACH_PALM27X + help + Say Y here if you intend to run this kernel on a Palm Tungsten|T5 + handheld computer. + +config MACH_PALMTX + bool "Palm T|X" + default y + depends on ARCH_PXA_PALM + select PXA27x + select IWMMXT + select MACH_PALM27X + help + Say Y here if you intend to run this kernel on a Palm T|X + handheld computer. + +config MACH_PALMZ72 + bool "Palm Zire 72" + default y + depends on ARCH_PXA_PALM + select PXA27x + select IWMMXT + select MACH_PALM27X + help + Say Y here if you intend to run this kernel on Palm Zire 72 + handheld computer. + +config MACH_PALMLD + bool "Palm LifeDrive" + default y + depends on ARCH_PXA_PALM + select PXA27x + select IWMMXT + select MACH_PALM27X + help + Say Y here if you intend to run this kernel on a Palm LifeDrive + handheld computer. + +config PALM_TREO + bool + depends on ARCH_PXA_PALM + +config MACH_CENTRO + bool "Palm Centro 685 (GSM)" + default y + depends on ARCH_PXA_PALM + select MACH_PALM27X + select PXA27x + select IWMMXT + select PALM_TREO + help + Say Y here if you intend to run this kernel on Palm Centro 685 (GSM) + smartphone. + +config MACH_TREO680 + bool "Palm Treo 680" + default y + depends on ARCH_PXA_PALM + select MACH_PALM27X + select PXA27x + select IWMMXT + select PALM_TREO + help + Say Y here if you intend to run this kernel on Palm Treo 680 + smartphone. + +config MACH_RAUMFELD_RC + bool "Raumfeld Controller" + select PXA3xx + select CPU_PXA300 + select POWER_SUPPLY + select HAVE_PWM + +config MACH_RAUMFELD_CONNECTOR + bool "Raumfeld Connector" + select POWER_SUPPLY + select PXA3xx + select CPU_PXA300 + +config MACH_RAUMFELD_SPEAKER + bool "Raumfeld Speaker" + select POWER_SUPPLY + select PXA3xx + select CPU_PXA300 + +config PXA_SHARPSL + bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models" + select SHARP_SCOOP + select SHARP_PARAM + help + Say Y here if you intend to run this kernel on a + Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi), + SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita), + SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa) + handheld computer. + +config PXA_SHARPSL_DETECT_MACH_ID + bool "Detect machine ID at run-time in the decompressor" + depends on PXA_SHARPSL + help + Say Y here if you want the zImage decompressor to detect + the Zaurus machine ID at run-time. For latest kexec-based + boot loader, this is not necessary. + +config MACH_POODLE + bool "Enable Sharp SL-5600 (Poodle) Support" + depends on PXA_SHARPSL + select PXA25x + select SHARP_LOCOMO + +config MACH_CORGI + bool "Enable Sharp SL-C700 (Corgi) Support" + depends on PXA_SHARPSL + select PXA25x + select PXA_SHARP_C7xx + +config MACH_SHEPHERD + bool "Enable Sharp SL-C750 (Shepherd) Support" + depends on PXA_SHARPSL + select PXA25x + select PXA_SHARP_C7xx + +config MACH_HUSKY + bool "Enable Sharp SL-C760 (Husky) Support" + depends on PXA_SHARPSL + select PXA25x + select PXA_SHARP_C7xx + +config MACH_AKITA + bool "Enable Sharp SL-1000 (Akita) Support" + depends on PXA_SHARPSL + select PXA27x + select PXA_SHARP_Cxx00 + select MACH_SPITZ + select I2C + select I2C_PXA + +config MACH_SPITZ + bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" + depends on PXA_SHARPSL + select PXA27x + select PXA_SHARP_Cxx00 + +config MACH_BORZOI + bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support" + depends on PXA_SHARPSL + select PXA27x + select PXA_SHARP_Cxx00 + +config MACH_TOSA + bool "Enable Sharp SL-6000x (Tosa) Support" + depends on PXA_SHARPSL + select PXA25x + +config TOSA_BT + tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" + depends on MACH_TOSA + select RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on tosa. + +config TOSA_USE_EXT_KEYCODES + bool "Tosa keyboard: use extended keycodes" + depends on MACH_TOSA + default n + help + Say Y here to enable the tosa keyboard driver to generate extended + (>= 127) keycodes. Be aware, that they can't be correctly interpreted + by either console keyboard driver or by Kdrive keybd driver. + + Say Y only if you know, what you are doing! + +config MACH_ICONTROL + bool "TMT iControl/SafeTCam based on the MXM-8x10 CoM" + select CPU_PXA320 + select PXA3xx + +config ARCH_PXA_ESERIES + bool "PXA based Toshiba e-series PDAs" + select PXA25x + select FB_W100 + +config MACH_E330 + bool "Toshiba e330" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e330 family PDA. + +config MACH_E350 + bool "Toshiba e350" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e350 family PDA. + +config MACH_E740 + bool "Toshiba e740" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e740 family PDA. + +config MACH_E750 + bool "Toshiba e750" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e750 family PDA. + +config MACH_E400 + bool "Toshiba e400" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e400 family PDA. + +config MACH_E800 + bool "Toshiba e800" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e800 family PDA. + +config MACH_ZIPIT2 + bool "Zipit Z2 Handheld" + select PXA27x + select HAVE_PWM +endif +endmenu + +config PXA25x + bool + select CPU_XSCALE + help + Select code specific to PXA21x/25x/26x variants + +config PXA27x + bool + select CPU_XSCALE + help + Select code specific to PXA27x variants + +config CPU_PXA26x + bool + select PXA25x + help + Select code specific to PXA26x (codename Dalhart) + +config PXA3xx + bool + select CPU_XSC3 + help + Select code specific to PXA3xx variants + +config CPU_PXA300 + bool + select PXA3xx + help + PXA300 (codename Monahans-L) + +config CPU_PXA310 + bool + select CPU_PXA300 + select PXA310_ULPI if USB_ULPI + help + PXA310 (codename Monahans-LV) + +config CPU_PXA320 + bool + select PXA3xx + help + PXA320 (codename Monahans-P) + +config CPU_PXA930 + bool + select PXA3xx + help + PXA930 (codename Tavor-P) + +config CPU_PXA935 + bool + select CPU_PXA930 + help + PXA935 (codename Tavor-P65) + +config PXA95x + bool + select CPU_PJ4 + help + Select code specific to PXA95x variants + +config CPU_PXA955 + bool + select PXA95x + help + PXA950 (codename MG1) + +config PXA_SHARP_C7xx + bool + select SHARPSL_PM + help + Enable support for all Sharp C7xx models + +config PXA_SHARP_Cxx00 + bool + select SHARPSL_PM + help + Enable common support for Sharp Cxx00 models + +config SHARPSL_PM + bool + select APM_EMULATION + select SHARPSL_PM_MAX1111 + +config SHARPSL_PM_MAX1111 + bool + select HWMON + select SPI + select SPI_MASTER + select SENSORS_MAX1111 + +config PXA_HAVE_ISA_IRQS + bool + +config PXA310_ULPI + bool + +endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile new file mode 100644 index 00000000000..be0f7df8685 --- /dev/null +++ b/arch/arm/mach-pxa/Makefile @@ -0,0 +1,106 @@ +# +# Makefile for the linux kernel. +# + +# Common support (must be linked before board specific support) +obj-y += clock.o devices.o generic.o irq.o \ + time.o reset.o +obj-$(CONFIG_PM) += pm.o sleep.o standby.o + +ifeq ($(CONFIG_CPU_FREQ),y) +obj-$(CONFIG_PXA25x) += cpufreq-pxa2xx.o +obj-$(CONFIG_PXA27x) += cpufreq-pxa2xx.o +obj-$(CONFIG_PXA3xx) += cpufreq-pxa3xx.o +endif + +# Generic drivers that other drivers may depend upon + +# SoC-specific code +obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa25x.o +obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa27x.o +obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o +obj-$(CONFIG_PXA95x) += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o pxa95x.o smemc.o +obj-$(CONFIG_CPU_PXA300) += pxa300.o +obj-$(CONFIG_CPU_PXA320) += pxa320.o +obj-$(CONFIG_CPU_PXA930) += pxa930.o + +# NOTE: keep the order of boards in accordance to their order in Kconfig + +# Intel/Marvell Dev Platforms +obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o +obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o +obj-$(CONFIG_MACH_ZYLONITE300) += zylonite.o zylonite_pxa300.o +obj-$(CONFIG_MACH_ZYLONITE320) += zylonite.o zylonite_pxa320.o +obj-$(CONFIG_MACH_LITTLETON) += littleton.o +obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o +obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o +obj-$(CONFIG_MACH_SAAR) += saar.o +obj-$(CONFIG_MACH_SAARB) += saarb.o + +# 3rd Party Dev Platforms +obj-$(CONFIG_ARCH_PXA_IDP) += idp.o +obj-$(CONFIG_ARCH_VIPER) += viper.o +obj-$(CONFIG_MACH_ARCOM_ZEUS) += zeus.o +obj-$(CONFIG_MACH_BALLOON3) += balloon3.o +obj-$(CONFIG_MACH_CSB726) += csb726.o +obj-$(CONFIG_CSB726_CSB701) += csb701.o +obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx.o cm-x255.o cm-x270.o +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx-pci.o +endif +obj-$(CONFIG_MACH_EM_X270) += em-x270.o +obj-$(CONFIG_MACH_CM_X300) += cm-x300.o +obj-$(CONFIG_MACH_CAPC7117) += capc7117.o mxm8x10.o +obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o +obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o +obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o +obj-$(CONFIG_MACH_INTELMOTE2) += stargate2.o +obj-$(CONFIG_MACH_STARGATE2) += stargate2.o +obj-$(CONFIG_MACH_XCEP) += xcep.o +obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o +obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o +obj-$(CONFIG_MACH_PCM027) += pcm027.o +obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o +obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o +obj-$(CONFIG_MACH_COLIBRI_EVALBOARD) += colibri-evalboard.o +obj-$(CONFIG_MACH_COLIBRI_PXA270_INCOME) += colibri-pxa270-income.o +obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o +obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o +obj-$(CONFIG_MACH_VPAC270) += vpac270.o + +# End-user Products +obj-$(CONFIG_MACH_H4700) += hx4700.o +obj-$(CONFIG_MACH_H5000) += h5000.o +obj-$(CONFIG_MACH_HIMALAYA) += himalaya.o +obj-$(CONFIG_MACH_MAGICIAN) += magician.o +obj-$(CONFIG_MACH_MIOA701) += mioa701.o mioa701_bootresume.o +obj-$(CONFIG_PXA_EZX) += ezx.o +obj-$(CONFIG_MACH_MP900C) += mp900.o +obj-$(CONFIG_MACH_PALMTE2) += palmte2.o +obj-$(CONFIG_MACH_PALMTC) += palmtc.o +obj-$(CONFIG_MACH_PALM27X) += palm27x.o +obj-$(CONFIG_MACH_PALMT5) += palmt5.o +obj-$(CONFIG_MACH_PALMTX) += palmtx.o +obj-$(CONFIG_MACH_PALMZ72) += palmz72.o +obj-$(CONFIG_MACH_PALMLD) += palmld.o +obj-$(CONFIG_PALM_TREO) += palmtreo.o +obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o +obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o sharpsl_pm.o spitz_pm.o +obj-$(CONFIG_MACH_POODLE) += poodle.o +obj-$(CONFIG_MACH_TOSA) += tosa.o +obj-$(CONFIG_MACH_ICONTROL) += icontrol.o mxm8x10.o +obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o +obj-$(CONFIG_MACH_RAUMFELD_RC) += raumfeld.o +obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o +obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o +obj-$(CONFIG_MACH_ZIPIT2) += z2.o + +# Support for blinky lights +led-y := leds.o +led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o +led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o +led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o + +obj-$(CONFIG_LEDS) += $(led-y) + +obj-$(CONFIG_TOSA_BT) += tosa-bt.o diff --git a/arch/arm/mach-pxa/Makefile.boot b/arch/arm/mach-pxa/Makefile.boot new file mode 100644 index 00000000000..2c1ae92f210 --- /dev/null +++ b/arch/arm/mach-pxa/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y += 0xa0008000 + diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c new file mode 100644 index 00000000000..ccdac4b6a46 --- /dev/null +++ b/arch/arm/mach-pxa/am200epd.c @@ -0,0 +1,387 @@ +/* + * am200epd.c -- Platform device for AM200 EPD kit + * + * Copyright (C) 2008, Jaya Kumar + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * + * This work was made possible by help and equipment support from E-Ink + * Corporation. http://support.eink.com/community + * + * This driver is written to be used with the Metronome display controller. + * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600 + * Vizplex EPD on a Gumstix board using the Lyre interface board. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/gpio.h> + +#include <mach/pxa25x.h> +#include <mach/gumstix.h> +#include <mach/pxafb.h> + +#include "generic.h" + +#include <video/metronomefb.h> + +static unsigned int panel_type = 6; +static struct platform_device *am200_device; +static struct metronome_board am200_board; + +static struct pxafb_mode_info am200_fb_mode_9inch7 = { + .pixclock = 40000, + .xres = 1200, + .yres = 842, + .bpp = 16, + .hsync_len = 2, + .left_margin = 2, + .right_margin = 2, + .vsync_len = 1, + .upper_margin = 2, + .lower_margin = 25, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}; + +static struct pxafb_mode_info am200_fb_mode_8inch = { + .pixclock = 40000, + .xres = 1088, + .yres = 791, + .bpp = 16, + .hsync_len = 28, + .left_margin = 8, + .right_margin = 30, + .vsync_len = 8, + .upper_margin = 10, + .lower_margin = 8, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}; + +static struct pxafb_mode_info am200_fb_mode_6inch = { + .pixclock = 40189, + .xres = 832, + .yres = 622, + .bpp = 16, + .hsync_len = 28, + .left_margin = 34, + .right_margin = 34, + .vsync_len = 25, + .upper_margin = 0, + .lower_margin = 2, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}; + +static struct pxafb_mach_info am200_fb_info = { + .modes = &am200_fb_mode_6inch, + .num_modes = 1, + .lcd_conn = LCD_TYPE_COLOR_TFT | LCD_PCLK_EDGE_FALL | + LCD_AC_BIAS_FREQ(24), +}; + +/* register offsets for gpio control */ +#define LED_GPIO_PIN 51 +#define STDBY_GPIO_PIN 48 +#define RST_GPIO_PIN 49 +#define RDY_GPIO_PIN 32 +#define ERR_GPIO_PIN 17 +#define PCBPWR_GPIO_PIN 16 +static int gpios[] = { LED_GPIO_PIN , STDBY_GPIO_PIN , RST_GPIO_PIN, + RDY_GPIO_PIN, ERR_GPIO_PIN, PCBPWR_GPIO_PIN }; +static char *gpio_names[] = { "LED" , "STDBY" , "RST", "RDY", "ERR", "PCBPWR" }; + +static int am200_init_gpio_regs(struct metronomefb_par *par) +{ + int i; + int err; + + for (i = 0; i < ARRAY_SIZE(gpios); i++) { + err = gpio_request(gpios[i], gpio_names[i]); + if (err) { + dev_err(&am200_device->dev, "failed requesting " + "gpio %s, err=%d\n", gpio_names[i], err); + goto err_req_gpio; + } + } + + gpio_direction_output(LED_GPIO_PIN, 0); + gpio_direction_output(STDBY_GPIO_PIN, 0); + gpio_direction_output(RST_GPIO_PIN, 0); + + gpio_direction_input(RDY_GPIO_PIN); + gpio_direction_input(ERR_GPIO_PIN); + + gpio_direction_output(PCBPWR_GPIO_PIN, 0); + + return 0; + +err_req_gpio: + while (--i >= 0) + gpio_free(gpios[i]); + + return err; +} + +static void am200_cleanup(struct metronomefb_par *par) +{ + int i; + + free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par); + + for (i = 0; i < ARRAY_SIZE(gpios); i++) + gpio_free(gpios[i]); +} + +static int am200_share_video_mem(struct fb_info *info) +{ + /* rough check if this is our desired fb and not something else */ + if ((info->var.xres != am200_fb_info.modes->xres) + || (info->var.yres != am200_fb_info.modes->yres)) + return 0; + + /* we've now been notified that we have our new fb */ + am200_board.metromem = info->screen_base; + am200_board.host_fbinfo = info; + + /* try to refcount host drv since we are the consumer after this */ + if (!try_module_get(info->fbops->owner)) + return -ENODEV; + + return 0; +} + +static int am200_unshare_video_mem(struct fb_info *info) +{ + dev_dbg(&am200_device->dev, "ENTER %s\n", __func__); + + if (info != am200_board.host_fbinfo) + return 0; + + module_put(am200_board.host_fbinfo->fbops->owner); + return 0; +} + +static int am200_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + struct fb_info *info = evdata->info; + + dev_dbg(&am200_device->dev, "ENTER %s\n", __func__); + + if (event == FB_EVENT_FB_REGISTERED) + return am200_share_video_mem(info); + else if (event == FB_EVENT_FB_UNREGISTERED) + return am200_unshare_video_mem(info); + + return 0; +} + +static struct notifier_block am200_fb_notif = { + .notifier_call = am200_fb_notifier_callback, +}; + +/* this gets called as part of our init. these steps must be done now so + * that we can use pxa_set_fb_info */ +static void __init am200_presetup_fb(void) +{ + int fw; + int fh; + int padding_size; + int totalsize; + + switch (panel_type) { + case 6: + am200_fb_info.modes = &am200_fb_mode_6inch; + break; + case 8: + am200_fb_info.modes = &am200_fb_mode_8inch; + break; + case 97: + am200_fb_info.modes = &am200_fb_mode_9inch7; + break; + default: + dev_err(&am200_device->dev, "invalid panel_type selection," + " setting to 6\n"); + am200_fb_info.modes = &am200_fb_mode_6inch; + break; + } + + /* the frame buffer is divided as follows: + command | CRC | padding + 16kb waveform data | CRC | padding + image data | CRC + */ + + fw = am200_fb_info.modes->xres; + fh = am200_fb_info.modes->yres; + + /* waveform must be 16k + 2 for checksum */ + am200_board.wfm_size = roundup(16*1024 + 2, fw); + + padding_size = PAGE_SIZE + (4 * fw); + + /* total is 1 cmd , 1 wfm, padding and image */ + totalsize = fw + am200_board.wfm_size + padding_size + (fw*fh); + + /* save this off because we're manipulating fw after this and + * we'll need it when we're ready to setup the framebuffer */ + am200_board.fw = fw; + am200_board.fh = fh; + + /* the reason we do this adjustment is because we want to acquire + * more framebuffer memory without imposing custom awareness on the + * underlying pxafb driver */ + am200_fb_info.modes->yres = DIV_ROUND_UP(totalsize, fw); + + /* we divide since we told the LCD controller we're 16bpp */ + am200_fb_info.modes->xres /= 2; + + pxa_set_fb_info(NULL, &am200_fb_info); + +} + +/* this gets called by metronomefb as part of its init, in our case, we + * have already completed initial framebuffer init in presetup_fb so we + * can just setup the fb access pointers */ +static int am200_setup_fb(struct metronomefb_par *par) +{ + int fw; + int fh; + + fw = am200_board.fw; + fh = am200_board.fh; + + /* metromem was set up by the notifier in share_video_mem so now + * we can use its value to calculate the other entries */ + par->metromem_cmd = (struct metromem_cmd *) am200_board.metromem; + par->metromem_wfm = am200_board.metromem + fw; + par->metromem_img = par->metromem_wfm + am200_board.wfm_size; + par->metromem_img_csum = (u16 *) (par->metromem_img + (fw * fh)); + par->metromem_dma = am200_board.host_fbinfo->fix.smem_start; + + return 0; +} + +static int am200_get_panel_type(void) +{ + return panel_type; +} + +static irqreturn_t am200_handle_irq(int irq, void *dev_id) +{ + struct metronomefb_par *par = dev_id; + + wake_up_interruptible(&par->waitq); + return IRQ_HANDLED; +} + +static int am200_setup_irq(struct fb_info *info) +{ + int ret; + + ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am200_handle_irq, + IRQF_DISABLED|IRQF_TRIGGER_FALLING, + "AM200", info->par); + if (ret) + dev_err(&am200_device->dev, "request_irq failed: %d\n", ret); + + return ret; +} + +static void am200_set_rst(struct metronomefb_par *par, int state) +{ + gpio_set_value(RST_GPIO_PIN, state); +} + +static void am200_set_stdby(struct metronomefb_par *par, int state) +{ + gpio_set_value(STDBY_GPIO_PIN, state); +} + +static int am200_wait_event(struct metronomefb_par *par) +{ + return wait_event_timeout(par->waitq, gpio_get_value(RDY_GPIO_PIN), HZ); +} + +static int am200_wait_event_intr(struct metronomefb_par *par) +{ + return wait_event_interruptible_timeout(par->waitq, + gpio_get_value(RDY_GPIO_PIN), HZ); +} + +static struct metronome_board am200_board = { + .owner = THIS_MODULE, + .setup_irq = am200_setup_irq, + .setup_io = am200_init_gpio_regs, + .setup_fb = am200_setup_fb, + .set_rst = am200_set_rst, + .set_stdby = am200_set_stdby, + .met_wait_event = am200_wait_event, + .met_wait_event_intr = am200_wait_event_intr, + .get_panel_type = am200_get_panel_type, + .cleanup = am200_cleanup, +}; + +static unsigned long am200_pin_config[] __initdata = { + GPIO51_GPIO, + GPIO49_GPIO, + GPIO48_GPIO, + GPIO32_GPIO, + GPIO17_GPIO, + GPIO16_GPIO, +}; + +int __init am200_init(void) +{ + int ret; + + /* before anything else, we request notification for any fb + * creation events */ + fb_register_client(&am200_fb_notif); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(am200_pin_config)); + + /* request our platform independent driver */ + request_module("metronomefb"); + + am200_device = platform_device_alloc("metronomefb", -1); + if (!am200_device) + return -ENOMEM; + + /* the am200_board that will be seen by metronomefb is a copy */ + platform_device_add_data(am200_device, &am200_board, + sizeof(am200_board)); + + /* this _add binds metronomefb to am200. metronomefb refcounts am200 */ + ret = platform_device_add(am200_device); + + if (ret) { + platform_device_put(am200_device); + fb_unregister_client(&am200_fb_notif); + return ret; + } + + am200_presetup_fb(); + + return 0; +} + +module_param(panel_type, uint, 0); +MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97"); + +MODULE_DESCRIPTION("board driver for am200 metronome epd kit"); +MODULE_AUTHOR("Jaya Kumar"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c new file mode 100644 index 00000000000..76c4b949403 --- /dev/null +++ b/arch/arm/mach-pxa/am300epd.c @@ -0,0 +1,296 @@ +/* + * am300epd.c -- Platform device for AM300 EPD kit + * + * Copyright (C) 2008, Jaya Kumar + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * This work was made possible by help and equipment support from E-Ink + * Corporation. http://support.eink.com/community + * + * This driver is written to be used with the Broadsheet display controller. + * on the AM300 EPD prototype kit/development kit with an E-Ink 800x600 + * Vizplex EPD on a Gumstix board using the Broadsheet interface board. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/gpio.h> + +#include <mach/gumstix.h> +#include <mach/mfp-pxa25x.h> +#include <mach/pxafb.h> + +#include "generic.h" + +#include <video/broadsheetfb.h> + +static unsigned int panel_type = 6; +static struct platform_device *am300_device; +static struct broadsheet_board am300_board; + +static unsigned long am300_pin_config[] __initdata = { + GPIO16_GPIO, + GPIO17_GPIO, + GPIO32_GPIO, + GPIO48_GPIO, + GPIO49_GPIO, + GPIO51_GPIO, + GPIO74_GPIO, + GPIO75_GPIO, + GPIO76_GPIO, + GPIO77_GPIO, + + /* this is the 16-bit hdb bus 58-73 */ + GPIO58_GPIO, + GPIO59_GPIO, + GPIO60_GPIO, + GPIO61_GPIO, + + GPIO62_GPIO, + GPIO63_GPIO, + GPIO64_GPIO, + GPIO65_GPIO, + + GPIO66_GPIO, + GPIO67_GPIO, + GPIO68_GPIO, + GPIO69_GPIO, + + GPIO70_GPIO, + GPIO71_GPIO, + GPIO72_GPIO, + GPIO73_GPIO, +}; + +/* register offsets for gpio control */ +#define PWR_GPIO_PIN 16 +#define CFG_GPIO_PIN 17 +#define RDY_GPIO_PIN 32 +#define DC_GPIO_PIN 48 +#define RST_GPIO_PIN 49 +#define LED_GPIO_PIN 51 +#define RD_GPIO_PIN 74 +#define WR_GPIO_PIN 75 +#define CS_GPIO_PIN 76 +#define IRQ_GPIO_PIN 77 + +/* hdb bus */ +#define DB0_GPIO_PIN 58 +#define DB15_GPIO_PIN 73 + +static int gpios[] = { PWR_GPIO_PIN, CFG_GPIO_PIN, RDY_GPIO_PIN, DC_GPIO_PIN, + RST_GPIO_PIN, RD_GPIO_PIN, WR_GPIO_PIN, CS_GPIO_PIN, + IRQ_GPIO_PIN, LED_GPIO_PIN }; +static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR", + "CS", "IRQ", "LED" }; + +static int am300_wait_event(struct broadsheetfb_par *par) +{ + /* todo: improve err recovery */ + wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN)); + return 0; +} + +static int am300_init_gpio_regs(struct broadsheetfb_par *par) +{ + int i; + int err; + char dbname[8]; + + for (i = 0; i < ARRAY_SIZE(gpios); i++) { + err = gpio_request(gpios[i], gpio_names[i]); + if (err) { + dev_err(&am300_device->dev, "failed requesting " + "gpio %s, err=%d\n", gpio_names[i], err); + goto err_req_gpio; + } + } + + /* we also need to take care of the hdb bus */ + for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) { + sprintf(dbname, "DB%d", i); + err = gpio_request(i, dbname); + if (err) { + dev_err(&am300_device->dev, "failed requesting " + "gpio %d, err=%d\n", i, err); + goto err_req_gpio2; + } + } + + /* setup the outputs and init values */ + gpio_direction_output(PWR_GPIO_PIN, 0); + gpio_direction_output(CFG_GPIO_PIN, 1); + gpio_direction_output(DC_GPIO_PIN, 0); + gpio_direction_output(RD_GPIO_PIN, 1); + gpio_direction_output(WR_GPIO_PIN, 1); + gpio_direction_output(CS_GPIO_PIN, 1); + gpio_direction_output(RST_GPIO_PIN, 0); + + /* setup the inputs */ + gpio_direction_input(RDY_GPIO_PIN); + gpio_direction_input(IRQ_GPIO_PIN); + + /* start the hdb bus as an input */ + for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) + gpio_direction_output(i, 0); + + /* go into command mode */ + gpio_set_value(CFG_GPIO_PIN, 1); + gpio_set_value(RST_GPIO_PIN, 0); + msleep(10); + gpio_set_value(RST_GPIO_PIN, 1); + msleep(10); + am300_wait_event(par); + + return 0; + +err_req_gpio2: + while (--i >= DB0_GPIO_PIN) + gpio_free(i); + i = ARRAY_SIZE(gpios); +err_req_gpio: + while (--i >= 0) + gpio_free(gpios[i]); + + return err; +} + +static int am300_init_board(struct broadsheetfb_par *par) +{ + return am300_init_gpio_regs(par); +} + +static void am300_cleanup(struct broadsheetfb_par *par) +{ + int i; + + free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par); + + for (i = 0; i < ARRAY_SIZE(gpios); i++) + gpio_free(gpios[i]); + + for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) + gpio_free(i); + +} + +static u16 am300_get_hdb(struct broadsheetfb_par *par) +{ + u16 res = 0; + int i; + + for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++) + res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0; + + return res; +} + +static void am300_set_hdb(struct broadsheetfb_par *par, u16 data) +{ + int i; + + for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++) + gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01); +} + + +static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit, + u8 state) +{ + switch (bit) { + case BS_CS: + gpio_set_value(CS_GPIO_PIN, state); + break; + case BS_DC: + gpio_set_value(DC_GPIO_PIN, state); + break; + case BS_WR: + gpio_set_value(WR_GPIO_PIN, state); + break; + } +} + +static int am300_get_panel_type(void) +{ + return panel_type; +} + +static irqreturn_t am300_handle_irq(int irq, void *dev_id) +{ + struct broadsheetfb_par *par = dev_id; + + wake_up(&par->waitq); + return IRQ_HANDLED; +} + +static int am300_setup_irq(struct fb_info *info) +{ + int ret; + struct broadsheetfb_par *par = info->par; + + ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am300_handle_irq, + IRQF_DISABLED|IRQF_TRIGGER_RISING, + "AM300", par); + if (ret) + dev_err(&am300_device->dev, "request_irq failed: %d\n", ret); + + return ret; +} + +static struct broadsheet_board am300_board = { + .owner = THIS_MODULE, + .init = am300_init_board, + .cleanup = am300_cleanup, + .set_hdb = am300_set_hdb, + .get_hdb = am300_get_hdb, + .set_ctl = am300_set_ctl, + .wait_for_rdy = am300_wait_event, + .get_panel_type = am300_get_panel_type, + .setup_irq = am300_setup_irq, +}; + +int __init am300_init(void) +{ + int ret; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config)); + + /* request our platform independent driver */ + request_module("broadsheetfb"); + + am300_device = platform_device_alloc("broadsheetfb", -1); + if (!am300_device) + return -ENOMEM; + + /* the am300_board that will be seen by broadsheetfb is a copy */ + platform_device_add_data(am300_device, &am300_board, + sizeof(am300_board)); + + ret = platform_device_add(am300_device); + + if (ret) { + platform_device_put(am300_device); + return ret; + } + + return 0; +} + +module_param(panel_type, uint, 0); +MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97"); + +MODULE_DESCRIPTION("board driver for am300 epd kit"); +MODULE_AUTHOR("Jaya Kumar"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c new file mode 100644 index 00000000000..c35456f02ac --- /dev/null +++ b/arch/arm/mach-pxa/balloon3.c @@ -0,0 +1,834 @@ +/* + * linux/arch/arm/mach-pxa/balloon3.c + * + * Support for Balloonboard.org Balloon3 board. + * + * Author: Nick Bane, Wookey, Jonathan McDowell + * Created: June, 2006 + * Copyright: Toby Churchill Ltd + * Derived from mainstone.c, by Nico Pitre + * + * 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/export.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/bitops.h> +#include <linux/fb.h> +#include <linux/gpio.h> +#include <linux/ioport.h> +#include <linux/ucb1400.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/types.h> +#include <linux/i2c/pcf857x.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/physmap.h> +#include <linux/regulator/max1586.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/sizes.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/flash.h> + +#include <mach/pxa27x.h> +#include <mach/balloon3.h> +#include <mach/audio.h> +#include <mach/pxafb.h> +#include <mach/mmc.h> +#include <mach/udc.h> +#include <mach/pxa27x-udc.h> +#include <mach/irda.h> +#include <mach/ohci.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long balloon3_pin_config[] __initdata = { + /* Select BTUART 'COM1/ttyS0' as IO option for pins 42/43/44/45 */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* Reset, configured as GPIO wakeup source */ + GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, +}; + +/****************************************************************************** + * Compatibility: Parameter parsing + ******************************************************************************/ +static unsigned long balloon3_irq_enabled; + +static unsigned long balloon3_features_present = + (1 << BALLOON3_FEATURE_OHCI) | (1 << BALLOON3_FEATURE_CF) | + (1 << BALLOON3_FEATURE_AUDIO) | + (1 << BALLOON3_FEATURE_TOPPOLY); + +int balloon3_has(enum balloon3_features feature) +{ + return (balloon3_features_present & (1 << feature)) ? 1 : 0; +} +EXPORT_SYMBOL_GPL(balloon3_has); + +int __init parse_balloon3_features(char *arg) +{ + if (!arg) + return 0; + + return strict_strtoul(arg, 0, &balloon3_features_present); +} +early_param("balloon3_features", parse_balloon3_features); + +/****************************************************************************** + * Compact Flash slot + ******************************************************************************/ +#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE) +static unsigned long balloon3_cf_pin_config[] __initdata = { + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO79_PSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, +}; + +static void __init balloon3_cf_init(void) +{ + if (!balloon3_has(BALLOON3_FEATURE_CF)) + return; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config)); +} +#else +static inline void balloon3_cf_init(void) {} +#endif + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition balloon3_nor_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data balloon3_flash_data[] = { + { + .width = 2, /* bankwidth in bytes */ + .parts = balloon3_nor_partitions, + .nr_parts = ARRAY_SIZE(balloon3_nor_partitions) + } +}; + +static struct resource balloon3_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device balloon3_flash = { + .name = "physmap-flash", + .id = 0, + .resource = &balloon3_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = balloon3_flash_data, + }, +}; +static void __init balloon3_nor_init(void) +{ + platform_device_register(&balloon3_flash); +} +#else +static inline void balloon3_nor_init(void) {} +#endif + +/****************************************************************************** + * Audio and Touchscreen + ******************************************************************************/ +#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ + defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static unsigned long balloon3_ac97_pin_config[] __initdata = { + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO113_AC97_nRESET, + GPIO95_GPIO, +}; + +static struct ucb1400_pdata vpac270_ucb1400_pdata = { + .irq = PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ), +}; + + +static struct platform_device balloon3_ucb1400_device = { + .name = "ucb1400_core", + .id = -1, + .dev = { + .platform_data = &vpac270_ucb1400_pdata, + }, +}; + +static void __init balloon3_ts_init(void) +{ + if (!balloon3_has(BALLOON3_FEATURE_AUDIO)) + return; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config)); + pxa_set_ac97_info(NULL); + platform_device_register(&balloon3_ucb1400_device); +} +#else +static inline void balloon3_ts_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static unsigned long balloon3_lcd_pin_config[] __initdata = { + GPIOxx_LCD_TFT_16BPP, + GPIO99_GPIO, +}; + +static struct pxafb_mode_info balloon3_lcd_modes[] = { + { + .pixclock = 38000, + .xres = 480, + .yres = 640, + .bpp = 16, + .hsync_len = 8, + .left_margin = 8, + .right_margin = 8, + .vsync_len = 2, + .upper_margin = 4, + .lower_margin = 5, + .sync = 0, + }, +}; + +static struct pxafb_mach_info balloon3_lcd_screen = { + .modes = balloon3_lcd_modes, + .num_modes = ARRAY_SIZE(balloon3_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +static void balloon3_backlight_power(int on) +{ + gpio_set_value(BALLOON3_GPIO_RUN_BACKLIGHT, on); +} + +static void __init balloon3_lcd_init(void) +{ + int ret; + + if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY)) + return; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config)); + + ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON"); + if (ret) { + pr_err("Requesting BKL-ON GPIO failed!\n"); + goto err; + } + + ret = gpio_direction_output(BALLOON3_GPIO_RUN_BACKLIGHT, 1); + if (ret) { + pr_err("Setting BKL-ON GPIO direction failed!\n"); + goto err2; + } + + balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power; + pxa_set_fb_info(NULL, &balloon3_lcd_screen); + return; + +err2: + gpio_free(BALLOON3_GPIO_RUN_BACKLIGHT); +err: + return; +} +#else +static inline void balloon3_lcd_init(void) {} +#endif + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static unsigned long balloon3_mmc_pin_config[] __initdata = { + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, +}; + +static struct pxamci_platform_data balloon3_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, + .detect_delay_ms = 200, +}; + +static void __init balloon3_mmc_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config)); + pxa_set_mci_info(&balloon3_mci_platform_data); +} +#else +static inline void balloon3_mmc_init(void) {} +#endif + +/****************************************************************************** + * USB Gadget + ******************************************************************************/ +#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) +static void balloon3_udc_command(int cmd) +{ + if (cmd == PXA2XX_UDC_CMD_CONNECT) + UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE; + else if (cmd == PXA2XX_UDC_CMD_DISCONNECT) + UP2OCR &= ~UP2OCR_DPPUE; +} + +static int balloon3_udc_is_connected(void) +{ + return 1; +} + +static struct pxa2xx_udc_mach_info balloon3_udc_info __initdata = { + .udc_command = balloon3_udc_command, + .udc_is_connected = balloon3_udc_is_connected, + .gpio_pullup = -1, +}; + +static void __init balloon3_udc_init(void) +{ + pxa_set_udc_info(&balloon3_udc_info); + platform_device_register(&balloon3_gpio_vbus); +} +#else +static inline void balloon3_udc_init(void) {} +#endif + +/****************************************************************************** + * IrDA + ******************************************************************************/ +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) +static struct pxaficp_platform_data balloon3_ficp_platform_data = { + .transceiver_cap = IR_FIRMODE | IR_SIRMODE | IR_OFF, +}; + +static void __init balloon3_irda_init(void) +{ + pxa_set_ficp_info(&balloon3_ficp_platform_data); +} +#else +static inline void balloon3_irda_init(void) {} +#endif + +/****************************************************************************** + * USB Host + ******************************************************************************/ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static unsigned long balloon3_uhc_pin_config[] __initdata = { + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, +}; + +static struct pxaohci_platform_data balloon3_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, +}; + +static void __init balloon3_uhc_init(void) +{ + if (!balloon3_has(BALLOON3_FEATURE_OHCI)) + return; + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config)); + pxa_set_ohci_info(&balloon3_ohci_info); +} +#else +static inline void balloon3_uhc_init(void) {} +#endif + +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static unsigned long balloon3_led_pin_config[] __initdata = { + GPIO9_GPIO, /* NAND activity LED */ + GPIO10_GPIO, /* Heartbeat LED */ +}; + +struct gpio_led balloon3_gpio_leds[] = { + { + .name = "balloon3:green:idle", + .default_trigger = "heartbeat", + .gpio = BALLOON3_GPIO_LED_IDLE, + .active_low = 1, + }, { + .name = "balloon3:green:nand", + .default_trigger = "nand-disk", + .gpio = BALLOON3_GPIO_LED_NAND, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data balloon3_gpio_led_info = { + .leds = balloon3_gpio_leds, + .num_leds = ARRAY_SIZE(balloon3_gpio_leds), +}; + +static struct platform_device balloon3_leds = { + .name = "leds-gpio", + .id = 0, + .dev = { + .platform_data = &balloon3_gpio_led_info, + } +}; + +struct gpio_led balloon3_pcf_gpio_leds[] = { + { + .name = "balloon3:green:led0", + .gpio = BALLOON3_PCF_GPIO_LED0, + .active_low = 1, + }, { + .name = "balloon3:green:led1", + .gpio = BALLOON3_PCF_GPIO_LED1, + .active_low = 1, + }, { + .name = "balloon3:orange:led2", + .gpio = BALLOON3_PCF_GPIO_LED2, + .active_low = 1, + }, { + .name = "balloon3:orange:led3", + .gpio = BALLOON3_PCF_GPIO_LED3, + .active_low = 1, + }, { + .name = "balloon3:orange:led4", + .gpio = BALLOON3_PCF_GPIO_LED4, + .active_low = 1, + }, { + .name = "balloon3:orange:led5", + .gpio = BALLOON3_PCF_GPIO_LED5, + .active_low = 1, + }, { + .name = "balloon3:red:led6", + .gpio = BALLOON3_PCF_GPIO_LED6, + .active_low = 1, + }, { + .name = "balloon3:red:led7", + .gpio = BALLOON3_PCF_GPIO_LED7, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data balloon3_pcf_gpio_led_info = { + .leds = balloon3_pcf_gpio_leds, + .num_leds = ARRAY_SIZE(balloon3_pcf_gpio_leds), +}; + +static struct platform_device balloon3_pcf_leds = { + .name = "leds-gpio", + .id = 1, + .dev = { + .platform_data = &balloon3_pcf_gpio_led_info, + } +}; + +static void __init balloon3_leds_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config)); + platform_device_register(&balloon3_leds); + platform_device_register(&balloon3_pcf_leds); +} +#else +static inline void balloon3_leds_init(void) {} +#endif + +/****************************************************************************** + * FPGA IRQ + ******************************************************************************/ +static void balloon3_mask_irq(struct irq_data *d) +{ + int balloon3_irq = (d->irq - BALLOON3_IRQ(0)); + balloon3_irq_enabled &= ~(1 << balloon3_irq); + __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG); +} + +static void balloon3_unmask_irq(struct irq_data *d) +{ + int balloon3_irq = (d->irq - BALLOON3_IRQ(0)); + balloon3_irq_enabled |= (1 << balloon3_irq); + __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG); +} + +static struct irq_chip balloon3_irq_chip = { + .name = "FPGA", + .irq_ack = balloon3_mask_irq, + .irq_mask = balloon3_mask_irq, + .irq_unmask = balloon3_unmask_irq, +}; + +static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long pending = __raw_readl(BALLOON3_INT_CONTROL_REG) & + balloon3_irq_enabled; + do { + /* clear useless edge notification */ + if (desc->irq_data.chip->irq_ack) { + struct irq_data *d; + + d = irq_get_irq_data(BALLOON3_AUX_NIRQ); + desc->irq_data.chip->irq_ack(d); + } + + while (pending) { + irq = BALLOON3_IRQ(0) + __ffs(pending); + generic_handle_irq(irq); + pending &= pending - 1; + } + pending = __raw_readl(BALLOON3_INT_CONTROL_REG) & + balloon3_irq_enabled; + } while (pending); +} + +static void __init balloon3_init_irq(void) +{ + int irq; + + pxa27x_init_irq(); + /* setup extra Balloon3 irqs */ + for (irq = BALLOON3_IRQ(0); irq <= BALLOON3_IRQ(7); irq++) { + irq_set_chip_and_handler(irq, &balloon3_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + irq_set_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler); + irq_set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING); + + pr_debug("%s: chained handler installed - irq %d automatically " + "enabled\n", __func__, BALLOON3_AUX_NIRQ); +} + +/****************************************************************************** + * GPIO expander + ******************************************************************************/ +#if defined(CONFIG_GPIO_PCF857X) || defined(CONFIG_GPIO_PCF857X_MODULE) +static struct pcf857x_platform_data balloon3_pcf857x_pdata = { + .gpio_base = BALLOON3_PCF_GPIO_BASE, + .n_latch = 0, + .setup = NULL, + .teardown = NULL, + .context = NULL, +}; + +static struct i2c_board_info __initdata balloon3_i2c_devs[] = { + { + I2C_BOARD_INFO("pcf8574a", 0x38), + .platform_data = &balloon3_pcf857x_pdata, + }, +}; + +static void __init balloon3_i2c_init(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(balloon3_i2c_devs)); +} +#else +static inline void balloon3_i2c_init(void) {} +#endif + +/****************************************************************************** + * NAND + ******************************************************************************/ +#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) +static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0; + + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CLE) + balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLCLE; + else + balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLCLE; + + if (ctrl & NAND_ALE) + balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLALE; + else + balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLALE; + + if (balloon3_ctl_clr) + __raw_writel(balloon3_ctl_clr, + BALLOON3_NAND_CONTROL_REG); + if (balloon3_ctl_set) + __raw_writel(balloon3_ctl_set, + BALLOON3_NAND_CONTROL_REG + + BALLOON3_FPGA_SETnCLR); + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + +static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip) +{ + if (chip < 0 || chip > 3) + return; + + /* Assert all nCE lines */ + __raw_writew( + BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | + BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3, + BALLOON3_NAND_CONTROL_REG + BALLOON3_FPGA_SETnCLR); + + /* Deassert correct nCE line */ + __raw_writew(BALLOON3_NAND_CONTROL_FLCE0 << chip, + BALLOON3_NAND_CONTROL_REG); +} + +static int balloon3_nand_dev_ready(struct mtd_info *mtd) +{ + return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB; +} + +static int balloon3_nand_probe(struct platform_device *pdev) +{ + uint16_t ver; + int ret; + + __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, + BALLOON3_NAND_CONTROL2_REG + BALLOON3_FPGA_SETnCLR); + + ver = __raw_readw(BALLOON3_FPGA_VER); + if (ver < 0x4f08) + pr_warn("The FPGA code, version 0x%04x, is too old. " + "NAND support might be broken in this version!", ver); + + /* Power up the NAND chips */ + ret = gpio_request(BALLOON3_GPIO_RUN_NAND, "NAND"); + if (ret) + goto err1; + + ret = gpio_direction_output(BALLOON3_GPIO_RUN_NAND, 1); + if (ret) + goto err2; + + gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1); + + /* Deassert all nCE lines and write protect line */ + __raw_writel( + BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | + BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 | + BALLOON3_NAND_CONTROL_FLWP, + BALLOON3_NAND_CONTROL_REG + BALLOON3_FPGA_SETnCLR); + return 0; + +err2: + gpio_free(BALLOON3_GPIO_RUN_NAND); +err1: + return ret; +} + +static void balloon3_nand_remove(struct platform_device *pdev) +{ + /* Power down the NAND chips */ + gpio_set_value(BALLOON3_GPIO_RUN_NAND, 0); + gpio_free(BALLOON3_GPIO_RUN_NAND); +} + +static struct mtd_partition balloon3_partition_info[] = { + [0] = { + .name = "Boot", + .offset = 0, + .size = SZ_4M, + }, + [1] = { + .name = "RootFS", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; + +static const char *balloon3_part_probes[] = { "cmdlinepart", NULL }; + +struct platform_nand_data balloon3_nand_pdata = { + .chip = { + .nr_chips = 4, + .chip_offset = 0, + .nr_partitions = ARRAY_SIZE(balloon3_partition_info), + .partitions = balloon3_partition_info, + .chip_delay = 50, + .part_probe_types = balloon3_part_probes, + }, + .ctrl = { + .hwcontrol = 0, + .dev_ready = balloon3_nand_dev_ready, + .select_chip = balloon3_nand_select_chip, + .cmd_ctrl = balloon3_nand_cmd_ctl, + .probe = balloon3_nand_probe, + .remove = balloon3_nand_remove, + }, +}; + +static struct resource balloon3_nand_resource[] = { + [0] = { + .start = BALLOON3_NAND_BASE, + .end = BALLOON3_NAND_BASE + 0x4, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device balloon3_nand = { + .name = "gen_nand", + .num_resources = ARRAY_SIZE(balloon3_nand_resource), + .resource = balloon3_nand_resource, + .id = -1, + .dev = { + .platform_data = &balloon3_nand_pdata, + } +}; + +static void __init balloon3_nand_init(void) +{ + platform_device_register(&balloon3_nand); +} +#else +static inline void balloon3_nand_init(void) {} +#endif + +/****************************************************************************** + * Core power regulator + ******************************************************************************/ +#if defined(CONFIG_REGULATOR_MAX1586) || \ + defined(CONFIG_REGULATOR_MAX1586_MODULE) +static struct regulator_consumer_supply balloon3_max1587a_consumers[] = { + { + .supply = "vcc_core", + } +}; + +static struct regulator_init_data balloon3_max1587a_v3_info = { + .constraints = { + .name = "vcc_core range", + .min_uV = 900000, + .max_uV = 1705000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .consumer_supplies = balloon3_max1587a_consumers, + .num_consumer_supplies = ARRAY_SIZE(balloon3_max1587a_consumers), +}; + +static struct max1586_subdev_data balloon3_max1587a_subdevs[] = { + { + .name = "vcc_core", + .id = MAX1586_V3, + .platform_data = &balloon3_max1587a_v3_info, + } +}; + +static struct max1586_platform_data balloon3_max1587a_info = { + .subdevs = balloon3_max1587a_subdevs, + .num_subdevs = ARRAY_SIZE(balloon3_max1587a_subdevs), + .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */ +}; + +static struct i2c_board_info __initdata balloon3_pi2c_board_info[] = { + { + I2C_BOARD_INFO("max1586", 0x14), + .platform_data = &balloon3_max1587a_info, + }, +}; + +static void __init balloon3_pmic_init(void) +{ + pxa27x_set_i2c_power_info(NULL); + i2c_register_board_info(1, ARRAY_AND_SIZE(balloon3_pi2c_board_info)); +} +#else +static inline void balloon3_pmic_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init balloon3_init(void) +{ + ARB_CNTRL = ARB_CORE_PARK | 0x234; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + balloon3_i2c_init(); + balloon3_irda_init(); + balloon3_lcd_init(); + balloon3_leds_init(); + balloon3_mmc_init(); + balloon3_nand_init(); + balloon3_nor_init(); + balloon3_pmic_init(); + balloon3_ts_init(); + balloon3_udc_init(); + balloon3_uhc_init(); + balloon3_cf_init(); +} + +static struct map_desc balloon3_io_desc[] __initdata = { + { /* CPLD/FPGA */ + .virtual = (unsigned long)BALLOON3_FPGA_VIRT, + .pfn = __phys_to_pfn(BALLOON3_FPGA_PHYS), + .length = BALLOON3_FPGA_LENGTH, + .type = MT_DEVICE, + }, +}; + +static void __init balloon3_map_io(void) +{ + pxa27x_map_io(); + iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc)); +} + +MACHINE_START(BALLOON3, "Balloon3") + /* Maintainer: Nick Bane. */ + .map_io = balloon3_map_io, + .nr_irqs = BALLOON3_NR_IRQS, + .init_irq = balloon3_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = balloon3_init, + .atag_offset = 0x100, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c new file mode 100644 index 00000000000..c91727d1fe0 --- /dev/null +++ b/arch/arm/mach-pxa/capc7117.c @@ -0,0 +1,158 @@ +/* + * linux/arch/arm/mach-pxa/capc7117.c + * + * Support for the Embedian CAPC-7117 Evaluation Kit + * based on the Embedian MXM-8x10 Computer on Module + * + * Copyright (C) 2009 Embedian Inc. + * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd. + * + * 2007-09-04: eric miao <eric.y.miao@gmail.com> + * rewrite to align with latest kernel + * + * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za> + * Hennie van der Merwe <hvdmerwe@tmtservices.co.za> + * rework for upstream merge + * + * 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/irq.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/serial_8250.h> +#include <linux/gpio.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa320.h> +#include <mach/mxm8x10.h> + +#include "generic.h" + +/* IDE (PATA) Support */ +static struct pata_platform_info pata_platform_data = { + .ioport_shift = 1 +}; + +static struct resource capc7117_ide_resources[] = { + [0] = { + .start = 0x11000020, + .end = 0x1100003f, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = 0x1100001c, + .end = 0x1100001c, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)), + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING + } +}; + +static struct platform_device capc7117_ide_device = { + .name = "pata_platform", + .num_resources = ARRAY_SIZE(capc7117_ide_resources), + .resource = capc7117_ide_resources, + .dev = { + .platform_data = &pata_platform_data, + .coherent_dma_mask = ~0 /* grumble */ + } +}; + +static void __init capc7117_ide_init(void) +{ + platform_device_register(&capc7117_ide_device); +} + +/* TI16C752 UART support */ +#define TI16C752_FLAGS (UPF_BOOT_AUTOCONF | \ + UPF_IOREMAP | \ + UPF_BUGGY_UART | \ + UPF_SKIP_TEST) +#define TI16C752_UARTCLK (22118400) +static struct plat_serial8250_port ti16c752_platform_data[] = { + [0] = { + .mapbase = 0x14000000, + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO78)), + .irqflags = IRQF_TRIGGER_RISING, + .flags = TI16C752_FLAGS, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = TI16C752_UARTCLK + }, + [1] = { + .mapbase = 0x14000040, + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO79)), + .irqflags = IRQF_TRIGGER_RISING, + .flags = TI16C752_FLAGS, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = TI16C752_UARTCLK + }, + [2] = { + .mapbase = 0x14000080, + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO80)), + .irqflags = IRQF_TRIGGER_RISING, + .flags = TI16C752_FLAGS, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = TI16C752_UARTCLK + }, + [3] = { + .mapbase = 0x140000c0, + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO81)), + .irqflags = IRQF_TRIGGER_RISING, + .flags = TI16C752_FLAGS, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = TI16C752_UARTCLK + }, + [4] = { + /* end of array */ + } +}; + +static struct platform_device ti16c752_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = ti16c752_platform_data + } +}; + +static void __init capc7117_uarts_init(void) +{ + platform_device_register(&ti16c752_device); +} + +static void __init capc7117_init(void) +{ + /* Init CoM */ + mxm_8x10_barebones_init(); + + /* Init evaluation board peripherals */ + mxm_8x10_ac97_init(); + mxm_8x10_usb_host_init(); + mxm_8x10_mmc_init(); + + capc7117_uarts_init(); + capc7117_ide_init(); +} + +MACHINE_START(CAPC7117, + "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .timer = &pxa_timer, + .init_machine = capc7117_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/clock-pxa2xx.c b/arch/arm/mach-pxa/clock-pxa2xx.c new file mode 100644 index 00000000000..1d5859d9a0e --- /dev/null +++ b/arch/arm/mach-pxa/clock-pxa2xx.c @@ -0,0 +1,54 @@ +/* + * linux/arch/arm/mach-pxa/clock-pxa2xx.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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/syscore_ops.h> + +#include <mach/pxa2xx-regs.h> + +#include "clock.h" + +void clk_pxa2xx_cken_enable(struct clk *clk) +{ + CKEN |= 1 << clk->cken; +} + +void clk_pxa2xx_cken_disable(struct clk *clk) +{ + CKEN &= ~(1 << clk->cken); +} + +const struct clkops clk_pxa2xx_cken_ops = { + .enable = clk_pxa2xx_cken_enable, + .disable = clk_pxa2xx_cken_disable, +}; + +#ifdef CONFIG_PM +static uint32_t saved_cken; + +static int pxa2xx_clock_suspend(void) +{ + saved_cken = CKEN; + return 0; +} + +static void pxa2xx_clock_resume(void) +{ + CKEN = saved_cken; +} +#else +#define pxa2xx_clock_suspend NULL +#define pxa2xx_clock_resume NULL +#endif + +struct syscore_ops pxa2xx_clock_syscore_ops = { + .suspend = pxa2xx_clock_suspend, + .resume = pxa2xx_clock_resume, +}; diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c new file mode 100644 index 00000000000..2a37a9a8f62 --- /dev/null +++ b/arch/arm/mach-pxa/clock-pxa3xx.c @@ -0,0 +1,208 @@ +/* + * linux/arch/arm/mach-pxa/clock-pxa3xx.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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/syscore_ops.h> + +#include <mach/smemc.h> +#include <mach/pxa3xx-regs.h> + +#include "clock.h" + +/* Crystal clock: 13MHz */ +#define BASE_CLK 13000000 + +/* Ring Oscillator Clock: 60MHz */ +#define RO_CLK 60000000 + +#define ACCR_D0CS (1 << 26) +#define ACCR_PCCE (1 << 11) + +/* crystal frequency to HSIO bus frequency multiplier (HSS) */ +static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; + +/* + * Get the clock frequency as reflected by CCSR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int pxa3xx_get_clk_frequency_khz(int info) +{ + unsigned long acsr, xclkcfg; + unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; + + /* Read XCLKCFG register turbo bit */ + __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); + t = xclkcfg & 0x1; + + acsr = ACSR; + + xl = acsr & 0x1f; + xn = (acsr >> 8) & 0x7; + hss = (acsr >> 14) & 0x3; + + XL = xl * BASE_CLK; + XN = xn * XL; + + ro = acsr & ACCR_D0CS; + + CLK = (ro) ? RO_CLK : ((t) ? XN : XL); + HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; + + if (info) { + pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", + RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, + (ro) ? "" : "in"); + pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", + XL / 1000000, (XL % 1000000) / 10000, xl); + pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", + XN / 1000000, (XN % 1000000) / 10000, xn, + (t) ? "" : "in"); + pr_info("HSIO bus clock: %d.%02dMHz\n", + HSS / 1000000, (HSS % 1000000) / 10000); + } + + return CLK / 1000; +} + +/* + * Return the current AC97 clock frequency. + */ +static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) +{ + unsigned long rate = 312000000; + unsigned long ac97_div; + + ac97_div = AC97_DIV; + + /* This may loose precision for some rates but won't for the + * standard 24.576MHz. + */ + rate /= (ac97_div >> 12) & 0x7fff; + rate *= (ac97_div & 0xfff); + + return rate; +} + +/* + * Return the current HSIO bus clock frequency + */ +static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) +{ + unsigned long acsr; + unsigned int hss, hsio_clk; + + acsr = ACSR; + + hss = (acsr >> 14) & 0x3; + hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; + + return hsio_clk; +} + +/* crystal frequency to static memory controller multiplier (SMCFS) */ +static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; +static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 }; + +static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk) +{ + unsigned long acsr = ACSR; + unsigned long memclkcfg = __raw_readl(MEMCLKCFG); + + return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] / + df_clkdiv[(memclkcfg >> 16) & 0x3]; +} + +void clk_pxa3xx_cken_enable(struct clk *clk) +{ + unsigned long mask = 1ul << (clk->cken & 0x1f); + + if (clk->cken < 32) + CKENA |= mask; + else + CKENB |= mask; +} + +void clk_pxa3xx_cken_disable(struct clk *clk) +{ + unsigned long mask = 1ul << (clk->cken & 0x1f); + + if (clk->cken < 32) + CKENA &= ~mask; + else + CKENB &= ~mask; +} + +const struct clkops clk_pxa3xx_cken_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, +}; + +const struct clkops clk_pxa3xx_hsio_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, + .getrate = clk_pxa3xx_hsio_getrate, +}; + +const struct clkops clk_pxa3xx_ac97_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, + .getrate = clk_pxa3xx_ac97_getrate, +}; + +const struct clkops clk_pxa3xx_smemc_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, + .getrate = clk_pxa3xx_smemc_getrate, +}; + +static void clk_pout_enable(struct clk *clk) +{ + OSCC |= OSCC_PEN; +} + +static void clk_pout_disable(struct clk *clk) +{ + OSCC &= ~OSCC_PEN; +} + +const struct clkops clk_pxa3xx_pout_ops = { + .enable = clk_pout_enable, + .disable = clk_pout_disable, +}; + +#ifdef CONFIG_PM +static uint32_t cken[2]; +static uint32_t accr; + +static int pxa3xx_clock_suspend(void) +{ + cken[0] = CKENA; + cken[1] = CKENB; + accr = ACCR; + return 0; +} + +static void pxa3xx_clock_resume(void) +{ + ACCR = accr; + CKENA = cken[0]; + CKENB = cken[1]; +} +#else +#define pxa3xx_clock_suspend NULL +#define pxa3xx_clock_resume NULL +#endif + +struct syscore_ops pxa3xx_clock_syscore_ops = { + .suspend = pxa3xx_clock_suspend, + .resume = pxa3xx_clock_resume, +}; diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c new file mode 100644 index 00000000000..4d466102a02 --- /dev/null +++ b/arch/arm/mach-pxa/clock.c @@ -0,0 +1,86 @@ +/* + * linux/arch/arm/mach-sa1100/clock.c + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/clkdev.h> + +#include "clock.h" + +static DEFINE_SPINLOCK(clocks_lock); + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + if (clk->enabled++ == 0) + clk->ops->enable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + + if (clk->delay) + udelay(clk->delay); + + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + WARN_ON(clk->enabled == 0); + + spin_lock_irqsave(&clocks_lock, flags); + if (--clk->enabled == 0) + clk->ops->disable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + unsigned long rate; + + rate = clk->rate; + if (clk->ops->getrate) + rate = clk->ops->getrate(clk); + + return rate; +} +EXPORT_SYMBOL(clk_get_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + int ret = -EINVAL; + + if (clk->ops->setrate) { + spin_lock_irqsave(&clocks_lock, flags); + ret = clk->ops->setrate(clk, rate); + spin_unlock_irqrestore(&clocks_lock, flags); + } + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +void clk_dummy_enable(struct clk *clk) +{ +} + +void clk_dummy_disable(struct clk *clk) +{ +} + +const struct clkops clk_dummy_ops = { + .enable = clk_dummy_enable, + .disable = clk_dummy_disable, +}; + +struct clk clk_dummy = { + .ops = &clk_dummy_ops, +}; diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h new file mode 100644 index 00000000000..3a258b1bf1a --- /dev/null +++ b/arch/arm/mach-pxa/clock.h @@ -0,0 +1,80 @@ +#include <linux/clkdev.h> +#include <linux/syscore_ops.h> + +struct clkops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); + unsigned long (*getrate)(struct clk *); + int (*setrate)(struct clk *, unsigned long); +}; + +struct clk { + const struct clkops *ops; + unsigned long rate; + unsigned int cken; + unsigned int delay; + unsigned int enabled; +}; + +void clk_dummy_enable(struct clk *); +void clk_dummy_disable(struct clk *); + +extern const struct clkops clk_dummy_ops; +extern struct clk clk_dummy; + +#define INIT_CLKREG(_clk,_devname,_conname) \ + { \ + .clk = _clk, \ + .dev_id = _devname, \ + .con_id = _conname, \ + } + +#define DEFINE_CK(_name, _cken, _ops) \ +struct clk clk_##_name = { \ + .ops = _ops, \ + .cken = CKEN_##_cken, \ + } + +#define DEFINE_CLK(_name, _ops, _rate, _delay) \ +struct clk clk_##_name = { \ + .ops = _ops, \ + .rate = _rate, \ + .delay = _delay, \ + } + +#define DEFINE_PXA2_CKEN(_name, _cken, _rate, _delay) \ +struct clk clk_##_name = { \ + .ops = &clk_pxa2xx_cken_ops, \ + .rate = _rate, \ + .cken = CKEN_##_cken, \ + .delay = _delay, \ + } + +extern const struct clkops clk_pxa2xx_cken_ops; + +void clk_pxa2xx_cken_enable(struct clk *clk); +void clk_pxa2xx_cken_disable(struct clk *clk); + +extern struct syscore_ops pxa2xx_clock_syscore_ops; + +#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) +#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \ +struct clk clk_##_name = { \ + .ops = &clk_pxa3xx_cken_ops, \ + .rate = _rate, \ + .cken = CKEN_##_cken, \ + .delay = _delay, \ + } + +extern const struct clkops clk_pxa3xx_cken_ops; +extern const struct clkops clk_pxa3xx_hsio_ops; +extern const struct clkops clk_pxa3xx_ac97_ops; +extern const struct clkops clk_pxa3xx_pout_ops; +extern const struct clkops clk_pxa3xx_smemc_ops; + +extern void clk_pxa3xx_cken_enable(struct clk *); +extern void clk_pxa3xx_cken_disable(struct clk *); + +extern struct syscore_ops pxa3xx_clock_syscore_ops; + +#endif diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c new file mode 100644 index 00000000000..be751470d37 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x255.c @@ -0,0 +1,236 @@ +/* + * linux/arch/arm/mach-pxa/cm-x255.c + * + * Copyright (C) 2007, 2008 CompuLab, Ltd. + * Mike Rapoport <mike@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. + */ + +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/nand-gpio.h> + +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> +#include <asm/mach/map.h> + +#include <mach/pxa25x.h> + +#include "generic.h" + +#define GPIO_NAND_CS (5) +#define GPIO_NAND_ALE (4) +#define GPIO_NAND_CLE (3) +#define GPIO_NAND_RB (10) + +static unsigned long cmx255_pin_config[] = { + /* AC'97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* SSP1 */ + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* SSP2 */ + GPIO81_SSP2_CLK_OUT, + GPIO82_SSP2_FRM_OUT, + GPIO83_SSP2_TXD, + GPIO84_SSP2_RXD, + + /* PC Card */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO54_nPSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* SDRAM and local bus */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO33_nCS_5, + GPIO18_RDY, + + /* GPIO */ + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, + GPIO9_GPIO, /* PC card reset */ + + /* NAND controls */ + GPIO5_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ + GPIO4_GPIO | MFP_LPM_DRIVE_LOW, /* NAND ALE */ + GPIO3_GPIO | MFP_LPM_DRIVE_LOW, /* NAND CLE */ + GPIO10_GPIO, /* NAND Ready/Busy */ + + /* interrupts */ + GPIO22_GPIO, /* DM9000 interrupt */ +}; + +#if defined(CONFIG_SPI_PXA2XX) +static struct pxa2xx_spi_master pxa_ssp_master_info = { + .num_chipselect = 1, +}; + +static struct spi_board_info spi_board_info[] __initdata = { + [0] = { + .modalias = "rtc-max6902", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 0, + }, +}; + +static void __init cmx255_init_rtc(void) +{ + pxa2xx_set_spi_info(1, &pxa_ssp_master_info); + spi_register_board_info(ARRAY_AND_SIZE(spi_board_info)); +} +#else +static inline void cmx255_init_rtc(void) {} +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition cmx255_nor_partitions[] = { + { + .name = "ARMmon", + .size = 0x00030000, + .offset = 0, + .mask_flags = MTD_WRITEABLE /* force read-only */ + } , { + .name = "ARMmon setup block", + .size = 0x00010000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE /* force read-only */ + } , { + .name = "kernel", + .size = 0x00160000, + .offset = MTDPART_OFS_APPEND, + } , { + .name = "ramdisk", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND + } +}; + +static struct physmap_flash_data cmx255_nor_flash_data[] = { + { + .width = 2, /* bankwidth in bytes */ + .parts = cmx255_nor_partitions, + .nr_parts = ARRAY_SIZE(cmx255_nor_partitions) + } +}; + +static struct resource cmx255_nor_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cmx255_nor = { + .name = "physmap-flash", + .id = -1, + .dev = { + .platform_data = cmx255_nor_flash_data, + }, + .resource = &cmx255_nor_resource, + .num_resources = 1, +}; + +static void __init cmx255_init_nor(void) +{ + platform_device_register(&cmx255_nor); +} +#else +static inline void cmx255_init_nor(void) {} +#endif + +#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) +static struct resource cmx255_nand_resource[] = { + [0] = { + .start = PXA_CS1_PHYS, + .end = PXA_CS1_PHYS + 11, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_CS5_PHYS, + .end = PXA_CS5_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct mtd_partition cmx255_nand_parts[] = { + [0] = { + .name = "cmx255-nand", + .size = MTDPART_SIZ_FULL, + .offset = 0, + }, +}; + +static struct gpio_nand_platdata cmx255_nand_platdata = { + .gpio_nce = GPIO_NAND_CS, + .gpio_cle = GPIO_NAND_CLE, + .gpio_ale = GPIO_NAND_ALE, + .gpio_rdy = GPIO_NAND_RB, + .gpio_nwp = -1, + .parts = cmx255_nand_parts, + .num_parts = ARRAY_SIZE(cmx255_nand_parts), + .chip_delay = 25, +}; + +static struct platform_device cmx255_nand = { + .name = "gpio-nand", + .num_resources = ARRAY_SIZE(cmx255_nand_resource), + .resource = cmx255_nand_resource, + .id = -1, + .dev = { + .platform_data = &cmx255_nand_platdata, + } +}; + +static void __init cmx255_init_nand(void) +{ + platform_device_register(&cmx255_nand); +} +#else +static inline void cmx255_init_nand(void) {} +#endif + +void __init cmx255_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx255_pin_config)); + + cmx255_init_rtc(); + cmx255_init_nor(); + cmx255_init_nand(); +} diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c new file mode 100644 index 00000000000..431ef56700c --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270.c @@ -0,0 +1,412 @@ +/* + * linux/arch/arm/mach-pxa/cm-x270.c + * + * Copyright (C) 2007, 2008 CompuLab, Ltd. + * Mike Rapoport <mike@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. + */ + +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/gpio.h> +#include <linux/delay.h> + +#include <linux/rtc-v3020.h> +#include <video/mbxfb.h> + +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/spi/libertas_spi.h> + +#include <mach/pxa27x.h> +#include <mach/ohci.h> +#include <mach/mmc.h> + +#include "generic.h" + +/* physical address if local-bus attached devices */ +#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) + +/* GPIO IRQ usage */ +#define GPIO83_MMC_IRQ (83) + +#define CMX270_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO83_MMC_IRQ) + +/* MMC power enable */ +#define GPIO105_MMC_POWER (105) + +/* WLAN GPIOS */ +#define GPIO19_WLAN_STRAP (19) +#define GPIO102_WLAN_RST (102) + +static unsigned long cmx270_pin_config[] = { + /* AC'97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO98_AC97_SYSCLK, + GPIO113_AC97_nRESET, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* MCI controller */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* SSP1 */ + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* SSP2 */ + GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */ + GPIO14_GPIO, + GPIO87_SSP2_TXD, + GPIO88_SSP2_RXD, + + /* PC Card */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* SDRAM and local bus */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO33_nCS_5, + GPIO49_nPWE, + GPIO18_RDY, + + /* GPIO */ + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, + GPIO105_GPIO | MFP_LPM_DRIVE_HIGH, /* MMC/SD power */ + GPIO53_GPIO, /* PC card reset */ + GPIO102_GPIO, /* WLAN reset */ + + /* NAND controls */ + GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ + GPIO89_GPIO, /* NAND Ready/Busy */ + + /* interrupts */ + GPIO10_GPIO, /* DM9000 interrupt */ + GPIO83_GPIO, /* MMC card detect */ + GPIO95_GPIO, /* WLAN interrupt */ +}; + +/* V3020 RTC */ +#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) +static struct resource cmx270_v3020_resource[] = { + [0] = { + .start = RTC_PHYS_BASE, + .end = RTC_PHYS_BASE + 4, + .flags = IORESOURCE_MEM, + }, +}; + +struct v3020_platform_data cmx270_v3020_pdata = { + .leftshift = 16, +}; + +static struct platform_device cmx270_rtc_device = { + .name = "v3020", + .num_resources = ARRAY_SIZE(cmx270_v3020_resource), + .resource = cmx270_v3020_resource, + .id = -1, + .dev = { + .platform_data = &cmx270_v3020_pdata, + } +}; + +static void __init cmx270_init_rtc(void) +{ + platform_device_register(&cmx270_rtc_device); +} +#else +static inline void cmx270_init_rtc(void) {} +#endif + +/* 2700G graphics */ +#if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE) +static u64 fb_dma_mask = ~(u64)0; + +static struct resource cmx270_2700G_resource[] = { + /* frame buffer memory including ODFB and External SDRAM */ + [0] = { + .start = PXA_CS2_PHYS, + .end = PXA_CS2_PHYS + 0x01ffffff, + .flags = IORESOURCE_MEM, + }, + /* Marathon registers */ + [1] = { + .start = PXA_CS2_PHYS + 0x03fe0000, + .end = PXA_CS2_PHYS + 0x03ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static unsigned long cmx270_marathon_on[] = { + GPIO58_GPIO, + GPIO59_GPIO, + GPIO60_GPIO, + GPIO61_GPIO, + GPIO62_GPIO, + GPIO63_GPIO, + GPIO64_GPIO, + GPIO65_GPIO, + GPIO66_GPIO, + GPIO67_GPIO, + GPIO68_GPIO, + GPIO69_GPIO, + GPIO70_GPIO, + GPIO71_GPIO, + GPIO72_GPIO, + GPIO73_GPIO, + GPIO74_GPIO, + GPIO75_GPIO, + GPIO76_GPIO, + GPIO77_GPIO, +}; + +static unsigned long cmx270_marathon_off[] = { + GPIOxx_LCD_TFT_16BPP, +}; + +static int cmx270_marathon_probe(struct fb_info *fb) +{ + int gpio, err; + + for (gpio = 58; gpio <= 77; gpio++) { + err = gpio_request(gpio, "LCD"); + if (err) + return err; + gpio_direction_input(gpio); + } + + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_on)); + return 0; +} + +static int cmx270_marathon_remove(struct fb_info *fb) +{ + int gpio; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_off)); + + for (gpio = 58; gpio <= 77; gpio++) + gpio_free(gpio); + + return 0; +} + +static struct mbxfb_platform_data cmx270_2700G_data = { + .xres = { + .min = 240, + .max = 1200, + .defval = 640, + }, + .yres = { + .min = 240, + .max = 1200, + .defval = 480, + }, + .bpp = { + .min = 16, + .max = 32, + .defval = 16, + }, + .memsize = 8*1024*1024, + .probe = cmx270_marathon_probe, + .remove = cmx270_marathon_remove, +}; + +static struct platform_device cmx270_2700G = { + .name = "mbx-fb", + .dev = { + .platform_data = &cmx270_2700G_data, + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(cmx270_2700G_resource), + .resource = cmx270_2700G_resource, + .id = -1, +}; + +static void __init cmx270_init_2700G(void) +{ + platform_device_register(&cmx270_2700G); +} +#else +static inline void cmx270_init_2700G(void) {} +#endif + +/* PXA27x OHCI controller setup */ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static struct pxaohci_platform_data cmx270_ohci_platform_data = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW, +}; + +static void __init cmx270_init_ohci(void) +{ + pxa_set_ohci_info(&cmx270_ohci_platform_data); +} +#else +static inline void cmx270_init_ohci(void) {} +#endif + +#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) +static struct pxamci_platform_data cmx270_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = GPIO83_MMC_IRQ, + .gpio_card_ro = -1, + .gpio_power = GPIO105_MMC_POWER, + .gpio_power_invert = 1, +}; + +static void __init cmx270_init_mmc(void) +{ + pxa_set_mci_info(&cmx270_mci_platform_data); +} +#else +static inline void cmx270_init_mmc(void) {} +#endif + +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +static struct pxa2xx_spi_master cm_x270_spi_info = { + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct pxa2xx_spi_chip cm_x270_libertas_chip = { + .rx_threshold = 1, + .tx_threshold = 1, + .timeout = 1000, + .gpio_cs = 14, +}; + +static unsigned long cm_x270_libertas_pin_config[] = { + /* SSP2 */ + GPIO19_SSP2_SCLK, + GPIO14_GPIO, + GPIO87_SSP2_TXD, + GPIO88_SSP2_RXD, + +}; + +static int cm_x270_libertas_setup(struct spi_device *spi) +{ + int err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP"); + if (err) + return err; + + err = gpio_request(GPIO102_WLAN_RST, "WLAN RST"); + if (err) + goto err_free_strap; + + err = gpio_direction_output(GPIO102_WLAN_RST, 0); + if (err) + goto err_free_strap; + msleep(100); + + err = gpio_direction_output(GPIO19_WLAN_STRAP, 1); + if (err) + goto err_free_strap; + msleep(100); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(cm_x270_libertas_pin_config)); + + gpio_set_value(GPIO102_WLAN_RST, 1); + msleep(100); + + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; + +err_free_strap: + gpio_free(GPIO19_WLAN_STRAP); + + return err; +} + +static int cm_x270_libertas_teardown(struct spi_device *spi) +{ + gpio_set_value(GPIO102_WLAN_RST, 0); + gpio_free(GPIO102_WLAN_RST); + gpio_free(GPIO19_WLAN_STRAP); + + return 0; +} + +struct libertas_spi_platform_data cm_x270_libertas_pdata = { + .use_dummy_writes = 1, + .setup = cm_x270_libertas_setup, + .teardown = cm_x270_libertas_teardown, +}; + +static struct spi_board_info cm_x270_spi_devices[] __initdata = { + { + .modalias = "libertas_spi", + .max_speed_hz = 13000000, + .bus_num = 2, + .irq = PXA_GPIO_TO_IRQ(95), + .chip_select = 0, + .controller_data = &cm_x270_libertas_chip, + .platform_data = &cm_x270_libertas_pdata, + }, +}; + +static void __init cmx270_init_spi(void) +{ + pxa2xx_set_spi_info(2, &cm_x270_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(cm_x270_spi_devices)); +} +#else +static inline void cmx270_init_spi(void) {} +#endif + +void __init cmx270_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); + +#ifdef CONFIG_PM + pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP); +#endif + + cmx270_init_rtc(); + cmx270_init_mmc(); + cmx270_init_ohci(); + cmx270_init_2700G(); + cmx270_init_spi(); +} diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c new file mode 100644 index 00000000000..ebd9259f5ac --- /dev/null +++ b/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -0,0 +1,200 @@ +/* + * linux/arch/arm/mach-pxa/cm-x2xx-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + * + * Copyright (C) 2007, 2008 Compulab, Ltd. + * Mike Rapoport <mike@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. + */ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/gpio.h> + +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +#include <asm/hardware/it8152.h> + +void __iomem *it8152_base_address; +static int cmx2xx_it8152_irq_gpio; + +static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) +{ + /* clear our parent irq */ + desc->irq_data.chip->irq_ack(&desc->irq_data); + + it8152_irq_demux(irq, desc); +} + +void __cmx2xx_pci_init_irq(int irq_gpio) +{ + it8152_init_irq(); + + cmx2xx_it8152_irq_gpio = irq_gpio; + + irq_set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); + + irq_set_chained_handler(gpio_to_irq(irq_gpio), + cmx2xx_it8152_irq_demux); +} + +#ifdef CONFIG_PM +static unsigned long sleep_save_ite[10]; + +void __cmx2xx_pci_suspend(void) +{ + /* save ITE state */ + sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR); + sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR); + sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR); + + /* Clear ITE IRQ's */ + __raw_writel((0), IT8152_INTC_PDCNIRR); + __raw_writel((0), IT8152_INTC_LPCNIRR); +} + +void __cmx2xx_pci_resume(void) +{ + /* restore IT8152 state */ + __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR); + __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR); + __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR); +} +#else +void cmx2xx_pci_suspend(void) {} +void cmx2xx_pci_resume(void) {} +#endif + +/* PCI IRQ mapping*/ +static int __init cmx2xx_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + dev_dbg(&dev->dev, "%s: slot=%x, pin=%x\n", __func__, slot, pin); + + irq = it8152_pci_map_irq(dev, slot, pin); + if (irq) + return irq; + + /* + Here comes the ugly part. The routing is baseboard specific, + but defining a platform for each possible base of CM-X2XX is + unrealistic. Here we keep mapping for ATXBase and SB-X2XX. + */ + /* ATXBASE PCI slot */ + if (slot == 7) + return IT8152_PCI_INTA; + + /* ATXBase/SB-X2XX CardBus */ + if (slot == 8 || slot == 0) + return IT8152_PCI_INTB; + + /* ATXBase Ethernet */ + if (slot == 9) + return IT8152_PCI_INTA; + + /* CM-x255 Onboard Ethernet */ + if (slot == 15) + return IT8152_PCI_INTC; + + /* SB-x2xx Ethernet */ + if (slot == 16) + return IT8152_PCI_INTA; + + /* PC104+ interrupt routing */ + if ((slot == 17) || (slot == 19)) + return IT8152_PCI_INTA; + if ((slot == 18) || (slot == 20)) + return IT8152_PCI_INTB; + + return(0); +} + +static void cmx2xx_pci_preinit(void) +{ + pr_info("Initializing CM-X2XX PCI subsystem\n"); + + pcibios_min_io = 0; + pcibios_min_mem = 0; + + __raw_writel(0x800, IT8152_PCI_CFG_ADDR); + if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) { + pr_info("PCI Bridge found.\n"); + + /* set PCI I/O base at 0 */ + writel(0x848, IT8152_PCI_CFG_ADDR); + writel(0, IT8152_PCI_CFG_DATA); + + /* set PCI memory base at 0 */ + writel(0x840, IT8152_PCI_CFG_ADDR); + writel(0, IT8152_PCI_CFG_DATA); + + writel(0x20, IT8152_GPIO_GPDR); + + /* CardBus Controller on ATXbase baseboard */ + writel(0x4000, IT8152_PCI_CFG_ADDR); + if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) { + pr_info("CardBus Bridge found.\n"); + + /* Configure socket 0 */ + writel(0x408C, IT8152_PCI_CFG_ADDR); + writel(0x1022, IT8152_PCI_CFG_DATA); + + writel(0x4080, IT8152_PCI_CFG_ADDR); + writel(0x3844d060, IT8152_PCI_CFG_DATA); + + writel(0x4090, IT8152_PCI_CFG_ADDR); + writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) | + 0x60440000), + IT8152_PCI_CFG_DATA); + + writel(0x4018, IT8152_PCI_CFG_ADDR); + writel(0xb0000000, IT8152_PCI_CFG_DATA); + + /* Configure socket 1 */ + writel(0x418C, IT8152_PCI_CFG_ADDR); + writel(0x1022, IT8152_PCI_CFG_DATA); + + writel(0x4180, IT8152_PCI_CFG_ADDR); + writel(0x3844d060, IT8152_PCI_CFG_DATA); + + writel(0x4190, IT8152_PCI_CFG_ADDR); + writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) | + 0x60440000), + IT8152_PCI_CFG_DATA); + + writel(0x4118, IT8152_PCI_CFG_ADDR); + writel(0xb0000000, IT8152_PCI_CFG_DATA); + } + } +} + +static struct hw_pci cmx2xx_pci __initdata = { + .swizzle = pci_std_swizzle, + .map_irq = cmx2xx_pci_map_irq, + .nr_controllers = 1, + .setup = it8152_pci_setup, + .scan = it8152_pci_scan_bus, + .preinit = cmx2xx_pci_preinit, +}; + +static int __init cmx2xx_init_pci(void) +{ + if (machine_is_armcore()) + pci_common_init(&cmx2xx_pci); + + return 0; +} + +subsys_initcall(cmx2xx_init_pci); diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.h b/arch/arm/mach-pxa/cm-x2xx-pci.h new file mode 100644 index 00000000000..e24aad2e3ad --- /dev/null +++ b/arch/arm/mach-pxa/cm-x2xx-pci.h @@ -0,0 +1,13 @@ +extern void __cmx2xx_pci_init_irq(int irq_gpio); +extern void __cmx2xx_pci_suspend(void); +extern void __cmx2xx_pci_resume(void); + +#ifdef CONFIG_PCI +#define cmx2xx_pci_init_irq(x) __cmx2xx_pci_init_irq(x) +#define cmx2xx_pci_suspend(x) __cmx2xx_pci_suspend(x) +#define cmx2xx_pci_resume(x) __cmx2xx_pci_resume(x) +#else +#define cmx2xx_pci_init_irq(x) do {} while (0) +#define cmx2xx_pci_suspend(x) do {} while (0) +#define cmx2xx_pci_resume(x) do {} while (0) +#endif diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c new file mode 100644 index 00000000000..8fa4ad27edf --- /dev/null +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -0,0 +1,528 @@ +/* + * linux/arch/arm/mach-pxa/cm-x2xx.c + * + * Copyright (C) 2008 CompuLab, Ltd. + * Mike Rapoport <mike@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. + */ + +#include <linux/platform_device.h> +#include <linux/syscore_ops.h> +#include <linux/irq.h> +#include <linux/gpio.h> + +#include <linux/dm9000.h> +#include <linux/leds.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> +#include <asm/mach/map.h> + +#include <mach/pxa25x.h> +#include <mach/pxa27x.h> +#include <mach/audio.h> +#include <mach/pxafb.h> +#include <mach/smemc.h> + +#include <asm/hardware/it8152.h> + +#include "generic.h" +#include "cm-x2xx-pci.h" + +extern void cmx255_init(void); +extern void cmx270_init(void); + +/* reserve IRQs for IT8152 */ +#define CMX2XX_NR_IRQS (IRQ_BOARD_START + 40) + +/* virtual addresses for statically mapped regions */ +#define CMX2XX_VIRT_BASE (void __iomem *)(0xe8000000) +#define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE) + +/* physical address if local-bus attached devices */ +#define CMX255_DM9000_PHYS_BASE (PXA_CS1_PHYS + (8 << 22)) +#define CMX270_DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) + +/* leds */ +#define CMX255_GPIO_RED (27) +#define CMX255_GPIO_GREEN (32) +#define CMX270_GPIO_RED (93) +#define CMX270_GPIO_GREEN (94) + +/* GPIO IRQ usage */ +#define GPIO22_ETHIRQ (22) +#define GPIO10_ETHIRQ (10) +#define CMX255_GPIO_IT8152_IRQ (0) +#define CMX270_GPIO_IT8152_IRQ (22) + +#define CMX255_ETHIRQ PXA_GPIO_TO_IRQ(GPIO22_ETHIRQ) +#define CMX270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO10_ETHIRQ) + +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource cmx255_dm9000_resource[] = { + [0] = { + .start = CMX255_DM9000_PHYS_BASE, + .end = CMX255_DM9000_PHYS_BASE + 3, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CMX255_DM9000_PHYS_BASE + 4, + .end = CMX255_DM9000_PHYS_BASE + 4 + 500, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = CMX255_ETHIRQ, + .end = CMX255_ETHIRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct resource cmx270_dm9000_resource[] = { + [0] = { + .start = CMX270_DM9000_PHYS_BASE, + .end = CMX270_DM9000_PHYS_BASE + 3, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CMX270_DM9000_PHYS_BASE + 8, + .end = CMX270_DM9000_PHYS_BASE + 8 + 500, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = CMX270_ETHIRQ, + .end = CMX270_ETHIRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct dm9000_plat_data cmx270_dm9000_platdata = { + .flags = DM9000_PLATF_32BITONLY | DM9000_PLATF_NO_EEPROM, +}; + +static struct platform_device cmx2xx_dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(cmx270_dm9000_resource), + .dev = { + .platform_data = &cmx270_dm9000_platdata, + } +}; + +static void __init cmx2xx_init_dm9000(void) +{ + if (cpu_is_pxa25x()) + cmx2xx_dm9000_device.resource = cmx255_dm9000_resource; + else + cmx2xx_dm9000_device.resource = cmx270_dm9000_resource; + platform_device_register(&cmx2xx_dm9000_device); +} +#else +static inline void cmx2xx_init_dm9000(void) {} +#endif + +/* UCB1400 touchscreen controller */ +#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static struct platform_device cmx2xx_ts_device = { + .name = "ucb1400_core", + .id = -1, +}; + +static void __init cmx2xx_init_touchscreen(void) +{ + platform_device_register(&cmx2xx_ts_device); +} +#else +static inline void cmx2xx_init_touchscreen(void) {} +#endif + +/* CM-X270 LEDs */ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led cmx2xx_leds[] = { + [0] = { + .name = "cm-x2xx:red", + .default_trigger = "nand-disk", + .active_low = 1, + }, + [1] = { + .name = "cm-x2xx:green", + .default_trigger = "heartbeat", + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data cmx2xx_gpio_led_pdata = { + .num_leds = ARRAY_SIZE(cmx2xx_leds), + .leds = cmx2xx_leds, +}; + +static struct platform_device cmx2xx_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &cmx2xx_gpio_led_pdata, + }, +}; + +static void __init cmx2xx_init_leds(void) +{ + if (cpu_is_pxa25x()) { + cmx2xx_leds[0].gpio = CMX255_GPIO_RED; + cmx2xx_leds[1].gpio = CMX255_GPIO_GREEN; + } else { + cmx2xx_leds[0].gpio = CMX270_GPIO_RED; + cmx2xx_leds[1].gpio = CMX270_GPIO_GREEN; + } + platform_device_register(&cmx2xx_led_device); +} +#else +static inline void cmx2xx_init_leds(void) {} +#endif + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +/* + Display definitions + keep these for backwards compatibility, although symbolic names (as + e.g. in lpd270.c) looks better +*/ +#define MTYPE_STN320x240 0 +#define MTYPE_TFT640x480 1 +#define MTYPE_CRT640x480 2 +#define MTYPE_CRT800x600 3 +#define MTYPE_TFT320x240 6 +#define MTYPE_STN640x480 7 + +static struct pxafb_mode_info generic_stn_320x240_mode = { + .pixclock = 76923, + .bpp = 8, + .xres = 320, + .yres = 240, + .hsync_len = 3, + .vsync_len = 2, + .left_margin = 3, + .upper_margin = 0, + .right_margin = 3, + .lower_margin = 0, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_stn_320x240 = { + .modes = &generic_stn_320x240_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_STN_8BPP | LCD_PCLK_EDGE_FALL |\ + LCD_AC_BIAS_FREQ(0xff), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_tft_640x480_mode = { + .pixclock = 38461, + .bpp = 8, + .xres = 640, + .yres = 480, + .hsync_len = 60, + .vsync_len = 2, + .left_margin = 70, + .upper_margin = 10, + .right_margin = 70, + .lower_margin = 5, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_tft_640x480 = { + .modes = &generic_tft_640x480_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_8BPP | LCD_PCLK_EDGE_FALL |\ + LCD_AC_BIAS_FREQ(0xff), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_crt_640x480_mode = { + .pixclock = 38461, + .bpp = 8, + .xres = 640, + .yres = 480, + .hsync_len = 63, + .vsync_len = 2, + .left_margin = 81, + .upper_margin = 33, + .right_margin = 16, + .lower_margin = 10, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_crt_640x480 = { + .modes = &generic_crt_640x480_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_8BPP | LCD_AC_BIAS_FREQ(0xff), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_crt_800x600_mode = { + .pixclock = 28846, + .bpp = 8, + .xres = 800, + .yres = 600, + .hsync_len = 63, + .vsync_len = 2, + .left_margin = 26, + .upper_margin = 21, + .right_margin = 26, + .lower_margin = 11, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_crt_800x600 = { + .modes = &generic_crt_800x600_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_8BPP | LCD_AC_BIAS_FREQ(0xff), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_tft_320x240_mode = { + .pixclock = 134615, + .bpp = 16, + .xres = 320, + .yres = 240, + .hsync_len = 63, + .vsync_len = 7, + .left_margin = 75, + .upper_margin = 0, + .right_margin = 15, + .lower_margin = 15, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_tft_320x240 = { + .modes = &generic_tft_320x240_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_AC_BIAS_FREQ(0xff), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_stn_640x480_mode = { + .pixclock = 57692, + .bpp = 8, + .xres = 640, + .yres = 480, + .hsync_len = 4, + .vsync_len = 2, + .left_margin = 10, + .upper_margin = 5, + .right_margin = 10, + .lower_margin = 5, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_stn_640x480 = { + .modes = &generic_stn_640x480_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_STN_8BPP | LCD_AC_BIAS_FREQ(0xff), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mach_info *cmx2xx_display = &generic_crt_640x480; + +static int __init cmx2xx_set_display(char *str) +{ + int disp_type = simple_strtol(str, NULL, 0); + switch (disp_type) { + case MTYPE_STN320x240: + cmx2xx_display = &generic_stn_320x240; + break; + case MTYPE_TFT640x480: + cmx2xx_display = &generic_tft_640x480; + break; + case MTYPE_CRT640x480: + cmx2xx_display = &generic_crt_640x480; + break; + case MTYPE_CRT800x600: + cmx2xx_display = &generic_crt_800x600; + break; + case MTYPE_TFT320x240: + cmx2xx_display = &generic_tft_320x240; + break; + case MTYPE_STN640x480: + cmx2xx_display = &generic_stn_640x480; + break; + default: /* fallback to CRT 640x480 */ + cmx2xx_display = &generic_crt_640x480; + break; + } + return 1; +} + +/* + This should be done really early to get proper configuration for + frame buffer. + Indeed, pxafb parameters can be used istead, but CM-X2XX bootloader + has limitied line length for kernel command line, and also it will + break compatibitlty with proprietary releases already in field. +*/ +__setup("monitor=", cmx2xx_set_display); + +static void __init cmx2xx_init_display(void) +{ + pxa_set_fb_info(NULL, cmx2xx_display); +} +#else +static inline void cmx2xx_init_display(void) {} +#endif + +#ifdef CONFIG_PM +static unsigned long sleep_save_msc[10]; + +static int cmx2xx_suspend(void) +{ + cmx2xx_pci_suspend(); + + /* save MSC registers */ + sleep_save_msc[0] = __raw_readl(MSC0); + sleep_save_msc[1] = __raw_readl(MSC1); + sleep_save_msc[2] = __raw_readl(MSC2); + + /* setup power saving mode registers */ + PCFR = 0x0; + PSLR = 0xff400000; + PMCR = 0x00000005; + PWER = 0x80000000; + PFER = 0x00000000; + PRER = 0x00000000; + PGSR0 = 0xC0018800; + PGSR1 = 0x004F0002; + PGSR2 = 0x6021C000; + PGSR3 = 0x00020000; + + return 0; +} + +static void cmx2xx_resume(void) +{ + cmx2xx_pci_resume(); + + /* restore MSC registers */ + __raw_writel(sleep_save_msc[0], MSC0); + __raw_writel(sleep_save_msc[1], MSC1); + __raw_writel(sleep_save_msc[2], MSC2); +} + +static struct syscore_ops cmx2xx_pm_syscore_ops = { + .resume = cmx2xx_resume, + .suspend = cmx2xx_suspend, +}; + +static int __init cmx2xx_pm_init(void) +{ + register_syscore_ops(&cmx2xx_pm_syscore_ops); + + return 0; +} +#else +static int __init cmx2xx_pm_init(void) { return 0; } +#endif + +#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) +static void __init cmx2xx_init_ac97(void) +{ + pxa_set_ac97_info(NULL); +} +#else +static inline void cmx2xx_init_ac97(void) {} +#endif + +static void __init cmx2xx_init(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + cmx2xx_pm_init(); + + if (cpu_is_pxa25x()) + cmx255_init(); + else + cmx270_init(); + + cmx2xx_init_dm9000(); + cmx2xx_init_display(); + cmx2xx_init_ac97(); + cmx2xx_init_touchscreen(); + cmx2xx_init_leds(); +} + +static void __init cmx2xx_init_irq(void) +{ + if (cpu_is_pxa25x()) { + pxa25x_init_irq(); + cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ); + } else { + pxa27x_init_irq(); + cmx2xx_pci_init_irq(CMX270_GPIO_IT8152_IRQ); + } +} + +#ifdef CONFIG_PCI +/* Map PCI companion statically */ +static struct map_desc cmx2xx_io_desc[] __initdata = { + [0] = { /* PCI bridge */ + .virtual = (unsigned long)CMX2XX_IT8152_VIRT, + .pfn = __phys_to_pfn(PXA_CS4_PHYS), + .length = SZ_64M, + .type = MT_DEVICE + }, +}; + +static void __init cmx2xx_map_io(void) +{ + if (cpu_is_pxa25x()) + pxa25x_map_io(); + + if (cpu_is_pxa27x()) + pxa27x_map_io(); + + iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc)); + + it8152_base_address = CMX2XX_IT8152_VIRT; +} +#else +static void __init cmx2xx_map_io(void) +{ + if (cpu_is_pxa25x()) + pxa25x_map_io(); + + if (cpu_is_pxa27x()) + pxa27x_map_io(); +} +#endif + +MACHINE_START(ARMCORE, "Compulab CM-X2XX") + .atag_offset = 0x100, + .map_io = cmx2xx_map_io, + .nr_irqs = CMX2XX_NR_IRQS, + .init_irq = cmx2xx_init_irq, + /* NOTE: pxa25x_handle_irq() works on PXA27x w/o camera support */ + .handle_irq = pxa25x_handle_irq, + .timer = &pxa_timer, + .init_machine = cmx2xx_init, +#ifdef CONFIG_PCI + .dma_zone_size = SZ_64M, +#endif + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c new file mode 100644 index 00000000000..4b981b82d2a --- /dev/null +++ b/arch/arm/mach-pxa/cm-x300.c @@ -0,0 +1,862 @@ +/* + * linux/arch/arm/mach-pxa/cm-x300.c + * + * Support for the CompuLab CM-X300 modules + * + * Copyright (C) 2008,2009 CompuLab Ltd. + * + * 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. + */ +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/clk.h> + +#include <linux/gpio.h> +#include <linux/dm9000.h> +#include <linux/leds.h> +#include <linux/rtc-v3020.h> +#include <linux/pwm_backlight.h> + +#include <linux/i2c.h> +#include <linux/i2c/pca953x.h> +#include <linux/i2c/pxa-i2c.h> + +#include <linux/mfd/da903x.h> +#include <linux/regulator/machine.h> +#include <linux/power_supply.h> +#include <linux/apm-emulation.h> + +#include <linux/spi/spi.h> +#include <linux/spi/spi_gpio.h> +#include <linux/spi/tdo24m.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/setup.h> + +#include <mach/pxa300.h> +#include <mach/pxa27x-udc.h> +#include <mach/pxafb.h> +#include <mach/mmc.h> +#include <mach/ohci.h> +#include <plat/pxa3xx_nand.h> +#include <mach/audio.h> +#include <mach/pxa3xx-u2d.h> + +#include <asm/mach/map.h> + +#include "generic.h" +#include "devices.h" + +#define CM_X300_ETH_PHYS 0x08000010 + +#define GPIO82_MMC_IRQ (82) +#define GPIO85_MMC_WP (85) + +#define CM_X300_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO82_MMC_IRQ) + +#define GPIO95_RTC_CS (95) +#define GPIO96_RTC_WR (96) +#define GPIO97_RTC_RD (97) +#define GPIO98_RTC_IO (98) + +#define GPIO_ULPI_PHY_RST (127) + +static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = { + /* LCD */ + GPIO54_LCD_LDD_0, + GPIO55_LCD_LDD_1, + GPIO56_LCD_LDD_2, + GPIO57_LCD_LDD_3, + GPIO58_LCD_LDD_4, + GPIO59_LCD_LDD_5, + GPIO60_LCD_LDD_6, + GPIO61_LCD_LDD_7, + GPIO62_LCD_LDD_8, + GPIO63_LCD_LDD_9, + GPIO64_LCD_LDD_10, + GPIO65_LCD_LDD_11, + GPIO66_LCD_LDD_12, + GPIO67_LCD_LDD_13, + GPIO68_LCD_LDD_14, + GPIO69_LCD_LDD_15, + GPIO72_LCD_FCLK, + GPIO73_LCD_LCLK, + GPIO74_LCD_PCLK, + GPIO75_LCD_BIAS, + + /* BTUART */ + GPIO111_UART2_RTS, + GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL, + GPIO113_UART2_TXD, + GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH, + + /* STUART */ + GPIO109_UART3_TXD, + GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL, + + /* AC97 */ + GPIO23_AC97_nACRESET, + GPIO24_AC97_SYSCLK, + GPIO29_AC97_BITCLK, + GPIO25_AC97_SDATA_IN_0, + GPIO27_AC97_SDATA_OUT, + GPIO28_AC97_SYNC, + + /* Keypad */ + GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH, + GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH, + GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH, + GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH, + GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH, + GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH, + GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH, + GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH, + GPIO121_KP_MKOUT_0, + GPIO122_KP_MKOUT_1, + GPIO123_KP_MKOUT_2, + GPIO124_KP_MKOUT_3, + GPIO125_KP_MKOUT_4, + GPIO4_2_KP_MKOUT_5, + + /* MMC1 */ + GPIO3_MMC1_DAT0, + GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH, + GPIO5_MMC1_DAT2, + GPIO6_MMC1_DAT3, + GPIO7_MMC1_CLK, + GPIO8_MMC1_CMD, /* CMD0 for slot 0 */ + + /* MMC2 */ + GPIO9_MMC2_DAT0, + GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH, + GPIO11_MMC2_DAT2, + GPIO12_MMC2_DAT3, + GPIO13_MMC2_CLK, + GPIO14_MMC2_CMD, + + /* FFUART */ + GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL, + GPIO31_UART1_TXD, + GPIO32_UART1_CTS, + GPIO37_UART1_RTS, + GPIO33_UART1_DCD, + GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL, + GPIO35_UART1_RI, + GPIO36_UART1_DTR, + + /* GPIOs */ + GPIO82_GPIO | MFP_PULL_HIGH, /* MMC CD */ + GPIO85_GPIO, /* MMC WP */ + GPIO99_GPIO, /* Ethernet IRQ */ + + /* RTC GPIOs */ + GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */ + GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */ + GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */ + GPIO98_GPIO, /* RTC IO */ + + /* Standard I2C */ + GPIO21_I2C_SCL, + GPIO22_I2C_SDA, + + /* PWM Backlight */ + GPIO19_PWM2_OUT, +}; + +static mfp_cfg_t cm_x3xx_rev_lt130_mfp_cfg[] __initdata = { + /* GPIOs */ + GPIO79_GPIO, /* LED */ + GPIO77_GPIO, /* WiFi reset */ + GPIO78_GPIO, /* BT reset */ +}; + +static mfp_cfg_t cm_x3xx_rev_ge130_mfp_cfg[] __initdata = { + /* GPIOs */ + GPIO76_GPIO, /* LED */ + GPIO71_GPIO, /* WiFi reset */ + GPIO70_GPIO, /* BT reset */ +}; + +static mfp_cfg_t cm_x310_mfp_cfg[] __initdata = { + /* USB PORT 2 */ + ULPI_STP, + ULPI_NXT, + ULPI_DIR, + GPIO30_ULPI_DATA_OUT_0, + GPIO31_ULPI_DATA_OUT_1, + GPIO32_ULPI_DATA_OUT_2, + GPIO33_ULPI_DATA_OUT_3, + GPIO34_ULPI_DATA_OUT_4, + GPIO35_ULPI_DATA_OUT_5, + GPIO36_ULPI_DATA_OUT_6, + GPIO37_ULPI_DATA_OUT_7, + GPIO38_ULPI_CLK, + /* external PHY reset pin */ + GPIO127_GPIO, + + /* USB PORT 3 */ + GPIO77_USB_P3_1, + GPIO78_USB_P3_2, + GPIO79_USB_P3_3, + GPIO80_USB_P3_4, + GPIO81_USB_P3_5, + GPIO82_USB_P3_6, + GPIO0_2_USBH_PEN, +}; + +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource dm9000_resources[] = { + [0] = { + .start = CM_X300_ETH_PHYS, + .end = CM_X300_ETH_PHYS + 0x3, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CM_X300_ETH_PHYS + 0x4, + .end = CM_X300_ETH_PHYS + 0x4 + 500, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct dm9000_plat_data cm_x300_dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM, +}; + +static struct platform_device dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(dm9000_resources), + .resource = dm9000_resources, + .dev = { + .platform_data = &cm_x300_dm9000_platdata, + } + +}; + +static void __init cm_x300_init_dm9000(void) +{ + platform_device_register(&dm9000_device); +} +#else +static inline void cm_x300_init_dm9000(void) {} +#endif + +/* LCD */ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info cm_x300_lcd_modes[] = { + [0] = { + .pixclock = 38250, + .bpp = 16, + .xres = 480, + .yres = 640, + .hsync_len = 8, + .vsync_len = 2, + .left_margin = 8, + .upper_margin = 2, + .right_margin = 24, + .lower_margin = 4, + .cmap_greyscale = 0, + }, + [1] = { + .pixclock = 153800, + .bpp = 16, + .xres = 240, + .yres = 320, + .hsync_len = 8, + .vsync_len = 2, + .left_margin = 8, + .upper_margin = 2, + .right_margin = 88, + .lower_margin = 2, + .cmap_greyscale = 0, + }, +}; + +static struct pxafb_mach_info cm_x300_lcd = { + .modes = cm_x300_lcd_modes, + .num_modes = ARRAY_SIZE(cm_x300_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +static void __init cm_x300_init_lcd(void) +{ + pxa_set_fb_info(NULL, &cm_x300_lcd); +} +#else +static inline void cm_x300_init_lcd(void) {} +#endif + +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static struct platform_pwm_backlight_data cm_x300_backlight_data = { + .pwm_id = 2, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 10000, +}; + +static struct platform_device cm_x300_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &cm_x300_backlight_data, + }, +}; + +static void cm_x300_init_bl(void) +{ + platform_device_register(&cm_x300_backlight_device); +} +#else +static inline void cm_x300_init_bl(void) {} +#endif + +#if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE) +#define GPIO_LCD_BASE (144) +#define GPIO_LCD_DIN (GPIO_LCD_BASE + 8) /* aux_gpio3_0 */ +#define GPIO_LCD_DOUT (GPIO_LCD_BASE + 9) /* aux_gpio3_1 */ +#define GPIO_LCD_SCL (GPIO_LCD_BASE + 10) /* aux_gpio3_2 */ +#define GPIO_LCD_CS (GPIO_LCD_BASE + 11) /* aux_gpio3_3 */ +#define LCD_SPI_BUS_NUM (1) + +static struct spi_gpio_platform_data cm_x300_spi_gpio_pdata = { + .sck = GPIO_LCD_SCL, + .mosi = GPIO_LCD_DIN, + .miso = GPIO_LCD_DOUT, + .num_chipselect = 1, +}; + +static struct platform_device cm_x300_spi_gpio = { + .name = "spi_gpio", + .id = LCD_SPI_BUS_NUM, + .dev = { + .platform_data = &cm_x300_spi_gpio_pdata, + }, +}; + +static struct tdo24m_platform_data cm_x300_tdo24m_pdata = { + .model = TDO35S, +}; + +static struct spi_board_info cm_x300_spi_devices[] __initdata = { + { + .modalias = "tdo24m", + .max_speed_hz = 1000000, + .bus_num = LCD_SPI_BUS_NUM, + .chip_select = 0, + .controller_data = (void *) GPIO_LCD_CS, + .platform_data = &cm_x300_tdo24m_pdata, + }, +}; + +static void __init cm_x300_init_spi(void) +{ + spi_register_board_info(cm_x300_spi_devices, + ARRAY_SIZE(cm_x300_spi_devices)); + platform_device_register(&cm_x300_spi_gpio); +} +#else +static inline void cm_x300_init_spi(void) {} +#endif + +#if defined(CONFIG_SND_PXA2XX_LIB_AC97) +static void __init cm_x300_init_ac97(void) +{ + pxa_set_ac97_info(NULL); +} +#else +static inline void cm_x300_init_ac97(void) {} +#endif + +#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +static struct mtd_partition cm_x300_nand_partitions[] = { + [0] = { + .name = "OBM", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [1] = { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [2] = { + .name = "Environment", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + }, + [3] = { + .name = "reserved", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K + SZ_1M, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [4] = { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + }, + [5] = { + .name = "fs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct pxa3xx_nand_platform_data cm_x300_nand_info = { + .enable_arbiter = 1, + .keep_config = 1, + .num_cs = 1, + .parts[0] = cm_x300_nand_partitions, + .nr_parts[0] = ARRAY_SIZE(cm_x300_nand_partitions), +}; + +static void __init cm_x300_init_nand(void) +{ + pxa3xx_set_nand_info(&cm_x300_nand_info); +} +#else +static inline void cm_x300_init_nand(void) {} +#endif + +#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) +static struct pxamci_platform_data cm_x300_mci_platform_data = { + .detect_delay_ms = 200, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = GPIO82_MMC_IRQ, + .gpio_card_ro = GPIO85_MMC_WP, + .gpio_power = -1, +}; + +/* The second MMC slot of CM-X300 is hardwired to Libertas card and has + no detection/ro pins */ +static int cm_x300_mci2_init(struct device *dev, + irq_handler_t cm_x300_detect_int, + void *data) +{ + return 0; +} + +static void cm_x300_mci2_exit(struct device *dev, void *data) +{ +} + +static struct pxamci_platform_data cm_x300_mci2_platform_data = { + .detect_delay_ms = 200, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = cm_x300_mci2_init, + .exit = cm_x300_mci2_exit, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +static void __init cm_x300_init_mmc(void) +{ + pxa_set_mci_info(&cm_x300_mci_platform_data); + pxa3xx_set_mci2_info(&cm_x300_mci2_platform_data); +} +#else +static inline void cm_x300_init_mmc(void) {} +#endif + +#if defined(CONFIG_PXA310_ULPI) +static struct clk *pout_clk; + +static int cm_x300_ulpi_phy_reset(void) +{ + int err; + + /* reset the PHY */ + err = gpio_request_one(GPIO_ULPI_PHY_RST, GPIOF_OUT_INIT_LOW, + "ulpi reset"); + if (err) { + pr_err("failed to request ULPI reset GPIO: %d\n", err); + return err; + } + + msleep(10); + gpio_set_value(GPIO_ULPI_PHY_RST, 1); + msleep(10); + + gpio_free(GPIO_ULPI_PHY_RST); + + return 0; +} + +static inline int cm_x300_u2d_init(struct device *dev) +{ + int err = 0; + + if (cpu_is_pxa310()) { + /* CLK_POUT is connected to the ULPI PHY */ + pout_clk = clk_get(NULL, "CLK_POUT"); + if (IS_ERR(pout_clk)) { + err = PTR_ERR(pout_clk); + pr_err("failed to get CLK_POUT: %d\n", err); + return err; + } + clk_enable(pout_clk); + + err = cm_x300_ulpi_phy_reset(); + if (err) { + clk_disable(pout_clk); + clk_put(pout_clk); + } + } + + return err; +} + +static void cm_x300_u2d_exit(struct device *dev) +{ + if (cpu_is_pxa310()) { + clk_disable(pout_clk); + clk_put(pout_clk); + } +} + +static struct pxa3xx_u2d_platform_data cm_x300_u2d_platform_data = { + .ulpi_mode = ULPI_SER_6PIN, + .init = cm_x300_u2d_init, + .exit = cm_x300_u2d_exit, +}; + +static void cm_x300_init_u2d(void) +{ + pxa3xx_set_u2d_info(&cm_x300_u2d_platform_data); +} +#else +static inline void cm_x300_init_u2d(void) {} +#endif + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static int cm_x300_ohci_init(struct device *dev) +{ + if (cpu_is_pxa300()) + UP2OCR = UP2OCR_HXS + | UP2OCR_HXOE | UP2OCR_DMPDE | UP2OCR_DPPDE; + + return 0; +} + +static struct pxaohci_platform_data cm_x300_ohci_platform_data = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW, + .init = cm_x300_ohci_init, +}; + +static void __init cm_x300_init_ohci(void) +{ + pxa_set_ohci_info(&cm_x300_ohci_platform_data); +} +#else +static inline void cm_x300_init_ohci(void) {} +#endif + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led cm_x300_leds[] = { + [0] = { + .name = "cm-x300:green", + .default_trigger = "heartbeat", + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data cm_x300_gpio_led_pdata = { + .num_leds = ARRAY_SIZE(cm_x300_leds), + .leds = cm_x300_leds, +}; + +static struct platform_device cm_x300_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &cm_x300_gpio_led_pdata, + }, +}; + +static void __init cm_x300_init_leds(void) +{ + if (system_rev < 130) + cm_x300_leds[0].gpio = 79; + else + cm_x300_leds[0].gpio = 76; + + platform_device_register(&cm_x300_led_device); +} +#else +static inline void cm_x300_init_leds(void) {} +#endif + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +/* PCA9555 */ +static struct pca953x_platform_data cm_x300_gpio_ext_pdata_0 = { + .gpio_base = 128, +}; + +static struct pca953x_platform_data cm_x300_gpio_ext_pdata_1 = { + .gpio_base = 144, +}; + +static struct i2c_board_info cm_x300_gpio_ext_info[] = { + [0] = { + I2C_BOARD_INFO("pca9555", 0x24), + .platform_data = &cm_x300_gpio_ext_pdata_0, + }, + [1] = { + I2C_BOARD_INFO("pca9555", 0x25), + .platform_data = &cm_x300_gpio_ext_pdata_1, + }, +}; + +static void __init cm_x300_init_i2c(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, cm_x300_gpio_ext_info, + ARRAY_SIZE(cm_x300_gpio_ext_info)); +} +#else +static inline void cm_x300_init_i2c(void) {} +#endif + +#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) +struct v3020_platform_data cm_x300_v3020_pdata = { + .use_gpio = 1, + .gpio_cs = GPIO95_RTC_CS, + .gpio_wr = GPIO96_RTC_WR, + .gpio_rd = GPIO97_RTC_RD, + .gpio_io = GPIO98_RTC_IO, +}; + +static struct platform_device cm_x300_rtc_device = { + .name = "v3020", + .id = -1, + .dev = { + .platform_data = &cm_x300_v3020_pdata, + } +}; + +static void __init cm_x300_init_rtc(void) +{ + platform_device_register(&cm_x300_rtc_device); +} +#else +static inline void cm_x300_init_rtc(void) {} +#endif + +/* Battery */ +struct power_supply_info cm_x300_psy_info = { + .name = "battery", + .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, + .voltage_max_design = 4200000, + .voltage_min_design = 3000000, + .use_for_apm = 1, +}; + +static void cm_x300_battery_low(void) +{ +#if defined(CONFIG_APM_EMULATION) + apm_queue_event(APM_LOW_BATTERY); +#endif +} + +static void cm_x300_battery_critical(void) +{ +#if defined(CONFIG_APM_EMULATION) + apm_queue_event(APM_CRITICAL_SUSPEND); +#endif +} + +struct da9030_battery_info cm_x300_battery_info = { + .battery_info = &cm_x300_psy_info, + + .charge_milliamp = 1000, + .charge_millivolt = 4200, + + .vbat_low = 3600, + .vbat_crit = 3400, + .vbat_charge_start = 4100, + .vbat_charge_stop = 4200, + .vbat_charge_restart = 4000, + + .vcharge_min = 3200, + .vcharge_max = 5500, + + .tbat_low = 197, + .tbat_high = 78, + .tbat_restart = 100, + + .batmon_interval = 0, + + .battery_low = cm_x300_battery_low, + .battery_critical = cm_x300_battery_critical, +}; + +static struct regulator_consumer_supply buck2_consumers[] = { + { + .dev = NULL, + .supply = "vcc_core", + }, +}; + +static struct regulator_init_data buck2_data = { + .constraints = { + .min_uV = 1375000, + .max_uV = 1375000, + .state_mem = { + .enabled = 0, + }, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .apply_uV = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(buck2_consumers), + .consumer_supplies = buck2_consumers, +}; + +/* DA9030 */ +struct da903x_subdev_info cm_x300_da9030_subdevs[] = { + { + .name = "da903x-battery", + .id = DA9030_ID_BAT, + .platform_data = &cm_x300_battery_info, + }, + { + .name = "da903x-regulator", + .id = DA9030_ID_BUCK2, + .platform_data = &buck2_data, + }, +}; + +static struct da903x_platform_data cm_x300_da9030_info = { + .num_subdevs = ARRAY_SIZE(cm_x300_da9030_subdevs), + .subdevs = cm_x300_da9030_subdevs, +}; + +static struct i2c_board_info cm_x300_pmic_info = { + I2C_BOARD_INFO("da9030", 0x49), + .irq = IRQ_WAKEUP0, + .platform_data = &cm_x300_da9030_info, +}; + +static struct i2c_pxa_platform_data cm_x300_pwr_i2c_info = { + .use_pio = 1, +}; + +static void __init cm_x300_init_da9030(void) +{ + pxa3xx_set_i2c_power_info(&cm_x300_pwr_i2c_info); + i2c_register_board_info(1, &cm_x300_pmic_info, 1); + irq_set_irq_wake(IRQ_WAKEUP0, 1); +} + +/* wi2wi gpio setting for system_rev >= 130 */ +static struct gpio cm_x300_wi2wi_gpios[] __initdata = { + { 71, GPIOF_OUT_INIT_HIGH, "wlan en" }, + { 70, GPIOF_OUT_INIT_HIGH, "bt reset" }, +}; + +static void __init cm_x300_init_wi2wi(void) +{ + int err; + + if (system_rev < 130) { + cm_x300_wi2wi_gpios[0].gpio = 77; /* wlan en */ + cm_x300_wi2wi_gpios[1].gpio = 78; /* bt reset */ + } + + /* Libertas and CSR reset */ + err = gpio_request_array(ARRAY_AND_SIZE(cm_x300_wi2wi_gpios)); + if (err) { + pr_err("failed to request wifi/bt gpios: %d\n", err); + return; + } + + udelay(10); + gpio_set_value(cm_x300_wi2wi_gpios[1].gpio, 0); + udelay(10); + gpio_set_value(cm_x300_wi2wi_gpios[1].gpio, 1); + + gpio_free_array(ARRAY_AND_SIZE(cm_x300_wi2wi_gpios)); +} + +/* MFP */ +static void __init cm_x300_init_mfp(void) +{ + /* board-processor specific GPIO initialization */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_mfp_cfg)); + + if (system_rev < 130) + pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_rev_lt130_mfp_cfg)); + else + pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_rev_ge130_mfp_cfg)); + + if (cpu_is_pxa310()) + pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x310_mfp_cfg)); +} + +static void __init cm_x300_init(void) +{ + cm_x300_init_mfp(); + + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + if (cpu_is_pxa300()) + pxa_set_ffuart_info(NULL); + + cm_x300_init_da9030(); + cm_x300_init_dm9000(); + cm_x300_init_lcd(); + cm_x300_init_u2d(); + cm_x300_init_ohci(); + cm_x300_init_mmc(); + cm_x300_init_nand(); + cm_x300_init_leds(); + cm_x300_init_i2c(); + cm_x300_init_spi(); + cm_x300_init_rtc(); + cm_x300_init_ac97(); + cm_x300_init_wi2wi(); + cm_x300_init_bl(); +} + +static void __init cm_x300_fixup(struct tag *tags, char **cmdline, + struct meminfo *mi) +{ + /* Make sure that mi->bank[0].start = PHYS_ADDR */ + for (; tags->hdr.size; tags = tag_next(tags)) + if (tags->hdr.tag == ATAG_MEM && + tags->u.mem.start == 0x80000000) { + tags->u.mem.start = 0xa0000000; + break; + } +} + +MACHINE_START(CM_X300, "CM-X300 module") + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .timer = &pxa_timer, + .init_machine = cm_x300_init, + .fixup = cm_x300_fixup, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/colibri-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c new file mode 100644 index 00000000000..d28e802e244 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-evalboard.c @@ -0,0 +1,119 @@ +/* + * linux/arch/arm/mach-pxa/colibri-evalboard.c + * + * Support for Toradex Colibri Evaluation Carrier Board + * Daniel Mack <daniel@caiaq.de> + * Marek Vasut <marek.vasut@gmail.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/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <asm/mach/arch.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> + +#include <mach/pxa27x.h> +#include <mach/colibri.h> +#include <mach/mmc.h> +#include <mach/ohci.h> +#include <mach/pxa27x-udc.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data colibri_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_power = -1, + .gpio_card_ro = -1, + .detect_delay_ms = 200, +}; + +static void __init colibri_mmc_init(void) +{ + if (machine_is_colibri()) /* PXA270 Colibri */ + colibri_mci_platform_data.gpio_card_detect = + GPIO0_COLIBRI_PXA270_SD_DETECT; + if (machine_is_colibri300()) /* PXA300 Colibri */ + colibri_mci_platform_data.gpio_card_detect = + GPIO13_COLIBRI_PXA300_SD_DETECT; + else /* PXA320 Colibri */ + colibri_mci_platform_data.gpio_card_detect = + GPIO28_COLIBRI_PXA320_SD_DETECT; + + pxa_set_mci_info(&colibri_mci_platform_data); +} +#else +static inline void colibri_mmc_init(void) {} +#endif + +/****************************************************************************** + * USB Host + ******************************************************************************/ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static int colibri_ohci_init(struct device *dev) +{ + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; + return 0; +} + +static struct pxaohci_platform_data colibri_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | + POWER_CONTROL_LOW | POWER_SENSE_LOW, + .init = colibri_ohci_init, +}; + +static void __init colibri_uhc_init(void) +{ + /* Colibri PXA270 has two usb ports, TBA for 320 */ + if (machine_is_colibri()) + colibri_ohci_info.flags |= ENABLE_PORT2; + + pxa_set_ohci_info(&colibri_ohci_info); +} +#else +static inline void colibri_uhc_init(void) {} +#endif + +/****************************************************************************** + * I2C RTC + ******************************************************************************/ +#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE) +static struct i2c_board_info __initdata colibri_i2c_devs[] = { + { + I2C_BOARD_INFO("m41t00", 0x68), + }, +}; + +static void __init colibri_rtc_init(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(colibri_i2c_devs)); +} +#else +static inline void colibri_rtc_init(void) {} +#endif + +void __init colibri_evalboard_init(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + colibri_mmc_init(); + colibri_uhc_init(); + colibri_rtc_init(); +} diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c new file mode 100644 index 00000000000..248804bb2c9 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -0,0 +1,223 @@ +/* + * linux/arch/arm/mach-pxa/income.c + * + * Support for Income s.r.o. SH-Dmaster PXA270 SBC + * + * Copyright (C) 2010 + * Marek Vasut <marek.vasut@gmail.com> + * Pavel Revak <palo@bielyvlk.sk> + * + * 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/bitops.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/pwm_backlight.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <mach/hardware.h> +#include <mach/mmc.h> +#include <mach/ohci.h> +#include <mach/pxa27x.h> +#include <mach/pxa27x-udc.h> +#include <mach/pxafb.h> + +#include "devices.h" +#include "generic.h" + +#define GPIO114_INCOME_ETH_IRQ (114) +#define GPIO0_INCOME_SD_DETECT (0) +#define GPIO0_INCOME_SD_RO (1) +#define GPIO54_INCOME_LED_A (54) +#define GPIO55_INCOME_LED_B (55) +#define GPIO113_INCOME_TS_IRQ (113) + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data income_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_power = -1, + .gpio_card_detect = GPIO0_INCOME_SD_DETECT, + .gpio_card_ro = GPIO0_INCOME_SD_RO, + .detect_delay_ms = 200, +}; + +static void __init income_mmc_init(void) +{ + pxa_set_mci_info(&income_mci_platform_data); +} +#else +static inline void income_mmc_init(void) {} +#endif + +/****************************************************************************** + * USB Host + ******************************************************************************/ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static struct pxaohci_platform_data income_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW, +}; + +static void __init income_uhc_init(void) +{ + pxa_set_ohci_info(&income_ohci_info); +} +#else +static inline void income_uhc_init(void) {} +#endif + +/****************************************************************************** + * LED + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led income_gpio_leds[] = { + { + .name = "income:green:leda", + .default_trigger = "none", + .gpio = GPIO54_INCOME_LED_A, + .active_low = 1, + }, + { + .name = "income:green:ledb", + .default_trigger = "none", + .gpio = GPIO55_INCOME_LED_B, + .active_low = 1, + } +}; + +static struct gpio_led_platform_data income_gpio_led_info = { + .leds = income_gpio_leds, + .num_leds = ARRAY_SIZE(income_gpio_leds), +}; + +static struct platform_device income_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &income_gpio_led_info, + } +}; + +static void __init income_led_init(void) +{ + platform_device_register(&income_leds); +} +#else +static inline void income_led_init(void) {} +#endif + +/****************************************************************************** + * I2C + ******************************************************************************/ +#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) +static struct i2c_board_info __initdata income_i2c_devs[] = { + { + I2C_BOARD_INFO("ds1340", 0x68), + }, { + I2C_BOARD_INFO("lm75", 0x4f), + }, +}; + +static void __init income_i2c_init(void) +{ + pxa_set_i2c_info(NULL); + pxa27x_set_i2c_power_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(income_i2c_devs)); +} +#else +static inline void income_i2c_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info income_lcd_modes[] = { +{ + .pixclock = 144700, + .xres = 320, + .yres = 240, + .bpp = 32, + .depth = 18, + + .left_margin = 10, + .right_margin = 10, + .upper_margin = 7, + .lower_margin = 8, + + .hsync_len = 20, + .vsync_len = 2, + + .sync = FB_SYNC_VERT_HIGH_ACT, +}, +}; + +static struct pxafb_mach_info income_lcd_screen = { + .modes = income_lcd_modes, + .num_modes = ARRAY_SIZE(income_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_18BPP | LCD_PCLK_EDGE_FALL, +}; + +static void __init income_lcd_init(void) +{ + pxa_set_fb_info(NULL, &income_lcd_screen); +} +#else +static inline void income_lcd_init(void) {} +#endif + +/****************************************************************************** + * Backlight + ******************************************************************************/ +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static struct platform_pwm_backlight_data income_backlight_data = { + .pwm_id = 0, + .max_brightness = 0x3ff, + .dft_brightness = 0x1ff, + .pwm_period_ns = 1000000, +}; + +static struct platform_device income_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &income_backlight_data, + }, +}; + +static void __init income_pwm_init(void) +{ + platform_device_register(&income_backlight); +} +#else +static inline void income_pwm_init(void) {} +#endif + +void __init colibri_pxa270_income_boardinit(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + income_mmc_init(); + income_uhc_init(); + income_led_init(); + income_i2c_init(); + income_lcd_init(); + income_pwm_init(); +} + diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c new file mode 100644 index 00000000000..29d5d541f60 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -0,0 +1,328 @@ +/* + * linux/arch/arm/mach-pxa/colibri-pxa270.c + * + * Support for Toradex PXA270 based Colibri module + * Daniel Mack <daniel@caiaq.de> + * Marek Vasut <marek.vasut@gmail.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/init.h> +#include <linux/interrupt.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <linux/ucb1400.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach-types.h> +#include <asm/sizes.h> + +#include <mach/audio.h> +#include <mach/colibri.h> +#include <mach/pxa27x.h> + +#include "devices.h" +#include "generic.h" + +/****************************************************************************** + * Evaluation board MFP + ******************************************************************************/ +#ifdef CONFIG_MACH_COLIBRI_EVALBOARD +static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = { + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + GPIO0_GPIO, /* SD detect */ + + /* FFUART */ + GPIO39_FFUART_TXD, + GPIO34_FFUART_RXD, + + /* UHC */ + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + GPIO119_USBH2_PWR, + GPIO120_USBH2_PEN, + + /* PCMCIA */ + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO49_nPWE, + GPIO48_nPOE, + GPIO57_nIOIS16, + GPIO56_nPWAIT, + GPIO104_PSKTSEL, + GPIO53_GPIO, /* RESET */ + GPIO83_GPIO, /* BVD1 */ + GPIO82_GPIO, /* BVD2 */ + GPIO1_GPIO, /* READY */ + GPIO84_GPIO, /* DETECT */ + GPIO107_GPIO, /* PPEN */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, +}; +#else +static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {}; +#endif + +#ifdef CONFIG_MACH_COLIBRI_PXA270_INCOME +static mfp_cfg_t income_pin_config[] __initdata = { + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + GPIO0_GPIO, /* SD detect */ + GPIO1_GPIO, /* SD read-only */ + + /* FFUART */ + GPIO39_FFUART_TXD, + GPIO34_FFUART_RXD, + + /* BFUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* UHC */ + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* LED */ + GPIO54_GPIO, /* LED A */ + GPIO55_GPIO, /* LED B */ +}; +#else +static mfp_cfg_t income_pin_config[] __initdata = {}; +#endif + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = { + /* Ethernet */ + GPIO78_nCS_2, /* Ethernet CS */ + GPIO114_GPIO, /* Ethernet IRQ */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO95_AC97_nRESET, + GPIO98_AC97_SYSCLK, + GPIO113_GPIO, /* Touchscreen IRQ */ +}; + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition colibri_partitions[] = { + { + .name = "Bootloader", + .offset = 0x00000000, + .size = 0x00040000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, { + .name = "Kernel", + .offset = 0x00040000, + .size = 0x00400000, + .mask_flags = 0 + }, { + .name = "Rootfs", + .offset = 0x00440000, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct physmap_flash_data colibri_flash_data[] = { + { + .width = 4, /* bankwidth in bytes */ + .parts = colibri_partitions, + .nr_parts = ARRAY_SIZE(colibri_partitions) + } +}; + +static struct resource colibri_pxa270_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device colibri_pxa270_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = colibri_flash_data, + }, + .resource = &colibri_pxa270_flash_resource, + .num_resources = 1, +}; + +static void __init colibri_pxa270_nor_init(void) +{ + platform_device_register(&colibri_pxa270_flash_device); +} +#else +static inline void colibri_pxa270_nor_init(void) {} +#endif + +/****************************************************************************** + * Ethernet + ******************************************************************************/ +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource colibri_pxa270_dm9000_resources[] = { + { + .start = PXA_CS2_PHYS, + .end = PXA_CS2_PHYS + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = PXA_CS2_PHYS + 4, + .end = PXA_CS2_PHYS + 4 + 500, + .flags = IORESOURCE_MEM, + }, + { + .start = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ), + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, + }, +}; + +static struct platform_device colibri_pxa270_dm9000_device = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(colibri_pxa270_dm9000_resources), + .resource = colibri_pxa270_dm9000_resources, +}; + +static void __init colibri_pxa270_eth_init(void) +{ + platform_device_register(&colibri_pxa270_dm9000_device); +} +#else +static inline void colibri_pxa270_eth_init(void) {} +#endif + +/****************************************************************************** + * Audio and Touchscreen + ******************************************************************************/ +#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ + defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static pxa2xx_audio_ops_t colibri_pxa270_ac97_pdata = { + .reset_gpio = 95, +}; + +static struct ucb1400_pdata colibri_pxa270_ucb1400_pdata = { + .irq = PXA_GPIO_TO_IRQ(GPIO113_COLIBRI_PXA270_TS_IRQ), +}; + +static struct platform_device colibri_pxa270_ucb1400_device = { + .name = "ucb1400_core", + .id = -1, + .dev = { + .platform_data = &colibri_pxa270_ucb1400_pdata, + }, +}; + +static void __init colibri_pxa270_tsc_init(void) +{ + pxa_set_ac97_info(&colibri_pxa270_ac97_pdata); + platform_device_register(&colibri_pxa270_ucb1400_device); +} +#else +static inline void colibri_pxa270_tsc_init(void) {} +#endif + +static int colibri_pxa270_baseboard; +core_param(colibri_pxa270_baseboard, colibri_pxa270_baseboard, int, 0444); + +static void __init colibri_pxa270_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_pin_config)); + + colibri_pxa270_nor_init(); + colibri_pxa270_eth_init(); + colibri_pxa270_tsc_init(); + + switch (colibri_pxa270_baseboard) { + case COLIBRI_EVALBOARD: + pxa2xx_mfp_config(ARRAY_AND_SIZE( + colibri_pxa270_evalboard_pin_config)); + colibri_evalboard_init(); + break; + case COLIBRI_PXA270_INCOME: + pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config)); + colibri_pxa270_income_boardinit(); + break; + default: + printk(KERN_ERR "Illegal colibri_pxa270_baseboard type %d\n", + colibri_pxa270_baseboard); + } +} + +/* The "Income s.r.o. SH-Dmaster PXA270 SBC" board can be booted either + * with the INCOME mach type or with COLIBRI and the kernel parameter + * "colibri_pxa270_baseboard=1" + */ +static void __init colibri_pxa270_income_init(void) +{ + colibri_pxa270_baseboard = COLIBRI_PXA270_INCOME; + colibri_pxa270_init(); +} + +MACHINE_START(COLIBRI, "Toradex Colibri PXA270") + .atag_offset = 0x100, + .init_machine = colibri_pxa270_init, + .map_io = pxa27x_map_io, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END + +MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") + .atag_offset = 0x100, + .init_machine = colibri_pxa270_income_init, + .map_io = pxa27x_map_io, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END + diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c new file mode 100644 index 00000000000..0846d210cb0 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -0,0 +1,194 @@ +/* + * arch/arm/mach-pxa/colibri-pxa300.c + * + * Support for Toradex PXA300/310 based Colibri module + * + * Daniel Mack <daniel@caiaq.de> + * Matthias Meier <matthias.j.meier@gmx.net> + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> + +#include <asm/mach-types.h> +#include <asm/sizes.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> + +#include <mach/pxa300.h> +#include <mach/colibri.h> +#include <mach/ohci.h> +#include <mach/pxafb.h> +#include <mach/audio.h> + +#include "generic.h" +#include "devices.h" + + +#ifdef CONFIG_MACH_COLIBRI_EVALBOARD +static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = { + /* MMC */ + GPIO7_MMC1_CLK, + GPIO14_MMC1_CMD, + GPIO3_MMC1_DAT0, + GPIO4_MMC1_DAT1, + GPIO5_MMC1_DAT2, + GPIO6_MMC1_DAT3, + GPIO13_GPIO, /* GPIO13_COLIBRI_PXA300_SD_DETECT */ + + /* UHC */ + GPIO0_2_USBH_PEN, + GPIO1_2_USBH_PWR, + GPIO77_USB_P3_1, + GPIO78_USB_P3_2, + GPIO79_USB_P3_3, + GPIO80_USB_P3_4, + GPIO81_USB_P3_5, + GPIO82_USB_P3_6, + + /* I2C */ + GPIO21_I2C_SCL, + GPIO22_I2C_SDA, +}; +#else +static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {}; +#endif + +#if defined(CONFIG_AX88796) +#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO) +/* + * Asix AX88796 Ethernet + */ +static struct ax_plat_data colibri_asix_platdata = { + .flags = 0, /* defined later */ + .wordlength = 2, +}; + +static struct resource colibri_asix_resource[] = { + [0] = { + .start = PXA3xx_CS2_PHYS, + .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), + .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, + } +}; + +static struct platform_device asix_device = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(colibri_asix_resource), + .resource = colibri_asix_resource, + .dev = { + .platform_data = &colibri_asix_platdata + } +}; + +static mfp_cfg_t colibri_pxa300_eth_pin_config[] __initdata = { + GPIO1_nCS2, /* AX88796 chip select */ + GPIO26_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */ +}; + +static void __init colibri_pxa300_init_eth(void) +{ + colibri_pxa3xx_init_eth(&colibri_asix_platdata); + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_eth_pin_config)); + platform_device_register(&asix_device); +} +#else +static inline void __init colibri_pxa300_init_eth(void) {} +#endif /* CONFIG_AX88796 */ + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = { + GPIO54_LCD_LDD_0, + GPIO55_LCD_LDD_1, + GPIO56_LCD_LDD_2, + GPIO57_LCD_LDD_3, + GPIO58_LCD_LDD_4, + GPIO59_LCD_LDD_5, + GPIO60_LCD_LDD_6, + GPIO61_LCD_LDD_7, + GPIO62_LCD_LDD_8, + GPIO63_LCD_LDD_9, + GPIO64_LCD_LDD_10, + GPIO65_LCD_LDD_11, + GPIO66_LCD_LDD_12, + GPIO67_LCD_LDD_13, + GPIO68_LCD_LDD_14, + GPIO69_LCD_LDD_15, + GPIO70_LCD_LDD_16, + GPIO71_LCD_LDD_17, + GPIO62_LCD_CS_N, + GPIO72_LCD_FCLK, + GPIO73_LCD_LCLK, + GPIO74_LCD_PCLK, + GPIO75_LCD_BIAS, + GPIO76_LCD_VSYNC, +}; + +static void __init colibri_pxa300_init_lcd(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_lcd_pin_config)); +} + +#else +static inline void colibri_pxa300_init_lcd(void) {} +#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */ + +#if defined(CONFIG_SND_AC97_CODEC) || defined(CONFIG_SND_AC97_CODEC_MODULE) +static mfp_cfg_t colibri_pxa310_ac97_pin_config[] __initdata = { + GPIO24_AC97_SYSCLK, + GPIO23_AC97_nACRESET, + GPIO25_AC97_SDATA_IN_0, + GPIO27_AC97_SDATA_OUT, + GPIO28_AC97_SYNC, + GPIO29_AC97_BITCLK +}; + +static inline void __init colibri_pxa310_init_ac97(void) +{ + /* no AC97 codec on Colibri PXA300 */ + if (!cpu_is_pxa310()) + return; + + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa310_ac97_pin_config)); + pxa_set_ac97_info(NULL); +} +#else +static inline void colibri_pxa310_init_ac97(void) {} +#endif + +void __init colibri_pxa300_init(void) +{ + colibri_pxa300_init_eth(); + colibri_pxa3xx_init_nand(); + colibri_pxa300_init_lcd(); + colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO)); + colibri_pxa310_init_ac97(); + + /* Evalboard init */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_evalboard_pin_config)); + colibri_evalboard_init(); +} + +MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") + .atag_offset = 0x100, + .init_machine = colibri_pxa300_init, + .map_io = pxa3xx_map_io, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END + diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c new file mode 100644 index 00000000000..6ad3359063a --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -0,0 +1,264 @@ +/* + * arch/arm/mach-pxa/colibri-pxa320.c + * + * Support for Toradex PXA320/310 based Colibri module + * + * Daniel Mack <daniel@caiaq.de> + * Matthias Meier <matthias.j.meier@gmx.net> + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/usb/gpio_vbus.h> + +#include <asm/mach-types.h> +#include <asm/sizes.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> + +#include <mach/pxa320.h> +#include <mach/colibri.h> +#include <mach/pxafb.h> +#include <mach/ohci.h> +#include <mach/audio.h> +#include <mach/pxa27x-udc.h> +#include <mach/udc.h> + +#include "generic.h" +#include "devices.h" + +#ifdef CONFIG_MACH_COLIBRI_EVALBOARD +static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = { + /* MMC */ + GPIO22_MMC1_CLK, + GPIO23_MMC1_CMD, + GPIO18_MMC1_DAT0, + GPIO19_MMC1_DAT1, + GPIO20_MMC1_DAT2, + GPIO21_MMC1_DAT3, + GPIO28_GPIO, /* SD detect */ + + /* UART 1 configuration (may be set by bootloader) */ + GPIO99_UART1_CTS, + GPIO104_UART1_RTS, + GPIO97_UART1_RXD, + GPIO98_UART1_TXD, + GPIO101_UART1_DTR, + GPIO103_UART1_DSR, + GPIO100_UART1_DCD, + GPIO102_UART1_RI, + + /* UART 2 configuration */ + GPIO109_UART2_CTS, + GPIO112_UART2_RTS, + GPIO110_UART2_RXD, + GPIO111_UART2_TXD, + + /* UART 3 configuration */ + GPIO30_UART3_RXD, + GPIO31_UART3_TXD, + + /* UHC */ + GPIO2_2_USBH_PEN, + GPIO3_2_USBH_PWR, + + /* I2C */ + GPIO32_I2C_SCL, + GPIO33_I2C_SDA, + + /* PCMCIA */ + MFP_CFG(GPIO59, AF7), /* PRST ; AF7 to tristate */ + MFP_CFG(GPIO61, AF7), /* PCE1 ; AF7 to tristate */ + MFP_CFG(GPIO60, AF7), /* PCE2 ; AF7 to tristate */ + MFP_CFG(GPIO62, AF7), /* PCD ; AF7 to tristate */ + MFP_CFG(GPIO56, AF7), /* PSKTSEL ; AF7 to tristate */ + GPIO27_GPIO, /* RDnWR ; input/tristate */ + GPIO50_GPIO, /* PREG ; input/tristate */ + GPIO2_RDY, + GPIO5_NPIOR, + GPIO6_NPIOW, + GPIO7_NPIOS16, + GPIO8_NPWAIT, + GPIO29_GPIO, /* PRDY (READY GPIO) */ + GPIO57_GPIO, /* PPEN (POWER GPIO) */ + GPIO81_GPIO, /* PCD (DETECT GPIO) */ + GPIO77_GPIO, /* PRST (RESET GPIO) */ + GPIO53_GPIO, /* PBVD1 */ + GPIO79_GPIO, /* PBVD2 */ + GPIO54_GPIO, /* POE */ +}; +#else +static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {}; +#endif + +#if defined(CONFIG_AX88796) +#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO) +/* + * Asix AX88796 Ethernet + */ +static struct ax_plat_data colibri_asix_platdata = { + .flags = 0, /* defined later */ + .wordlength = 2, +}; + +static struct resource colibri_asix_resource[] = { + [0] = { + .start = PXA3xx_CS2_PHYS, + .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), + .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, + } +}; + +static struct platform_device asix_device = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(colibri_asix_resource), + .resource = colibri_asix_resource, + .dev = { + .platform_data = &colibri_asix_platdata + } +}; + +static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = { + GPIO3_nCS2, /* AX88796 chip select */ + GPIO36_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */ +}; + +static void __init colibri_pxa320_init_eth(void) +{ + colibri_pxa3xx_init_eth(&colibri_asix_platdata); + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config)); + platform_device_register(&asix_device); +} +#else +static inline void __init colibri_pxa320_init_eth(void) {} +#endif /* CONFIG_AX88796 */ + +#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) +static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = { + .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96), + .gpio_pullup = -1, +}; + +static struct platform_device colibri_pxa320_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &colibri_pxa320_gpio_vbus_info, + }, +}; + +static void colibri_pxa320_udc_command(int cmd) +{ + if (cmd == PXA2XX_UDC_CMD_CONNECT) + UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE; + else if (cmd == PXA2XX_UDC_CMD_DISCONNECT) + UP2OCR = UP2OCR_HXOE; +} + +static struct pxa2xx_udc_mach_info colibri_pxa320_udc_info __initdata = { + .udc_command = colibri_pxa320_udc_command, + .gpio_pullup = -1, +}; + +static void __init colibri_pxa320_init_udc(void) +{ + pxa_set_udc_info(&colibri_pxa320_udc_info); + platform_device_register(&colibri_pxa320_gpio_vbus); +} +#else +static inline void colibri_pxa320_init_udc(void) {} +#endif + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = { + GPIO6_2_LCD_LDD_0, + GPIO7_2_LCD_LDD_1, + GPIO8_2_LCD_LDD_2, + GPIO9_2_LCD_LDD_3, + GPIO10_2_LCD_LDD_4, + GPIO11_2_LCD_LDD_5, + GPIO12_2_LCD_LDD_6, + GPIO13_2_LCD_LDD_7, + GPIO63_LCD_LDD_8, + GPIO64_LCD_LDD_9, + GPIO65_LCD_LDD_10, + GPIO66_LCD_LDD_11, + GPIO67_LCD_LDD_12, + GPIO68_LCD_LDD_13, + GPIO69_LCD_LDD_14, + GPIO70_LCD_LDD_15, + GPIO71_LCD_LDD_16, + GPIO72_LCD_LDD_17, + GPIO73_LCD_CS_N, + GPIO74_LCD_VSYNC, + GPIO14_2_LCD_FCLK, + GPIO15_2_LCD_LCLK, + GPIO16_2_LCD_PCLK, + GPIO17_2_LCD_BIAS, +}; + +static void __init colibri_pxa320_init_lcd(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_lcd_pin_config)); +} +#else +static inline void colibri_pxa320_init_lcd(void) {} +#endif + +#if defined(CONFIG_SND_AC97_CODEC) || \ + defined(CONFIG_SND_AC97_CODEC_MODULE) +static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = { + GPIO34_AC97_SYSCLK, + GPIO35_AC97_SDATA_IN_0, + GPIO37_AC97_SDATA_OUT, + GPIO38_AC97_SYNC, + GPIO39_AC97_BITCLK, + GPIO40_AC97_nACRESET +}; + +static inline void __init colibri_pxa320_init_ac97(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_ac97_pin_config)); + pxa_set_ac97_info(NULL); +} +#else +static inline void colibri_pxa320_init_ac97(void) {} +#endif + +void __init colibri_pxa320_init(void) +{ + colibri_pxa320_init_eth(); + colibri_pxa3xx_init_nand(); + colibri_pxa320_init_lcd(); + colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO)); + colibri_pxa320_init_ac97(); + colibri_pxa320_init_udc(); + + /* Evalboard init */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_evalboard_pin_config)); + colibri_evalboard_init(); +} + +MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") + .atag_offset = 0x100, + .init_machine = colibri_pxa320_init, + .map_io = pxa3xx_map_io, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END + diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c new file mode 100644 index 00000000000..2b8ca0de8a3 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -0,0 +1,152 @@ +/* + * arch/arm/mach-pxa/colibri-pxa3xx.c + * + * Common functions for all Toradex PXA3xx modules + * + * Daniel Mack <daniel@caiaq.de> + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/etherdevice.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <asm/sizes.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <mach/pxa3xx-regs.h> +#include <mach/mfp-pxa300.h> +#include <mach/colibri.h> +#include <mach/mmc.h> +#include <mach/pxafb.h> +#include <plat/pxa3xx_nand.h> + +#include "generic.h" +#include "devices.h" + +#if defined(CONFIG_AX88796) +#define ETHER_ADDR_LEN 6 +static u8 ether_mac_addr[ETHER_ADDR_LEN]; + +void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data) +{ + int i; + u64 serial = ((u64) system_serial_high << 32) | system_serial_low; + + /* + * If the bootloader passed in a serial boot tag, which contains a + * valid ethernet MAC, pass it to the interface. Toradex ships the + * modules with their own bootloader which provides a valid MAC + * this way. + */ + + for (i = 0; i < ETHER_ADDR_LEN; i++) { + ether_mac_addr[i] = serial & 0xff; + serial >>= 8; + } + + if (is_valid_ether_addr(ether_mac_addr)) { + plat_data->flags |= AXFLG_MAC_FROMPLATFORM; + plat_data->mac_addr = ether_mac_addr; + printk(KERN_INFO "%s(): taking MAC from serial boot tag\n", + __func__); + } else { + plat_data->flags |= AXFLG_MAC_FROMDEV; + printk(KERN_INFO "%s(): no valid serial boot tag found, " + "taking MAC from device\n", __func__); + } +} +#endif + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static int lcd_bl_pin; + +/* + * LCD panel (Sharp LQ043T3DX02) + */ +static void colibri_lcd_backlight(int on) +{ + gpio_set_value(lcd_bl_pin, !!on); +} + +static struct pxafb_mode_info sharp_lq43_mode = { + .pixclock = 101936, + .xres = 480, + .yres = 272, + .bpp = 32, + .depth = 18, + .hsync_len = 41, + .left_margin = 2, + .right_margin = 2, + .vsync_len = 10, + .upper_margin = 2, + .lower_margin = 2, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info sharp_lq43_info = { + .modes = &sharp_lq43_mode, + .num_modes = 1, + .cmap_inverse = 0, + .cmap_static = 0, + .lcd_conn = LCD_COLOR_TFT_18BPP, + .pxafb_backlight_power = colibri_lcd_backlight, +}; + +void __init colibri_pxa3xx_init_lcd(int bl_pin) +{ + lcd_bl_pin = bl_pin; + gpio_request(bl_pin, "lcd backlight"); + gpio_direction_output(bl_pin, 0); + pxa_set_fb_info(NULL, &sharp_lq43_info); +} +#endif + +#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +static struct mtd_partition colibri_nand_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = SZ_512K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "reserved", + .offset = MTDPART_OFS_APPEND, + .size = SZ_1M, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "fs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct pxa3xx_nand_platform_data colibri_nand_info = { + .enable_arbiter = 1, + .keep_config = 1, + .num_cs = 1, + .parts[0] = colibri_nand_partitions, + .nr_parts[0] = ARRAY_SIZE(colibri_nand_partitions), +}; + +void __init colibri_pxa3xx_init_nand(void) +{ + pxa3xx_set_nand_info(&colibri_nand_info); +} +#endif + diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c new file mode 100644 index 00000000000..11f1e735966 --- /dev/null +++ b/arch/arm/mach-pxa/corgi.c @@ -0,0 +1,764 @@ +/* + * Support for Sharp SL-C7xx PDAs + * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky) + * + * Copyright (c) 2004-2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches/lubbock.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/major.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/mmc/host.h> +#include <linux/mtd/physmap.h> +#include <linux/pm.h> +#include <linux/gpio.h> +#include <linux/backlight.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/spi/corgi_lcd.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/mtd/sharpsl.h> +#include <linux/input/matrix_keypad.h> +#include <linux/module.h> +#include <video/w100fb.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <asm/irq.h> +#include <asm/system.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/pxa25x.h> +#include <mach/irda.h> +#include <mach/mmc.h> +#include <mach/udc.h> +#include <mach/corgi.h> +#include <mach/sharpsl_pm.h> + +#include <asm/mach/sharpsl_param.h> +#include <asm/hardware/scoop.h> + +#include "generic.h" +#include "devices.h" + +static unsigned long corgi_pin_config[] __initdata = { + /* Static Memory I/O */ + GPIO78_nCS_2, /* w100fb */ + GPIO80_nCS_4, /* scoop */ + + /* SSP1 */ + GPIO23_SSP1_SCLK, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + GPIO24_GPIO, /* CORGI_GPIO_ADS7846_CS - SFRM as chip select */ + + /* I2S */ + GPIO28_I2S_BITCLK_OUT, + GPIO29_I2S_SDATA_IN, + GPIO30_I2S_SDATA_OUT, + GPIO31_I2S_SYNC, + GPIO32_I2S_SYSCLK, + + /* Infra-Red */ + GPIO47_FICP_TXD, + GPIO46_FICP_RXD, + + /* FFUART */ + GPIO40_FFUART_DTR, + GPIO41_FFUART_RTS, + GPIO39_FFUART_TXD, + GPIO37_FFUART_DSR, + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + + /* PC Card */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO54_nPSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* MMC */ + GPIO6_MMC_CLK, + GPIO8_MMC_CS0, + + /* GPIO Matrix Keypad */ + GPIO66_GPIO | MFP_LPM_DRIVE_HIGH, /* column 0 */ + GPIO67_GPIO | MFP_LPM_DRIVE_HIGH, /* column 1 */ + GPIO68_GPIO | MFP_LPM_DRIVE_HIGH, /* column 2 */ + GPIO69_GPIO | MFP_LPM_DRIVE_HIGH, /* column 3 */ + GPIO70_GPIO | MFP_LPM_DRIVE_HIGH, /* column 4 */ + GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* column 5 */ + GPIO72_GPIO | MFP_LPM_DRIVE_HIGH, /* column 6 */ + GPIO73_GPIO | MFP_LPM_DRIVE_HIGH, /* column 7 */ + GPIO74_GPIO | MFP_LPM_DRIVE_HIGH, /* column 8 */ + GPIO75_GPIO | MFP_LPM_DRIVE_HIGH, /* column 9 */ + GPIO76_GPIO | MFP_LPM_DRIVE_HIGH, /* column 10 */ + GPIO77_GPIO | MFP_LPM_DRIVE_HIGH, /* column 11 */ + GPIO58_GPIO, /* row 0 */ + GPIO59_GPIO, /* row 1 */ + GPIO60_GPIO, /* row 2 */ + GPIO61_GPIO, /* row 3 */ + GPIO62_GPIO, /* row 4 */ + GPIO63_GPIO, /* row 5 */ + GPIO64_GPIO, /* row 6 */ + GPIO65_GPIO, /* row 7 */ + + /* GPIO */ + GPIO9_GPIO, /* CORGI_GPIO_nSD_DETECT */ + GPIO7_GPIO, /* CORGI_GPIO_nSD_WP */ + GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */ + GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_LED_ORANGE */ + GPIO21_GPIO, /* CORGI_GPIO_ADC_TEMP */ + GPIO22_GPIO, /* CORGI_GPIO_IR_ON */ + GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */ + GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_ON */ + GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_UKN */ + GPIO44_GPIO, /* CORGI_GPIO_HSYNC */ + + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_KEY_INT */ + GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* CORGI_GPIO_AC_IN */ + GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_WAKEUP */ +}; + +/* + * Corgi SCOOP Device + */ +static struct resource corgi_scoop_resources[] = { + [0] = { + .start = 0x10800000, + .end = 0x10800fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct scoop_config corgi_scoop_setup = { + .io_dir = CORGI_SCOOP_IO_DIR, + .io_out = CORGI_SCOOP_IO_OUT, + .gpio_base = CORGI_SCOOP_GPIO_BASE, +}; + +struct platform_device corgiscoop_device = { + .name = "sharp-scoop", + .id = -1, + .dev = { + .platform_data = &corgi_scoop_setup, + }, + .num_resources = ARRAY_SIZE(corgi_scoop_resources), + .resource = corgi_scoop_resources, +}; + +static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { +{ + .dev = &corgiscoop_device.dev, + .irq = CORGI_IRQ_GPIO_CF_IRQ, + .cd_irq = CORGI_IRQ_GPIO_CF_CD, + .cd_irq_str = "PCMCIA0 CD", +}, +}; + +static struct scoop_pcmcia_config corgi_pcmcia_config = { + .devs = &corgi_pcmcia_scoop[0], + .num_devs = 1, +}; + +static struct w100_mem_info corgi_fb_mem = { + .ext_cntl = 0x00040003, + .sdram_mode_reg = 0x00650021, + .ext_timing_cntl = 0x10002a4a, + .io_cntl = 0x7ff87012, + .size = 0x1fffff, +}; + +static struct w100_gen_regs corgi_fb_regs = { + .lcd_format = 0x00000003, + .lcdd_cntl1 = 0x01CC0000, + .lcdd_cntl2 = 0x0003FFFF, + .genlcd_cntl1 = 0x00FFFF0D, + .genlcd_cntl2 = 0x003F3003, + .genlcd_cntl3 = 0x000102aa, +}; + +static struct w100_gpio_regs corgi_fb_gpio = { + .init_data1 = 0x000000bf, + .init_data2 = 0x00000000, + .gpio_dir1 = 0x00000000, + .gpio_oe1 = 0x03c0feff, + .gpio_dir2 = 0x00000000, + .gpio_oe2 = 0x00000000, +}; + +static struct w100_mode corgi_fb_modes[] = { +{ + .xres = 480, + .yres = 640, + .left_margin = 0x56, + .right_margin = 0x55, + .upper_margin = 0x03, + .lower_margin = 0x00, + .crtc_ss = 0x82360056, + .crtc_ls = 0xA0280000, + .crtc_gs = 0x80280028, + .crtc_vpos_gs = 0x02830002, + .crtc_rev = 0x00400008, + .crtc_dclk = 0xA0000000, + .crtc_gclk = 0x8015010F, + .crtc_goe = 0x80100110, + .crtc_ps1_active = 0x41060010, + .pll_freq = 75, + .fast_pll_freq = 100, + .sysclk_src = CLK_SRC_PLL, + .sysclk_divider = 0, + .pixclk_src = CLK_SRC_PLL, + .pixclk_divider = 2, + .pixclk_divider_rotated = 6, +},{ + .xres = 240, + .yres = 320, + .left_margin = 0x27, + .right_margin = 0x2e, + .upper_margin = 0x01, + .lower_margin = 0x00, + .crtc_ss = 0x81170027, + .crtc_ls = 0xA0140000, + .crtc_gs = 0xC0140014, + .crtc_vpos_gs = 0x00010141, + .crtc_rev = 0x00400008, + .crtc_dclk = 0xA0000000, + .crtc_gclk = 0x8015010F, + .crtc_goe = 0x80100110, + .crtc_ps1_active = 0x41060010, + .pll_freq = 0, + .fast_pll_freq = 0, + .sysclk_src = CLK_SRC_XTAL, + .sysclk_divider = 0, + .pixclk_src = CLK_SRC_XTAL, + .pixclk_divider = 1, + .pixclk_divider_rotated = 1, +}, + +}; + +static struct w100fb_mach_info corgi_fb_info = { + .init_mode = INIT_MODE_ROTATED, + .mem = &corgi_fb_mem, + .regs = &corgi_fb_regs, + .modelist = &corgi_fb_modes[0], + .num_modes = 2, + .gpio = &corgi_fb_gpio, + .xtal_freq = 12500000, + .xtal_dbl = 0, +}; + +static struct resource corgi_fb_resources[] = { + [0] = { + .start = 0x08000000, + .end = 0x08ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device corgifb_device = { + .name = "w100fb", + .id = -1, + .num_resources = ARRAY_SIZE(corgi_fb_resources), + .resource = corgi_fb_resources, + .dev = { + .platform_data = &corgi_fb_info, + }, + +}; + +/* + * Corgi Keyboard Device + */ +#define CORGI_KEY_CALENDER KEY_F1 +#define CORGI_KEY_ADDRESS KEY_F2 +#define CORGI_KEY_FN KEY_F3 +#define CORGI_KEY_CANCEL KEY_F4 +#define CORGI_KEY_OFF KEY_SUSPEND +#define CORGI_KEY_EXOK KEY_F5 +#define CORGI_KEY_EXCANCEL KEY_F6 +#define CORGI_KEY_EXJOGDOWN KEY_F7 +#define CORGI_KEY_EXJOGUP KEY_F8 +#define CORGI_KEY_JAP1 KEY_LEFTCTRL +#define CORGI_KEY_JAP2 KEY_LEFTALT +#define CORGI_KEY_MAIL KEY_F10 +#define CORGI_KEY_OK KEY_F11 +#define CORGI_KEY_MENU KEY_F12 + +static const uint32_t corgikbd_keymap[] = { + KEY(0, 1, KEY_1), + KEY(0, 2, KEY_3), + KEY(0, 3, KEY_5), + KEY(0, 4, KEY_6), + KEY(0, 5, KEY_7), + KEY(0, 6, KEY_9), + KEY(0, 7, KEY_0), + KEY(0, 8, KEY_BACKSPACE), + KEY(1, 1, KEY_2), + KEY(1, 2, KEY_4), + KEY(1, 3, KEY_R), + KEY(1, 4, KEY_Y), + KEY(1, 5, KEY_8), + KEY(1, 6, KEY_I), + KEY(1, 7, KEY_O), + KEY(1, 8, KEY_P), + KEY(2, 0, KEY_TAB), + KEY(2, 1, KEY_Q), + KEY(2, 2, KEY_E), + KEY(2, 3, KEY_T), + KEY(2, 4, KEY_G), + KEY(2, 5, KEY_U), + KEY(2, 6, KEY_J), + KEY(2, 7, KEY_K), + KEY(3, 0, CORGI_KEY_CALENDER), + KEY(3, 1, KEY_W), + KEY(3, 2, KEY_S), + KEY(3, 3, KEY_F), + KEY(3, 4, KEY_V), + KEY(3, 5, KEY_H), + KEY(3, 6, KEY_M), + KEY(3, 7, KEY_L), + KEY(3, 9, KEY_RIGHTSHIFT), + KEY(4, 0, CORGI_KEY_ADDRESS), + KEY(4, 1, KEY_A), + KEY(4, 2, KEY_D), + KEY(4, 3, KEY_C), + KEY(4, 4, KEY_B), + KEY(4, 5, KEY_N), + KEY(4, 6, KEY_DOT), + KEY(4, 8, KEY_ENTER), + KEY(4, 10, KEY_LEFTSHIFT), + KEY(5, 0, CORGI_KEY_MAIL), + KEY(5, 1, KEY_Z), + KEY(5, 2, KEY_X), + KEY(5, 3, KEY_MINUS), + KEY(5, 4, KEY_SPACE), + KEY(5, 5, KEY_COMMA), + KEY(5, 7, KEY_UP), + KEY(5, 11, CORGI_KEY_FN), + KEY(6, 0, KEY_SYSRQ), + KEY(6, 1, CORGI_KEY_JAP1), + KEY(6, 2, CORGI_KEY_JAP2), + KEY(6, 3, CORGI_KEY_CANCEL), + KEY(6, 4, CORGI_KEY_OK), + KEY(6, 5, CORGI_KEY_MENU), + KEY(6, 6, KEY_LEFT), + KEY(6, 7, KEY_DOWN), + KEY(6, 8, KEY_RIGHT), + KEY(7, 0, CORGI_KEY_OFF), + KEY(7, 1, CORGI_KEY_EXOK), + KEY(7, 2, CORGI_KEY_EXCANCEL), + KEY(7, 3, CORGI_KEY_EXJOGDOWN), + KEY(7, 4, CORGI_KEY_EXJOGUP), +}; + +static struct matrix_keymap_data corgikbd_keymap_data = { + .keymap = corgikbd_keymap, + .keymap_size = ARRAY_SIZE(corgikbd_keymap), +}; + +static const int corgikbd_row_gpios[] = + { 58, 59, 60, 61, 62, 63, 64, 65 }; +static const int corgikbd_col_gpios[] = + { 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 }; + +static struct matrix_keypad_platform_data corgikbd_pdata = { + .keymap_data = &corgikbd_keymap_data, + .row_gpios = corgikbd_row_gpios, + .col_gpios = corgikbd_col_gpios, + .num_row_gpios = ARRAY_SIZE(corgikbd_row_gpios), + .num_col_gpios = ARRAY_SIZE(corgikbd_col_gpios), + .col_scan_delay_us = 10, + .debounce_ms = 10, + .wakeup = 1, +}; + +static struct platform_device corgikbd_device = { + .name = "matrix-keypad", + .id = -1, + .dev = { + .platform_data = &corgikbd_pdata, + }, +}; + +/* + * Corgi LEDs + */ +static struct gpio_led corgi_gpio_leds[] = { + { + .name = "corgi:amber:charge", + .default_trigger = "sharpsl-charge", + .gpio = CORGI_GPIO_LED_ORANGE, + }, + { + .name = "corgi:green:mail", + .default_trigger = "nand-disk", + .gpio = CORGI_GPIO_LED_GREEN, + }, +}; + +static struct gpio_led_platform_data corgi_gpio_leds_info = { + .leds = corgi_gpio_leds, + .num_leds = ARRAY_SIZE(corgi_gpio_leds), +}; + +static struct platform_device corgiled_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &corgi_gpio_leds_info, + }, +}; + +/* + * Corgi Audio + */ +static struct platform_device corgi_audio_device = { + .name = "corgi-audio", + .id = -1, +}; + +/* + * MMC/SD Device + * + * The card detect interrupt isn't debounced so we delay it by 250ms + * to give the card a chance to fully insert/eject. + */ +static struct pxamci_platform_data corgi_mci_platform_data = { + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = CORGI_GPIO_nSD_DETECT, + .gpio_card_ro = CORGI_GPIO_nSD_WP, + .gpio_power = CORGI_GPIO_SD_PWR, +}; + + +/* + * Irda + */ +static struct pxaficp_platform_data corgi_ficp_platform_data = { + .gpio_pwdown = CORGI_GPIO_IR_ON, + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; + + +/* + * USB Device Controller + */ +static struct pxa2xx_udc_mach_info udc_info __initdata = { + /* no connect GPIO; corgi can't tell connection status */ + .gpio_pullup = CORGI_GPIO_USB_PULLUP, +}; + +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MASTER) +static struct pxa2xx_spi_master corgi_spi_info = { + .num_chipselect = 3, +}; + +static void corgi_wait_for_hsync(void) +{ + while (gpio_get_value(CORGI_GPIO_HSYNC)) + cpu_relax(); + + while (!gpio_get_value(CORGI_GPIO_HSYNC)) + cpu_relax(); +} + +static struct ads7846_platform_data corgi_ads7846_info = { + .model = 7846, + .vref_delay_usecs = 100, + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .gpio_pendown = CORGI_GPIO_TP_INT, + .wait_for_sync = corgi_wait_for_hsync, +}; + +static struct pxa2xx_spi_chip corgi_ads7846_chip = { + .gpio_cs = CORGI_GPIO_ADS7846_CS, +}; + +static void corgi_bl_kick_battery(void) +{ + void (*kick_batt)(void); + + kick_batt = symbol_get(sharpsl_battery_kick); + if (kick_batt) { + kick_batt(); + symbol_put(sharpsl_battery_kick); + } +} + +static struct corgi_lcd_platform_data corgi_lcdcon_info = { + .init_mode = CORGI_LCD_MODE_VGA, + .max_intensity = 0x2f, + .default_intensity = 0x1f, + .limit_mask = 0x0b, + .gpio_backlight_cont = CORGI_GPIO_BACKLIGHT_CONT, + .gpio_backlight_on = -1, + .kick_battery = corgi_bl_kick_battery, +}; + +static struct pxa2xx_spi_chip corgi_lcdcon_chip = { + .gpio_cs = CORGI_GPIO_LCDCON_CS, +}; + +static struct pxa2xx_spi_chip corgi_max1111_chip = { + .gpio_cs = CORGI_GPIO_MAX1111_CS, +}; + +static struct spi_board_info corgi_spi_devices[] = { + { + .modalias = "ads7846", + .max_speed_hz = 1200000, + .bus_num = 1, + .chip_select = 0, + .platform_data = &corgi_ads7846_info, + .controller_data= &corgi_ads7846_chip, + .irq = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT), + }, { + .modalias = "corgi-lcd", + .max_speed_hz = 50000, + .bus_num = 1, + .chip_select = 1, + .platform_data = &corgi_lcdcon_info, + .controller_data= &corgi_lcdcon_chip, + }, { + .modalias = "max1111", + .max_speed_hz = 450000, + .bus_num = 1, + .chip_select = 2, + .controller_data= &corgi_max1111_chip, + }, +}; + +static void __init corgi_init_spi(void) +{ + pxa2xx_set_spi_info(1, &corgi_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices)); +} +#else +static inline void corgi_init_spi(void) {} +#endif + +static struct mtd_partition sharpsl_nand_partitions[] = { + { + .name = "System Area", + .offset = 0, + .size = 7 * 1024 * 1024, + }, + { + .name = "Root Filesystem", + .offset = 7 * 1024 * 1024, + .size = 25 * 1024 * 1024, + }, + { + .name = "Home Filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr sharpsl_bbt = { + .options = 0, + .offs = 4, + .len = 2, + .pattern = scan_ff_pattern +}; + +static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = { + .badblock_pattern = &sharpsl_bbt, + .partitions = sharpsl_nand_partitions, + .nr_partitions = ARRAY_SIZE(sharpsl_nand_partitions), +}; + +static struct resource sharpsl_nand_resources[] = { + { + .start = 0x0C000000, + .end = 0x0C000FFF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sharpsl_nand_device = { + .name = "sharpsl-nand", + .id = -1, + .resource = sharpsl_nand_resources, + .num_resources = ARRAY_SIZE(sharpsl_nand_resources), + .dev.platform_data = &sharpsl_nand_platform_data, +}; + +static struct mtd_partition sharpsl_rom_parts[] = { + { + .name ="Boot PROM Filesystem", + .offset = 0x00120000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data sharpsl_rom_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(sharpsl_rom_parts), + .parts = sharpsl_rom_parts, +}; + +static struct resource sharpsl_rom_resources[] = { + { + .start = 0x00000000, + .end = 0x007fffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sharpsl_rom_device = { + .name = "physmap-flash", + .id = -1, + .resource = sharpsl_rom_resources, + .num_resources = ARRAY_SIZE(sharpsl_rom_resources), + .dev.platform_data = &sharpsl_rom_data, +}; + +static struct platform_device *devices[] __initdata = { + &corgiscoop_device, + &corgifb_device, + &corgikbd_device, + &corgiled_device, + &corgi_audio_device, + &sharpsl_nand_device, + &sharpsl_rom_device, +}; + +static struct i2c_board_info __initdata corgi_i2c_devices[] = { + { I2C_BOARD_INFO("wm8731", 0x1b) }, +}; + +static void corgi_poweroff(void) +{ + if (!machine_is_corgi()) + /* Green LED off tells the bootloader to halt */ + gpio_set_value(CORGI_GPIO_LED_GREEN, 0); + + pxa_restart('h', NULL); +} + +static void corgi_restart(char mode, const char *cmd) +{ + if (!machine_is_corgi()) + /* Green LED on tells the bootloader to reboot */ + gpio_set_value(CORGI_GPIO_LED_GREEN, 1); + + pxa_restart('h', cmd); +} + +static void __init corgi_init(void) +{ + pm_power_off = corgi_poweroff; + + /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ + PCFR |= PCFR_OPDE; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); + + /* allow wakeup from various GPIOs */ + gpio_set_wake(CORGI_GPIO_KEY_INT, 1); + gpio_set_wake(CORGI_GPIO_WAKEUP, 1); + gpio_set_wake(CORGI_GPIO_AC_IN, 1); + gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1); + + if (!machine_is_corgi()) + gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + corgi_init_spi(); + + pxa_set_udc_info(&udc_info); + pxa_set_mci_info(&corgi_mci_platform_data); + pxa_set_ficp_info(&corgi_ficp_platform_data); + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(corgi_i2c_devices)); + + platform_scoop_config = &corgi_pcmcia_config; + + if (machine_is_husky()) + sharpsl_nand_partitions[1].size = 53 * 1024 * 1024; + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init fixup_corgi(struct tag *tags, char **cmdline, + struct meminfo *mi) +{ + sharpsl_save_param(); + mi->nr_banks=1; + mi->bank[0].start = 0xa0000000; + if (machine_is_corgi()) + mi->bank[0].size = (32*1024*1024); + else + mi->bank[0].size = (64*1024*1024); +} + +#ifdef CONFIG_MACH_CORGI +MACHINE_START(CORGI, "SHARP Corgi") + .fixup = fixup_corgi, + .map_io = pxa25x_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, + .restart = corgi_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_SHEPHERD +MACHINE_START(SHEPHERD, "SHARP Shepherd") + .fixup = fixup_corgi, + .map_io = pxa25x_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, + .restart = corgi_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_HUSKY +MACHINE_START(HUSKY, "SHARP Husky") + .fixup = fixup_corgi, + .map_io = pxa25x_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, + .restart = corgi_restart, +MACHINE_END +#endif + diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c new file mode 100644 index 00000000000..39e265cfc86 --- /dev/null +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -0,0 +1,230 @@ +/* + * Battery and Power Management code for the Sharp SL-C7xx + * + * Copyright (c) 2005 Richard Purdie + * + * 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/module.h> +#include <linux/stat.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/gpio-pxa.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/apm-emulation.h> + +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> + +#include <mach/corgi.h> +#include <mach/pxa2xx-regs.h> +#include <mach/sharpsl_pm.h> + +#include "generic.h" + +#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ +#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ +#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */ +#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */ +#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ +#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ + +static struct gpio charger_gpios[] = { + { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, + { CORGI_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, + { CORGI_GPIO_CHRG_UKN, GPIOF_OUT_INIT_LOW, "Charger Unknown" }, + { CORGI_GPIO_AC_IN, GPIOF_IN, "Charger Detection" }, + { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" }, + { CORGI_GPIO_WAKEUP, GPIOF_IN, "System wakeup notification" }, +}; + +static void corgi_charger_init(void) +{ + gpio_request_array(ARRAY_AND_SIZE(charger_gpios)); +} + +static void corgi_measure_temp(int on) +{ + gpio_set_value(CORGI_GPIO_ADC_TEMP_ON, on); +} + +static void corgi_charge(int on) +{ + if (on) { + if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) { + gpio_set_value(CORGI_GPIO_CHRG_ON, 0); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 1); + } else { + gpio_set_value(CORGI_GPIO_CHRG_ON, 1); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); + } + } else { + gpio_set_value(CORGI_GPIO_CHRG_ON, 0); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); + } +} + +static void corgi_discharge(int on) +{ + gpio_set_value(CORGI_GPIO_DISCHARGE_ON, on); +} + +static void corgi_presuspend(void) +{ +} + +static void corgi_postsuspend(void) +{ +} + +/* + * Check what brought us out of the suspend. + * Return: 0 to sleep, otherwise wake + */ +static int corgi_should_wakeup(unsigned int resume_on_alarm) +{ + int is_resume = 0; + + dev_dbg(sharpsl_pm.dev, "PEDR = %x, GPIO_AC_IN = %d, " + "GPIO_CHRG_FULL = %d, GPIO_KEY_INT = %d, GPIO_WAKEUP = %d\n", + PEDR, gpio_get_value(CORGI_GPIO_AC_IN), + gpio_get_value(CORGI_GPIO_CHRG_FULL), + gpio_get_value(CORGI_GPIO_KEY_INT), + gpio_get_value(CORGI_GPIO_WAKEUP)); + + if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) { + if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { + /* charge on */ + dev_dbg(sharpsl_pm.dev, "ac insert\n"); + sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; + } else { + /* charge off */ + dev_dbg(sharpsl_pm.dev, "ac remove\n"); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.charge_mode = CHRG_OFF; + } + } + + if ((PEDR & GPIO_bit(CORGI_GPIO_CHRG_FULL))) + dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n"); + + if (PEDR & GPIO_bit(CORGI_GPIO_KEY_INT)) + is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT); + + if (PEDR & GPIO_bit(CORGI_GPIO_WAKEUP)) + is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP); + + if (resume_on_alarm && (PEDR & PWER_RTC)) + is_resume |= PWER_RTC; + + dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume); + return is_resume; +} + +static unsigned long corgi_charger_wakeup(void) +{ + unsigned long ret; + + ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN)) + | (!gpio_get_value(CORGI_GPIO_KEY_INT) + << GPIO_bit(CORGI_GPIO_KEY_INT)) + | (!gpio_get_value(CORGI_GPIO_WAKEUP) + << GPIO_bit(CORGI_GPIO_WAKEUP)); + return ret; +} + +unsigned long corgipm_read_devdata(int type) +{ + switch(type) { + case SHARPSL_STATUS_ACIN: + return !gpio_get_value(CORGI_GPIO_AC_IN); + case SHARPSL_STATUS_LOCK: + return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); + case SHARPSL_STATUS_CHRGFULL: + return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull); + case SHARPSL_STATUS_FATAL: + return gpio_get_value(sharpsl_pm.machinfo->gpio_fatal); + case SHARPSL_ACIN_VOLT: + return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT); + case SHARPSL_BATT_TEMP: + return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP); + case SHARPSL_BATT_VOLT: + default: + return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT); + } +} + +static struct sharpsl_charger_machinfo corgi_pm_machinfo = { + .init = corgi_charger_init, + .exit = NULL, + .gpio_batlock = CORGI_GPIO_BAT_COVER, + .gpio_acin = CORGI_GPIO_AC_IN, + .gpio_batfull = CORGI_GPIO_CHRG_FULL, + .discharge = corgi_discharge, + .charge = corgi_charge, + .measure_temp = corgi_measure_temp, + .presuspend = corgi_presuspend, + .postsuspend = corgi_postsuspend, + .read_devdata = corgipm_read_devdata, + .charger_wakeup = corgi_charger_wakeup, + .should_wakeup = corgi_should_wakeup, +#if defined(CONFIG_LCD_CORGI) + .backlight_limit = corgi_lcd_limit_intensity, +#endif + .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, + .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, + .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, + .charge_acin_low = SHARPSL_CHARGE_ON_ACIN_LOW, + .fatal_acin_volt = SHARPSL_FATAL_ACIN_VOLT, + .fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT, + .bat_levels = 40, + .bat_levels_noac = sharpsl_battery_levels_noac, + .bat_levels_acin = sharpsl_battery_levels_acin, + .status_high_acin = 188, + .status_low_acin = 178, + .status_high_noac = 185, + .status_low_noac = 175, +}; + +static struct platform_device *corgipm_device; + +static int __devinit corgipm_init(void) +{ + int ret; + + if (!machine_is_corgi() && !machine_is_shepherd() + && !machine_is_husky()) + return -ENODEV; + + corgipm_device = platform_device_alloc("sharpsl-pm", -1); + if (!corgipm_device) + return -ENOMEM; + + if (!machine_is_corgi()) + corgi_pm_machinfo.batfull_irq = 1; + + corgipm_device->dev.platform_data = &corgi_pm_machinfo; + ret = platform_device_add(corgipm_device); + + if (ret) + platform_device_put(corgipm_device); + + return ret; +} + +static void corgipm_exit(void) +{ + platform_device_unregister(corgipm_device); +} + +module_init(corgipm_init); +module_exit(corgipm_exit); diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c new file mode 100644 index 00000000000..6a7aeab42f6 --- /dev/null +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c @@ -0,0 +1,494 @@ +/* + * linux/arch/arm/mach-pxa/cpufreq-pxa2xx.c + * + * Copyright (C) 2002,2003 Intrinsyc Software + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * History: + * 31-Jul-2002 : Initial version [FB] + * 29-Jan-2003 : added PXA255 support [FB] + * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) + * + * Note: + * This driver may change the memory bus clock rate, but will not do any + * platform specific access timing changes... for example if you have flash + * memory connected to CS0, you will need to register a platform specific + * notifier which will adjust the memory access strobes to maintain a + * minimum strobe width. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/cpufreq.h> +#include <linux/err.h> +#include <linux/regulator/consumer.h> +#include <linux/io.h> + +#include <mach/pxa2xx-regs.h> +#include <mach/smemc.h> + +#ifdef DEBUG +static unsigned int freq_debug; +module_param(freq_debug, uint, 0); +MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); +#else +#define freq_debug 0 +#endif + +static struct regulator *vcc_core; + +static unsigned int pxa27x_maxfreq; +module_param(pxa27x_maxfreq, uint, 0); +MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz" + "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)"); + +typedef struct { + unsigned int khz; + unsigned int membus; + unsigned int cccr; + unsigned int div2; + unsigned int cclkcfg; + int vmin; + int vmax; +} pxa_freqs_t; + +/* Define the refresh period in mSec for the SDRAM and the number of rows */ +#define SDRAM_TREF 64 /* standard 64ms SDRAM */ +static unsigned int sdram_rows; + +#define CCLKCFG_TURBO 0x1 +#define CCLKCFG_FCS 0x2 +#define CCLKCFG_HALFTURBO 0x4 +#define CCLKCFG_FASTBUS 0x8 +#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) +#define MDREFR_DRI_MASK 0xFFF + +#define MDCNFG_DRAC2(mdcnfg) (((mdcnfg) >> 21) & 0x3) +#define MDCNFG_DRAC0(mdcnfg) (((mdcnfg) >> 5) & 0x3) + +/* + * PXA255 definitions + */ +/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */ +#define CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS + +static pxa_freqs_t pxa255_run_freqs[] = +{ + /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ + { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */ + {132700, 132700, 0x123, 1, CCLKCFG, -1, -1}, /* 133, 133, 66, 66 */ + {199100, 99500, 0x141, 0, CCLKCFG, -1, -1}, /* 199, 199, 99, 99 */ + {265400, 132700, 0x143, 1, CCLKCFG, -1, -1}, /* 265, 265, 133, 66 */ + {331800, 165900, 0x145, 1, CCLKCFG, -1, -1}, /* 331, 331, 166, 83 */ + {398100, 99500, 0x161, 0, CCLKCFG, -1, -1}, /* 398, 398, 196, 99 */ +}; + +/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ +static pxa_freqs_t pxa255_turbo_freqs[] = +{ + /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ + { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */ + {199100, 99500, 0x221, 0, CCLKCFG, -1, -1}, /* 99, 199, 50, 99 */ + {298500, 99500, 0x321, 0, CCLKCFG, -1, -1}, /* 99, 287, 50, 99 */ + {298600, 99500, 0x1c1, 0, CCLKCFG, -1, -1}, /* 199, 287, 99, 99 */ + {398100, 99500, 0x241, 0, CCLKCFG, -1, -1}, /* 199, 398, 99, 99 */ +}; + +#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) +#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs) + +static struct cpufreq_frequency_table + pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1]; +static struct cpufreq_frequency_table + pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1]; + +static unsigned int pxa255_turbo_table; +module_param(pxa255_turbo_table, uint, 0); +MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table, !0 = turbo table)"); + +/* + * PXA270 definitions + * + * For the PXA27x: + * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG. + * + * A = 0 => memory controller clock from table 3-7, + * A = 1 => memory controller clock = system bus clock + * Run mode frequency = 13 MHz * L + * Turbo mode frequency = 13 MHz * L * N + * System bus frequency = 13 MHz * L / (B + 1) + * + * In CCCR: + * A = 1 + * L = 16 oscillator to run mode ratio + * 2N = 6 2 * (turbo mode to run mode ratio) + * + * In CCLKCFG: + * B = 1 Fast bus mode + * HT = 0 Half-Turbo mode + * T = 1 Turbo mode + * + * For now, just support some of the combinations in table 3-7 of + * PXA27x Processor Family Developer's Manual to simplify frequency + * change sequences. + */ +#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L) +#define CCLKCFG2(B, HT, T) \ + (CCLKCFG_FCS | \ + ((B) ? CCLKCFG_FASTBUS : 0) | \ + ((HT) ? CCLKCFG_HALFTURBO : 0) | \ + ((T) ? CCLKCFG_TURBO : 0)) + +static pxa_freqs_t pxa27x_freqs[] = { + {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 }, + {156000, 104000, PXA27x_CCCR(1, 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 }, + {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 }, + {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 }, + {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 }, + {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1), 1450000, 1705000 }, + {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1), 1550000, 1705000 } +}; + +#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs) +static struct cpufreq_frequency_table + pxa27x_freq_table[NUM_PXA27x_FREQS+1]; + +extern unsigned get_clk_frequency_khz(int info); + +#ifdef CONFIG_REGULATOR + +static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) +{ + int ret = 0; + int vmin, vmax; + + if (!cpu_is_pxa27x()) + return 0; + + vmin = pxa_freq->vmin; + vmax = pxa_freq->vmax; + if ((vmin == -1) || (vmax == -1)) + return 0; + + ret = regulator_set_voltage(vcc_core, vmin, vmax); + if (ret) + pr_err("cpufreq: Failed to set vcc_core in [%dmV..%dmV]\n", + vmin, vmax); + return ret; +} + +static __init void pxa_cpufreq_init_voltages(void) +{ + vcc_core = regulator_get(NULL, "vcc_core"); + if (IS_ERR(vcc_core)) { + pr_info("cpufreq: Didn't find vcc_core regulator\n"); + vcc_core = NULL; + } else { + pr_info("cpufreq: Found vcc_core regulator\n"); + } +} +#else +static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) +{ + return 0; +} + +static __init void pxa_cpufreq_init_voltages(void) { } +#endif + +static void find_freq_tables(struct cpufreq_frequency_table **freq_table, + pxa_freqs_t **pxa_freqs) +{ + if (cpu_is_pxa25x()) { + if (!pxa255_turbo_table) { + *pxa_freqs = pxa255_run_freqs; + *freq_table = pxa255_run_freq_table; + } else { + *pxa_freqs = pxa255_turbo_freqs; + *freq_table = pxa255_turbo_freq_table; + } + } + if (cpu_is_pxa27x()) { + *pxa_freqs = pxa27x_freqs; + *freq_table = pxa27x_freq_table; + } +} + +static void pxa27x_guess_max_freq(void) +{ + if (!pxa27x_maxfreq) { + pxa27x_maxfreq = 416000; + printk(KERN_INFO "PXA CPU 27x max frequency not defined " + "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n", + pxa27x_maxfreq); + } else { + pxa27x_maxfreq *= 1000; + } +} + +static void init_sdram_rows(void) +{ + uint32_t mdcnfg = __raw_readl(MDCNFG); + unsigned int drac2 = 0, drac0 = 0; + + if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3)) + drac2 = MDCNFG_DRAC2(mdcnfg); + + if (mdcnfg & (MDCNFG_DE0 | MDCNFG_DE1)) + drac0 = MDCNFG_DRAC0(mdcnfg); + + sdram_rows = 1 << (11 + max(drac0, drac2)); +} + +static u32 mdrefr_dri(unsigned int freq) +{ + u32 interval = freq * SDRAM_TREF / sdram_rows; + + return (interval - (cpu_is_pxa27x() ? 31 : 0)) / 32; +} + +/* find a valid frequency point */ +static int pxa_verify_policy(struct cpufreq_policy *policy) +{ + struct cpufreq_frequency_table *pxa_freqs_table; + pxa_freqs_t *pxa_freqs; + int ret; + + find_freq_tables(&pxa_freqs_table, &pxa_freqs); + ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table); + + if (freq_debug) + pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n", + policy->min, policy->max); + + return ret; +} + +static unsigned int pxa_cpufreq_get(unsigned int cpu) +{ + return get_clk_frequency_khz(0); +} + +static int pxa_set_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct cpufreq_frequency_table *pxa_freqs_table; + pxa_freqs_t *pxa_freq_settings; + struct cpufreq_freqs freqs; + unsigned int idx; + unsigned long flags; + unsigned int new_freq_cpu, new_freq_mem; + unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; + int ret = 0; + + /* Get the current policy */ + find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); + + /* Lookup the next frequency */ + if (cpufreq_frequency_table_target(policy, pxa_freqs_table, + target_freq, relation, &idx)) { + return -EINVAL; + } + + new_freq_cpu = pxa_freq_settings[idx].khz; + new_freq_mem = pxa_freq_settings[idx].membus; + freqs.old = policy->cur; + freqs.new = new_freq_cpu; + freqs.cpu = policy->cpu; + + if (freq_debug) + pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", + freqs.new / 1000, (pxa_freq_settings[idx].div2) ? + (new_freq_mem / 2000) : (new_freq_mem / 1000)); + + if (vcc_core && freqs.new > freqs.old) + ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); + if (ret) + return ret; + /* + * Tell everyone what we're about to do... + * you should add a notify client with any platform specific + * Vcc changing capability + */ + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* Calculate the next MDREFR. If we're slowing down the SDRAM clock + * we need to preset the smaller DRI before the change. If we're + * speeding up we need to set the larger DRI value after the change. + */ + preset_mdrefr = postset_mdrefr = __raw_readl(MDREFR); + if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) { + preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK); + preset_mdrefr |= mdrefr_dri(new_freq_mem); + } + postset_mdrefr = + (postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem); + + /* If we're dividing the memory clock by two for the SDRAM clock, this + * must be set prior to the change. Clearing the divide must be done + * after the change. + */ + if (pxa_freq_settings[idx].div2) { + preset_mdrefr |= MDREFR_DB2_MASK; + postset_mdrefr |= MDREFR_DB2_MASK; + } else { + postset_mdrefr &= ~MDREFR_DB2_MASK; + } + + local_irq_save(flags); + + /* Set new the CCCR and prepare CCLKCFG */ + CCCR = pxa_freq_settings[idx].cccr; + cclkcfg = pxa_freq_settings[idx].cclkcfg; + + asm volatile(" \n\ + ldr r4, [%1] /* load MDREFR */ \n\ + b 2f \n\ + .align 5 \n\ +1: \n\ + str %3, [%1] /* preset the MDREFR */ \n\ + mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\ + str %4, [%1] /* postset the MDREFR */ \n\ + \n\ + b 3f \n\ +2: b 1b \n\ +3: nop \n\ + " + : "=&r" (unused) + : "r" (MDREFR), "r" (cclkcfg), + "r" (preset_mdrefr), "r" (postset_mdrefr) + : "r4", "r5"); + local_irq_restore(flags); + + /* + * Tell everyone what we've just done... + * you should add a notify client with any platform specific + * SDRAM refresh timer adjustments + */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + /* + * Even if voltage setting fails, we don't report it, as the frequency + * change succeeded. The voltage reduction is not a critical failure, + * only power savings will suffer from this. + * + * Note: if the voltage change fails, and a return value is returned, a + * bug is triggered (seems a deadlock). Should anybody find out where, + * the "return 0" should become a "return ret". + */ + if (vcc_core && freqs.new < freqs.old) + ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); + + return 0; +} + +static int pxa_cpufreq_init(struct cpufreq_policy *policy) +{ + int i; + unsigned int freq; + struct cpufreq_frequency_table *pxa255_freq_table; + pxa_freqs_t *pxa255_freqs; + + /* try to guess pxa27x cpu */ + if (cpu_is_pxa27x()) + pxa27x_guess_max_freq(); + + pxa_cpufreq_init_voltages(); + + init_sdram_rows(); + + /* set default policy and cpuinfo */ + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ + policy->cur = get_clk_frequency_khz(0); /* current freq */ + policy->min = policy->max = policy->cur; + + /* Generate pxa25x the run cpufreq_frequency_table struct */ + for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) { + pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz; + pxa255_run_freq_table[i].index = i; + } + pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END; + + /* Generate pxa25x the turbo cpufreq_frequency_table struct */ + for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) { + pxa255_turbo_freq_table[i].frequency = + pxa255_turbo_freqs[i].khz; + pxa255_turbo_freq_table[i].index = i; + } + pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; + + pxa255_turbo_table = !!pxa255_turbo_table; + + /* Generate the pxa27x cpufreq_frequency_table struct */ + for (i = 0; i < NUM_PXA27x_FREQS; i++) { + freq = pxa27x_freqs[i].khz; + if (freq > pxa27x_maxfreq) + break; + pxa27x_freq_table[i].frequency = freq; + pxa27x_freq_table[i].index = i; + } + pxa27x_freq_table[i].index = i; + pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; + + /* + * Set the policy's minimum and maximum frequencies from the tables + * just constructed. This sets cpuinfo.mxx_freq, min and max. + */ + if (cpu_is_pxa25x()) { + find_freq_tables(&pxa255_freq_table, &pxa255_freqs); + pr_info("PXA255 cpufreq using %s frequency table\n", + pxa255_turbo_table ? "turbo" : "run"); + cpufreq_frequency_table_cpuinfo(policy, pxa255_freq_table); + } + else if (cpu_is_pxa27x()) + cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table); + + printk(KERN_INFO "PXA CPU frequency change support initialized\n"); + + return 0; +} + +static struct cpufreq_driver pxa_cpufreq_driver = { + .verify = pxa_verify_policy, + .target = pxa_set_target, + .init = pxa_cpufreq_init, + .get = pxa_cpufreq_get, + .name = "PXA2xx", +}; + +static int __init pxa_cpu_init(void) +{ + int ret = -ENODEV; + if (cpu_is_pxa25x() || cpu_is_pxa27x()) + ret = cpufreq_register_driver(&pxa_cpufreq_driver); + return ret; +} + +static void __exit pxa_cpu_exit(void) +{ + cpufreq_unregister_driver(&pxa_cpufreq_driver); +} + + +MODULE_AUTHOR("Intrinsyc Software Inc."); +MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture"); +MODULE_LICENSE("GPL"); +module_init(pxa_cpu_init); +module_exit(pxa_cpu_exit); diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c new file mode 100644 index 00000000000..88fbec05ec5 --- /dev/null +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c @@ -0,0 +1,257 @@ +/* + * linux/arch/arm/mach-pxa/cpufreq-pxa3xx.c + * + * Copyright (C) 2008 Marvell International Ltd. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/cpufreq.h> +#include <linux/slab.h> + +#include <mach/pxa3xx-regs.h> + +#include "generic.h" + +#define HSS_104M (0) +#define HSS_156M (1) +#define HSS_208M (2) +#define HSS_312M (3) + +#define SMCFS_78M (0) +#define SMCFS_104M (2) +#define SMCFS_208M (5) + +#define SFLFS_104M (0) +#define SFLFS_156M (1) +#define SFLFS_208M (2) +#define SFLFS_312M (3) + +#define XSPCLK_156M (0) +#define XSPCLK_NONE (3) + +#define DMCFS_26M (0) +#define DMCFS_260M (3) + +struct pxa3xx_freq_info { + unsigned int cpufreq_mhz; + unsigned int core_xl : 5; + unsigned int core_xn : 3; + unsigned int hss : 2; + unsigned int dmcfs : 2; + unsigned int smcfs : 3; + unsigned int sflfs : 2; + unsigned int df_clkdiv : 3; + + int vcc_core; /* in mV */ + int vcc_sram; /* in mV */ +}; + +#define OP(cpufreq, _xl, _xn, _hss, _dmc, _smc, _sfl, _dfi, vcore, vsram) \ +{ \ + .cpufreq_mhz = cpufreq, \ + .core_xl = _xl, \ + .core_xn = _xn, \ + .hss = HSS_##_hss##M, \ + .dmcfs = DMCFS_##_dmc##M, \ + .smcfs = SMCFS_##_smc##M, \ + .sflfs = SFLFS_##_sfl##M, \ + .df_clkdiv = _dfi, \ + .vcc_core = vcore, \ + .vcc_sram = vsram, \ +} + +static struct pxa3xx_freq_info pxa300_freqs[] = { + /* CPU XL XN HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */ + OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100), /* 104MHz */ + OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */ + OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */ + OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */ +}; + +static struct pxa3xx_freq_info pxa320_freqs[] = { + /* CPU XL XN HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */ + OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100), /* 104MHz */ + OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */ + OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */ + OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */ + OP(806, 31, 2, 208, 260, 208, 312, 3, 1400, 1400), /* 806MHz */ +}; + +static unsigned int pxa3xx_freqs_num; +static struct pxa3xx_freq_info *pxa3xx_freqs; +static struct cpufreq_frequency_table *pxa3xx_freqs_table; + +static int setup_freqs_table(struct cpufreq_policy *policy, + struct pxa3xx_freq_info *freqs, int num) +{ + struct cpufreq_frequency_table *table; + int i; + + table = kzalloc((num + 1) * sizeof(*table), GFP_KERNEL); + if (table == NULL) + return -ENOMEM; + + for (i = 0; i < num; i++) { + table[i].index = i; + table[i].frequency = freqs[i].cpufreq_mhz * 1000; + } + table[num].index = i; + table[num].frequency = CPUFREQ_TABLE_END; + + pxa3xx_freqs = freqs; + pxa3xx_freqs_num = num; + pxa3xx_freqs_table = table; + + return cpufreq_frequency_table_cpuinfo(policy, table); +} + +static void __update_core_freq(struct pxa3xx_freq_info *info) +{ + uint32_t mask = ACCR_XN_MASK | ACCR_XL_MASK; + uint32_t accr = ACCR; + uint32_t xclkcfg; + + accr &= ~(ACCR_XN_MASK | ACCR_XL_MASK | ACCR_XSPCLK_MASK); + accr |= ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl); + + /* No clock until core PLL is re-locked */ + accr |= ACCR_XSPCLK(XSPCLK_NONE); + + xclkcfg = (info->core_xn == 2) ? 0x3 : 0x2; /* turbo bit */ + + ACCR = accr; + __asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg)); + + while ((ACSR & mask) != (accr & mask)) + cpu_relax(); +} + +static void __update_bus_freq(struct pxa3xx_freq_info *info) +{ + uint32_t mask; + uint32_t accr = ACCR; + + mask = ACCR_SMCFS_MASK | ACCR_SFLFS_MASK | ACCR_HSS_MASK | + ACCR_DMCFS_MASK; + + accr &= ~mask; + accr |= ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) | + ACCR_HSS(info->hss) | ACCR_DMCFS(info->dmcfs); + + ACCR = accr; + + while ((ACSR & mask) != (accr & mask)) + cpu_relax(); +} + +static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, pxa3xx_freqs_table); +} + +static unsigned int pxa3xx_cpufreq_get(unsigned int cpu) +{ + return pxa3xx_get_clk_frequency_khz(0); +} + +static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct pxa3xx_freq_info *next; + struct cpufreq_freqs freqs; + unsigned long flags; + int idx; + + if (policy->cpu != 0) + return -EINVAL; + + /* Lookup the next frequency */ + if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table, + target_freq, relation, &idx)) + return -EINVAL; + + next = &pxa3xx_freqs[idx]; + + freqs.old = policy->cur; + freqs.new = next->cpufreq_mhz * 1000; + freqs.cpu = policy->cpu; + + pr_debug("CPU frequency from %d MHz to %d MHz%s\n", + freqs.old / 1000, freqs.new / 1000, + (freqs.old == freqs.new) ? " (skipped)" : ""); + + if (freqs.old == target_freq) + return 0; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + local_irq_save(flags); + __update_core_freq(next); + __update_bus_freq(next); + local_irq_restore(flags); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) +{ + int ret = -EINVAL; + + /* set default policy and cpuinfo */ + policy->cpuinfo.min_freq = 104000; + policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000; + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ + policy->max = pxa3xx_get_clk_frequency_khz(0); + policy->cur = policy->min = policy->max; + + if (cpu_is_pxa300() || cpu_is_pxa310()) + ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs)); + + if (cpu_is_pxa320()) + ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa320_freqs)); + + if (ret) { + pr_err("failed to setup frequency table\n"); + return ret; + } + + pr_info("CPUFREQ support for PXA3xx initialized\n"); + return 0; +} + +static struct cpufreq_driver pxa3xx_cpufreq_driver = { + .verify = pxa3xx_cpufreq_verify, + .target = pxa3xx_cpufreq_set, + .init = pxa3xx_cpufreq_init, + .get = pxa3xx_cpufreq_get, + .name = "pxa3xx-cpufreq", +}; + +static int __init cpufreq_init(void) +{ + if (cpu_is_pxa3xx()) + return cpufreq_register_driver(&pxa3xx_cpufreq_driver); + + return 0; +} +module_init(cpufreq_init); + +static void __exit cpufreq_exit(void) +{ + cpufreq_unregister_driver(&pxa3xx_cpufreq_driver); +} +module_exit(cpufreq_exit); + +MODULE_DESCRIPTION("CPU frequency scaling driver for PXA3xx"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-pxa/csb701.c b/arch/arm/mach-pxa/csb701.c new file mode 100644 index 00000000000..5a221a49ea4 --- /dev/null +++ b/arch/arm/mach-pxa/csb701.c @@ -0,0 +1,66 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/leds.h> + +#include <asm/mach-types.h> + +static struct gpio_keys_button csb701_buttons[] = { + { + .code = 0x7, + .gpio = 1, + .active_low = 1, + .desc = "SW2", + .type = EV_SW, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data csb701_gpio_keys_data = { + .buttons = csb701_buttons, + .nbuttons = ARRAY_SIZE(csb701_buttons), +}; + +static struct gpio_led csb701_leds[] = { + { + .name = "csb701:yellow:heartbeat", + .default_trigger = "heartbeat", + .gpio = 11, + .active_low = 1, + }, +}; + +static struct platform_device csb701_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev.platform_data = &csb701_gpio_keys_data, +}; + +static struct gpio_led_platform_data csb701_leds_gpio_data = { + .leds = csb701_leds, + .num_leds = ARRAY_SIZE(csb701_leds), +}; + +static struct platform_device csb701_leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &csb701_leds_gpio_data, +}; + +static struct platform_device *devices[] __initdata = { + &csb701_gpio_keys, + &csb701_leds_gpio, +}; + +static int __init csb701_init(void) +{ + if (!machine_is_csb726()) + return -ENODEV; + + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +module_init(csb701_init); + diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c new file mode 100644 index 00000000000..fb5a51d834e --- /dev/null +++ b/arch/arm/mach-pxa/csb726.c @@ -0,0 +1,282 @@ +/* + * Support for Cogent CSB726 + * + * Copyright (c) 2008 Dmitry Eremin-Solenikov + * + * 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/io.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/partitions.h> +#include <linux/sm501.h> +#include <linux/smsc911x.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/csb726.h> +#include <mach/pxa27x.h> +#include <mach/mmc.h> +#include <mach/ohci.h> +#include <mach/audio.h> +#include <mach/smemc.h> + +#include "generic.h" +#include "devices.h" + +/* + * n/a: 2, 5, 6, 7, 8, 23, 24, 25, 26, 27, 87, 88, 89, + * nu: 58 -- 77, 90, 91, 93, 102, 105-108, 114-116, + * XXX: 21, + * XXX: 79 CS_3 for LAN9215 or PSKTSEL on R2, R3 + * XXX: 33 CS_5 for LAN9215 on R1 + */ + +static unsigned long csb726_pin_config[] = { + GPIO78_nCS_2, /* EXP_CS */ + GPIO79_nCS_3, /* SMSC9215 */ + GPIO80_nCS_4, /* SM501 */ + + GPIO52_GPIO, /* #SMSC9251 int */ + GPIO53_GPIO, /* SM501 int */ + + GPIO1_GPIO, /* GPIO0 */ + GPIO11_GPIO, /* GPIO1 */ + GPIO9_GPIO, /* GPIO2 */ + GPIO10_GPIO, /* GPIO3 */ + GPIO16_PWM0_OUT, /* or GPIO4 */ + GPIO17_PWM1_OUT, /* or GPIO5 */ + GPIO94_GPIO, /* GPIO6 */ + GPIO95_GPIO, /* GPIO7 */ + GPIO96_GPIO, /* GPIO8 */ + GPIO97_GPIO, /* GPIO9 */ + GPIO15_GPIO, /* EXP_IRQ */ + GPIO18_RDY, /* EXP_WAIT */ + + GPIO0_GPIO, /* PWR_INT */ + GPIO104_GPIO, /* PWR_OFF */ + + GPIO12_GPIO, /* touch irq */ + + GPIO13_SSP2_TXD, + GPIO14_SSP2_SFRM, + MFP_CFG_OUT(GPIO19, AF1, DRIVE_LOW),/* SSP2_SYSCLK */ + GPIO22_SSP2_SCLK, + + GPIO81_SSP3_TXD, + GPIO82_SSP3_RXD, + GPIO83_SSP3_SFRM, + GPIO84_SSP3_SCLK, + + GPIO20_GPIO, /* SDIO int */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + GPIO100_GPIO, /* SD CD */ + GPIO101_GPIO, /* SD WP */ + + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO113_AC97_nRESET, + + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + GPIO36_FFUART_DCD, + GPIO37_FFUART_DSR, + GPIO38_FFUART_RI, + GPIO39_FFUART_TXD, + GPIO40_FFUART_DTR, + GPIO41_FFUART_RTS, + + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, /* maybe unused */ + GPIO85_nPCE_1, + GPIO98_GPIO, /* CF IRQ */ + GPIO99_GPIO, /* CF CD */ + GPIO103_GPIO, /* Reset */ + + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, +}; + +static struct pxamci_platform_data csb726_mci = { + .detect_delay_ms = 500, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + /* FIXME setpower */ + .gpio_card_detect = CSB726_GPIO_MMC_DETECT, + .gpio_card_ro = CSB726_GPIO_MMC_RO, + .gpio_power = -1, +}; + +static struct pxaohci_platform_data csb726_ohci_platform_data = { + .port_mode = PMM_NPS_MODE, + .flags = ENABLE_PORT1 | NO_OC_PROTECTION, +}; + +static struct mtd_partition csb726_flash_partitions[] = { + { + .name = "Bootloader", + .offset = 0, + .size = CSB726_FLASH_uMON, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "root", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data csb726_flash_data = { + .width = 2, + .parts = csb726_flash_partitions, + .nr_parts = ARRAY_SIZE(csb726_flash_partitions), +}; + +static struct resource csb726_flash_resources[] = { + { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + CSB726_FLASH_SIZE - 1 , + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device csb726_flash = { + .name = "physmap-flash", + .dev = { + .platform_data = &csb726_flash_data, + }, + .resource = csb726_flash_resources, + .num_resources = ARRAY_SIZE(csb726_flash_resources), +}; + +static struct resource csb726_sm501_resources[] = { + { + .start = PXA_CS4_PHYS, + .end = PXA_CS4_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + .name = "sm501-localmem", + }, + { + .start = PXA_CS4_PHYS + SZ_64M - SZ_2M, + .end = PXA_CS4_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, + .name = "sm501-regs", + }, + { + .start = CSB726_IRQ_SM501, + .end = CSB726_IRQ_SM501, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sm501_initdata csb726_sm501_initdata = { +/* .devices = SM501_USE_USB_HOST, */ + .devices = SM501_USE_USB_HOST | SM501_USE_UART0 | SM501_USE_UART1, +}; + +static struct sm501_platdata csb726_sm501_platdata = { + .init = &csb726_sm501_initdata, +}; + +static struct platform_device csb726_sm501 = { + .name = "sm501", + .id = 0, + .num_resources = ARRAY_SIZE(csb726_sm501_resources), + .resource = csb726_sm501_resources, + .dev = { + .platform_data = &csb726_sm501_platdata, + }, +}; + +static struct resource csb726_lan_resources[] = { + { + .start = PXA_CS3_PHYS, + .end = PXA_CS3_PHYS + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = CSB726_IRQ_LAN, + .end = CSB726_IRQ_LAN, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, +}; + +struct smsc911x_platform_config csb726_lan_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .flags = SMSC911X_USE_32BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + + +static struct platform_device csb726_lan = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(csb726_lan_resources), + .resource = csb726_lan_resources, + .dev = { + .platform_data = &csb726_lan_config, + }, +}; + +static struct platform_device *devices[] __initdata = { + &csb726_flash, + &csb726_sm501, + &csb726_lan, +}; + +static void __init csb726_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config)); +/* __raw_writel(0x7ffc3ffc, MSC1); *//* LAN9215/EXP_CS */ +/* __raw_writel(0x06697ff4, MSC2); *//* none/SM501 */ + __raw_writel((__raw_readl(MSC2) & ~0xffff) | 0x7ff4, MSC2); /* SM501 */ + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + pxa_set_i2c_info(NULL); + pxa27x_set_i2c_power_info(NULL); + pxa_set_mci_info(&csb726_mci); + pxa_set_ohci_info(&csb726_ohci_platform_data); + pxa_set_ac97_info(NULL); + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +MACHINE_START(CSB726, "Cogent CSB726") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_machine = csb726_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c new file mode 100644 index 00000000000..5bc13121eac --- /dev/null +++ b/arch/arm/mach-pxa/devices.c @@ -0,0 +1,1099 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/pmu.h> +#include <mach/udc.h> +#include <mach/pxa3xx-u2d.h> +#include <mach/pxafb.h> +#include <mach/mmc.h> +#include <mach/irda.h> +#include <mach/ohci.h> +#include <plat/pxa27x_keypad.h> +#include <mach/camera.h> +#include <mach/audio.h> +#include <mach/hardware.h> +#include <plat/pxa3xx_nand.h> + +#include "devices.h" +#include "generic.h" + +void __init pxa_register_device(struct platform_device *dev, void *data) +{ + int ret; + + dev->dev.platform_data = data; + + ret = platform_device_register(dev); + if (ret) + dev_err(&dev->dev, "unable to register device: %d\n", ret); +} + +static struct resource pxa_resource_pmu = { + .start = IRQ_PMU, + .end = IRQ_PMU, + .flags = IORESOURCE_IRQ, +}; + +struct platform_device pxa_device_pmu = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .resource = &pxa_resource_pmu, + .num_resources = 1, +}; + +static struct resource pxamci_resources[] = { + [0] = { + .start = 0x41100000, + .end = 0x41100fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC, + .end = IRQ_MMC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 21, + .end = 21, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = 22, + .end = 22, + .flags = IORESOURCE_DMA, + }, +}; + +static u64 pxamci_dmamask = 0xffffffffUL; + +struct platform_device pxa_device_mci = { + .name = "pxa2xx-mci", + .id = 0, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxamci_resources), + .resource = pxamci_resources, +}; + +void __init pxa_set_mci_info(struct pxamci_platform_data *info) +{ + pxa_register_device(&pxa_device_mci, info); +} + + +static struct pxa2xx_udc_mach_info pxa_udc_info = { + .gpio_pullup = -1, +}; + +void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) +{ + memcpy(&pxa_udc_info, info, sizeof *info); +} + +static struct resource pxa2xx_udc_resources[] = { + [0] = { + .start = 0x40600000, + .end = 0x4060ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB, + .end = IRQ_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dma_mask = ~(u32)0; + +struct platform_device pxa25x_device_udc = { + .name = "pxa25x-udc", + .id = -1, + .resource = pxa2xx_udc_resources, + .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), + .dev = { + .platform_data = &pxa_udc_info, + .dma_mask = &udc_dma_mask, + } +}; + +struct platform_device pxa27x_device_udc = { + .name = "pxa27x-udc", + .id = -1, + .resource = pxa2xx_udc_resources, + .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), + .dev = { + .platform_data = &pxa_udc_info, + .dma_mask = &udc_dma_mask, + } +}; + +#ifdef CONFIG_PXA3xx +static struct resource pxa3xx_u2d_resources[] = { + [0] = { + .start = 0x54100000, + .end = 0x54100fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB2, + .end = IRQ_USB2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa3xx_device_u2d = { + .name = "pxa3xx-u2d", + .id = -1, + .resource = pxa3xx_u2d_resources, + .num_resources = ARRAY_SIZE(pxa3xx_u2d_resources), +}; + +void __init pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_u2d, info); +} +#endif /* CONFIG_PXA3xx */ + +static struct resource pxafb_resources[] = { + [0] = { + .start = 0x44000000, + .end = 0x4400ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fb_dma_mask = ~(u64)0; + +struct platform_device pxa_device_fb = { + .name = "pxa2xx-fb", + .id = -1, + .dev = { + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxafb_resources), + .resource = pxafb_resources, +}; + +void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info) +{ + pxa_device_fb.dev.parent = parent; + pxa_register_device(&pxa_device_fb, info); +} + +static struct resource pxa_resource_ffuart[] = { + { + .start = 0x40100000, + .end = 0x40100023, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_FFUART, + .end = IRQ_FFUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_ffuart = { + .name = "pxa2xx-uart", + .id = 0, + .resource = pxa_resource_ffuart, + .num_resources = ARRAY_SIZE(pxa_resource_ffuart), +}; + +void __init pxa_set_ffuart_info(void *info) +{ + pxa_register_device(&pxa_device_ffuart, info); +} + +static struct resource pxa_resource_btuart[] = { + { + .start = 0x40200000, + .end = 0x40200023, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_BTUART, + .end = IRQ_BTUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_btuart = { + .name = "pxa2xx-uart", + .id = 1, + .resource = pxa_resource_btuart, + .num_resources = ARRAY_SIZE(pxa_resource_btuart), +}; + +void __init pxa_set_btuart_info(void *info) +{ + pxa_register_device(&pxa_device_btuart, info); +} + +static struct resource pxa_resource_stuart[] = { + { + .start = 0x40700000, + .end = 0x40700023, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_STUART, + .end = IRQ_STUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_stuart = { + .name = "pxa2xx-uart", + .id = 2, + .resource = pxa_resource_stuart, + .num_resources = ARRAY_SIZE(pxa_resource_stuart), +}; + +void __init pxa_set_stuart_info(void *info) +{ + pxa_register_device(&pxa_device_stuart, info); +} + +static struct resource pxa_resource_hwuart[] = { + { + .start = 0x41600000, + .end = 0x4160002F, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_HWUART, + .end = IRQ_HWUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_hwuart = { + .name = "pxa2xx-uart", + .id = 3, + .resource = pxa_resource_hwuart, + .num_resources = ARRAY_SIZE(pxa_resource_hwuart), +}; + +void __init pxa_set_hwuart_info(void *info) +{ + if (cpu_is_pxa255()) + pxa_register_device(&pxa_device_hwuart, info); + else + pr_info("UART: Ignoring attempt to register HWUART on non-PXA255 hardware"); +} + +static struct resource pxai2c_resources[] = { + { + .start = 0x40301680, + .end = 0x403016a3, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_I2C, + .end = IRQ_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa_device_i2c = { + .name = "pxa2xx-i2c", + .id = 0, + .resource = pxai2c_resources, + .num_resources = ARRAY_SIZE(pxai2c_resources), +}; + +void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) +{ + pxa_register_device(&pxa_device_i2c, info); +} + +#ifdef CONFIG_PXA27x +static struct resource pxa27x_resources_i2c_power[] = { + { + .start = 0x40f00180, + .end = 0x40f001a3, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PWRI2C, + .end = IRQ_PWRI2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa27x_device_i2c_power = { + .name = "pxa2xx-i2c", + .id = 1, + .resource = pxa27x_resources_i2c_power, + .num_resources = ARRAY_SIZE(pxa27x_resources_i2c_power), +}; +#endif + +static struct resource pxai2s_resources[] = { + { + .start = 0x40400000, + .end = 0x40400083, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_I2S, + .end = IRQ_I2S, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa_device_i2s = { + .name = "pxa2xx-i2s", + .id = -1, + .resource = pxai2s_resources, + .num_resources = ARRAY_SIZE(pxai2s_resources), +}; + +struct platform_device pxa_device_asoc_ssp1 = { + .name = "pxa-ssp-dai", + .id = 0, +}; + +struct platform_device pxa_device_asoc_ssp2= { + .name = "pxa-ssp-dai", + .id = 1, +}; + +struct platform_device pxa_device_asoc_ssp3 = { + .name = "pxa-ssp-dai", + .id = 2, +}; + +struct platform_device pxa_device_asoc_ssp4 = { + .name = "pxa-ssp-dai", + .id = 3, +}; + +struct platform_device pxa_device_asoc_platform = { + .name = "pxa-pcm-audio", + .id = -1, +}; + +static u64 pxaficp_dmamask = ~(u32)0; + +struct platform_device pxa_device_ficp = { + .name = "pxa2xx-ir", + .id = -1, + .dev = { + .dma_mask = &pxaficp_dmamask, + .coherent_dma_mask = 0xffffffff, + }, +}; + +void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) +{ + pxa_register_device(&pxa_device_ficp, info); +} + +static struct resource pxa_rtc_resources[] = { + [0] = { + .start = 0x40900000, + .end = 0x40900000 + 0x3b, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device sa1100_device_rtc = { + .name = "sa1100-rtc", + .id = -1, +}; + +struct platform_device pxa_device_rtc = { + .name = "pxa-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(pxa_rtc_resources), + .resource = pxa_rtc_resources, +}; + +static struct resource pxa_ac97_resources[] = { + [0] = { + .start = 0x40500000, + .end = 0x40500000 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa_ac97_dmamask = 0xffffffffUL; + +struct platform_device pxa_device_ac97 = { + .name = "pxa2xx-ac97", + .id = -1, + .dev = { + .dma_mask = &pxa_ac97_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa_ac97_resources), + .resource = pxa_ac97_resources, +}; + +void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops) +{ + pxa_register_device(&pxa_device_ac97, ops); +} + +#ifdef CONFIG_PXA25x + +static struct resource pxa25x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm0 = { + .name = "pxa25x-pwm", + .id = 0, + .resource = pxa25x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm0), +}; + +static struct resource pxa25x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm1 = { + .name = "pxa25x-pwm", + .id = 1, + .resource = pxa25x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm1), +}; + +static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa25x_resource_ssp[] = { + [0] = { + .start = 0x41000000, + .end = 0x4100001f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP, + .end = IRQ_SSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 13, + .end = 13, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 14, + .end = 14, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa25x_device_ssp = { + .name = "pxa25x-ssp", + .id = 0, + .dev = { + .dma_mask = &pxa25x_ssp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa25x_resource_ssp, + .num_resources = ARRAY_SIZE(pxa25x_resource_ssp), +}; + +static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa25x_resource_nssp[] = { + [0] = { + .start = 0x41400000, + .end = 0x4140002f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NSSP, + .end = IRQ_NSSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 15, + .end = 15, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 16, + .end = 16, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa25x_device_nssp = { + .name = "pxa25x-nssp", + .id = 1, + .dev = { + .dma_mask = &pxa25x_nssp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa25x_resource_nssp, + .num_resources = ARRAY_SIZE(pxa25x_resource_nssp), +}; + +static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa25x_resource_assp[] = { + [0] = { + .start = 0x41500000, + .end = 0x4150002f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_ASSP, + .end = IRQ_ASSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 23, + .end = 23, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 24, + .end = 24, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa25x_device_assp = { + /* ASSP is basically equivalent to NSSP */ + .name = "pxa25x-nssp", + .id = 2, + .dev = { + .dma_mask = &pxa25x_assp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa25x_resource_assp, + .num_resources = ARRAY_SIZE(pxa25x_resource_assp), +}; +#endif /* CONFIG_PXA25x */ + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) +static struct resource pxa27x_resource_camera[] = { + [0] = { + .start = 0x50000000, + .end = 0x50000fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CAMERA, + .end = IRQ_CAMERA, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32); + +static struct platform_device pxa27x_device_camera = { + .name = "pxa27x-camera", + .id = 0, /* This is used to put cameras on this interface */ + .dev = { + .dma_mask = &pxa27x_dma_mask_camera, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa27x_resource_camera), + .resource = pxa27x_resource_camera, +}; + +void __init pxa_set_camera_info(struct pxacamera_platform_data *info) +{ + pxa_register_device(&pxa27x_device_camera, info); +} + +static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ohci[] = { + [0] = { + .start = 0x4C000000, + .end = 0x4C00ff6f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBH1, + .end = IRQ_USBH1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa27x_device_ohci = { + .name = "pxa27x-ohci", + .id = -1, + .dev = { + .dma_mask = &pxa27x_ohci_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(pxa27x_resource_ohci), + .resource = pxa27x_resource_ohci, +}; + +void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) +{ + pxa_register_device(&pxa27x_device_ohci, info); +} +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) +static struct resource pxa27x_resource_keypad[] = { + [0] = { + .start = 0x41500000, + .end = 0x4150004c, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_KEYPAD, + .end = IRQ_KEYPAD, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa27x_device_keypad = { + .name = "pxa27x-keypad", + .id = -1, + .resource = pxa27x_resource_keypad, + .num_resources = ARRAY_SIZE(pxa27x_resource_keypad), +}; + +void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info) +{ + pxa_register_device(&pxa27x_device_keypad, info); +} + +static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ssp1[] = { + [0] = { + .start = 0x41000000, + .end = 0x4100003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP, + .end = IRQ_SSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 13, + .end = 13, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 14, + .end = 14, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa27x_device_ssp1 = { + .name = "pxa27x-ssp", + .id = 0, + .dev = { + .dma_mask = &pxa27x_ssp1_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa27x_resource_ssp1, + .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1), +}; + +static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ssp2[] = { + [0] = { + .start = 0x41700000, + .end = 0x4170003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP2, + .end = IRQ_SSP2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 15, + .end = 15, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 16, + .end = 16, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa27x_device_ssp2 = { + .name = "pxa27x-ssp", + .id = 1, + .dev = { + .dma_mask = &pxa27x_ssp2_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa27x_resource_ssp2, + .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2), +}; + +static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ssp3[] = { + [0] = { + .start = 0x41900000, + .end = 0x4190003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP3, + .end = IRQ_SSP3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 66, + .end = 66, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 67, + .end = 67, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa27x_device_ssp3 = { + .name = "pxa27x-ssp", + .id = 2, + .dev = { + .dma_mask = &pxa27x_ssp3_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa27x_resource_ssp3, + .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), +}; + +static struct resource pxa27x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm0 = { + .name = "pxa27x-pwm", + .id = 0, + .resource = pxa27x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm0), +}; + +static struct resource pxa27x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm1 = { + .name = "pxa27x-pwm", + .id = 1, + .resource = pxa27x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), +}; +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA95x*/ + +#ifdef CONFIG_PXA3xx +static struct resource pxa3xx_resources_mci2[] = { + [0] = { + .start = 0x42000000, + .end = 0x42000fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC2, + .end = IRQ_MMC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 93, + .end = 93, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = 94, + .end = 94, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa3xx_device_mci2 = { + .name = "pxa2xx-mci", + .id = 1, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2), + .resource = pxa3xx_resources_mci2, +}; + +void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_mci2, info); +} + +static struct resource pxa3xx_resources_mci3[] = { + [0] = { + .start = 0x42500000, + .end = 0x42500fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC3, + .end = IRQ_MMC3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 100, + .end = 100, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = 101, + .end = 101, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa3xx_device_mci3 = { + .name = "pxa2xx-mci", + .id = 2, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3), + .resource = pxa3xx_resources_mci3, +}; + +void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_mci3, info); +} + +static struct resource pxa3xx_resources_gcu[] = { + { + .start = 0x54000000, + .end = 0x54000fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_GCU, + .end = IRQ_GCU, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32); + +struct platform_device pxa3xx_device_gcu = { + .name = "pxa3xx-gcu", + .id = -1, + .num_resources = ARRAY_SIZE(pxa3xx_resources_gcu), + .resource = pxa3xx_resources_gcu, + .dev = { + .dma_mask = &pxa3xx_gcu_dmamask, + .coherent_dma_mask = 0xffffffff, + }, +}; + +#endif /* CONFIG_PXA3xx */ + +#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) +static struct resource pxa3xx_resources_i2c_power[] = { + { + .start = 0x40f500c0, + .end = 0x40f500d3, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PWRI2C, + .end = IRQ_PWRI2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa3xx_device_i2c_power = { + .name = "pxa3xx-pwri2c", + .id = 1, + .resource = pxa3xx_resources_i2c_power, + .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power), +}; + +static struct resource pxa3xx_resources_nand[] = { + [0] = { + .start = 0x43100000, + .end = 0x43100053, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NAND, + .end = IRQ_NAND, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for Data DMA */ + .start = 97, + .end = 97, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for Command DMA */ + .start = 99, + .end = 99, + .flags = IORESOURCE_DMA, + }, +}; + +static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32); + +struct platform_device pxa3xx_device_nand = { + .name = "pxa3xx-nand", + .id = -1, + .dev = { + .dma_mask = &pxa3xx_nand_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_nand), + .resource = pxa3xx_resources_nand, +}; + +void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_nand, info); +} + +static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa3xx_resource_ssp4[] = { + [0] = { + .start = 0x41a00000, + .end = 0x41a0003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP4, + .end = IRQ_SSP4, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 2, + .end = 2, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 3, + .end = 3, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa3xx_device_ssp4 = { + /* PXA3xx SSP is basically equivalent to PXA27x */ + .name = "pxa27x-ssp", + .id = 3, + .dev = { + .dma_mask = &pxa3xx_ssp4_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa3xx_resource_ssp4, + .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4), +}; +#endif /* CONFIG_PXA3xx || CONFIG_PXA95x */ + +struct resource pxa_resource_gpio[] = { + { + .start = 0x40e00000, + .end = 0x40e0ffff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_GPIO0, + .end = IRQ_GPIO0, + .name = "gpio0", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_GPIO1, + .end = IRQ_GPIO1, + .name = "gpio1", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_GPIO_2_x, + .end = IRQ_GPIO_2_x, + .name = "gpio_mux", + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa_device_gpio = { + .name = "pxa-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(pxa_resource_gpio), + .resource = pxa_resource_gpio, +}; + +/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. + * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ +void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) +{ + struct platform_device *pd; + + pd = platform_device_alloc("pxa2xx-spi", id); + if (pd == NULL) { + printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n", + id); + return; + } + + pd->dev.platform_data = info; + platform_device_add(pd); +} diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h new file mode 100644 index 00000000000..1475db10725 --- /dev/null +++ b/arch/arm/mach-pxa/devices.h @@ -0,0 +1,49 @@ +extern struct platform_device pxa_device_pmu; +extern struct platform_device pxa_device_mci; +extern struct platform_device pxa3xx_device_mci2; +extern struct platform_device pxa3xx_device_mci3; +extern struct platform_device pxa25x_device_udc; +extern struct platform_device pxa27x_device_udc; +extern struct platform_device pxa3xx_device_u2d; +extern struct platform_device pxa_device_fb; +extern struct platform_device pxa_device_ffuart; +extern struct platform_device pxa_device_btuart; +extern struct platform_device pxa_device_stuart; +extern struct platform_device pxa_device_hwuart; +extern struct platform_device pxa_device_i2c; +extern struct platform_device pxa_device_i2s; +extern struct platform_device pxa_device_ficp; +extern struct platform_device sa1100_device_rtc; +extern struct platform_device pxa_device_rtc; +extern struct platform_device pxa_device_ac97; +extern struct platform_device pxa_device_gpio; + +extern struct platform_device pxa27x_device_i2c_power; +extern struct platform_device pxa27x_device_ohci; +extern struct platform_device pxa27x_device_keypad; + +extern struct platform_device pxa25x_device_ssp; +extern struct platform_device pxa25x_device_nssp; +extern struct platform_device pxa25x_device_assp; +extern struct platform_device pxa27x_device_ssp1; +extern struct platform_device pxa27x_device_ssp2; +extern struct platform_device pxa27x_device_ssp3; +extern struct platform_device pxa3xx_device_ssp4; + +extern struct platform_device pxa25x_device_pwm0; +extern struct platform_device pxa25x_device_pwm1; +extern struct platform_device pxa27x_device_pwm0; +extern struct platform_device pxa27x_device_pwm1; + +extern struct platform_device pxa3xx_device_nand; +extern struct platform_device pxa3xx_device_i2c_power; + +extern struct platform_device pxa3xx_device_gcu; + +extern struct platform_device pxa_device_asoc_platform; +extern struct platform_device pxa_device_asoc_ssp1; +extern struct platform_device pxa_device_asoc_ssp2; +extern struct platform_device pxa_device_asoc_ssp3; +extern struct platform_device pxa_device_asoc_ssp4; + +void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c new file mode 100644 index 00000000000..d80c0ba9a09 --- /dev/null +++ b/arch/arm/mach-pxa/em-x270.c @@ -0,0 +1,1319 @@ +/* + * Support for CompuLab EM-X270 platform + * + * Copyright (C) 2007, 2008 CompuLab, Ltd. + * Author: Mike Rapoport <mike@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. + */ + +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#include <linux/dm9000.h> +#include <linux/rtc-v3020.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> +#include <linux/gpio.h> +#include <linux/mfd/da903x.h> +#include <linux/regulator/machine.h> +#include <linux/spi/spi.h> +#include <linux/spi/tdo24m.h> +#include <linux/spi/libertas_spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/power_supply.h> +#include <linux/apm-emulation.h> +#include <linux/i2c.h> +#include <linux/i2c/pca953x.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/regulator/userspace-consumer.h> + +#include <media/soc_camera.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa27x.h> +#include <mach/pxa27x-udc.h> +#include <mach/audio.h> +#include <mach/pxafb.h> +#include <mach/ohci.h> +#include <mach/mmc.h> +#include <plat/pxa27x_keypad.h> +#include <mach/camera.h> + +#include "generic.h" +#include "devices.h" + +/* EM-X270 specific GPIOs */ +#define GPIO13_MMC_CD (13) +#define GPIO95_MMC_WP (95) +#define GPIO56_NAND_RB (56) +#define GPIO93_CAM_RESET (93) +#define GPIO16_USB_HUB_RESET (16) + +/* eXeda specific GPIOs */ +#define GPIO114_MMC_CD (114) +#define GPIO20_NAND_RB (20) +#define GPIO38_SD_PWEN (38) +#define GPIO37_WLAN_RST (37) +#define GPIO95_TOUCHPAD_INT (95) +#define GPIO130_CAM_RESET (130) +#define GPIO10_USB_HUB_RESET (10) + +/* common GPIOs */ +#define GPIO11_NAND_CS (11) +#define GPIO41_ETHIRQ (41) +#define EM_X270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO41_ETHIRQ) +#define GPIO115_WLAN_PWEN (115) +#define GPIO19_WLAN_STRAP (19) +#define GPIO9_USB_VBUS_EN (9) + +static int mmc_cd; +static int nand_rb; +static int dm9000_flags; +static int cam_reset; +static int usb_hub_reset; + +static unsigned long common_pin_config[] = { + /* AC'97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO98_AC97_SYSCLK, + GPIO113_AC97_nRESET, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* MCI controller */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* QCI */ + GPIO84_CIF_FV, + GPIO25_CIF_LV, + GPIO53_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO81_CIF_DD_0, + GPIO55_CIF_DD_1, + GPIO51_CIF_DD_2, + GPIO50_CIF_DD_3, + GPIO52_CIF_DD_4, + GPIO48_CIF_DD_5, + GPIO17_CIF_DD_6, + GPIO12_CIF_DD_7, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* Keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO39_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, + GPIO91_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH, + GPIO36_KP_MKIN_7 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, + GPIO96_KP_MKOUT_6, + GPIO22_KP_MKOUT_7, + + /* SSP1 */ + GPIO26_SSP1_RXD, + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO57_SSP1_TXD, + + /* SSP2 */ + GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */ + GPIO14_GPIO, + GPIO89_SSP2_TXD, + GPIO88_SSP2_RXD, + + /* SDRAM and local bus */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO49_nPWE, + GPIO18_RDY, + + /* GPIO */ + GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */ + + /* power controls */ + GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ + GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */ + + /* NAND controls */ + GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ + + /* interrupts */ + GPIO41_GPIO, /* DM9000 interrupt */ +}; + +static unsigned long em_x270_pin_config[] = { + GPIO13_GPIO, /* MMC card detect */ + GPIO16_GPIO, /* USB hub reset */ + GPIO56_GPIO, /* NAND Ready/Busy */ + GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */ + GPIO95_GPIO, /* MMC Write protect */ +}; + +static unsigned long exeda_pin_config[] = { + GPIO10_GPIO, /* USB hub reset */ + GPIO20_GPIO, /* NAND Ready/Busy */ + GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */ + GPIO95_GPIO, /* touchpad IRQ */ + GPIO114_GPIO, /* MMC card detect */ +}; + +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource em_x270_dm9000_resource[] = { + [0] = { + .start = PXA_CS2_PHYS, + .end = PXA_CS2_PHYS + 3, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_CS2_PHYS + 8, + .end = PXA_CS2_PHYS + 8 + 0x3f, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = EM_X270_ETHIRQ, + .end = EM_X270_ETHIRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct dm9000_plat_data em_x270_dm9000_platdata = { + .flags = DM9000_PLATF_NO_EEPROM, +}; + +static struct platform_device em_x270_dm9000 = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(em_x270_dm9000_resource), + .resource = em_x270_dm9000_resource, + .dev = { + .platform_data = &em_x270_dm9000_platdata, + } +}; + +static void __init em_x270_init_dm9000(void) +{ + em_x270_dm9000_platdata.flags |= dm9000_flags; + platform_device_register(&em_x270_dm9000); +} +#else +static inline void em_x270_init_dm9000(void) {} +#endif + +/* V3020 RTC */ +#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) +static struct resource em_x270_v3020_resource[] = { + [0] = { + .start = PXA_CS4_PHYS, + .end = PXA_CS4_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct v3020_platform_data em_x270_v3020_platdata = { + .leftshift = 0, +}; + +static struct platform_device em_x270_rtc = { + .name = "v3020", + .num_resources = ARRAY_SIZE(em_x270_v3020_resource), + .resource = em_x270_v3020_resource, + .id = -1, + .dev = { + .platform_data = &em_x270_v3020_platdata, + } +}; + +static void __init em_x270_init_rtc(void) +{ + platform_device_register(&em_x270_rtc); +} +#else +static inline void em_x270_init_rtc(void) {} +#endif + +/* NAND flash */ +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) +static inline void nand_cs_on(void) +{ + gpio_set_value(GPIO11_NAND_CS, 0); +} + +static void nand_cs_off(void) +{ + dsb(); + + gpio_set_value(GPIO11_NAND_CS, 1); +} + +/* hardware specific access to control-lines */ +static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat, + unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; + + dsb(); + + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_ALE) + nandaddr |= (1 << 3); + else + nandaddr &= ~(1 << 3); + if (ctrl & NAND_CLE) + nandaddr |= (1 << 2); + else + nandaddr &= ~(1 << 2); + if (ctrl & NAND_NCE) + nand_cs_on(); + else + nand_cs_off(); + } + + dsb(); + this->IO_ADDR_W = (void __iomem *)nandaddr; + if (dat != NAND_CMD_NONE) + writel(dat, this->IO_ADDR_W); + + dsb(); +} + +/* read device ready pin */ +static int em_x270_nand_device_ready(struct mtd_info *mtd) +{ + dsb(); + + return gpio_get_value(nand_rb); +} + +static struct mtd_partition em_x270_partition_info[] = { + [0] = { + .name = "em_x270-0", + .offset = 0, + .size = SZ_4M, + }, + [1] = { + .name = "em_x270-1", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; + +static const char *em_x270_part_probes[] = { "cmdlinepart", NULL }; + +struct platform_nand_data em_x270_nand_platdata = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .nr_partitions = ARRAY_SIZE(em_x270_partition_info), + .partitions = em_x270_partition_info, + .chip_delay = 20, + .part_probe_types = em_x270_part_probes, + }, + .ctrl = { + .hwcontrol = 0, + .dev_ready = em_x270_nand_device_ready, + .select_chip = 0, + .cmd_ctrl = em_x270_nand_cmd_ctl, + }, +}; + +static struct resource em_x270_nand_resource[] = { + [0] = { + .start = PXA_CS1_PHYS, + .end = PXA_CS1_PHYS + 12, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device em_x270_nand = { + .name = "gen_nand", + .num_resources = ARRAY_SIZE(em_x270_nand_resource), + .resource = em_x270_nand_resource, + .id = -1, + .dev = { + .platform_data = &em_x270_nand_platdata, + } +}; + +static void __init em_x270_init_nand(void) +{ + int err; + + err = gpio_request(GPIO11_NAND_CS, "NAND CS"); + if (err) { + pr_warning("EM-X270: failed to request NAND CS gpio\n"); + return; + } + + gpio_direction_output(GPIO11_NAND_CS, 1); + + err = gpio_request(nand_rb, "NAND R/B"); + if (err) { + pr_warning("EM-X270: failed to request NAND R/B gpio\n"); + gpio_free(GPIO11_NAND_CS); + return; + } + + gpio_direction_input(nand_rb); + + platform_device_register(&em_x270_nand); +} +#else +static inline void em_x270_init_nand(void) {} +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition em_x270_nor_parts[] = { + { + .name = "Bootloader", + .offset = 0x00000000, + .size = 0x00050000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, { + .name = "Environment", + .offset = 0x00050000, + .size = 0x00010000, + }, { + .name = "Reserved", + .offset = 0x00060000, + .size = 0x00050000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, { + .name = "Splashscreen", + .offset = 0x000b0000, + .size = 0x00050000, + } +}; + +static struct physmap_flash_data em_x270_nor_data[] = { + [0] = { + .width = 2, + .parts = em_x270_nor_parts, + .nr_parts = ARRAY_SIZE(em_x270_nor_parts), + }, +}; + +static struct resource em_x270_nor_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_1M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device em_x270_physmap_flash = { + .name = "physmap-flash", + .id = 0, + .num_resources = 1, + .resource = &em_x270_nor_flash_resource, + .dev = { + .platform_data = &em_x270_nor_data, + }, +}; + +static void __init em_x270_init_nor(void) +{ + platform_device_register(&em_x270_physmap_flash); +} +#else +static inline void em_x270_init_nor(void) {} +#endif + +/* PXA27x OHCI controller setup */ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static struct regulator *em_x270_usb_ldo; + +static int em_x270_usb_hub_init(void) +{ + int err; + + em_x270_usb_ldo = regulator_get(NULL, "vcc usb"); + if (IS_ERR(em_x270_usb_ldo)) + return PTR_ERR(em_x270_usb_ldo); + + err = gpio_request(GPIO9_USB_VBUS_EN, "vbus en"); + if (err) + goto err_free_usb_ldo; + + err = gpio_request(usb_hub_reset, "hub rst"); + if (err) + goto err_free_vbus_gpio; + + /* USB Hub power-on and reset */ + gpio_direction_output(usb_hub_reset, 1); + gpio_direction_output(GPIO9_USB_VBUS_EN, 0); + regulator_enable(em_x270_usb_ldo); + gpio_set_value(usb_hub_reset, 0); + gpio_set_value(usb_hub_reset, 1); + regulator_disable(em_x270_usb_ldo); + regulator_enable(em_x270_usb_ldo); + gpio_set_value(usb_hub_reset, 0); + gpio_set_value(GPIO9_USB_VBUS_EN, 1); + + return 0; + +err_free_vbus_gpio: + gpio_free(GPIO9_USB_VBUS_EN); +err_free_usb_ldo: + regulator_put(em_x270_usb_ldo); + + return err; +} + +static int em_x270_ohci_init(struct device *dev) +{ + int err; + + /* we don't want to entirely disable USB if the HUB init failed */ + err = em_x270_usb_hub_init(); + if (err) + pr_err("USB Hub initialization failed: %d\n", err); + + /* enable port 2 transiever */ + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; + + return 0; +} + +static void em_x270_ohci_exit(struct device *dev) +{ + gpio_free(usb_hub_reset); + gpio_free(GPIO9_USB_VBUS_EN); + + if (!IS_ERR(em_x270_usb_ldo)) { + if (regulator_is_enabled(em_x270_usb_ldo)) + regulator_disable(em_x270_usb_ldo); + + regulator_put(em_x270_usb_ldo); + } +} + +static struct pxaohci_platform_data em_x270_ohci_platform_data = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW, + .init = em_x270_ohci_init, + .exit = em_x270_ohci_exit, +}; + +static void __init em_x270_init_ohci(void) +{ + pxa_set_ohci_info(&em_x270_ohci_platform_data); +} +#else +static inline void em_x270_init_ohci(void) {} +#endif + +/* MCI controller setup */ +#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) +static struct regulator *em_x270_sdio_ldo; + +static int em_x270_mci_init(struct device *dev, + irq_handler_t em_x270_detect_int, + void *data) +{ + int err; + + em_x270_sdio_ldo = regulator_get(dev, "vcc sdio"); + if (IS_ERR(em_x270_sdio_ldo)) { + dev_err(dev, "can't request SDIO power supply: %ld\n", + PTR_ERR(em_x270_sdio_ldo)); + return PTR_ERR(em_x270_sdio_ldo); + } + + err = request_irq(gpio_to_irq(mmc_cd), em_x270_detect_int, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "MMC card detect", data); + if (err) { + dev_err(dev, "can't request MMC card detect IRQ: %d\n", err); + goto err_irq; + } + + if (machine_is_em_x270()) { + err = gpio_request(GPIO95_MMC_WP, "MMC WP"); + if (err) { + dev_err(dev, "can't request MMC write protect: %d\n", + err); + goto err_gpio_wp; + } + gpio_direction_input(GPIO95_MMC_WP); + } else { + err = gpio_request(GPIO38_SD_PWEN, "sdio power"); + if (err) { + dev_err(dev, "can't request MMC power control : %d\n", + err); + goto err_gpio_wp; + } + gpio_direction_output(GPIO38_SD_PWEN, 1); + } + + return 0; + +err_gpio_wp: + free_irq(gpio_to_irq(mmc_cd), data); +err_irq: + regulator_put(em_x270_sdio_ldo); + + return err; +} + +static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data* p_d = dev->platform_data; + + if ((1 << vdd) & p_d->ocr_mask) { + int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000; + + regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV); + regulator_enable(em_x270_sdio_ldo); + } else { + regulator_disable(em_x270_sdio_ldo); + } +} + +static void em_x270_mci_exit(struct device *dev, void *data) +{ + free_irq(gpio_to_irq(mmc_cd), data); + regulator_put(em_x270_sdio_ldo); + + if (machine_is_em_x270()) + gpio_free(GPIO95_MMC_WP); + else + gpio_free(GPIO38_SD_PWEN); +} + +static int em_x270_mci_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO95_MMC_WP); +} + +static struct pxamci_platform_data em_x270_mci_platform_data = { + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23| + MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27| + MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30| + MMC_VDD_30_31|MMC_VDD_31_32, + .init = em_x270_mci_init, + .setpower = em_x270_mci_setpower, + .exit = em_x270_mci_exit, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +static void __init em_x270_init_mmc(void) +{ + if (machine_is_em_x270()) + em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro; + + pxa_set_mci_info(&em_x270_mci_platform_data); +} +#else +static inline void em_x270_init_mmc(void) {} +#endif + +/* LCD */ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info em_x270_lcd_modes[] = { + [0] = { + .pixclock = 38250, + .bpp = 16, + .xres = 480, + .yres = 640, + .hsync_len = 8, + .vsync_len = 2, + .left_margin = 8, + .upper_margin = 2, + .right_margin = 24, + .lower_margin = 4, + .sync = 0, + }, + [1] = { + .pixclock = 153800, + .bpp = 16, + .xres = 240, + .yres = 320, + .hsync_len = 8, + .vsync_len = 2, + .left_margin = 8, + .upper_margin = 2, + .right_margin = 88, + .lower_margin = 2, + .sync = 0, + }, +}; + +static struct pxafb_mach_info em_x270_lcd = { + .modes = em_x270_lcd_modes, + .num_modes = 2, + .lcd_conn = LCD_COLOR_TFT_16BPP, +}; + +static void __init em_x270_init_lcd(void) +{ + pxa_set_fb_info(NULL, &em_x270_lcd); +} +#else +static inline void em_x270_init_lcd(void) {} +#endif + +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +static struct pxa2xx_spi_master em_x270_spi_info = { + .num_chipselect = 1, +}; + +static struct pxa2xx_spi_chip em_x270_tdo24m_chip = { + .rx_threshold = 1, + .tx_threshold = 1, + .gpio_cs = -1, +}; + +static struct tdo24m_platform_data em_x270_tdo24m_pdata = { + .model = TDO35S, +}; + +static struct pxa2xx_spi_master em_x270_spi_2_info = { + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct pxa2xx_spi_chip em_x270_libertas_chip = { + .rx_threshold = 1, + .tx_threshold = 1, + .timeout = 1000, + .gpio_cs = 14, +}; + +static unsigned long em_x270_libertas_pin_config[] = { + /* SSP2 */ + GPIO19_SSP2_SCLK, + GPIO14_GPIO, + GPIO89_SSP2_TXD, + GPIO88_SSP2_RXD, +}; + +static int em_x270_libertas_setup(struct spi_device *spi) +{ + int err = gpio_request(GPIO115_WLAN_PWEN, "WLAN PWEN"); + if (err) + return err; + + err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP"); + if (err) + goto err_free_pwen; + + if (machine_is_exeda()) { + err = gpio_request(GPIO37_WLAN_RST, "WLAN RST"); + if (err) + goto err_free_strap; + + gpio_direction_output(GPIO37_WLAN_RST, 1); + msleep(100); + } + + gpio_direction_output(GPIO19_WLAN_STRAP, 1); + msleep(100); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config)); + + gpio_direction_output(GPIO115_WLAN_PWEN, 0); + msleep(100); + gpio_set_value(GPIO115_WLAN_PWEN, 1); + msleep(100); + + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; + +err_free_strap: + gpio_free(GPIO19_WLAN_STRAP); +err_free_pwen: + gpio_free(GPIO115_WLAN_PWEN); + + return err; +} + +static int em_x270_libertas_teardown(struct spi_device *spi) +{ + gpio_set_value(GPIO115_WLAN_PWEN, 0); + gpio_free(GPIO115_WLAN_PWEN); + gpio_free(GPIO19_WLAN_STRAP); + + if (machine_is_exeda()) { + gpio_set_value(GPIO37_WLAN_RST, 0); + gpio_free(GPIO37_WLAN_RST); + } + + return 0; +} + +struct libertas_spi_platform_data em_x270_libertas_pdata = { + .use_dummy_writes = 1, + .setup = em_x270_libertas_setup, + .teardown = em_x270_libertas_teardown, +}; + +static struct spi_board_info em_x270_spi_devices[] __initdata = { + { + .modalias = "tdo24m", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 0, + .controller_data = &em_x270_tdo24m_chip, + .platform_data = &em_x270_tdo24m_pdata, + }, + { + .modalias = "libertas_spi", + .max_speed_hz = 13000000, + .bus_num = 2, + .irq = PXA_GPIO_TO_IRQ(116), + .chip_select = 0, + .controller_data = &em_x270_libertas_chip, + .platform_data = &em_x270_libertas_pdata, + }, +}; + +static void __init em_x270_init_spi(void) +{ + pxa2xx_set_spi_info(1, &em_x270_spi_info); + pxa2xx_set_spi_info(2, &em_x270_spi_2_info); + spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices)); +} +#else +static inline void em_x270_init_spi(void) {} +#endif + +#if defined(CONFIG_SND_PXA2XX_LIB_AC97) +static pxa2xx_audio_ops_t em_x270_ac97_info = { + .reset_gpio = 113, +}; + +static void __init em_x270_init_ac97(void) +{ + pxa_set_ac97_info(&em_x270_ac97_info); +} +#else +static inline void em_x270_init_ac97(void) {} +#endif + +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static unsigned int em_x270_module_matrix_keys[] = { + KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B), + KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT), + KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D), +}; + +struct pxa27x_keypad_platform_data em_x270_module_keypad_info = { + /* code map for the matrix keys */ + .matrix_key_rows = 3, + .matrix_key_cols = 3, + .matrix_key_map = em_x270_module_matrix_keys, + .matrix_key_map_size = ARRAY_SIZE(em_x270_module_matrix_keys), +}; + +static unsigned int em_x270_exeda_matrix_keys[] = { + KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL), + KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE), + KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL), + KEY(0, 6, KEY_ENTER), KEY(0, 7, KEY_SLASH), + + KEY(1, 0, KEY_DOT), KEY(1, 1, KEY_M), + KEY(1, 2, KEY_N), KEY(1, 3, KEY_B), + KEY(1, 4, KEY_V), KEY(1, 5, KEY_C), + KEY(1, 6, KEY_X), KEY(1, 7, KEY_Z), + + KEY(2, 0, KEY_LEFTSHIFT), KEY(2, 1, KEY_SEMICOLON), + KEY(2, 2, KEY_L), KEY(2, 3, KEY_K), + KEY(2, 4, KEY_J), KEY(2, 5, KEY_H), + KEY(2, 6, KEY_G), KEY(2, 7, KEY_F), + + KEY(3, 0, KEY_D), KEY(3, 1, KEY_S), + KEY(3, 2, KEY_A), KEY(3, 3, KEY_TAB), + KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_P), + KEY(3, 6, KEY_O), KEY(3, 7, KEY_I), + + KEY(4, 0, KEY_U), KEY(4, 1, KEY_Y), + KEY(4, 2, KEY_T), KEY(4, 3, KEY_R), + KEY(4, 4, KEY_E), KEY(4, 5, KEY_W), + KEY(4, 6, KEY_Q), KEY(4, 7, KEY_MINUS), + + KEY(5, 0, KEY_0), KEY(5, 1, KEY_9), + KEY(5, 2, KEY_8), KEY(5, 3, KEY_7), + KEY(5, 4, KEY_6), KEY(5, 5, KEY_5), + KEY(5, 6, KEY_4), KEY(5, 7, KEY_3), + + KEY(6, 0, KEY_2), KEY(6, 1, KEY_1), + KEY(6, 2, KEY_ENTER), KEY(6, 3, KEY_END), + KEY(6, 4, KEY_DOWN), KEY(6, 5, KEY_UP), + KEY(6, 6, KEY_MENU), KEY(6, 7, KEY_F1), + + KEY(7, 0, KEY_LEFT), KEY(7, 1, KEY_RIGHT), + KEY(7, 2, KEY_BACK), KEY(7, 3, KEY_HOME), + KEY(7, 4, 0), KEY(7, 5, 0), + KEY(7, 6, 0), KEY(7, 7, 0), +}; + +struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = { + /* code map for the matrix keys */ + .matrix_key_rows = 8, + .matrix_key_cols = 8, + .matrix_key_map = em_x270_exeda_matrix_keys, + .matrix_key_map_size = ARRAY_SIZE(em_x270_exeda_matrix_keys), +}; + +static void __init em_x270_init_keypad(void) +{ + if (machine_is_em_x270()) + pxa_set_keypad_info(&em_x270_module_keypad_info); + else + pxa_set_keypad_info(&em_x270_exeda_keypad_info); +} +#else +static inline void em_x270_init_keypad(void) {} +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button gpio_keys_button[] = { + [0] = { + .desc = "sleep/wakeup", + .code = KEY_SUSPEND, + .type = EV_PWR, + .gpio = 1, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data em_x270_gpio_keys_data = { + .buttons = gpio_keys_button, + .nbuttons = 1, +}; + +static struct platform_device em_x270_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &em_x270_gpio_keys_data, + }, +}; + +static void __init em_x270_init_gpio_keys(void) +{ + platform_device_register(&em_x270_gpio_keys); +} +#else +static inline void em_x270_init_gpio_keys(void) {} +#endif + +/* Quick Capture Interface and sensor setup */ +#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) +static struct regulator *em_x270_camera_ldo; + +static int em_x270_sensor_init(void) +{ + int ret; + + ret = gpio_request(cam_reset, "camera reset"); + if (ret) + return ret; + + gpio_direction_output(cam_reset, 0); + + em_x270_camera_ldo = regulator_get(NULL, "vcc cam"); + if (em_x270_camera_ldo == NULL) { + gpio_free(cam_reset); + return -ENODEV; + } + + ret = regulator_enable(em_x270_camera_ldo); + if (ret) { + regulator_put(em_x270_camera_ldo); + gpio_free(cam_reset); + return ret; + } + + gpio_set_value(cam_reset, 1); + + return 0; +} + +struct pxacamera_platform_data em_x270_camera_platform_data = { + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, + .mclk_10khz = 2600, +}; + +static int em_x270_sensor_power(struct device *dev, int on) +{ + int ret; + int is_on = regulator_is_enabled(em_x270_camera_ldo); + + if (on == is_on) + return 0; + + gpio_set_value(cam_reset, !on); + + if (on) + ret = regulator_enable(em_x270_camera_ldo); + else + ret = regulator_disable(em_x270_camera_ldo); + + if (ret) + return ret; + + gpio_set_value(cam_reset, on); + + return 0; +} + +static struct i2c_board_info em_x270_i2c_cam_info[] = { + { + I2C_BOARD_INFO("mt9m111", 0x48), + }, +}; + +static struct soc_camera_link iclink = { + .bus_id = 0, + .power = em_x270_sensor_power, + .board_info = &em_x270_i2c_cam_info[0], + .i2c_adapter_id = 0, +}; + +static struct platform_device em_x270_camera = { + .name = "soc-camera-pdrv", + .id = -1, + .dev = { + .platform_data = &iclink, + }, +}; + +static void __init em_x270_init_camera(void) +{ + if (em_x270_sensor_init() == 0) { + pxa_set_camera_info(&em_x270_camera_platform_data); + platform_device_register(&em_x270_camera); + } +} +#else +static inline void em_x270_init_camera(void) {} +#endif + +static struct regulator_bulk_data em_x270_gps_consumer_supply = { + .supply = "vcc gps", +}; + +static struct regulator_userspace_consumer_data em_x270_gps_consumer_data = { + .name = "vcc gps", + .num_supplies = 1, + .supplies = &em_x270_gps_consumer_supply, +}; + +static struct platform_device em_x270_gps_userspace_consumer = { + .name = "reg-userspace-consumer", + .id = 0, + .dev = { + .platform_data = &em_x270_gps_consumer_data, + }, +}; + +static struct regulator_bulk_data em_x270_gprs_consumer_supply = { + .supply = "vcc gprs", +}; + +static struct regulator_userspace_consumer_data em_x270_gprs_consumer_data = { + .name = "vcc gprs", + .num_supplies = 1, + .supplies = &em_x270_gprs_consumer_supply +}; + +static struct platform_device em_x270_gprs_userspace_consumer = { + .name = "reg-userspace-consumer", + .id = 1, + .dev = { + .platform_data = &em_x270_gprs_consumer_data, + } +}; + +static struct platform_device *em_x270_userspace_consumers[] = { + &em_x270_gps_userspace_consumer, + &em_x270_gprs_userspace_consumer, +}; + +static void __init em_x270_userspace_consumers_init(void) +{ + platform_add_devices(ARRAY_AND_SIZE(em_x270_userspace_consumers)); +} + +/* DA9030 related initializations */ +#define REGULATOR_CONSUMER(_name, _dev, _supply) \ + static struct regulator_consumer_supply _name##_consumers[] = { \ + { \ + .dev = _dev, \ + .supply = _supply, \ + }, \ + } + +REGULATOR_CONSUMER(ldo3, &em_x270_gps_userspace_consumer.dev, "vcc gps"); +REGULATOR_CONSUMER(ldo5, NULL, "vcc cam"); +REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio"); +REGULATOR_CONSUMER(ldo12, NULL, "vcc usb"); +REGULATOR_CONSUMER(ldo19, &em_x270_gprs_userspace_consumer.dev, "vcc gprs"); +REGULATOR_CONSUMER(buck2, NULL, "vcc_core"); + +#define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \ + static struct regulator_init_data _ldo##_data = { \ + .constraints = { \ + .min_uV = _min_uV, \ + .max_uV = _max_uV, \ + .state_mem = { \ + .enabled = 0, \ + }, \ + .valid_ops_mask = _ops_mask, \ + .apply_uV = 1, \ + }, \ + .num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers), \ + .consumer_supplies = _ldo##_consumers, \ + }; + +REGULATOR_INIT(ldo3, 3200000, 3200000, REGULATOR_CHANGE_STATUS); +REGULATOR_INIT(ldo5, 3000000, 3000000, REGULATOR_CHANGE_STATUS); +REGULATOR_INIT(ldo10, 2000000, 3200000, + REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE); +REGULATOR_INIT(ldo12, 3000000, 3000000, REGULATOR_CHANGE_STATUS); +REGULATOR_INIT(ldo19, 3200000, 3200000, REGULATOR_CHANGE_STATUS); +REGULATOR_INIT(buck2, 1000000, 1650000, REGULATOR_CHANGE_VOLTAGE); + +struct led_info em_x270_led_info = { + .name = "em-x270:orange", + .default_trigger = "battery-charging-or-full", +}; + +struct power_supply_info em_x270_psy_info = { + .name = "battery", + .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, + .voltage_max_design = 4200000, + .voltage_min_design = 3000000, + .use_for_apm = 1, +}; + +static void em_x270_battery_low(void) +{ +#if defined(CONFIG_APM_EMULATION) + apm_queue_event(APM_LOW_BATTERY); +#endif +} + +static void em_x270_battery_critical(void) +{ +#if defined(CONFIG_APM_EMULATION) + apm_queue_event(APM_CRITICAL_SUSPEND); +#endif +} + +struct da9030_battery_info em_x270_batterty_info = { + .battery_info = &em_x270_psy_info, + + .charge_milliamp = 1000, + .charge_millivolt = 4200, + + .vbat_low = 3600, + .vbat_crit = 3400, + .vbat_charge_start = 4100, + .vbat_charge_stop = 4200, + .vbat_charge_restart = 4000, + + .vcharge_min = 3200, + .vcharge_max = 5500, + + .tbat_low = 197, + .tbat_high = 78, + .tbat_restart = 100, + + .batmon_interval = 0, + + .battery_low = em_x270_battery_low, + .battery_critical = em_x270_battery_critical, +}; + +#define DA9030_SUBDEV(_name, _id, _pdata) \ + { \ + .name = "da903x-" #_name, \ + .id = DA9030_ID_##_id, \ + .platform_data = _pdata, \ + } + +#define DA9030_LDO(num) DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data) + +struct da903x_subdev_info em_x270_da9030_subdevs[] = { + DA9030_LDO(3), + DA9030_LDO(5), + DA9030_LDO(10), + DA9030_LDO(12), + DA9030_LDO(19), + + DA9030_SUBDEV(regulator, BUCK2, &buck2_data), + + DA9030_SUBDEV(led, LED_PC, &em_x270_led_info), + DA9030_SUBDEV(backlight, WLED, &em_x270_led_info), + DA9030_SUBDEV(battery, BAT, &em_x270_batterty_info), +}; + +static struct da903x_platform_data em_x270_da9030_info = { + .num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs), + .subdevs = em_x270_da9030_subdevs, +}; + +static struct i2c_board_info em_x270_i2c_pmic_info = { + I2C_BOARD_INFO("da9030", 0x49), + .irq = PXA_GPIO_TO_IRQ(0), + .platform_data = &em_x270_da9030_info, +}; + +static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = { + .use_pio = 1, +}; + +static void __init em_x270_init_da9030(void) +{ + pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info); + i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1); +} + +static struct pca953x_platform_data exeda_gpio_ext_pdata = { + .gpio_base = 128, +}; + +static struct i2c_board_info exeda_i2c_info[] = { + { + I2C_BOARD_INFO("pca9555", 0x21), + .platform_data = &exeda_gpio_ext_pdata, + }, +}; + +static struct i2c_pxa_platform_data em_x270_i2c_info = { + .fast_mode = 1, +}; + +static void __init em_x270_init_i2c(void) +{ + pxa_set_i2c_info(&em_x270_i2c_info); + + if (machine_is_exeda()) + i2c_register_board_info(0, ARRAY_AND_SIZE(exeda_i2c_info)); +} + +static void __init em_x270_module_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config)); + + mmc_cd = GPIO13_MMC_CD; + nand_rb = GPIO56_NAND_RB; + dm9000_flags = DM9000_PLATF_32BITONLY; + cam_reset = GPIO93_CAM_RESET; + usb_hub_reset = GPIO16_USB_HUB_RESET; +} + +static void __init em_x270_exeda_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(exeda_pin_config)); + + mmc_cd = GPIO114_MMC_CD; + nand_rb = GPIO20_NAND_RB; + dm9000_flags = DM9000_PLATF_16BITONLY; + cam_reset = GPIO130_CAM_RESET; + usb_hub_reset = GPIO10_USB_HUB_RESET; +} + +static void __init em_x270_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + +#ifdef CONFIG_PM + pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP); +#endif + + if (machine_is_em_x270()) + em_x270_module_init(); + else if (machine_is_exeda()) + em_x270_exeda_init(); + else + panic("Unsupported machine: %d\n", machine_arch_type); + + em_x270_init_da9030(); + em_x270_init_dm9000(); + em_x270_init_rtc(); + em_x270_init_nand(); + em_x270_init_nor(); + em_x270_init_lcd(); + em_x270_init_mmc(); + em_x270_init_ohci(); + em_x270_init_keypad(); + em_x270_init_gpio_keys(); + em_x270_init_ac97(); + em_x270_init_spi(); + em_x270_init_i2c(); + em_x270_init_camera(); + em_x270_userspace_consumers_init(); +} + +MACHINE_START(EM_X270, "Compulab EM-X270") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = em_x270_init, + .restart = pxa_restart, +MACHINE_END + +MACHINE_START(EXEDA, "Compulab eXeda") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = em_x270_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c new file mode 100644 index 00000000000..4cb2391a782 --- /dev/null +++ b/arch/arm/mach-pxa/eseries.c @@ -0,0 +1,983 @@ +/* + * Hardware definitions for the Toshiba eseries PDAs + * + * Copyright (c) 2003 Ian Molton <spyro@f2s.com> + * + * This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/mfd/tc6387xb.h> +#include <linux/mfd/tc6393xb.h> +#include <linux/mfd/t7l66xb.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/usb/gpio_vbus.h> + +#include <video/w100fb.h> + +#include <asm/setup.h> +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +#include <mach/pxa25x.h> +#include <mach/eseries-gpio.h> +#include <mach/eseries-irq.h> +#include <mach/audio.h> +#include <mach/pxafb.h> +#include <mach/udc.h> +#include <mach/irda.h> + +#include "devices.h" +#include "generic.h" +#include "clock.h" + +/* Only e800 has 128MB RAM */ +void __init eseries_fixup(struct tag *tags, char **cmdline, struct meminfo *mi) +{ + mi->nr_banks=1; + mi->bank[0].start = 0xa0000000; + if (machine_is_e800()) + mi->bank[0].size = (128*1024*1024); + else + mi->bank[0].size = (64*1024*1024); +} + +struct gpio_vbus_mach_info e7xx_udc_info = { + .gpio_vbus = GPIO_E7XX_USB_DISC, + .gpio_pullup = GPIO_E7XX_USB_PULLUP, + .gpio_pullup_inverted = 1 +}; + +static struct platform_device e7xx_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &e7xx_udc_info, + }, +}; + +struct pxaficp_platform_data e7xx_ficp_platform_data = { + .gpio_pwdown = GPIO_E7XX_IR_OFF, + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; + +int eseries_tmio_enable(struct platform_device *dev) +{ + /* Reset - bring SUSPEND high before PCLR */ + gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0); + gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0); + msleep(1); + gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1); + msleep(1); + gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 1); + msleep(1); + return 0; +} + +int eseries_tmio_disable(struct platform_device *dev) +{ + gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0); + gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0); + return 0; +} + +int eseries_tmio_suspend(struct platform_device *dev) +{ + gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0); + return 0; +} + +int eseries_tmio_resume(struct platform_device *dev) +{ + gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1); + msleep(1); + return 0; +} + +void eseries_get_tmio_gpios(void) +{ + gpio_request(GPIO_ESERIES_TMIO_SUSPEND, NULL); + gpio_request(GPIO_ESERIES_TMIO_PCLR, NULL); + gpio_direction_output(GPIO_ESERIES_TMIO_SUSPEND, 0); + gpio_direction_output(GPIO_ESERIES_TMIO_PCLR, 0); +} + +/* TMIO controller uses the same resources on all e-series machines. */ +struct resource eseries_tmio_resources[] = { + [0] = { + .start = PXA_CS4_PHYS, + .end = PXA_CS4_PHYS + 0x1fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +/* Some e-series hardware cannot control the 32K clock */ +static void clk_32k_dummy(struct clk *clk) +{ +} + +static const struct clkops clk_32k_dummy_ops = { + .enable = clk_32k_dummy, + .disable = clk_32k_dummy, +}; + +static struct clk tmio_dummy_clk = { + .ops = &clk_32k_dummy_ops, + .rate = 32768, +}; + +static struct clk_lookup eseries_clkregs[] = { + INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"), +}; + +static void __init eseries_register_clks(void) +{ + clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs)); +} + +#ifdef CONFIG_MACH_E330 +/* -------------------- e330 tc6387xb parameters -------------------- */ + +static struct tc6387xb_platform_data e330_tc6387xb_info = { + .enable = &eseries_tmio_enable, + .disable = &eseries_tmio_disable, + .suspend = &eseries_tmio_suspend, + .resume = &eseries_tmio_resume, +}; + +static struct platform_device e330_tc6387xb_device = { + .name = "tc6387xb", + .id = -1, + .dev = { + .platform_data = &e330_tc6387xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; + +/* --------------------------------------------------------------- */ + +static struct platform_device *e330_devices[] __initdata = { + &e330_tc6387xb_device, + &e7xx_gpio_vbus, +}; + +static void __init e330_init(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + eseries_register_clks(); + eseries_get_tmio_gpios(); + platform_add_devices(ARRAY_AND_SIZE(e330_devices)); +} + +MACHINE_START(E330, "Toshiba e330") + /* Maintainer: Ian Molton (spyro@f2s.com) */ + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = ESERIES_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .fixup = eseries_fixup, + .init_machine = e330_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_E350 +/* -------------------- e350 t7l66xb parameters -------------------- */ + +static struct t7l66xb_platform_data e350_t7l66xb_info = { + .irq_base = IRQ_BOARD_START, + .enable = &eseries_tmio_enable, + .suspend = &eseries_tmio_suspend, + .resume = &eseries_tmio_resume, +}; + +static struct platform_device e350_t7l66xb_device = { + .name = "t7l66xb", + .id = -1, + .dev = { + .platform_data = &e350_t7l66xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; + +/* ---------------------------------------------------------- */ + +static struct platform_device *e350_devices[] __initdata = { + &e350_t7l66xb_device, + &e7xx_gpio_vbus, +}; + +static void __init e350_init(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + eseries_register_clks(); + eseries_get_tmio_gpios(); + platform_add_devices(ARRAY_AND_SIZE(e350_devices)); +} + +MACHINE_START(E350, "Toshiba e350") + /* Maintainer: Ian Molton (spyro@f2s.com) */ + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = ESERIES_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .fixup = eseries_fixup, + .init_machine = e350_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_E400 +/* ------------------------ E400 LCD definitions ------------------------ */ + +static struct pxafb_mode_info e400_pxafb_mode_info = { + .pixclock = 140703, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 4, + .left_margin = 28, + .right_margin = 8, + .vsync_len = 3, + .upper_margin = 5, + .lower_margin = 6, + .sync = 0, +}; + +static struct pxafb_mach_info e400_pxafb_mach_info = { + .modes = &e400_pxafb_mode_info, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP, + .lccr3 = 0, + .pxafb_backlight_power = NULL, +}; + +/* ------------------------ E400 MFP config ----------------------------- */ + +static unsigned long e400_pin_config[] __initdata = { + /* Chip selects */ + GPIO15_nCS_1, /* CS1 - Flash */ + GPIO80_nCS_4, /* CS4 - TMIO */ + + /* Clocks */ + GPIO12_32KHz, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + + /* TMIO controller */ + GPIO19_GPIO, /* t7l66xb #PCLR */ + GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */ + + /* wakeup */ + GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, +}; + +/* ---------------------------------------------------------------------- */ + +static struct mtd_partition partition_a = { + .name = "Internal NAND flash", + .offset = 0, + .size = MTDPART_SIZ_FULL, +}; + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr e400_t7l66xb_nand_bbt = { + .options = 0, + .offs = 4, + .len = 2, + .pattern = scan_ff_pattern +}; + +static struct tmio_nand_data e400_t7l66xb_nand_config = { + .num_partitions = 1, + .partition = &partition_a, + .badblock_pattern = &e400_t7l66xb_nand_bbt, +}; + +static struct t7l66xb_platform_data e400_t7l66xb_info = { + .irq_base = IRQ_BOARD_START, + .enable = &eseries_tmio_enable, + .suspend = &eseries_tmio_suspend, + .resume = &eseries_tmio_resume, + + .nand_data = &e400_t7l66xb_nand_config, +}; + +static struct platform_device e400_t7l66xb_device = { + .name = "t7l66xb", + .id = -1, + .dev = { + .platform_data = &e400_t7l66xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; + +/* ---------------------------------------------------------- */ + +static struct platform_device *e400_devices[] __initdata = { + &e400_t7l66xb_device, + &e7xx_gpio_vbus, +}; + +static void __init e400_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + /* Fixme - e400 may have a switched clock */ + eseries_register_clks(); + eseries_get_tmio_gpios(); + pxa_set_fb_info(NULL, &e400_pxafb_mach_info); + platform_add_devices(ARRAY_AND_SIZE(e400_devices)); +} + +MACHINE_START(E400, "Toshiba e400") + /* Maintainer: Ian Molton (spyro@f2s.com) */ + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = ESERIES_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .fixup = eseries_fixup, + .init_machine = e400_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_E740 +/* ------------------------ e740 video support --------------------------- */ + +static struct w100_gen_regs e740_lcd_regs = { + .lcd_format = 0x00008023, + .lcdd_cntl1 = 0x0f000000, + .lcdd_cntl2 = 0x0003ffff, + .genlcd_cntl1 = 0x00ffff03, + .genlcd_cntl2 = 0x003c0f03, + .genlcd_cntl3 = 0x000143aa, +}; + +static struct w100_mode e740_lcd_mode = { + .xres = 240, + .yres = 320, + .left_margin = 20, + .right_margin = 28, + .upper_margin = 9, + .lower_margin = 8, + .crtc_ss = 0x80140013, + .crtc_ls = 0x81150110, + .crtc_gs = 0x80050005, + .crtc_vpos_gs = 0x000a0009, + .crtc_rev = 0x0040010a, + .crtc_dclk = 0xa906000a, + .crtc_gclk = 0x80050108, + .crtc_goe = 0x80050108, + .pll_freq = 57, + .pixclk_divider = 4, + .pixclk_divider_rotated = 4, + .pixclk_src = CLK_SRC_XTAL, + .sysclk_divider = 1, + .sysclk_src = CLK_SRC_PLL, + .crtc_ps1_active = 0x41060010, +}; + +static struct w100_gpio_regs e740_w100_gpio_info = { + .init_data1 = 0x21002103, + .gpio_dir1 = 0xffffdeff, + .gpio_oe1 = 0x03c00643, + .init_data2 = 0x003f003f, + .gpio_dir2 = 0xffffffff, + .gpio_oe2 = 0x000000ff, +}; + +static struct w100fb_mach_info e740_fb_info = { + .modelist = &e740_lcd_mode, + .num_modes = 1, + .regs = &e740_lcd_regs, + .gpio = &e740_w100_gpio_info, + .xtal_freq = 14318000, + .xtal_dbl = 1, +}; + +static struct resource e740_fb_resources[] = { + [0] = { + .start = 0x0c000000, + .end = 0x0cffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device e740_fb_device = { + .name = "w100fb", + .id = -1, + .dev = { + .platform_data = &e740_fb_info, + }, + .num_resources = ARRAY_SIZE(e740_fb_resources), + .resource = e740_fb_resources, +}; + +/* --------------------------- MFP Pin config -------------------------- */ + +static unsigned long e740_pin_config[] __initdata = { + /* Chip selects */ + GPIO15_nCS_1, /* CS1 - Flash */ + GPIO79_nCS_3, /* CS3 - IMAGEON */ + GPIO80_nCS_4, /* CS4 - TMIO */ + + /* Clocks */ + GPIO12_32KHz, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + + /* TMIO controller */ + GPIO19_GPIO, /* t7l66xb #PCLR */ + GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */ + + /* UDC */ + GPIO13_GPIO, + GPIO3_GPIO, + + /* IrDA */ + GPIO38_GPIO | MFP_LPM_DRIVE_HIGH, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* Audio power control */ + GPIO16_GPIO, /* AC97 codec AVDD2 supply (analogue power) */ + GPIO40_GPIO, /* Mic amp power */ + GPIO41_GPIO, /* Headphone amp power */ + + /* PC Card */ + GPIO8_GPIO, /* CD0 */ + GPIO44_GPIO, /* CD1 */ + GPIO11_GPIO, /* IRQ0 */ + GPIO6_GPIO, /* IRQ1 */ + GPIO27_GPIO, /* RST0 */ + GPIO24_GPIO, /* RST1 */ + GPIO20_GPIO, /* PWR0 */ + GPIO23_GPIO, /* PWR1 */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO54_nPSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* wakeup */ + GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, +}; + +/* -------------------- e740 t7l66xb parameters -------------------- */ + +static struct t7l66xb_platform_data e740_t7l66xb_info = { + .irq_base = IRQ_BOARD_START, + .enable = &eseries_tmio_enable, + .suspend = &eseries_tmio_suspend, + .resume = &eseries_tmio_resume, +}; + +static struct platform_device e740_t7l66xb_device = { + .name = "t7l66xb", + .id = -1, + .dev = { + .platform_data = &e740_t7l66xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; + +static struct platform_device e740_audio_device = { + .name = "e740-audio", + .id = -1, +}; + +/* ----------------------------------------------------------------------- */ + +static struct platform_device *e740_devices[] __initdata = { + &e740_fb_device, + &e740_t7l66xb_device, + &e7xx_gpio_vbus, + &e740_audio_device, +}; + +static void __init e740_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + eseries_register_clks(); + clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name, + "UDCCLK", &pxa25x_device_udc.dev), + eseries_get_tmio_gpios(); + platform_add_devices(ARRAY_AND_SIZE(e740_devices)); + pxa_set_ac97_info(NULL); + pxa_set_ficp_info(&e7xx_ficp_platform_data); +} + +MACHINE_START(E740, "Toshiba e740") + /* Maintainer: Ian Molton (spyro@f2s.com) */ + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = ESERIES_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .fixup = eseries_fixup, + .init_machine = e740_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_E750 +/* ---------------------- E750 LCD definitions -------------------- */ + +static struct w100_gen_regs e750_lcd_regs = { + .lcd_format = 0x00008003, + .lcdd_cntl1 = 0x00000000, + .lcdd_cntl2 = 0x0003ffff, + .genlcd_cntl1 = 0x00fff003, + .genlcd_cntl2 = 0x003c0f03, + .genlcd_cntl3 = 0x000143aa, +}; + +static struct w100_mode e750_lcd_mode = { + .xres = 240, + .yres = 320, + .left_margin = 21, + .right_margin = 22, + .upper_margin = 5, + .lower_margin = 4, + .crtc_ss = 0x80150014, + .crtc_ls = 0x8014000d, + .crtc_gs = 0xc1000005, + .crtc_vpos_gs = 0x00020147, + .crtc_rev = 0x0040010a, + .crtc_dclk = 0xa1700030, + .crtc_gclk = 0x80cc0015, + .crtc_goe = 0x80cc0015, + .crtc_ps1_active = 0x61060017, + .pll_freq = 57, + .pixclk_divider = 4, + .pixclk_divider_rotated = 4, + .pixclk_src = CLK_SRC_XTAL, + .sysclk_divider = 1, + .sysclk_src = CLK_SRC_PLL, +}; + +static struct w100_gpio_regs e750_w100_gpio_info = { + .init_data1 = 0x01192f1b, + .gpio_dir1 = 0xd5ffdeff, + .gpio_oe1 = 0x000020bf, + .init_data2 = 0x010f010f, + .gpio_dir2 = 0xffffffff, + .gpio_oe2 = 0x000001cf, +}; + +static struct w100fb_mach_info e750_fb_info = { + .modelist = &e750_lcd_mode, + .num_modes = 1, + .regs = &e750_lcd_regs, + .gpio = &e750_w100_gpio_info, + .xtal_freq = 14318000, + .xtal_dbl = 1, +}; + +static struct resource e750_fb_resources[] = { + [0] = { + .start = 0x0c000000, + .end = 0x0cffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device e750_fb_device = { + .name = "w100fb", + .id = -1, + .dev = { + .platform_data = &e750_fb_info, + }, + .num_resources = ARRAY_SIZE(e750_fb_resources), + .resource = e750_fb_resources, +}; + +/* -------------------- e750 MFP parameters -------------------- */ + +static unsigned long e750_pin_config[] __initdata = { + /* Chip selects */ + GPIO15_nCS_1, /* CS1 - Flash */ + GPIO79_nCS_3, /* CS3 - IMAGEON */ + GPIO80_nCS_4, /* CS4 - TMIO */ + + /* Clocks */ + GPIO11_3_6MHz, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + + /* TMIO controller */ + GPIO19_GPIO, /* t7l66xb #PCLR */ + GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */ + + /* UDC */ + GPIO13_GPIO, + GPIO3_GPIO, + + /* IrDA */ + GPIO38_GPIO | MFP_LPM_DRIVE_HIGH, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* Audio power control */ + GPIO4_GPIO, /* Headphone amp power */ + GPIO7_GPIO, /* Speaker amp power */ + GPIO37_GPIO, /* Headphone detect */ + + /* PC Card */ + GPIO8_GPIO, /* CD0 */ + GPIO44_GPIO, /* CD1 */ + GPIO11_GPIO, /* IRQ0 */ + GPIO6_GPIO, /* IRQ1 */ + GPIO27_GPIO, /* RST0 */ + GPIO24_GPIO, /* RST1 */ + GPIO20_GPIO, /* PWR0 */ + GPIO23_GPIO, /* PWR1 */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO54_nPSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* wakeup */ + GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, +}; + +/* ----------------- e750 tc6393xb parameters ------------------ */ + +static struct tc6393xb_platform_data e750_tc6393xb_info = { + .irq_base = IRQ_BOARD_START, + .scr_pll2cr = 0x0cc1, + .scr_gper = 0, + .gpio_base = -1, + .suspend = &eseries_tmio_suspend, + .resume = &eseries_tmio_resume, + .enable = &eseries_tmio_enable, + .disable = &eseries_tmio_disable, +}; + +static struct platform_device e750_tc6393xb_device = { + .name = "tc6393xb", + .id = -1, + .dev = { + .platform_data = &e750_tc6393xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; + +static struct platform_device e750_audio_device = { + .name = "e750-audio", + .id = -1, +}; + +/* ------------------------------------------------------------- */ + +static struct platform_device *e750_devices[] __initdata = { + &e750_fb_device, + &e750_tc6393xb_device, + &e7xx_gpio_vbus, + &e750_audio_device, +}; + +static void __init e750_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(e750_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name, + "GPIO11_CLK", NULL), + eseries_get_tmio_gpios(); + platform_add_devices(ARRAY_AND_SIZE(e750_devices)); + pxa_set_ac97_info(NULL); + pxa_set_ficp_info(&e7xx_ficp_platform_data); +} + +MACHINE_START(E750, "Toshiba e750") + /* Maintainer: Ian Molton (spyro@f2s.com) */ + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = ESERIES_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .fixup = eseries_fixup, + .init_machine = e750_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_E800 +/* ------------------------ e800 LCD definitions ------------------------- */ + +static unsigned long e800_pin_config[] __initdata = { + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, +}; + +static struct w100_gen_regs e800_lcd_regs = { + .lcd_format = 0x00008003, + .lcdd_cntl1 = 0x02a00000, + .lcdd_cntl2 = 0x0003ffff, + .genlcd_cntl1 = 0x000ff2a3, + .genlcd_cntl2 = 0x000002a3, + .genlcd_cntl3 = 0x000102aa, +}; + +static struct w100_mode e800_lcd_mode[2] = { + [0] = { + .xres = 480, + .yres = 640, + .left_margin = 52, + .right_margin = 148, + .upper_margin = 2, + .lower_margin = 6, + .crtc_ss = 0x80350034, + .crtc_ls = 0x802b0026, + .crtc_gs = 0x80160016, + .crtc_vpos_gs = 0x00020003, + .crtc_rev = 0x0040001d, + .crtc_dclk = 0xe0000000, + .crtc_gclk = 0x82a50049, + .crtc_goe = 0x80ee001c, + .crtc_ps1_active = 0x00000000, + .pll_freq = 128, + .pixclk_divider = 4, + .pixclk_divider_rotated = 6, + .pixclk_src = CLK_SRC_PLL, + .sysclk_divider = 0, + .sysclk_src = CLK_SRC_PLL, + }, + [1] = { + .xres = 240, + .yres = 320, + .left_margin = 15, + .right_margin = 88, + .upper_margin = 0, + .lower_margin = 7, + .crtc_ss = 0xd010000f, + .crtc_ls = 0x80070003, + .crtc_gs = 0x80000000, + .crtc_vpos_gs = 0x01460147, + .crtc_rev = 0x00400003, + .crtc_dclk = 0xa1700030, + .crtc_gclk = 0x814b0008, + .crtc_goe = 0x80cc0015, + .crtc_ps1_active = 0x00000000, + .pll_freq = 100, + .pixclk_divider = 6, /* Wince uses 14 which gives a */ + .pixclk_divider_rotated = 6, /* 7MHz Pclk. We use a 14MHz one */ + .pixclk_src = CLK_SRC_PLL, + .sysclk_divider = 0, + .sysclk_src = CLK_SRC_PLL, + } +}; + + +static struct w100_gpio_regs e800_w100_gpio_info = { + .init_data1 = 0xc13fc019, + .gpio_dir1 = 0x3e40df7f, + .gpio_oe1 = 0x003c3000, + .init_data2 = 0x00000000, + .gpio_dir2 = 0x00000000, + .gpio_oe2 = 0x00000000, +}; + +static struct w100_mem_info e800_w100_mem_info = { + .ext_cntl = 0x09640011, + .sdram_mode_reg = 0x00600021, + .ext_timing_cntl = 0x10001545, + .io_cntl = 0x7ddd7333, + .size = 0x1fffff, +}; + +static void e800_tg_change(struct w100fb_par *par) +{ + unsigned long tmp; + + tmp = w100fb_gpio_read(W100_GPIO_PORT_A); + if (par->mode->xres == 480) + tmp |= 0x100; + else + tmp &= ~0x100; + w100fb_gpio_write(W100_GPIO_PORT_A, tmp); +} + +static struct w100_tg_info e800_tg_info = { + .change = e800_tg_change, +}; + +static struct w100fb_mach_info e800_fb_info = { + .modelist = e800_lcd_mode, + .num_modes = 2, + .regs = &e800_lcd_regs, + .gpio = &e800_w100_gpio_info, + .mem = &e800_w100_mem_info, + .tg = &e800_tg_info, + .xtal_freq = 16000000, +}; + +static struct resource e800_fb_resources[] = { + [0] = { + .start = 0x0c000000, + .end = 0x0cffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device e800_fb_device = { + .name = "w100fb", + .id = -1, + .dev = { + .platform_data = &e800_fb_info, + }, + .num_resources = ARRAY_SIZE(e800_fb_resources), + .resource = e800_fb_resources, +}; + +/* --------------------------- UDC definitions --------------------------- */ + +static struct gpio_vbus_mach_info e800_udc_info = { + .gpio_vbus = GPIO_E800_USB_DISC, + .gpio_pullup = GPIO_E800_USB_PULLUP, + .gpio_pullup_inverted = 1 +}; + +static struct platform_device e800_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &e800_udc_info, + }, +}; + + +/* ----------------- e800 tc6393xb parameters ------------------ */ + +static struct tc6393xb_platform_data e800_tc6393xb_info = { + .irq_base = IRQ_BOARD_START, + .scr_pll2cr = 0x0cc1, + .scr_gper = 0, + .gpio_base = -1, + .suspend = &eseries_tmio_suspend, + .resume = &eseries_tmio_resume, + .enable = &eseries_tmio_enable, + .disable = &eseries_tmio_disable, +}; + +static struct platform_device e800_tc6393xb_device = { + .name = "tc6393xb", + .id = -1, + .dev = { + .platform_data = &e800_tc6393xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; + +static struct platform_device e800_audio_device = { + .name = "e800-audio", + .id = -1, +}; + +/* ----------------------------------------------------------------------- */ + +static struct platform_device *e800_devices[] __initdata = { + &e800_fb_device, + &e800_tc6393xb_device, + &e800_gpio_vbus, + &e800_audio_device, +}; + +static void __init e800_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(e800_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name, + "GPIO11_CLK", NULL), + eseries_get_tmio_gpios(); + platform_add_devices(ARRAY_AND_SIZE(e800_devices)); + pxa_set_ac97_info(NULL); +} + +MACHINE_START(E800, "Toshiba e800") + /* Maintainer: Ian Molton (spyro@f2s.com) */ + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = ESERIES_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .fixup = eseries_fixup, + .init_machine = e800_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h new file mode 100644 index 00000000000..b96949dd5ad --- /dev/null +++ b/arch/arm/mach-pxa/eseries.h @@ -0,0 +1,14 @@ +void __init eseries_fixup(struct tag *tags, char **cmdline, struct meminfo *mi); + +extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info; +extern struct pxaficp_platform_data e7xx_ficp_platform_data; +extern int e7xx_irda_init(void); + +extern int eseries_tmio_enable(struct platform_device *dev); +extern int eseries_tmio_disable(struct platform_device *dev); +extern int eseries_tmio_suspend(struct platform_device *dev); +extern int eseries_tmio_resume(struct platform_device *dev); +extern void eseries_get_tmio_gpios(void); +extern struct resource eseries_tmio_resources[]; +extern struct platform_device e300_tc6387xb_device; + diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c new file mode 100644 index 00000000000..15ab2533667 --- /dev/null +++ b/arch/arm/mach-pxa/ezx.c @@ -0,0 +1,1243 @@ +/* + * ezx.c - Common code for the EZX platform. + * + * Copyright (C) 2005-2006 Harald Welte <laforge@openezx.org>, + * 2007-2008 Daniel Ribeiro <drwyrm@gmail.com>, + * 2007-2008 Stefan Schmidt <stefan@datenfreihafen.org> + * + * 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/pwm_backlight.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/leds-lp3944.h> +#include <linux/i2c/pxa-i2c.h> + +#include <media/soc_camera.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa27x.h> +#include <mach/pxafb.h> +#include <mach/ohci.h> +#include <mach/hardware.h> +#include <plat/pxa27x_keypad.h> +#include <mach/camera.h> + +#include "devices.h" +#include "generic.h" + +#define EZX_NR_IRQS (IRQ_BOARD_START + 24) + +#define GPIO12_A780_FLIP_LID 12 +#define GPIO15_A1200_FLIP_LID 15 +#define GPIO15_A910_FLIP_LID 15 +#define GPIO12_E680_LOCK_SWITCH 12 +#define GPIO15_E6_LOCK_SWITCH 15 +#define GPIO50_nCAM_EN 50 +#define GPIO19_GEN1_CAM_RST 19 +#define GPIO28_GEN2_CAM_RST 28 + +static struct platform_pwm_backlight_data ezx_backlight_data = { + .pwm_id = 0, + .max_brightness = 1023, + .dft_brightness = 1023, + .pwm_period_ns = 78770, +}; + +static struct platform_device ezx_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &ezx_backlight_data, + }, +}; + +static struct pxafb_mode_info mode_ezx_old = { + .pixclock = 150000, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 10, + .left_margin = 20, + .right_margin = 10, + .vsync_len = 2, + .upper_margin = 3, + .lower_margin = 2, + .sync = 0, +}; + +static struct pxafb_mach_info ezx_fb_info_1 = { + .modes = &mode_ezx_old, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP, +}; + +static struct pxafb_mode_info mode_72r89803y01 = { + .pixclock = 192308, + .xres = 240, + .yres = 320, + .bpp = 32, + .depth = 18, + .hsync_len = 10, + .left_margin = 20, + .right_margin = 10, + .vsync_len = 2, + .upper_margin = 3, + .lower_margin = 2, + .sync = 0, +}; + +static struct pxafb_mach_info ezx_fb_info_2 = { + .modes = &mode_72r89803y01, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_18BPP, +}; + +static struct platform_device *ezx_devices[] __initdata = { + &ezx_backlight_device, +}; + +static unsigned long ezx_pin_config[] __initdata = { + /* PWM backlight */ + GPIO16_PWM0_OUT, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* PCAP SSP */ + GPIO29_SSP1_SCLK, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + GPIO24_GPIO, /* pcap chip select */ + GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* pcap interrupt */ + GPIO4_GPIO | MFP_LPM_DRIVE_HIGH, /* WDI_AP */ + GPIO55_GPIO | MFP_LPM_DRIVE_HIGH, /* SYS_RESTART */ + + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + GPIO11_GPIO, /* mmc detect */ + + /* usb to external transceiver */ + GPIO34_USB_P2_2, + GPIO35_USB_P2_1, + GPIO36_USB_P2_4, + GPIO39_USB_P2_6, + GPIO40_USB_P2_5, + GPIO53_USB_P2_3, + + /* usb to Neptune GSM chip */ + GPIO30_USB_P3_2, + GPIO31_USB_P3_6, + GPIO90_USB_P3_5, + GPIO91_USB_P3_1, + GPIO56_USB_P3_4, + GPIO113_USB_P3_3, +}; + +#if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680) +static unsigned long gen1_pin_config[] __initdata = { + /* flip / lockswitch */ + GPIO12_GPIO | WAKEUP_ON_EDGE_BOTH, + + /* bluetooth (bcm2035) */ + GPIO14_GPIO | WAKEUP_ON_EDGE_RISE, /* HOSTWAKE */ + GPIO48_GPIO, /* RESET */ + GPIO28_GPIO, /* WAKEUP */ + + /* Neptune handshake */ + GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* BP_RDY */ + GPIO57_GPIO | MFP_LPM_DRIVE_HIGH, /* AP_RDY */ + GPIO13_GPIO | WAKEUP_ON_EDGE_BOTH, /* WDI */ + GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* WDI2 */ + GPIO82_GPIO | MFP_LPM_DRIVE_HIGH, /* RESET */ + GPIO99_GPIO | MFP_LPM_DRIVE_HIGH, /* TC_MM_EN */ + + /* sound */ + GPIO52_SSP3_SCLK, + GPIO83_SSP3_SFRM, + GPIO81_SSP3_TXD, + GPIO89_SSP3_RXD, + + /* ssp2 pins to in */ + GPIO22_GPIO, /* SSP2_SCLK */ + GPIO37_GPIO, /* SSP2_SFRM */ + GPIO38_GPIO, /* SSP2_TXD */ + GPIO88_GPIO, /* SSP2_RXD */ + + /* camera */ + GPIO23_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO85_CIF_LV, + GPIO84_CIF_FV, + GPIO27_CIF_DD_0, + GPIO114_CIF_DD_1, + GPIO51_CIF_DD_2, + GPIO115_CIF_DD_3, + GPIO95_CIF_DD_4, + GPIO94_CIF_DD_5, + GPIO17_CIF_DD_6, + GPIO108_CIF_DD_7, + GPIO50_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_EN */ + GPIO19_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_RST */ + + /* EMU */ + GPIO120_GPIO, /* EMU_MUX1 */ + GPIO119_GPIO, /* EMU_MUX2 */ + GPIO86_GPIO, /* SNP_INT_CTL */ + GPIO87_GPIO, /* SNP_INT_IN */ +}; +#endif + +#if defined(CONFIG_MACH_EZX_A1200) || defined(CONFIG_MACH_EZX_A910) || \ + defined(CONFIG_MACH_EZX_E2) || defined(CONFIG_MACH_EZX_E6) +static unsigned long gen2_pin_config[] __initdata = { + /* flip / lockswitch */ + GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH, + + /* EOC */ + GPIO10_GPIO | WAKEUP_ON_EDGE_RISE, + + /* bluetooth (bcm2045) */ + GPIO13_GPIO | WAKEUP_ON_EDGE_RISE, /* HOSTWAKE */ + GPIO37_GPIO, /* RESET */ + GPIO57_GPIO, /* WAKEUP */ + + /* Neptune handshake */ + GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* BP_RDY */ + GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* AP_RDY */ + GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* WDI */ + GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* RESET */ + GPIO41_GPIO, /* BP_FLASH */ + + /* sound */ + GPIO52_SSP3_SCLK, + GPIO83_SSP3_SFRM, + GPIO81_SSP3_TXD, + GPIO82_SSP3_RXD, + + /* ssp2 pins to in */ + GPIO22_GPIO, /* SSP2_SCLK */ + GPIO14_GPIO, /* SSP2_SFRM */ + GPIO38_GPIO, /* SSP2_TXD */ + GPIO88_GPIO, /* SSP2_RXD */ + + /* camera */ + GPIO23_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO85_CIF_LV, + GPIO84_CIF_FV, + GPIO27_CIF_DD_0, + GPIO114_CIF_DD_1, + GPIO51_CIF_DD_2, + GPIO115_CIF_DD_3, + GPIO95_CIF_DD_4, + GPIO48_CIF_DD_5, + GPIO93_CIF_DD_6, + GPIO12_CIF_DD_7, + GPIO50_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_EN */ + GPIO28_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_RST */ + GPIO17_GPIO, /* CAM_FLASH */ +}; +#endif + +#ifdef CONFIG_MACH_EZX_A780 +static unsigned long a780_pin_config[] __initdata = { + /* keypad */ + GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + + /* attenuate sound */ + GPIO96_GPIO, +}; +#endif + +#ifdef CONFIG_MACH_EZX_E680 +static unsigned long e680_pin_config[] __initdata = { + /* keypad */ + GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO96_KP_DKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_DKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO98_KP_DKIN_5 | WAKEUP_ON_LEVEL_HIGH, + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + + /* MIDI */ + GPIO79_GPIO, /* VA_SEL_BUL */ + GPIO80_GPIO, /* FLT_SEL_BUL */ + GPIO78_GPIO, /* MIDI_RESET */ + GPIO33_GPIO, /* MIDI_CS */ + GPIO15_GPIO, /* MIDI_IRQ */ + GPIO49_GPIO, /* MIDI_NPWE */ + GPIO18_GPIO, /* MIDI_RDY */ + + /* leds */ + GPIO46_GPIO, + GPIO47_GPIO, +}; +#endif + +#ifdef CONFIG_MACH_EZX_A1200 +static unsigned long a1200_pin_config[] __initdata = { + /* keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, +}; +#endif + +#ifdef CONFIG_MACH_EZX_A910 +static unsigned long a910_pin_config[] __initdata = { + /* keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, + + /* WLAN */ + GPIO89_GPIO, /* RESET */ + GPIO33_GPIO, /* WAKEUP */ + GPIO94_GPIO | WAKEUP_ON_LEVEL_HIGH, /* HOSTWAKE */ + + /* MMC CS */ + GPIO20_GPIO, +}; +#endif + +#ifdef CONFIG_MACH_EZX_E2 +static unsigned long e2_pin_config[] __initdata = { + /* keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, +}; +#endif + +#ifdef CONFIG_MACH_EZX_E6 +static unsigned long e6_pin_config[] __initdata = { + /* keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, +}; +#endif + +/* KEYPAD */ +#ifdef CONFIG_MACH_EZX_A780 +static unsigned int a780_key_map[] = { + KEY(0, 0, KEY_SEND), + KEY(0, 1, KEY_BACK), + KEY(0, 2, KEY_END), + KEY(0, 3, KEY_PAGEUP), + KEY(0, 4, KEY_UP), + + KEY(1, 0, KEY_NUMERIC_1), + KEY(1, 1, KEY_NUMERIC_2), + KEY(1, 2, KEY_NUMERIC_3), + KEY(1, 3, KEY_SELECT), + KEY(1, 4, KEY_KPENTER), + + KEY(2, 0, KEY_NUMERIC_4), + KEY(2, 1, KEY_NUMERIC_5), + KEY(2, 2, KEY_NUMERIC_6), + KEY(2, 3, KEY_RECORD), + KEY(2, 4, KEY_LEFT), + + KEY(3, 0, KEY_NUMERIC_7), + KEY(3, 1, KEY_NUMERIC_8), + KEY(3, 2, KEY_NUMERIC_9), + KEY(3, 3, KEY_HOME), + KEY(3, 4, KEY_RIGHT), + + KEY(4, 0, KEY_NUMERIC_STAR), + KEY(4, 1, KEY_NUMERIC_0), + KEY(4, 2, KEY_NUMERIC_POUND), + KEY(4, 3, KEY_PAGEDOWN), + KEY(4, 4, KEY_DOWN), +}; + +static struct pxa27x_keypad_platform_data a780_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 5, + .matrix_key_map = a780_key_map, + .matrix_key_map_size = ARRAY_SIZE(a780_key_map), + + .direct_key_map = { KEY_CAMERA }, + .direct_key_num = 1, + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_A780 */ + +#ifdef CONFIG_MACH_EZX_E680 +static unsigned int e680_key_map[] = { + KEY(0, 0, KEY_UP), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_RESERVED), + KEY(0, 3, KEY_SEND), + + KEY(1, 0, KEY_DOWN), + KEY(1, 1, KEY_LEFT), + KEY(1, 2, KEY_PAGEUP), + KEY(1, 3, KEY_PAGEDOWN), + + KEY(2, 0, KEY_RESERVED), + KEY(2, 1, KEY_RESERVED), + KEY(2, 2, KEY_RESERVED), + KEY(2, 3, KEY_KPENTER), +}; + +static struct pxa27x_keypad_platform_data e680_keypad_platform_data = { + .matrix_key_rows = 3, + .matrix_key_cols = 4, + .matrix_key_map = e680_key_map, + .matrix_key_map_size = ARRAY_SIZE(e680_key_map), + + .direct_key_map = { + KEY_CAMERA, + KEY_RESERVED, + KEY_RESERVED, + KEY_F1, + KEY_CANCEL, + KEY_F2, + }, + .direct_key_num = 6, + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_E680 */ + +#ifdef CONFIG_MACH_EZX_A1200 +static unsigned int a1200_key_map[] = { + KEY(0, 0, KEY_RESERVED), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_PAGEDOWN), + KEY(0, 3, KEY_RESERVED), + KEY(0, 4, KEY_RESERVED), + KEY(0, 5, KEY_RESERVED), + + KEY(1, 0, KEY_RESERVED), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_CAMERA), + KEY(1, 3, KEY_RESERVED), + KEY(1, 4, KEY_RESERVED), + KEY(1, 5, KEY_RESERVED), + + KEY(2, 0, KEY_RESERVED), + KEY(2, 1, KEY_KPENTER), + KEY(2, 2, KEY_RECORD), + KEY(2, 3, KEY_RESERVED), + KEY(2, 4, KEY_RESERVED), + KEY(2, 5, KEY_SELECT), + + KEY(3, 0, KEY_RESERVED), + KEY(3, 1, KEY_UP), + KEY(3, 2, KEY_SEND), + KEY(3, 3, KEY_RESERVED), + KEY(3, 4, KEY_RESERVED), + KEY(3, 5, KEY_RESERVED), + + KEY(4, 0, KEY_RESERVED), + KEY(4, 1, KEY_LEFT), + KEY(4, 2, KEY_PAGEUP), + KEY(4, 3, KEY_RESERVED), + KEY(4, 4, KEY_RESERVED), + KEY(4, 5, KEY_RESERVED), +}; + +static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_key_map = a1200_key_map, + .matrix_key_map_size = ARRAY_SIZE(a1200_key_map), + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_A1200 */ + +#ifdef CONFIG_MACH_EZX_E6 +static unsigned int e6_key_map[] = { + KEY(0, 0, KEY_RESERVED), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_PAGEDOWN), + KEY(0, 3, KEY_RESERVED), + KEY(0, 4, KEY_RESERVED), + KEY(0, 5, KEY_NEXTSONG), + + KEY(1, 0, KEY_RESERVED), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_PROG1), + KEY(1, 3, KEY_RESERVED), + KEY(1, 4, KEY_RESERVED), + KEY(1, 5, KEY_RESERVED), + + KEY(2, 0, KEY_RESERVED), + KEY(2, 1, KEY_ENTER), + KEY(2, 2, KEY_CAMERA), + KEY(2, 3, KEY_RESERVED), + KEY(2, 4, KEY_RESERVED), + KEY(2, 5, KEY_WWW), + + KEY(3, 0, KEY_RESERVED), + KEY(3, 1, KEY_UP), + KEY(3, 2, KEY_SEND), + KEY(3, 3, KEY_RESERVED), + KEY(3, 4, KEY_RESERVED), + KEY(3, 5, KEY_PLAYPAUSE), + + KEY(4, 0, KEY_RESERVED), + KEY(4, 1, KEY_LEFT), + KEY(4, 2, KEY_PAGEUP), + KEY(4, 3, KEY_RESERVED), + KEY(4, 4, KEY_RESERVED), + KEY(4, 5, KEY_PREVIOUSSONG), +}; + +static struct pxa27x_keypad_platform_data e6_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_key_map = e6_key_map, + .matrix_key_map_size = ARRAY_SIZE(e6_key_map), + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_E6 */ + +#ifdef CONFIG_MACH_EZX_A910 +static unsigned int a910_key_map[] = { + KEY(0, 0, KEY_NUMERIC_6), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_PAGEDOWN), + KEY(0, 3, KEY_KPENTER), + KEY(0, 4, KEY_NUMERIC_5), + KEY(0, 5, KEY_CAMERA), + + KEY(1, 0, KEY_NUMERIC_8), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_RESERVED), + KEY(1, 3, KEY_F1), /* Left SoftKey */ + KEY(1, 4, KEY_NUMERIC_STAR), + KEY(1, 5, KEY_RESERVED), + + KEY(2, 0, KEY_NUMERIC_7), + KEY(2, 1, KEY_NUMERIC_9), + KEY(2, 2, KEY_RECORD), + KEY(2, 3, KEY_F2), /* Right SoftKey */ + KEY(2, 4, KEY_BACK), + KEY(2, 5, KEY_SELECT), + + KEY(3, 0, KEY_NUMERIC_2), + KEY(3, 1, KEY_UP), + KEY(3, 2, KEY_SEND), + KEY(3, 3, KEY_NUMERIC_0), + KEY(3, 4, KEY_NUMERIC_1), + KEY(3, 5, KEY_RECORD), + + KEY(4, 0, KEY_NUMERIC_4), + KEY(4, 1, KEY_LEFT), + KEY(4, 2, KEY_PAGEUP), + KEY(4, 3, KEY_NUMERIC_POUND), + KEY(4, 4, KEY_NUMERIC_3), + KEY(4, 5, KEY_RESERVED), +}; + +static struct pxa27x_keypad_platform_data a910_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_key_map = a910_key_map, + .matrix_key_map_size = ARRAY_SIZE(a910_key_map), + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_A910 */ + +#ifdef CONFIG_MACH_EZX_E2 +static unsigned int e2_key_map[] = { + KEY(0, 0, KEY_NUMERIC_6), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_NUMERIC_9), + KEY(0, 3, KEY_NEXTSONG), + KEY(0, 4, KEY_NUMERIC_5), + KEY(0, 5, KEY_F1), /* Left SoftKey */ + + KEY(1, 0, KEY_NUMERIC_8), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_RESERVED), + KEY(1, 3, KEY_PAGEUP), + KEY(1, 4, KEY_NUMERIC_STAR), + KEY(1, 5, KEY_F2), /* Right SoftKey */ + + KEY(2, 0, KEY_NUMERIC_7), + KEY(2, 1, KEY_KPENTER), + KEY(2, 2, KEY_RECORD), + KEY(2, 3, KEY_PAGEDOWN), + KEY(2, 4, KEY_BACK), + KEY(2, 5, KEY_NUMERIC_0), + + KEY(3, 0, KEY_NUMERIC_2), + KEY(3, 1, KEY_UP), + KEY(3, 2, KEY_SEND), + KEY(3, 3, KEY_PLAYPAUSE), + KEY(3, 4, KEY_NUMERIC_1), + KEY(3, 5, KEY_SOUND), /* Music SoftKey */ + + KEY(4, 0, KEY_NUMERIC_4), + KEY(4, 1, KEY_LEFT), + KEY(4, 2, KEY_NUMERIC_POUND), + KEY(4, 3, KEY_PREVIOUSSONG), + KEY(4, 4, KEY_NUMERIC_3), + KEY(4, 5, KEY_RESERVED), +}; + +static struct pxa27x_keypad_platform_data e2_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_key_map = e2_key_map, + .matrix_key_map_size = ARRAY_SIZE(e2_key_map), + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_E2 */ + +#ifdef CONFIG_MACH_EZX_A780 +/* gpio_keys */ +static struct gpio_keys_button a780_buttons[] = { + [0] = { + .code = SW_LID, + .gpio = GPIO12_A780_FLIP_LID, + .active_low = 0, + .desc = "A780 flip lid", + .type = EV_SW, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data a780_gpio_keys_platform_data = { + .buttons = a780_buttons, + .nbuttons = ARRAY_SIZE(a780_buttons), +}; + +static struct platform_device a780_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &a780_gpio_keys_platform_data, + }, +}; + +/* camera */ +static int a780_camera_init(void) +{ + int err; + + /* + * GPIO50_nCAM_EN is active low + * GPIO19_GEN1_CAM_RST is active on rising edge + */ + err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN"); + if (err) { + pr_err("%s: Failed to request nCAM_EN\n", __func__); + goto fail; + } + + err = gpio_request(GPIO19_GEN1_CAM_RST, "CAM_RST"); + if (err) { + pr_err("%s: Failed to request CAM_RST\n", __func__); + goto fail_gpio_cam_rst; + } + + gpio_direction_output(GPIO50_nCAM_EN, 1); + gpio_direction_output(GPIO19_GEN1_CAM_RST, 0); + + return 0; + +fail_gpio_cam_rst: + gpio_free(GPIO50_nCAM_EN); +fail: + return err; +} + +static int a780_camera_power(struct device *dev, int on) +{ + gpio_set_value(GPIO50_nCAM_EN, !on); + return 0; +} + +static int a780_camera_reset(struct device *dev) +{ + gpio_set_value(GPIO19_GEN1_CAM_RST, 0); + msleep(10); + gpio_set_value(GPIO19_GEN1_CAM_RST, 1); + + return 0; +} + +struct pxacamera_platform_data a780_pxacamera_platform_data = { + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, + .mclk_10khz = 5000, +}; + +static struct i2c_board_info a780_camera_i2c_board_info = { + I2C_BOARD_INFO("mt9m111", 0x5d), +}; + +static struct soc_camera_link a780_iclink = { + .bus_id = 0, + .flags = SOCAM_SENSOR_INVERT_PCLK, + .i2c_adapter_id = 0, + .board_info = &a780_camera_i2c_board_info, + .power = a780_camera_power, + .reset = a780_camera_reset, +}; + +static struct platform_device a780_camera = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &a780_iclink, + }, +}; + +static struct platform_device *a780_devices[] __initdata = { + &a780_gpio_keys, +}; + +static void __init a780_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(a780_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_i2c_info(NULL); + + pxa_set_fb_info(NULL, &ezx_fb_info_1); + + pxa_set_keypad_info(&a780_keypad_platform_data); + + if (a780_camera_init() == 0) { + pxa_set_camera_info(&a780_pxacamera_platform_data); + platform_device_register(&a780_camera); + } + + platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); + platform_add_devices(ARRAY_AND_SIZE(a780_devices)); +} + +MACHINE_START(EZX_A780, "Motorola EZX A780") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = a780_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_E680 +/* gpio_keys */ +static struct gpio_keys_button e680_buttons[] = { + [0] = { + .code = KEY_SCREENLOCK, + .gpio = GPIO12_E680_LOCK_SWITCH, + .active_low = 0, + .desc = "E680 lock switch", + .type = EV_KEY, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data e680_gpio_keys_platform_data = { + .buttons = e680_buttons, + .nbuttons = ARRAY_SIZE(e680_buttons), +}; + +static struct platform_device e680_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &e680_gpio_keys_platform_data, + }, +}; + +static struct i2c_board_info __initdata e680_i2c_board_info[] = { + { I2C_BOARD_INFO("tea5767", 0x81) }, +}; + +static struct platform_device *e680_devices[] __initdata = { + &e680_gpio_keys, +}; + +static void __init e680_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(e680_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info)); + + pxa_set_fb_info(NULL, &ezx_fb_info_1); + + pxa_set_keypad_info(&e680_keypad_platform_data); + + platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); + platform_add_devices(ARRAY_AND_SIZE(e680_devices)); +} + +MACHINE_START(EZX_E680, "Motorola EZX E680") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = e680_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_A1200 +/* gpio_keys */ +static struct gpio_keys_button a1200_buttons[] = { + [0] = { + .code = SW_LID, + .gpio = GPIO15_A1200_FLIP_LID, + .active_low = 0, + .desc = "A1200 flip lid", + .type = EV_SW, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data a1200_gpio_keys_platform_data = { + .buttons = a1200_buttons, + .nbuttons = ARRAY_SIZE(a1200_buttons), +}; + +static struct platform_device a1200_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &a1200_gpio_keys_platform_data, + }, +}; + +static struct i2c_board_info __initdata a1200_i2c_board_info[] = { + { I2C_BOARD_INFO("tea5767", 0x81) }, +}; + +static struct platform_device *a1200_devices[] __initdata = { + &a1200_gpio_keys, +}; + +static void __init a1200_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(a1200_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info)); + + pxa_set_fb_info(NULL, &ezx_fb_info_2); + + pxa_set_keypad_info(&a1200_keypad_platform_data); + + platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); + platform_add_devices(ARRAY_AND_SIZE(a1200_devices)); +} + +MACHINE_START(EZX_A1200, "Motorola EZX A1200") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = a1200_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_A910 +/* gpio_keys */ +static struct gpio_keys_button a910_buttons[] = { + [0] = { + .code = SW_LID, + .gpio = GPIO15_A910_FLIP_LID, + .active_low = 0, + .desc = "A910 flip lid", + .type = EV_SW, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data a910_gpio_keys_platform_data = { + .buttons = a910_buttons, + .nbuttons = ARRAY_SIZE(a910_buttons), +}; + +static struct platform_device a910_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &a910_gpio_keys_platform_data, + }, +}; + +/* camera */ +static int a910_camera_init(void) +{ + int err; + + /* + * GPIO50_nCAM_EN is active low + * GPIO28_GEN2_CAM_RST is active on rising edge + */ + err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN"); + if (err) { + pr_err("%s: Failed to request nCAM_EN\n", __func__); + goto fail; + } + + err = gpio_request(GPIO28_GEN2_CAM_RST, "CAM_RST"); + if (err) { + pr_err("%s: Failed to request CAM_RST\n", __func__); + goto fail_gpio_cam_rst; + } + + gpio_direction_output(GPIO50_nCAM_EN, 1); + gpio_direction_output(GPIO28_GEN2_CAM_RST, 0); + + return 0; + +fail_gpio_cam_rst: + gpio_free(GPIO50_nCAM_EN); +fail: + return err; +} + +static int a910_camera_power(struct device *dev, int on) +{ + gpio_set_value(GPIO50_nCAM_EN, !on); + return 0; +} + +static int a910_camera_reset(struct device *dev) +{ + gpio_set_value(GPIO28_GEN2_CAM_RST, 0); + msleep(10); + gpio_set_value(GPIO28_GEN2_CAM_RST, 1); + + return 0; +} + +struct pxacamera_platform_data a910_pxacamera_platform_data = { + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, + .mclk_10khz = 5000, +}; + +static struct i2c_board_info a910_camera_i2c_board_info = { + I2C_BOARD_INFO("mt9m111", 0x5d), +}; + +static struct soc_camera_link a910_iclink = { + .bus_id = 0, + .i2c_adapter_id = 0, + .board_info = &a910_camera_i2c_board_info, + .power = a910_camera_power, + .reset = a910_camera_reset, +}; + +static struct platform_device a910_camera = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &a910_iclink, + }, +}; + +/* leds-lp3944 */ +static struct lp3944_platform_data a910_lp3944_leds = { + .leds_size = LP3944_LEDS_MAX, + .leds = { + [0] = { + .name = "a910:red:", + .status = LP3944_LED_STATUS_OFF, + .type = LP3944_LED_TYPE_LED, + }, + [1] = { + .name = "a910:green:", + .status = LP3944_LED_STATUS_OFF, + .type = LP3944_LED_TYPE_LED, + }, + [2] { + .name = "a910:blue:", + .status = LP3944_LED_STATUS_OFF, + .type = LP3944_LED_TYPE_LED, + }, + /* Leds 3 and 4 are used as display power switches */ + [3] = { + .name = "a910::cli_display", + .status = LP3944_LED_STATUS_OFF, + .type = LP3944_LED_TYPE_LED_INVERTED + }, + [4] = { + .name = "a910::main_display", + .status = LP3944_LED_STATUS_ON, + .type = LP3944_LED_TYPE_LED_INVERTED + }, + [5] = { .type = LP3944_LED_TYPE_NONE }, + [6] = { + .name = "a910::torch", + .status = LP3944_LED_STATUS_OFF, + .type = LP3944_LED_TYPE_LED, + }, + [7] = { + .name = "a910::flash", + .status = LP3944_LED_STATUS_OFF, + .type = LP3944_LED_TYPE_LED_INVERTED, + }, + }, +}; + +static struct i2c_board_info __initdata a910_i2c_board_info[] = { + { + I2C_BOARD_INFO("lp3944", 0x60), + .platform_data = &a910_lp3944_leds, + }, +}; + +static struct platform_device *a910_devices[] __initdata = { + &a910_gpio_keys, +}; + +static void __init a910_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(a910_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info)); + + pxa_set_fb_info(NULL, &ezx_fb_info_2); + + pxa_set_keypad_info(&a910_keypad_platform_data); + + if (a910_camera_init() == 0) { + pxa_set_camera_info(&a910_pxacamera_platform_data); + platform_device_register(&a910_camera); + } + + platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); + platform_add_devices(ARRAY_AND_SIZE(a910_devices)); +} + +MACHINE_START(EZX_A910, "Motorola EZX A910") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = a910_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_E6 +/* gpio_keys */ +static struct gpio_keys_button e6_buttons[] = { + [0] = { + .code = KEY_SCREENLOCK, + .gpio = GPIO15_E6_LOCK_SWITCH, + .active_low = 0, + .desc = "E6 lock switch", + .type = EV_KEY, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data e6_gpio_keys_platform_data = { + .buttons = e6_buttons, + .nbuttons = ARRAY_SIZE(e6_buttons), +}; + +static struct platform_device e6_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &e6_gpio_keys_platform_data, + }, +}; + +static struct i2c_board_info __initdata e6_i2c_board_info[] = { + { I2C_BOARD_INFO("tea5767", 0x81) }, +}; + +static struct platform_device *e6_devices[] __initdata = { + &e6_gpio_keys, +}; + +static void __init e6_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(e6_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info)); + + pxa_set_fb_info(NULL, &ezx_fb_info_2); + + pxa_set_keypad_info(&e6_keypad_platform_data); + + platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); + platform_add_devices(ARRAY_AND_SIZE(e6_devices)); +} + +MACHINE_START(EZX_E6, "Motorola EZX E6") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = e6_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_E2 +static struct i2c_board_info __initdata e2_i2c_board_info[] = { + { I2C_BOARD_INFO("tea5767", 0x81) }, +}; + +static struct platform_device *e2_devices[] __initdata = { +}; + +static void __init e2_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(e2_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info)); + + pxa_set_fb_info(NULL, &ezx_fb_info_2); + + pxa_set_keypad_info(&e2_keypad_platform_data); + + platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); + platform_add_devices(ARRAY_AND_SIZE(e2_devices)); +} + +MACHINE_START(EZX_E2, "Motorola EZX E2") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .timer = &pxa_timer, + .init_machine = e2_init, + .restart = pxa_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c new file mode 100644 index 00000000000..5432ecb15de --- /dev/null +++ b/arch/arm/mach-pxa/generic.c @@ -0,0 +1,98 @@ +/* + * linux/arch/arm/mach-pxa/generic.c + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * Code common to all PXA machines. + * + * 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. + * + * Since this file should be linked before any other machine specific file, + * the __initcall() here will be executed first. This serves as default + * initialization stuff for PXA machines which can be overridden later if + * need be. + */ +#include <linux/gpio.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <mach/hardware.h> +#include <asm/system.h> +#include <asm/mach/map.h> +#include <asm/mach-types.h> + +#include <mach/reset.h> +#include <mach/smemc.h> +#include <mach/pxa3xx-regs.h> + +#include "generic.h" + +void clear_reset_status(unsigned int mask) +{ + if (cpu_is_pxa2xx()) + pxa2xx_clear_reset_status(mask); + else { + /* RESET_STATUS_* has a 1:1 mapping with ARSR */ + ARSR = mask; + } +} + +unsigned long get_clock_tick_rate(void) +{ + unsigned long clock_tick_rate; + + if (cpu_is_pxa25x()) + clock_tick_rate = 3686400; + else if (machine_is_mainstone()) + clock_tick_rate = 3249600; + else + clock_tick_rate = 3250000; + + return clock_tick_rate; +} +EXPORT_SYMBOL(get_clock_tick_rate); + +/* + * Get the clock frequency as reflected by CCCR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int get_clk_frequency_khz(int info) +{ + if (cpu_is_pxa25x()) + return pxa25x_get_clk_frequency_khz(info); + else if (cpu_is_pxa27x()) + return pxa27x_get_clk_frequency_khz(info); + return 0; +} +EXPORT_SYMBOL(get_clk_frequency_khz); + +/* + * Intel PXA2xx internal register mapping. + * + * Note: virtual 0xfffe0000-0xffffffff is reserved for the vector table + * and cache flush area. + */ +static struct map_desc common_io_desc[] __initdata = { + { /* Devs */ + .virtual = 0xf2000000, + .pfn = __phys_to_pfn(0x40000000), + .length = 0x02000000, + .type = MT_DEVICE + }, { /* UNCACHED_PHYS_0 */ + .virtual = 0xff000000, + .pfn = __phys_to_pfn(0x00000000), + .length = 0x00100000, + .type = MT_DEVICE + } +}; + +void __init pxa_map_io(void) +{ + iotable_init(ARRAY_AND_SIZE(common_io_desc)); +} diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h new file mode 100644 index 00000000000..42d5cca6625 --- /dev/null +++ b/arch/arm/mach-pxa/generic.h @@ -0,0 +1,60 @@ +/* + * linux/arch/arm/mach-pxa/generic.h + * + * Author: Nicolas Pitre + * Copyright: MontaVista Software 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. + */ + +struct irq_data; +struct sys_timer; + +extern struct sys_timer pxa_timer; + +extern void __init pxa_map_io(void); + +extern unsigned int get_clk_frequency_khz(int info); + +#define SET_BANK(__nr,__start,__size) \ + mi->bank[__nr].start = (__start), \ + mi->bank[__nr].size = (__size) + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#ifdef CONFIG_PXA25x +extern unsigned pxa25x_get_clk_frequency_khz(int); +#else +#define pxa25x_get_clk_frequency_khz(x) (0) +#endif + +#ifdef CONFIG_PXA27x +extern unsigned pxa27x_get_clk_frequency_khz(int); +#else +#define pxa27x_get_clk_frequency_khz(x) (0) +#endif + +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) +extern void pxa2xx_clear_reset_status(unsigned int); +#else +static inline void pxa2xx_clear_reset_status(unsigned int mask) {} +#endif + +#ifdef CONFIG_PXA3xx +extern unsigned pxa3xx_get_clk_frequency_khz(int); +#else +#define pxa3xx_get_clk_frequency_khz(x) (0) +#endif + +extern struct syscore_ops pxa_irq_syscore_ops; +extern struct syscore_ops pxa2xx_mfp_syscore_ops; +extern struct syscore_ops pxa3xx_mfp_syscore_ops; + +void __init pxa_set_ffuart_info(void *info); +void __init pxa_set_btuart_info(void *info); +void __init pxa_set_stuart_info(void *info); +void __init pxa_set_hwuart_info(void *info); + +void pxa_restart(char, const char *); diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c new file mode 100644 index 00000000000..ac3b1cef475 --- /dev/null +++ b/arch/arm/mach-pxa/gumstix.c @@ -0,0 +1,243 @@ +/* + * linux/arch/arm/mach-pxa/gumstix.c + * + * Support for the Gumstix motherboards. + * + * Original Author: Craig Hughes + * Created: Feb 14, 2008 + * Copyright: Craig Hughes + * + * 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. + * + * Implemented based on lubbock.c by Nicolas Pitre and code from Craig + * Hughes + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/gpio.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/usb/gpio_vbus.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <asm/irq.h> +#include <asm/sizes.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/flash.h> + +#include <mach/pxa25x.h> +#include <mach/mmc.h> +#include <mach/udc.h> +#include <mach/gumstix.h> + +#include "generic.h" + +static struct resource flash_resource = { + .start = 0x00000000, + .end = SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct mtd_partition gumstix_partitions[] = { + { + .name = "Bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE /* force read-only */ + } , { + .name = "rootfs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND + } +}; + +static struct flash_platform_data gumstix_flash_data = { + .map_name = "cfi_probe", + .parts = gumstix_partitions, + .nr_parts = ARRAY_SIZE(gumstix_partitions), + .width = 2, +}; + +static struct platform_device gumstix_flash_device = { + .name = "pxa2xx-flash", + .id = 0, + .dev = { + .platform_data = &gumstix_flash_data, + }, + .resource = &flash_resource, + .num_resources = 1, +}; + +static struct platform_device *devices[] __initdata = { + &gumstix_flash_device, +}; + +#ifdef CONFIG_MMC_PXA +static struct pxamci_platform_data gumstix_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +static void __init gumstix_mmc_init(void) +{ + pxa_set_mci_info(&gumstix_mci_platform_data); +} +#else +static void __init gumstix_mmc_init(void) +{ + pr_debug("Gumstix mmc disabled\n"); +} +#endif + +#ifdef CONFIG_USB_PXA25X +static struct gpio_vbus_mach_info gumstix_udc_info = { + .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn, + .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, +}; + +static struct platform_device gumstix_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &gumstix_udc_info, + }, +}; + +static void __init gumstix_udc_init(void) +{ + platform_device_register(&gumstix_gpio_vbus); +} +#else +static void gumstix_udc_init(void) +{ + pr_debug("Gumstix udc is disabled\n"); +} +#endif + +#ifdef CONFIG_BT +/* Normally, the bootloader would have enabled this 32kHz clock but many +** boards still have u-boot 1.1.4 so we check if it has been turned on and +** if not, we turn it on with a warning message. */ +static void gumstix_setup_bt_clock(void) +{ + int timeout = 500; + + if (!(OSCC & OSCC_OOK)) + pr_warning("32kHz clock was not on. Bootloader may need to " + "be updated\n"); + else + return; + + OSCC |= OSCC_OON; + do { + if (OSCC & OSCC_OOK) + break; + udelay(1); + } while (--timeout); + if (!timeout) + pr_err("Failed to start 32kHz clock\n"); +} + +static void __init gumstix_bluetooth_init(void) +{ + int err; + + gumstix_setup_bt_clock(); + + err = gpio_request(GPIO_GUMSTIX_BTRESET, "BTRST"); + if (err) { + pr_err("gumstix: failed request gpio for bluetooth reset\n"); + return; + } + + err = gpio_direction_output(GPIO_GUMSTIX_BTRESET, 1); + if (err) { + pr_err("gumstix: can't reset bluetooth\n"); + return; + } + gpio_set_value(GPIO_GUMSTIX_BTRESET, 0); + udelay(100); + gpio_set_value(GPIO_GUMSTIX_BTRESET, 1); +} +#else +static void gumstix_bluetooth_init(void) +{ + pr_debug("Gumstix Bluetooth is disabled\n"); +} +#endif + +static unsigned long gumstix_pin_config[] __initdata = { + GPIO12_32KHz, + /* BTUART */ + GPIO42_HWUART_RXD, + GPIO43_HWUART_TXD, + GPIO44_HWUART_CTS, + GPIO45_HWUART_RTS, + /* MMC */ + GPIO6_MMC_CLK, + GPIO53_MMC_CLK, + GPIO8_MMC_CS0, +}; + +int __attribute__((weak)) am200_init(void) +{ + return 0; +} + +int __attribute__((weak)) am300_init(void) +{ + return 0; +} + +static void __init carrier_board_init(void) +{ + /* + * put carrier/expansion board init here if + * they cannot be detected programatically + */ + am200_init(); + am300_init(); +} + +static void __init gumstix_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + pxa_set_hwuart_info(NULL); + + gumstix_bluetooth_init(); + gumstix_udc_init(); + gumstix_mmc_init(); + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); + carrier_board_init(); +} + +MACHINE_START(GUMSTIX, "Gumstix") + .atag_offset = 0x100, /* match u-boot bi_boot_params */ + .map_io = pxa25x_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .timer = &pxa_timer, + .init_machine = gumstix_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c new file mode 100644 index 00000000000..fde6b4c873c --- /dev/null +++ b/arch/arm/mach-pxa/h5000.c @@ -0,0 +1,213 @@ +/* + * Hardware definitions for HP iPAQ h5xxx Handheld Computers + * + * Copyright 2000-2003 Hewlett-Packard Company. + * Copyright 2002 Jamey Hicks <jamey.hicks@hp.com> + * Copyright 2004-2005 Phil Blundell <pb@handhelds.org> + * Copyright 2007-2008 Anton Vorontsov <cbouatmailru@gmail.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; either version 2 of the License, or + * (at your option) any later version. + * + * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, + * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS + * FITNESS FOR ANY PARTICULAR PURPOSE. + * + * Author: Jamey Hicks. + */ + +#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 <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/irq.h> + +#include <mach/pxa25x.h> +#include <mach/h5000.h> +#include <mach/udc.h> +#include <mach/smemc.h> + +#include "generic.h" + +/* + * Flash + */ + +static struct mtd_partition h5000_flash0_partitions[] = { + { + .name = "bootldr", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "root", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + }, +}; + +static struct mtd_partition h5000_flash1_partitions[] = { + { + .name = "second root", + .size = SZ_16M - 0x00040000, + .offset = 0, + }, + { + .name = "asset", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct physmap_flash_data h5000_flash0_data = { + .width = 4, + .parts = h5000_flash0_partitions, + .nr_parts = ARRAY_SIZE(h5000_flash0_partitions), +}; + +static struct physmap_flash_data h5000_flash1_data = { + .width = 4, + .parts = h5000_flash1_partitions, + .nr_parts = ARRAY_SIZE(h5000_flash1_partitions), +}; + +static struct resource h5000_flash0_resources = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, +}; + +static struct resource h5000_flash1_resources = { + .start = PXA_CS0_PHYS + SZ_32M, + .end = PXA_CS0_PHYS + SZ_32M + SZ_16M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, +}; + +static struct platform_device h5000_flash[] = { + { + .name = "physmap-flash", + .id = 0, + .resource = &h5000_flash0_resources, + .num_resources = 1, + .dev = { + .platform_data = &h5000_flash0_data, + }, + }, + { + .name = "physmap-flash", + .id = 1, + .resource = &h5000_flash1_resources, + .num_resources = 1, + .dev = { + .platform_data = &h5000_flash1_data, + }, + }, +}; + +/* + * USB Device Controller + */ + +static struct pxa2xx_udc_mach_info h5000_udc_mach_info __initdata = { + .gpio_pullup = H5000_GPIO_USB_PULLUP, +}; + +/* + * GPIO setup + */ + +static unsigned long h5000_pin_config[] __initdata = { + /* Crystal and Clock Signals */ + GPIO12_32KHz, + + /* SDRAM and Static Memory I/O Signals */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + GPIO36_FFUART_DCD, + GPIO37_FFUART_DSR, + GPIO38_FFUART_RI, + GPIO39_FFUART_TXD, + GPIO40_FFUART_DTR, + GPIO41_FFUART_RTS, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* SSP1 */ + GPIO23_SSP1_SCLK, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* I2S */ + GPIO28_I2S_BITCLK_OUT, + GPIO29_I2S_SDATA_IN, + GPIO30_I2S_SDATA_OUT, + GPIO31_I2S_SYNC, + GPIO32_I2S_SYSCLK, +}; + +/* + * Localbus setup: + * CS0: Flash; + * CS1: MediaQ chip, select 16-bit bus and vlio; + * CS5: SAMCOP. + */ + +static void fix_msc(void) +{ + __raw_writel(0x129c24f2, MSC0); + __raw_writel(0x7ff424fa, MSC1); + __raw_writel(0x7ff47ff4, MSC2); + + __raw_writel(__raw_readl(MDREFR) | 0x02080000, MDREFR); +} + +/* + * Platform devices + */ + +static struct platform_device *devices[] __initdata = { + &h5000_flash[0], + &h5000_flash[1], +}; + +static void __init h5000_init(void) +{ + fix_msc(); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(h5000_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + pxa_set_udc_info(&h5000_udc_mach_info); + platform_add_devices(ARRAY_AND_SIZE(devices)); +} + +MACHINE_START(H5400, "HP iPAQ H5000") + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .timer = &pxa_timer, + .init_machine = h5000_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c new file mode 100644 index 00000000000..26d069a9f90 --- /dev/null +++ b/arch/arm/mach-pxa/himalaya.c @@ -0,0 +1,168 @@ +/* + * linux/arch/arm/mach-pxa/himalaya.c + * + * Hardware definitions for the HTC Himalaya + * + * Based on 2.6.21-hh20's himalaya.c and himalaya_lcd.c + * + * Copyright (c) 2008 Zbynek Michl <Zbynek.Michl@seznam.cz> + * + * 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/device.h> +#include <linux/fb.h> +#include <linux/platform_device.h> + +#include <video/w100fb.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa25x.h> + +#include "generic.h" + +/* ---------------------- Himalaya LCD definitions -------------------- */ + +static struct w100_gen_regs himalaya_lcd_regs = { + .lcd_format = 0x00000003, + .lcdd_cntl1 = 0x00000000, + .lcdd_cntl2 = 0x0003ffff, + .genlcd_cntl1 = 0x00fff003, + .genlcd_cntl2 = 0x00000003, + .genlcd_cntl3 = 0x000102aa, +}; + +static struct w100_mode himalaya4_lcd_mode = { + .xres = 240, + .yres = 320, + .left_margin = 0, + .right_margin = 31, + .upper_margin = 15, + .lower_margin = 0, + .crtc_ss = 0x80150014, + .crtc_ls = 0xa0fb00f7, + .crtc_gs = 0xc0080007, + .crtc_vpos_gs = 0x00080007, + .crtc_rev = 0x0000000a, + .crtc_dclk = 0x81700030, + .crtc_gclk = 0x8015010f, + .crtc_goe = 0x00000000, + .pll_freq = 80, + .pixclk_divider = 15, + .pixclk_divider_rotated = 15, + .pixclk_src = CLK_SRC_PLL, + .sysclk_divider = 0, + .sysclk_src = CLK_SRC_PLL, +}; + +static struct w100_mode himalaya6_lcd_mode = { + .xres = 240, + .yres = 320, + .left_margin = 9, + .right_margin = 8, + .upper_margin = 5, + .lower_margin = 4, + .crtc_ss = 0x80150014, + .crtc_ls = 0xa0fb00f7, + .crtc_gs = 0xc0080007, + .crtc_vpos_gs = 0x00080007, + .crtc_rev = 0x0000000a, + .crtc_dclk = 0xa1700030, + .crtc_gclk = 0x8015010f, + .crtc_goe = 0x00000000, + .pll_freq = 95, + .pixclk_divider = 0xb, + .pixclk_divider_rotated = 4, + .pixclk_src = CLK_SRC_PLL, + .sysclk_divider = 1, + .sysclk_src = CLK_SRC_PLL, +}; + +static struct w100_gpio_regs himalaya_w100_gpio_info = { + .init_data1 = 0xffff0000, /* GPIO_DATA */ + .gpio_dir1 = 0x00000000, /* GPIO_CNTL1 */ + .gpio_oe1 = 0x003c0000, /* GPIO_CNTL2 */ + .init_data2 = 0x00000000, /* GPIO_DATA2 */ + .gpio_dir2 = 0x00000000, /* GPIO_CNTL3 */ + .gpio_oe2 = 0x00000000, /* GPIO_CNTL4 */ +}; + +static struct w100fb_mach_info himalaya_fb_info = { + .num_modes = 1, + .regs = &himalaya_lcd_regs, + .gpio = &himalaya_w100_gpio_info, + .xtal_freq = 16000000, +}; + +static struct resource himalaya_fb_resources[] = { + [0] = { + .start = 0x08000000, + .end = 0x08ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device himalaya_fb_device = { + .name = "w100fb", + .id = -1, + .dev = { + .platform_data = &himalaya_fb_info, + }, + .num_resources = ARRAY_SIZE(himalaya_fb_resources), + .resource = himalaya_fb_resources, +}; + +/* ----------------------------------------------------------------------- */ + +static struct platform_device *devices[] __initdata = { + &himalaya_fb_device, +}; + +static void __init himalaya_lcd_init(void) +{ + int himalaya_boardid; + + himalaya_boardid = 0x4; /* hardcoded (detection needs ASIC3 functions) */ + printk(KERN_INFO "himalaya LCD Driver init. boardid=%d\n", + himalaya_boardid); + + switch (himalaya_boardid) { + case 0x4: + himalaya_fb_info.modelist = &himalaya4_lcd_mode; + break; + case 0x6: + himalaya_fb_info.modelist = &himalaya6_lcd_mode; + break; + default: + printk(KERN_INFO "himalaya lcd_init: unknown boardid=%d. Using 0x4\n", + himalaya_boardid); + himalaya_fb_info.modelist = &himalaya4_lcd_mode; + } +} + +static void __init himalaya_init(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + himalaya_lcd_init(); + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + + +MACHINE_START(HIMALAYA, "HTC Himalaya") + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_machine = himalaya_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c new file mode 100644 index 00000000000..208eef1c048 --- /dev/null +++ b/arch/arm/mach-pxa/hx4700.c @@ -0,0 +1,874 @@ +/* + * Support for HP iPAQ hx4700 PDAs. + * + * Copyright (c) 2008-2009 Philipp Zabel + * + * Based on code: + * Copyright (c) 2004 Hewlett-Packard Company. + * Copyright (c) 2005 SDG Systems, LLC + * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru> + * + * 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/fb.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/lcd.h> +#include <linux/mfd/htc-egpio.h> +#include <linux/mfd/asic3.h> +#include <linux/mtd/physmap.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/regulator/bq24022.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/max1586.h> +#include <linux/spi/ads7846.h> +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/i2c/pxa-i2c.h> + +#include <mach/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa27x.h> +#include <mach/hx4700.h> +#include <mach/irda.h> + +#include <sound/ak4641.h> +#include <video/platform_lcd.h> +#include <video/w100fb.h> + +#include "devices.h" +#include "generic.h" + +/* Physical address space information */ + +#define ATI_W3220_PHYS PXA_CS2_PHYS /* ATI Imageon 3220 Graphics */ +#define ASIC3_PHYS PXA_CS3_PHYS +#define ASIC3_SD_PHYS (PXA_CS3_PHYS + 0x02000000) + +static unsigned long hx4700_pin_config[] __initdata = { + + /* SDRAM and Static Memory I/O Signals */ + GPIO20_nSDCS_2, + GPIO21_nSDCS_3, + GPIO15_nCS_1, + GPIO78_nCS_2, /* W3220 */ + GPIO79_nCS_3, /* ASIC3 */ + GPIO80_nCS_4, + GPIO33_nCS_5, /* EGPIO, WLAN */ + + /* PC CARD */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO85_nPCE_1, + GPIO104_PSKTSEL, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* FFUART (RS-232) */ + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + GPIO36_FFUART_DCD, + GPIO37_FFUART_DSR, + GPIO38_FFUART_RI, + GPIO39_FFUART_TXD, + GPIO40_FFUART_DTR, + GPIO41_FFUART_RTS, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* PWM 1 (Backlight) */ + GPIO17_PWM1_OUT, + + /* I2S */ + GPIO28_I2S_BITCLK_OUT, + GPIO29_I2S_SDATA_IN, + GPIO30_I2S_SDATA_OUT, + GPIO31_I2S_SYNC, + GPIO113_I2S_SYSCLK, + + /* SSP 1 (NavPoint) */ + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* SSP 2 (TSC2046) */ + GPIO19_SSP2_SCLK, + GPIO86_SSP2_RXD, + GPIO87_SSP2_TXD, + GPIO88_GPIO, + + /* HX4700 specific input GPIOs */ + GPIO12_GPIO, /* ASIC3_IRQ */ + GPIO13_GPIO, /* W3220_IRQ */ + GPIO14_GPIO, /* nWLAN_IRQ */ + + GPIO10_GPIO, /* GSM_IRQ */ + GPIO13_GPIO, /* CPLD_IRQ */ + GPIO107_GPIO, /* DS1WM_IRQ */ + GPIO108_GPIO, /* GSM_READY */ + GPIO58_GPIO, /* TSC2046_nPENIRQ */ + GPIO66_GPIO, /* nSDIO_IRQ */ +}; + +/* + * IRDA + */ + +static struct pxaficp_platform_data ficp_info = { + .gpio_pwdown = GPIO105_HX4700_nIR_ON, + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; + +/* + * GPIO Keys + */ + +#define INIT_KEY(_code, _gpio, _active_low, _desc) \ + { \ + .code = KEY_##_code, \ + .gpio = _gpio, \ + .active_low = _active_low, \ + .desc = _desc, \ + .type = EV_KEY, \ + .wakeup = 1, \ + } + +static struct gpio_keys_button gpio_keys_buttons[] = { + INIT_KEY(POWER, GPIO0_HX4700_nKEY_POWER, 1, "Power button"), + INIT_KEY(MAIL, GPIO94_HX4700_KEY_MAIL, 0, "Mail button"), + INIT_KEY(ADDRESSBOOK, GPIO99_HX4700_KEY_CONTACTS,0, "Contacts button"), + INIT_KEY(RECORD, GPIOD6_nKEY_RECORD, 1, "Record button"), + INIT_KEY(CALENDAR, GPIOD1_nKEY_CALENDAR, 1, "Calendar button"), + INIT_KEY(HOMEPAGE, GPIOD3_nKEY_HOME, 1, "Home button"), +}; + +static struct gpio_keys_platform_data gpio_keys_data = { + .buttons = gpio_keys_buttons, + .nbuttons = ARRAY_SIZE(gpio_keys_buttons), +}; + +static struct platform_device gpio_keys = { + .name = "gpio-keys", + .dev = { + .platform_data = &gpio_keys_data, + }, + .id = -1, +}; + +/* + * ASIC3 + */ + +static u16 asic3_gpio_config[] = { + /* ASIC3 GPIO banks A and B along with some of C and D + implement the buffering for the CF slot. */ + ASIC3_CONFIG_GPIO(0, 1, 1, 0), + ASIC3_CONFIG_GPIO(1, 1, 1, 0), + ASIC3_CONFIG_GPIO(2, 1, 1, 0), + ASIC3_CONFIG_GPIO(3, 1, 1, 0), + ASIC3_CONFIG_GPIO(4, 1, 1, 0), + ASIC3_CONFIG_GPIO(5, 1, 1, 0), + ASIC3_CONFIG_GPIO(6, 1, 1, 0), + ASIC3_CONFIG_GPIO(7, 1, 1, 0), + ASIC3_CONFIG_GPIO(8, 1, 1, 0), + ASIC3_CONFIG_GPIO(9, 1, 1, 0), + ASIC3_CONFIG_GPIO(10, 1, 1, 0), + ASIC3_CONFIG_GPIO(11, 1, 1, 0), + ASIC3_CONFIG_GPIO(12, 1, 1, 0), + ASIC3_CONFIG_GPIO(13, 1, 1, 0), + ASIC3_CONFIG_GPIO(14, 1, 1, 0), + ASIC3_CONFIG_GPIO(15, 1, 1, 0), + + ASIC3_CONFIG_GPIO(16, 1, 1, 0), + ASIC3_CONFIG_GPIO(17, 1, 1, 0), + ASIC3_CONFIG_GPIO(18, 1, 1, 0), + ASIC3_CONFIG_GPIO(19, 1, 1, 0), + ASIC3_CONFIG_GPIO(20, 1, 1, 0), + ASIC3_CONFIG_GPIO(21, 1, 1, 0), + ASIC3_CONFIG_GPIO(22, 1, 1, 0), + ASIC3_CONFIG_GPIO(23, 1, 1, 0), + ASIC3_CONFIG_GPIO(24, 1, 1, 0), + ASIC3_CONFIG_GPIO(25, 1, 1, 0), + ASIC3_CONFIG_GPIO(26, 1, 1, 0), + ASIC3_CONFIG_GPIO(27, 1, 1, 0), + ASIC3_CONFIG_GPIO(28, 1, 1, 0), + ASIC3_CONFIG_GPIO(29, 1, 1, 0), + ASIC3_CONFIG_GPIO(30, 1, 1, 0), + ASIC3_CONFIG_GPIO(31, 1, 1, 0), + + /* GPIOC - CF, LEDs, SD */ + ASIC3_GPIOC0_LED0, /* red */ + ASIC3_GPIOC1_LED1, /* green */ + ASIC3_GPIOC2_LED2, /* blue */ + ASIC3_GPIOC4_CF_nCD, + ASIC3_GPIOC5_nCIOW, + ASIC3_GPIOC6_nCIOR, + ASIC3_GPIOC7_nPCE_1, + ASIC3_GPIOC8_nPCE_2, + ASIC3_GPIOC9_nPOE, + ASIC3_GPIOC10_nPWE, + ASIC3_GPIOC11_PSKTSEL, + ASIC3_GPIOC12_nPREG, + ASIC3_GPIOC13_nPWAIT, + ASIC3_GPIOC14_nPIOIS16, + ASIC3_GPIOC15_nPIOR, + + /* GPIOD: input GPIOs, CF */ + ASIC3_GPIOD11_nCIOIS16, + ASIC3_GPIOD12_nCWAIT, + ASIC3_GPIOD15_nPIOW, +}; + +static struct resource asic3_resources[] = { + /* GPIO part */ + [0] = { + .start = ASIC3_PHYS, + .end = ASIC3_PHYS + ASIC3_MAP_SIZE_16BIT - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ), + .flags = IORESOURCE_IRQ, + }, + /* SD part */ + [2] = { + .start = ASIC3_SD_PHYS, + .end = ASIC3_SD_PHYS + ASIC3_MAP_SIZE_16BIT - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct asic3_platform_data asic3_platform_data = { + .gpio_config = asic3_gpio_config, + .gpio_config_num = ARRAY_SIZE(asic3_gpio_config), + .irq_base = IRQ_BOARD_START, + .gpio_base = HX4700_ASIC3_GPIO_BASE, +}; + +static struct platform_device asic3 = { + .name = "asic3", + .id = -1, + .resource = asic3_resources, + .num_resources = ARRAY_SIZE(asic3_resources), + .dev = { + .platform_data = &asic3_platform_data, + }, +}; + +/* + * EGPIO + */ + +static struct resource egpio_resources[] = { + [0] = { + .start = PXA_CS5_PHYS, + .end = PXA_CS5_PHYS + 0x4 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct htc_egpio_chip egpio_chips[] = { + [0] = { + .reg_start = 0, + .gpio_base = HX4700_EGPIO_BASE, + .num_gpios = 8, + .direction = HTC_EGPIO_OUTPUT, + }, +}; + +static struct htc_egpio_platform_data egpio_info = { + .reg_width = 16, + .bus_width = 16, + .chip = egpio_chips, + .num_chips = ARRAY_SIZE(egpio_chips), +}; + +static struct platform_device egpio = { + .name = "htc-egpio", + .id = -1, + .resource = egpio_resources, + .num_resources = ARRAY_SIZE(egpio_resources), + .dev = { + .platform_data = &egpio_info, + }, +}; + +/* + * LCD - Sony display connected to ATI Imageon w3220 + */ + +static void sony_lcd_init(void) +{ + gpio_set_value(GPIO84_HX4700_LCD_SQN, 1); + gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0); + gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 0); + gpio_set_value(GPIO70_HX4700_LCD_SLIN1, 0); + gpio_set_value(GPIO62_HX4700_LCD_nRESET, 0); + mdelay(10); + gpio_set_value(GPIO59_HX4700_LCD_PC1, 0); + gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0); + mdelay(20); + + gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 1); + mdelay(5); + gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 1); + + /* FIXME: init w3220 registers here */ + + mdelay(5); + gpio_set_value(GPIO70_HX4700_LCD_SLIN1, 1); + mdelay(10); + gpio_set_value(GPIO62_HX4700_LCD_nRESET, 1); + mdelay(10); + gpio_set_value(GPIO59_HX4700_LCD_PC1, 1); + mdelay(10); + gpio_set_value(GPIO112_HX4700_LCD_N2V7_7V3_ON, 1); +} + +static void sony_lcd_off(void) +{ + gpio_set_value(GPIO59_HX4700_LCD_PC1, 0); + gpio_set_value(GPIO62_HX4700_LCD_nRESET, 0); + mdelay(10); + gpio_set_value(GPIO112_HX4700_LCD_N2V7_7V3_ON, 0); + mdelay(10); + gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 0); + mdelay(10); + gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0); +} + +#ifdef CONFIG_PM +static void w3220_lcd_suspend(struct w100fb_par *wfb) +{ + sony_lcd_off(); +} + +static void w3220_lcd_resume(struct w100fb_par *wfb) +{ + sony_lcd_init(); +} +#else +#define w3220_lcd_resume NULL +#define w3220_lcd_suspend NULL +#endif + +static struct w100_tg_info w3220_tg_info = { + .suspend = w3220_lcd_suspend, + .resume = w3220_lcd_resume, +}; + +/* W3220_VGA QVGA */ +static struct w100_gen_regs w3220_regs = { + .lcd_format = 0x00000003, + .lcdd_cntl1 = 0x00000000, + .lcdd_cntl2 = 0x0003ffff, + .genlcd_cntl1 = 0x00abf003, /* 0x00fff003 */ + .genlcd_cntl2 = 0x00000003, + .genlcd_cntl3 = 0x000102aa, +}; + +static struct w100_mode w3220_modes[] = { +{ + .xres = 480, + .yres = 640, + .left_margin = 15, + .right_margin = 16, + .upper_margin = 8, + .lower_margin = 7, + .crtc_ss = 0x00000000, + .crtc_ls = 0xa1ff01f9, /* 0x21ff01f9 */ + .crtc_gs = 0xc0000000, /* 0x40000000 */ + .crtc_vpos_gs = 0x0000028f, + .crtc_ps1_active = 0x00000000, /* 0x41060010 */ + .crtc_rev = 0, + .crtc_dclk = 0x80000000, + .crtc_gclk = 0x040a0104, + .crtc_goe = 0, + .pll_freq = 95, + .pixclk_divider = 4, + .pixclk_divider_rotated = 4, + .pixclk_src = CLK_SRC_PLL, + .sysclk_divider = 0, + .sysclk_src = CLK_SRC_PLL, +}, +{ + .xres = 240, + .yres = 320, + .left_margin = 9, + .right_margin = 8, + .upper_margin = 5, + .lower_margin = 4, + .crtc_ss = 0x80150014, + .crtc_ls = 0xa0fb00f7, + .crtc_gs = 0xc0080007, + .crtc_vpos_gs = 0x00080007, + .crtc_rev = 0x0000000a, + .crtc_dclk = 0x81700030, + .crtc_gclk = 0x8015010f, + .crtc_goe = 0x00000000, + .pll_freq = 95, + .pixclk_divider = 4, + .pixclk_divider_rotated = 4, + .pixclk_src = CLK_SRC_PLL, + .sysclk_divider = 0, + .sysclk_src = CLK_SRC_PLL, +}, +}; + +struct w100_mem_info w3220_mem_info = { + .ext_cntl = 0x09640011, + .sdram_mode_reg = 0x00600021, + .ext_timing_cntl = 0x1a001545, /* 0x15001545 */ + .io_cntl = 0x7ddd7333, + .size = 0x1fffff, +}; + +struct w100_bm_mem_info w3220_bm_mem_info = { + .ext_mem_bw = 0x50413e01, + .offset = 0, + .ext_timing_ctl = 0x00043f7f, + .ext_cntl = 0x00000010, + .mode_reg = 0x00250000, + .io_cntl = 0x0fff0000, + .config = 0x08301480, +}; + +static struct w100_gpio_regs w3220_gpio_info = { + .init_data1 = 0xdfe00100, /* GPIO_DATA */ + .gpio_dir1 = 0xffff0000, /* GPIO_CNTL1 */ + .gpio_oe1 = 0x00000000, /* GPIO_CNTL2 */ + .init_data2 = 0x00000000, /* GPIO_DATA2 */ + .gpio_dir2 = 0x00000000, /* GPIO_CNTL3 */ + .gpio_oe2 = 0x00000000, /* GPIO_CNTL4 */ +}; + +static struct w100fb_mach_info w3220_info = { + .tg = &w3220_tg_info, + .mem = &w3220_mem_info, + .bm_mem = &w3220_bm_mem_info, + .gpio = &w3220_gpio_info, + .regs = &w3220_regs, + .modelist = w3220_modes, + .num_modes = 2, + .xtal_freq = 16000000, +}; + +static struct resource w3220_resources[] = { + [0] = { + .start = ATI_W3220_PHYS, + .end = ATI_W3220_PHYS + 0x00ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device w3220 = { + .name = "w100fb", + .id = -1, + .dev = { + .platform_data = &w3220_info, + }, + .num_resources = ARRAY_SIZE(w3220_resources), + .resource = w3220_resources, +}; + +static void hx4700_lcd_set_power(struct plat_lcd_data *pd, unsigned int power) +{ + if (power) + sony_lcd_init(); + else + sony_lcd_off(); +} + +static struct plat_lcd_data hx4700_lcd_data = { + .set_power = hx4700_lcd_set_power, +}; + +static struct platform_device hx4700_lcd = { + .name = "platform-lcd", + .id = -1, + .dev = { + .platform_data = &hx4700_lcd_data, + .parent = &w3220.dev, + }, +}; + +/* + * Backlight + */ + +static struct platform_pwm_backlight_data backlight_data = { + .pwm_id = 1, + .max_brightness = 200, + .dft_brightness = 100, + .pwm_period_ns = 30923, +}; + +static struct platform_device backlight = { + .name = "pwm-backlight", + .id = -1, + .dev = { + .parent = &pxa27x_device_pwm1.dev, + .platform_data = &backlight_data, + }, +}; + +/* + * USB "Transceiver" + */ + +static struct gpio_vbus_mach_info gpio_vbus_info = { + .gpio_pullup = GPIO76_HX4700_USBC_PUEN, + .gpio_vbus = GPIOD14_nUSBC_DETECT, + .gpio_vbus_inverted = 1, +}; + +static struct platform_device gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &gpio_vbus_info, + }, +}; + +/* + * Touchscreen - TSC2046 connected to SSP2 + */ + +static const struct ads7846_platform_data tsc2046_info = { + .model = 7846, + .vref_delay_usecs = 100, + .pressure_max = 1024, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .gpio_pendown = GPIO58_HX4700_TSC2046_nPENIRQ, +}; + +static struct pxa2xx_spi_chip tsc2046_chip = { + .tx_threshold = 1, + .rx_threshold = 2, + .timeout = 64, + .gpio_cs = GPIO88_HX4700_TSC2046_CS, +}; + +static struct spi_board_info tsc2046_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 2, + .max_speed_hz = 2600000, /* 100 kHz sample rate */ + .irq = PXA_GPIO_TO_IRQ(GPIO58_HX4700_TSC2046_nPENIRQ), + .platform_data = &tsc2046_info, + .controller_data = &tsc2046_chip, + }, +}; + +static struct pxa2xx_spi_master pxa_ssp2_master_info = { + .num_chipselect = 1, + .clock_enable = CKEN_SSP2, + .enable_dma = 1, +}; + +/* + * External power + */ + +static int power_supply_init(struct device *dev) +{ + return gpio_request(GPIOD9_nAC_IN, "AC charger detect"); +} + +static int hx4700_is_ac_online(void) +{ + return !gpio_get_value(GPIOD9_nAC_IN); +} + +static void power_supply_exit(struct device *dev) +{ + gpio_free(GPIOD9_nAC_IN); +} + +static char *hx4700_supplicants[] = { + "ds2760-battery.0", "backup-battery" +}; + +static struct pda_power_pdata power_supply_info = { + .init = power_supply_init, + .is_ac_online = hx4700_is_ac_online, + .exit = power_supply_exit, + .supplied_to = hx4700_supplicants, + .num_supplicants = ARRAY_SIZE(hx4700_supplicants), +}; + +static struct resource power_supply_resources[] = { + [0] = { + .name = "ac", + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + .start = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), + .end = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), + }, + [1] = { + .name = "usb", + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + .start = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), + .end = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), + }, +}; + +static struct platform_device power_supply = { + .name = "pda-power", + .id = -1, + .dev = { + .platform_data = &power_supply_info, + }, + .resource = power_supply_resources, + .num_resources = ARRAY_SIZE(power_supply_resources), +}; + +/* + * Battery charger + */ + +static struct regulator_consumer_supply bq24022_consumers[] = { + { + .dev = &gpio_vbus.dev, + .supply = "vbus_draw", + }, + { + .dev = &power_supply.dev, + .supply = "ac_draw", + }, +}; + +static struct regulator_init_data bq24022_init_data = { + .constraints = { + .max_uA = 500000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), + .consumer_supplies = bq24022_consumers, +}; + +static struct bq24022_mach_info bq24022_info = { + .gpio_nce = GPIO72_HX4700_BQ24022_nCHARGE_EN, + .gpio_iset2 = GPIO96_HX4700_BQ24022_ISET2, + .init_data = &bq24022_init_data, +}; + +static struct platform_device bq24022 = { + .name = "bq24022", + .id = -1, + .dev = { + .platform_data = &bq24022_info, + }, +}; + +/* + * StrataFlash + */ + +static void hx4700_set_vpp(struct platform_device *pdev, int vpp) +{ + gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp); +} + +static struct resource strataflash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_128M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct physmap_flash_data strataflash_data = { + .width = 4, + .set_vpp = hx4700_set_vpp, +}; + +static struct platform_device strataflash = { + .name = "physmap-flash", + .id = -1, + .resource = &strataflash_resource, + .num_resources = 1, + .dev = { + .platform_data = &strataflash_data, + }, +}; + +/* + * Maxim MAX1587A on PI2C + */ + +static struct regulator_consumer_supply max1587a_consumer = { + .supply = "vcc_core", +}; + +static struct regulator_init_data max1587a_v3_info = { + .constraints = { + .name = "vcc_core range", + .min_uV = 900000, + .max_uV = 1705000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max1587a_consumer, +}; + +static struct max1586_subdev_data max1587a_subdev = { + .name = "vcc_core", + .id = MAX1586_V3, + .platform_data = &max1587a_v3_info, +}; + +static struct max1586_platform_data max1587a_info = { + .num_subdevs = 1, + .subdevs = &max1587a_subdev, + .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */ +}; + +static struct i2c_board_info __initdata pi2c_board_info[] = { + { + I2C_BOARD_INFO("max1586", 0x14), + .platform_data = &max1587a_info, + }, +}; + +/* + * Asahi Kasei AK4641 on I2C + */ + +static struct ak4641_platform_data ak4641_info = { + .gpio_power = GPIO27_HX4700_CODEC_ON, + .gpio_npdn = GPIO109_HX4700_CODEC_nPDN, +}; + +static struct i2c_board_info i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("ak4641", 0x12), + .platform_data = &ak4641_info, + }, +}; + +static struct platform_device audio = { + .name = "hx4700-audio", + .id = -1, +}; + + +/* + * PCMCIA + */ + +static struct platform_device pcmcia = { + .name = "hx4700-pcmcia", + .dev = { + .parent = &asic3.dev, + }, +}; + +/* + * Platform devices + */ + +static struct platform_device *devices[] __initdata = { + &asic3, + &gpio_keys, + &backlight, + &w3220, + &hx4700_lcd, + &egpio, + &bq24022, + &gpio_vbus, + &power_supply, + &strataflash, + &audio, + &pcmcia, +}; + +static struct gpio global_gpios[] = { + { GPIO12_HX4700_ASIC3_IRQ, GPIOF_IN, "ASIC3_IRQ" }, + { GPIO13_HX4700_W3220_IRQ, GPIOF_IN, "W3220_IRQ" }, + { GPIO14_HX4700_nWLAN_IRQ, GPIOF_IN, "WLAN_IRQ" }, + { GPIO59_HX4700_LCD_PC1, GPIOF_OUT_INIT_HIGH, "LCD_PC1" }, + { GPIO62_HX4700_LCD_nRESET, GPIOF_OUT_INIT_HIGH, "LCD_RESET" }, + { GPIO70_HX4700_LCD_SLIN1, GPIOF_OUT_INIT_HIGH, "LCD_SLIN1" }, + { GPIO84_HX4700_LCD_SQN, GPIOF_OUT_INIT_HIGH, "LCD_SQN" }, + { GPIO110_HX4700_LCD_LVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_LVDD" }, + { GPIO111_HX4700_LCD_AVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_AVDD" }, + { GPIO32_HX4700_RS232_ON, GPIOF_OUT_INIT_HIGH, "RS232_ON" }, + { GPIO71_HX4700_ASIC3_nRESET, GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" }, + { GPIO82_HX4700_EUART_RESET, GPIOF_OUT_INIT_HIGH, "EUART_RESET" }, + { GPIO105_HX4700_nIR_ON, GPIOF_OUT_INIT_HIGH, "nIR_EN" }, +}; + +static void __init hx4700_init(void) +{ + int ret; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config)); + ret = gpio_request_array(ARRAY_AND_SIZE(global_gpios)); + if (ret) + pr_err ("hx4700: Failed to request GPIOs.\n"); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + pxa_set_ficp_info(&ficp_info); + pxa27x_set_i2c_power_info(NULL); + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info)); + i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info)); + pxa2xx_set_spi_info(2, &pxa_ssp2_master_info); + spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info)); + + gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 0); + mdelay(10); + gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1); + mdelay(10); +} + +MACHINE_START(H4700, "HP iPAQ HX4700") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = HX4700_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_machine = hx4700_init, + .timer = &pxa_timer, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c new file mode 100644 index 00000000000..67400192ed3 --- /dev/null +++ b/arch/arm/mach-pxa/icontrol.c @@ -0,0 +1,201 @@ +/* + * linux/arch/arm/mach-pxa/icontrol.c + * + * Support for the iControl and SafeTcam platforms from TMT Services + * using the Embedian MXM-8x10 Computer on Module + * + * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd. + * + * 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za> + * + * 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/irq.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa320.h> +#include <mach/mxm8x10.h> + +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/can/platform/mcp251x.h> + +#include "generic.h" + +#define ICONTROL_MCP251x_nCS1 (15) +#define ICONTROL_MCP251x_nCS2 (16) +#define ICONTROL_MCP251x_nCS3 (17) +#define ICONTROL_MCP251x_nCS4 (24) + +#define ICONTROL_MCP251x_nIRQ1 (74) +#define ICONTROL_MCP251x_nIRQ2 (75) +#define ICONTROL_MCP251x_nIRQ3 (76) +#define ICONTROL_MCP251x_nIRQ4 (77) + +static struct pxa2xx_spi_chip mcp251x_chip_info1 = { + .tx_threshold = 8, + .rx_threshold = 128, + .dma_burst_size = 8, + .timeout = 235, + .gpio_cs = ICONTROL_MCP251x_nCS1 +}; + +static struct pxa2xx_spi_chip mcp251x_chip_info2 = { + .tx_threshold = 8, + .rx_threshold = 128, + .dma_burst_size = 8, + .timeout = 235, + .gpio_cs = ICONTROL_MCP251x_nCS2 +}; + +static struct pxa2xx_spi_chip mcp251x_chip_info3 = { + .tx_threshold = 8, + .rx_threshold = 128, + .dma_burst_size = 8, + .timeout = 235, + .gpio_cs = ICONTROL_MCP251x_nCS3 +}; + +static struct pxa2xx_spi_chip mcp251x_chip_info4 = { + .tx_threshold = 8, + .rx_threshold = 128, + .dma_burst_size = 8, + .timeout = 235, + .gpio_cs = ICONTROL_MCP251x_nCS4 +}; + +static struct mcp251x_platform_data mcp251x_info = { + .oscillator_frequency = 16E6, + .board_specific_setup = NULL, + .power_enable = NULL, + .transceiver_enable = NULL +}; + +static struct spi_board_info mcp251x_board_info[] = { + { + .modalias = "mcp2515", + .max_speed_hz = 6500000, + .bus_num = 3, + .chip_select = 0, + .platform_data = &mcp251x_info, + .controller_data = &mcp251x_chip_info1, + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1) + }, + { + .modalias = "mcp2515", + .max_speed_hz = 6500000, + .bus_num = 3, + .chip_select = 1, + .platform_data = &mcp251x_info, + .controller_data = &mcp251x_chip_info2, + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2) + }, + { + .modalias = "mcp2515", + .max_speed_hz = 6500000, + .bus_num = 4, + .chip_select = 0, + .platform_data = &mcp251x_info, + .controller_data = &mcp251x_chip_info3, + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3) + }, + { + .modalias = "mcp2515", + .max_speed_hz = 6500000, + .bus_num = 4, + .chip_select = 1, + .platform_data = &mcp251x_info, + .controller_data = &mcp251x_chip_info4, + .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4) + } +}; + +static struct pxa2xx_spi_master pxa_ssp3_spi_master_info = { + .clock_enable = CKEN_SSP3, + .num_chipselect = 2, + .enable_dma = 1 +}; + +static struct pxa2xx_spi_master pxa_ssp4_spi_master_info = { + .clock_enable = CKEN_SSP4, + .num_chipselect = 2, + .enable_dma = 1 +}; + +struct platform_device pxa_spi_ssp3 = { + .name = "pxa2xx-spi", + .id = 3, + .dev = { + .platform_data = &pxa_ssp3_spi_master_info, + } +}; + +struct platform_device pxa_spi_ssp4 = { + .name = "pxa2xx-spi", + .id = 4, + .dev = { + .platform_data = &pxa_ssp4_spi_master_info, + } +}; + +static struct platform_device *icontrol_spi_devices[] __initdata = { + &pxa_spi_ssp3, + &pxa_spi_ssp4, +}; + +static mfp_cfg_t mfp_can_cfg[] __initdata = { + /* CAN CS lines */ + GPIO15_GPIO, + GPIO16_GPIO, + GPIO17_GPIO, + GPIO24_GPIO, + + /* SPI (SSP3) lines */ + GPIO89_SSP3_SCLK, + GPIO91_SSP3_TXD, + GPIO92_SSP3_RXD, + + /* SPI (SSP4) lines */ + GPIO93_SSP4_SCLK, + GPIO95_SSP4_TXD, + GPIO96_SSP4_RXD, + + /* CAN nIRQ lines */ + GPIO74_GPIO | MFP_LPM_EDGE_RISE, + GPIO75_GPIO | MFP_LPM_EDGE_RISE, + GPIO76_GPIO | MFP_LPM_EDGE_RISE, + GPIO77_GPIO | MFP_LPM_EDGE_RISE +}; + +static void __init icontrol_can_init(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg)); + platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices)); + spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info)); +} + +static void __init icontrol_init(void) +{ + mxm_8x10_barebones_init(); + mxm_8x10_usb_host_init(); + mxm_8x10_mmc_init(); + + icontrol_can_init(); +} + +MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .timer = &pxa_timer, + .init_machine = icontrol_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c new file mode 100644 index 00000000000..8af1840e12c --- /dev/null +++ b/arch/arm/mach-pxa/idp.c @@ -0,0 +1,203 @@ +/* + * linux/arch/arm/mach-pxa/idp.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. + * + * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc. + * + * 2001-09-13: Cliff Brake <cbrake@accelent.com> + * Initial code + * + * 2005-02-15: Cliff Brake <cliff.brake@gmail.com> + * <http://www.vibren.com> <http://bec-systems.com> + * Updated for 2.6 kernel + * + */ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/fb.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa25x.h> +#include <mach/idp.h> +#include <mach/pxafb.h> +#include <mach/bitfield.h> +#include <mach/mmc.h> + +#include "generic.h" +#include "devices.h" + +/* TODO: + * - add pxa2xx_audio_ops_t device structure + * - Ethernet interrupt + */ + +static unsigned long idp_pin_config[] __initdata = { + /* LCD */ + GPIOxx_LCD_DSTN_16BPP, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* MMC */ + GPIO6_MMC_CLK, + GPIO8_MMC_CS0, + + /* Ethernet */ + GPIO33_nCS_5, /* Ethernet CS */ + GPIO4_GPIO, /* Ethernet IRQ */ +}; + +static struct resource smc91x_resources[] = { + [0] = { + .start = (IDP_ETH_PHYS + 0x300), + .end = (IDP_ETH_PHYS + 0xfffff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(4), + .end = PXA_GPIO_TO_IRQ(4), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static void idp_backlight_power(int on) +{ + if (on) { + IDP_CPLD_LCD |= (1<<1); + } else { + IDP_CPLD_LCD &= ~(1<<1); + } +} + +static void idp_vlcd(int on) +{ + if (on) { + IDP_CPLD_LCD |= (1<<2); + } else { + IDP_CPLD_LCD &= ~(1<<2); + } +} + +static void idp_lcd_power(int on, struct fb_var_screeninfo *var) +{ + if (on) { + IDP_CPLD_LCD |= (1<<0); + } else { + IDP_CPLD_LCD &= ~(1<<0); + } + + /* call idp_vlcd for now as core driver does not support + * both power and vlcd hooks. Note, this is not technically + * the correct sequence, but seems to work. Disclaimer: + * this may eventually damage the display. + */ + + idp_vlcd(on); +} + +static struct pxafb_mode_info sharp_lm8v31_mode = { + .pixclock = 270000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 1, + .left_margin = 3, + .right_margin = 3, + .vsync_len = 1, + .upper_margin = 0, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info sharp_lm8v31 = { + .modes = &sharp_lm8v31_mode, + .num_modes = 1, + .cmap_inverse = 0, + .cmap_static = 0, + .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL | + LCD_AC_BIAS_FREQ(255), + .pxafb_backlight_power = &idp_backlight_power, + .pxafb_lcd_power = &idp_lcd_power +}; + +static struct pxamci_platform_data idp_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +static void __init idp_init(void) +{ + printk("idp_init()\n"); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(idp_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + platform_device_register(&smc91x_device); + //platform_device_register(&mst_audio_device); + pxa_set_fb_info(NULL, &sharp_lm8v31); + pxa_set_mci_info(&idp_mci_platform_data); +} + +static struct map_desc idp_io_desc[] __initdata = { + { + .virtual = IDP_COREVOLT_VIRT, + .pfn = __phys_to_pfn(IDP_COREVOLT_PHYS), + .length = IDP_COREVOLT_SIZE, + .type = MT_DEVICE + }, { + .virtual = IDP_CPLD_VIRT, + .pfn = __phys_to_pfn(IDP_CPLD_PHYS), + .length = IDP_CPLD_SIZE, + .type = MT_DEVICE + } +}; + +static void __init idp_map_io(void) +{ + pxa25x_map_io(); + iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc)); +} + + +MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") + /* Maintainer: Vibren Technologies */ + .map_io = idp_map_io, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .timer = &pxa_timer, + .init_machine = idp_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h new file mode 100644 index 00000000000..bbf9df37ad4 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/addr-map.h @@ -0,0 +1,48 @@ +#ifndef __ASM_MACH_ADDR_MAP_H +#define __ASM_MACH_ADDR_MAP_H + +/* + * Chip Selects + */ +#define PXA_CS0_PHYS 0x00000000 +#define PXA_CS1_PHYS 0x04000000 +#define PXA_CS2_PHYS 0x08000000 +#define PXA_CS3_PHYS 0x0C000000 +#define PXA_CS4_PHYS 0x10000000 +#define PXA_CS5_PHYS 0x14000000 + +#define PXA300_CS0_PHYS 0x00000000 /* PXA300/PXA310 _only_ */ +#define PXA300_CS1_PHYS 0x30000000 /* PXA300/PXA310 _only_ */ +#define PXA3xx_CS2_PHYS 0x10000000 +#define PXA3xx_CS3_PHYS 0x14000000 + +/* + * Peripheral Bus + */ +#define PERIPH_PHYS 0x40000000 +#define PERIPH_VIRT IOMEM(0xf2000000) +#define PERIPH_SIZE 0x02000000 + +/* + * Static Memory Controller (w/ SDRAM controls on PXA25x/PXA27x) + */ +#define PXA2XX_SMEMC_PHYS 0x48000000 +#define PXA3XX_SMEMC_PHYS 0x4a000000 +#define SMEMC_VIRT IOMEM(0xf6000000) +#define SMEMC_SIZE 0x00100000 + +/* + * Dynamic Memory Controller (only on PXA3xx) + */ +#define DMEMC_PHYS 0x48100000 +#define DMEMC_VIRT IOMEM(0xf6100000) +#define DMEMC_SIZE 0x00100000 + +/* + * Internal Memory Controller (PXA27x and later) + */ +#define IMEMC_PHYS 0x58000000 +#define IMEMC_VIRT IOMEM(0xfe000000) +#define IMEMC_SIZE 0x00100000 + +#endif /* __ASM_MACH_ADDR_MAP_H */ diff --git a/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h b/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h new file mode 100644 index 00000000000..d428be4db44 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h @@ -0,0 +1,11 @@ +#ifndef __ARCOM_PCMCIA_H +#define __ARCOM_PCMCIA_H + +struct arcom_pcmcia_pdata { + int cd_gpio; + int rdy_gpio; + int pwr_gpio; + void (*reset)(int state); +}; + +#endif diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h new file mode 100644 index 00000000000..a3449e35a6f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/audio.h @@ -0,0 +1,30 @@ +#ifndef __ASM_ARCH_AUDIO_H__ +#define __ASM_ARCH_AUDIO_H__ + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/ac97_codec.h> + +/* + * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) + * a -1 value means no gpio will be used for reset + * @codec_pdata: AC97 codec platform_data + + * reset_gpio should only be specified for pxa27x CPUs where a silicon + * bug prevents correct operation of the reset line. If not specified, + * the default behaviour on these CPUs is to consider gpio 113 as the + * AC97 reset line, which is the default on most boards. + */ +typedef struct { + int (*startup)(struct snd_pcm_substream *, void *); + void (*shutdown)(struct snd_pcm_substream *, void *); + void (*suspend)(void *); + void (*resume)(void *); + void *priv; + int reset_gpio; + void *codec_pdata[AC97_BUS_MAX_DEVICES]; +} pxa2xx_audio_ops_t; + +extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); + +#endif diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h new file mode 100644 index 00000000000..f02fa1e6ba8 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -0,0 +1,183 @@ +/* + * linux/include/asm-arm/arch-pxa/balloon3.h + * + * Authors: Nick Bane and Wookey + * Created: Oct, 2005 + * Copyright: Toby Churchill Ltd + * Cribbed from mainstone.c, by Nicholas Pitre + * + * 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 ASM_ARCH_BALLOON3_H +#define ASM_ARCH_BALLOON3_H + +enum balloon3_features { + BALLOON3_FEATURE_OHCI, + BALLOON3_FEATURE_MMC, + BALLOON3_FEATURE_CF, + BALLOON3_FEATURE_AUDIO, + BALLOON3_FEATURE_TOPPOLY, +}; + +#define BALLOON3_FPGA_PHYS PXA_CS4_PHYS +#define BALLOON3_FPGA_VIRT IOMEM(0xf1000000) /* as per balloon2 */ +#define BALLOON3_FPGA_LENGTH 0x01000000 + +#define BALLOON3_FPGA_SETnCLR (0x1000) + +/* FPGA / CPLD registers for CF socket */ +#define BALLOON3_CF_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00e00008) +#define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008) +/* FPGA / CPLD version register */ +#define BALLOON3_FPGA_VER (BALLOON3_FPGA_VIRT + 0x00e0001c) +/* FPGA / CPLD registers for NAND flash */ +#define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000) +#define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000) +#define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010) +#define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00014) +#define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014) + +/* fpga/cpld interrupt control register */ +#define BALLOON3_INT_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e0000C) +#define BALLOON3_VERSION_REG (BALLOON3_FPGA_VIRT + 0x00e0001c) + +#define BALLOON3_SAMOSA_ADDR_REG (BALLOON3_FPGA_VIRT + 0x00c00000) +#define BALLOON3_SAMOSA_DATA_REG (BALLOON3_FPGA_VIRT + 0x00c00004) +#define BALLOON3_SAMOSA_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00c0001c) + +/* CF Status Register bits (read-only) bits */ +#define BALLOON3_CF_nIRQ (1 << 0) +#define BALLOON3_CF_nSTSCHG_BVD1 (1 << 1) + +/* CF Control Set Register bits / CF Control Clear Register bits (write-only) */ +#define BALLOON3_CF_RESET (1 << 0) +#define BALLOON3_CF_ENABLE (1 << 1) +#define BALLOON3_CF_ADD_ENABLE (1 << 2) + +/* CF Interrupt sources */ +#define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0) +#define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1) + +/* NAND Control register */ +#define BALLOON3_NAND_CONTROL_FLWP (1 << 7) +#define BALLOON3_NAND_CONTROL_FLSE (1 << 6) +#define BALLOON3_NAND_CONTROL_FLCE3 (1 << 5) +#define BALLOON3_NAND_CONTROL_FLCE2 (1 << 4) +#define BALLOON3_NAND_CONTROL_FLCE1 (1 << 3) +#define BALLOON3_NAND_CONTROL_FLCE0 (1 << 2) +#define BALLOON3_NAND_CONTROL_FLALE (1 << 1) +#define BALLOON3_NAND_CONTROL_FLCLE (1 << 0) + +/* NAND Status register */ +#define BALLOON3_NAND_STAT_RNB (1 << 0) + +/* NAND Control2 register */ +#define BALLOON3_NAND_CONTROL2_16BIT (1 << 0) + +/* GPIOs for irqs */ +#define BALLOON3_GPIO_AUX_NIRQ (94) +#define BALLOON3_GPIO_CODEC_IRQ (95) + +/* Timer and Idle LED locations */ +#define BALLOON3_GPIO_LED_NAND (9) +#define BALLOON3_GPIO_LED_IDLE (10) + +/* backlight control */ +#define BALLOON3_GPIO_RUN_BACKLIGHT (99) + +#define BALLOON3_GPIO_S0_CD (105) + +/* NAND */ +#define BALLOON3_GPIO_RUN_NAND (102) + +/* PCF8574A Leds */ +#define BALLOON3_PCF_GPIO_BASE 160 +#define BALLOON3_PCF_GPIO_LED0 (BALLOON3_PCF_GPIO_BASE + 0) +#define BALLOON3_PCF_GPIO_LED1 (BALLOON3_PCF_GPIO_BASE + 1) +#define BALLOON3_PCF_GPIO_LED2 (BALLOON3_PCF_GPIO_BASE + 2) +#define BALLOON3_PCF_GPIO_LED3 (BALLOON3_PCF_GPIO_BASE + 3) +#define BALLOON3_PCF_GPIO_LED4 (BALLOON3_PCF_GPIO_BASE + 4) +#define BALLOON3_PCF_GPIO_LED5 (BALLOON3_PCF_GPIO_BASE + 5) +#define BALLOON3_PCF_GPIO_LED6 (BALLOON3_PCF_GPIO_BASE + 6) +#define BALLOON3_PCF_GPIO_LED7 (BALLOON3_PCF_GPIO_BASE + 7) + +/* FPGA Interrupt Mask/Acknowledge Register */ +#define BALLOON3_INT_S0_IRQ (1 << 0) /* PCMCIA 0 IRQ */ +#define BALLOON3_INT_S0_STSCHG (1 << 1) /* PCMCIA 0 status changed */ + +/* CPLD (and FPGA) interface definitions */ +#define CPLD_LCD0_DATA_SET 0x00 +#define CPLD_LCD0_DATA_CLR 0x10 +#define CPLD_LCD0_COMMAND_SET 0x01 +#define CPLD_LCD0_COMMAND_CLR 0x11 +#define CPLD_LCD1_DATA_SET 0x02 +#define CPLD_LCD1_DATA_CLR 0x12 +#define CPLD_LCD1_COMMAND_SET 0x03 +#define CPLD_LCD1_COMMAND_CLR 0x13 + +#define CPLD_MISC_SET 0x07 +#define CPLD_MISC_CLR 0x17 +#define CPLD_MISC_LOON_NRESET_BIT 0 +#define CPLD_MISC_LOON_UNSUSP_BIT 1 +#define CPLD_MISC_RUN_5V_BIT 2 +#define CPLD_MISC_CHG_D0_BIT 3 +#define CPLD_MISC_CHG_D1_BIT 4 +#define CPLD_MISC_DAC_NCS_BIT 5 + +#define CPLD_LCD_SET 0x08 +#define CPLD_LCD_CLR 0x18 +#define CPLD_LCD_BACKLIGHT_EN_0_BIT 0 +#define CPLD_LCD_BACKLIGHT_EN_1_BIT 1 +#define CPLD_LCD_LED_RED_BIT 4 +#define CPLD_LCD_LED_GREEN_BIT 5 +#define CPLD_LCD_NRESET_BIT 7 + +#define CPLD_LCD_RO_SET 0x09 +#define CPLD_LCD_RO_CLR 0x19 +#define CPLD_LCD_RO_LCD0_nWAIT_BIT 0 +#define CPLD_LCD_RO_LCD1_nWAIT_BIT 1 + +#define CPLD_SERIAL_SET 0x0a +#define CPLD_SERIAL_CLR 0x1a +#define CPLD_SERIAL_GSM_RI_BIT 0 +#define CPLD_SERIAL_GSM_CTS_BIT 1 +#define CPLD_SERIAL_GSM_DTR_BIT 2 +#define CPLD_SERIAL_LPR_CTS_BIT 3 +#define CPLD_SERIAL_TC232_CTS_BIT 4 +#define CPLD_SERIAL_TC232_DSR_BIT 5 + +#define CPLD_SROUTING_SET 0x0b +#define CPLD_SROUTING_CLR 0x1b +#define CPLD_SROUTING_MSP430_LPR 0 +#define CPLD_SROUTING_MSP430_TC232 1 +#define CPLD_SROUTING_MSP430_GSM 2 +#define CPLD_SROUTING_LOON_LPR (0 << 4) +#define CPLD_SROUTING_LOON_TC232 (1 << 4) +#define CPLD_SROUTING_LOON_GSM (2 << 4) + +#define CPLD_AROUTING_SET 0x0c +#define CPLD_AROUTING_CLR 0x1c +#define CPLD_AROUTING_MIC2PHONE_BIT 0 +#define CPLD_AROUTING_PHONE2INT_BIT 1 +#define CPLD_AROUTING_PHONE2EXT_BIT 2 +#define CPLD_AROUTING_LOONL2INT_BIT 3 +#define CPLD_AROUTING_LOONL2EXT_BIT 4 +#define CPLD_AROUTING_LOONR2PHONE_BIT 5 +#define CPLD_AROUTING_LOONR2INT_BIT 6 +#define CPLD_AROUTING_LOONR2EXT_BIT 7 + +/* Balloon3 Interrupts */ +#define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x)) + +#define BALLOON3_AUX_NIRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ) +#define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ) +#define BALLOON3_S0_CD_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD) + +#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16) + +extern int balloon3_has(enum balloon3_features feature); + +#endif diff --git a/arch/arm/mach-pxa/include/mach/bitfield.h b/arch/arm/mach-pxa/include/mach/bitfield.h new file mode 100644 index 00000000000..f1f0e3387d9 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/bitfield.h @@ -0,0 +1,113 @@ +/* + * FILE bitfield.h + * + * Version 1.1 + * Author Copyright (c) Marc A. Viredaz, 1998 + * DEC Western Research Laboratory, Palo Alto, CA + * Date April 1998 (April 1997) + * System Advanced RISC Machine (ARM) + * Language C or ARM Assembly + * Purpose Definition of macros to operate on bit fields. + */ + + + +#ifndef __BITFIELD_H +#define __BITFIELD_H + +#ifndef __ASSEMBLY__ +#define UData(Data) ((unsigned long) (Data)) +#else +#define UData(Data) (Data) +#endif + + +/* + * MACRO: Fld + * + * Purpose + * The macro "Fld" encodes a bit field, given its size and its shift value + * with respect to bit 0. + * + * Note + * A more intuitive way to encode bit fields would have been to use their + * mask. However, extracting size and shift value information from a bit + * field's mask is cumbersome and might break the assembler (255-character + * line-size limit). + * + * Input + * Size Size of the bit field, in number of bits. + * Shft Shift value of the bit field with respect to bit 0. + * + * Output + * Fld Encoded bit field. + */ + +#define Fld(Size, Shft) (((Size) << 16) + (Shft)) + + +/* + * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit + * + * Purpose + * The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return + * the size, shift value, mask, aligned mask, and first bit of a + * bit field. + * + * Input + * Field Encoded bit field (using the macro "Fld"). + * + * Output + * FSize Size of the bit field, in number of bits. + * FShft Shift value of the bit field with respect to bit 0. + * FMsk Mask for the bit field. + * FAlnMsk Mask for the bit field, aligned on bit 0. + * F1stBit First bit of the bit field. + */ + +#define FSize(Field) ((Field) >> 16) +#define FShft(Field) ((Field) & 0x0000FFFF) +#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field)) +#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1) +#define F1stBit(Field) (UData (1) << FShft (Field)) + + +/* + * MACRO: FInsrt + * + * Purpose + * The macro "FInsrt" inserts a value into a bit field by shifting the + * former appropriately. + * + * Input + * Value Bit-field value. + * Field Encoded bit field (using the macro "Fld"). + * + * Output + * FInsrt Bit-field value positioned appropriately. + */ + +#define FInsrt(Value, Field) \ + (UData (Value) << FShft (Field)) + + +/* + * MACRO: FExtr + * + * Purpose + * The macro "FExtr" extracts the value of a bit field by masking and + * shifting it appropriately. + * + * Input + * Data Data containing the bit-field to be extracted. + * Field Encoded bit field (using the macro "Fld"). + * + * Output + * FExtr Bit-field value. + */ + +#define FExtr(Data, Field) \ + ((UData (Data) >> FShft (Field)) & FAlnMsk (Field)) + + +#endif /* __BITFIELD_H */ diff --git a/arch/arm/mach-pxa/include/mach/camera.h b/arch/arm/mach-pxa/include/mach/camera.h new file mode 100644 index 00000000000..6709b1cd7c7 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/camera.h @@ -0,0 +1,44 @@ +/* + camera.h - PXA camera driver header file + + Copyright (C) 2003, Intel Corporation + Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> + + 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; either version 2 of the License, or + (at your option) any later version. + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ASM_ARCH_CAMERA_H_ +#define __ASM_ARCH_CAMERA_H_ + +#define PXA_CAMERA_MASTER 1 +#define PXA_CAMERA_DATAWIDTH_4 2 +#define PXA_CAMERA_DATAWIDTH_5 4 +#define PXA_CAMERA_DATAWIDTH_8 8 +#define PXA_CAMERA_DATAWIDTH_9 0x10 +#define PXA_CAMERA_DATAWIDTH_10 0x20 +#define PXA_CAMERA_PCLK_EN 0x40 +#define PXA_CAMERA_MCLK_EN 0x80 +#define PXA_CAMERA_PCP 0x100 +#define PXA_CAMERA_HSP 0x200 +#define PXA_CAMERA_VSP 0x400 + +struct pxacamera_platform_data { + unsigned long flags; + unsigned long mclk_10khz; +}; + +extern void pxa_set_camera_info(struct pxacamera_platform_data *); + +#endif /* __ASM_ARCH_CAMERA_H_ */ diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h new file mode 100644 index 00000000000..cb4236e98a0 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/colibri.h @@ -0,0 +1,69 @@ +#ifndef _COLIBRI_H_ +#define _COLIBRI_H_ + +#include <net/ax88796.h> +#include <mach/mfp.h> + +/* + * base board glue for PXA270 module + */ + +enum { + COLIBRI_EVALBOARD = 0, + COLIBRI_PXA270_INCOME, +}; + +#if defined(CONFIG_MACH_COLIBRI_EVALBOARD) +extern void colibri_evalboard_init(void); +#else +static inline void colibri_evalboard_init(void) {} +#endif + +#if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME) +extern void colibri_pxa270_income_boardinit(void); +#else +static inline void colibri_pxa270_income_boardinit(void) {} +#endif + +/* + * common settings for all modules + */ + +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +extern void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin); +#else +static inline void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin) {} +#endif + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +extern void colibri_pxa3xx_init_lcd(int bl_pin); +#else +static inline void colibri_pxa3xx_init_lcd(int bl_pin) {} +#endif + +#if defined(CONFIG_AX88796) +extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data); +#endif + +#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +extern void colibri_pxa3xx_init_nand(void); +#else +static inline void colibri_pxa3xx_init_nand(void) {} +#endif + +/* physical memory regions */ +#define COLIBRI_SDRAM_BASE 0xa0000000 /* SDRAM region */ + +/* GPIO definitions for Colibri PXA270 */ +#define GPIO114_COLIBRI_PXA270_ETH_IRQ 114 +#define GPIO0_COLIBRI_PXA270_SD_DETECT 0 +#define GPIO113_COLIBRI_PXA270_TS_IRQ 113 + +/* GPIO definitions for Colibri PXA300/310 */ +#define GPIO13_COLIBRI_PXA300_SD_DETECT 13 + +/* GPIO definitions for Colibri PXA320 */ +#define GPIO28_COLIBRI_PXA320_SD_DETECT 28 + +#endif /* _COLIBRI_H_ */ + diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h new file mode 100644 index 00000000000..f3c3493b468 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/corgi.h @@ -0,0 +1,113 @@ +/* + * Hardware specific definitions for SL-C7xx series of PDAs + * + * Copyright (c) 2004-2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches + * + * 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 __ASM_ARCH_CORGI_H +#define __ASM_ARCH_CORGI_H 1 + + +/* + * Corgi (Non Standard) GPIO Definitions + */ +#define CORGI_GPIO_KEY_INT (0) /* Keyboard Interrupt */ +#define CORGI_GPIO_AC_IN (1) /* Charger Detection */ +#define CORGI_GPIO_WAKEUP (3) /* System wakeup notification? */ +#define CORGI_GPIO_AK_INT (4) /* Headphone Jack Control Interrupt */ +#define CORGI_GPIO_TP_INT (5) /* Touch Panel Interrupt */ +#define CORGI_GPIO_nSD_WP (7) /* SD Write Protect? */ +#define CORGI_GPIO_nSD_DETECT (9) /* MMC/SD Card Detect */ +#define CORGI_GPIO_nSD_INT (10) /* SD Interrupt for SDIO? */ +#define CORGI_GPIO_MAIN_BAT_LOW (11) /* Main Battery Low Notification */ +#define CORGI_GPIO_BAT_COVER (11) /* Battery Cover Detect */ +#define CORGI_GPIO_LED_ORANGE (13) /* Orange LED Control */ +#define CORGI_GPIO_CF_CD (14) /* Compact Flash Card Detect */ +#define CORGI_GPIO_CHRG_FULL (16) /* Charging Complete Notification */ +#define CORGI_GPIO_CF_IRQ (17) /* Compact Flash Interrupt */ +#define CORGI_GPIO_LCDCON_CS (19) /* LCD Control Chip Select */ +#define CORGI_GPIO_MAX1111_CS (20) /* MAX1111 Chip Select */ +#define CORGI_GPIO_ADC_TEMP_ON (21) /* Select battery voltage or temperature */ +#define CORGI_GPIO_IR_ON (22) /* Enable IR Transceiver */ +#define CORGI_GPIO_ADS7846_CS (24) /* ADS7846 Chip Select */ +#define CORGI_GPIO_SD_PWR (33) /* MMC/SD Power */ +#define CORGI_GPIO_CHRG_ON (38) /* Enable battery Charging */ +#define CORGI_GPIO_DISCHARGE_ON (42) /* Enable battery Discharge */ +#define CORGI_GPIO_CHRG_UKN (43) /* Unknown Charging (Bypass Control?) */ +#define CORGI_GPIO_HSYNC (44) /* LCD HSync Pulse */ +#define CORGI_GPIO_USB_PULLUP (45) /* USB show presence to host */ + + +/* + * Corgi Keyboard Definitions + */ +#define CORGI_KEY_STROBE_NUM (12) +#define CORGI_KEY_SENSE_NUM (8) +#define CORGI_GPIO_ALL_STROBE_BIT (0x00003ffc) +#define CORGI_GPIO_HIGH_SENSE_BIT (0xfc000000) +#define CORGI_GPIO_HIGH_SENSE_RSHIFT (26) +#define CORGI_GPIO_LOW_SENSE_BIT (0x00000003) +#define CORGI_GPIO_LOW_SENSE_LSHIFT (6) +#define CORGI_GPIO_STROBE_BIT(a) GPIO_bit(66+(a)) +#define CORGI_GPIO_SENSE_BIT(a) GPIO_bit(58+(a)) +#define CORGI_GAFR_ALL_STROBE_BIT (0x0ffffff0) +#define CORGI_GAFR_HIGH_SENSE_BIT (0xfff00000) +#define CORGI_GAFR_LOW_SENSE_BIT (0x0000000f) +#define CORGI_GPIO_KEY_SENSE(a) (58+(a)) +#define CORGI_GPIO_KEY_STROBE(a) (66+(a)) + + +/* + * Corgi Interrupts + */ +#define CORGI_IRQ_GPIO_KEY_INT PXA_GPIO_TO_IRQ(0) +#define CORGI_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1) +#define CORGI_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(3) +#define CORGI_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(4) +#define CORGI_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5) +#define CORGI_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9) +#define CORGI_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(10) +#define CORGI_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(11) +#define CORGI_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14) +#define CORGI_IRQ_GPIO_CHRG_FULL PXA_GPIO_TO_IRQ(16) /* Battery fully charged */ +#define CORGI_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17) +#define CORGI_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(58+(a)) /* Keyboard Sense lines */ + + +/* + * Corgi SCOOP GPIOs and Config + */ +#define CORGI_SCP_LED_GREEN SCOOP_GPCR_PA11 +#define CORGI_SCP_SWA SCOOP_GPCR_PA12 /* Hinge Switch A */ +#define CORGI_SCP_SWB SCOOP_GPCR_PA13 /* Hinge Switch B */ +#define CORGI_SCP_MUTE_L SCOOP_GPCR_PA14 +#define CORGI_SCP_MUTE_R SCOOP_GPCR_PA15 +#define CORGI_SCP_AKIN_PULLUP SCOOP_GPCR_PA16 +#define CORGI_SCP_APM_ON SCOOP_GPCR_PA17 +#define CORGI_SCP_BACKLIGHT_CONT SCOOP_GPCR_PA18 +#define CORGI_SCP_MIC_BIAS SCOOP_GPCR_PA19 + +#define CORGI_SCOOP_IO_DIR ( CORGI_SCP_LED_GREEN | CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R | \ + CORGI_SCP_AKIN_PULLUP | CORGI_SCP_APM_ON | CORGI_SCP_BACKLIGHT_CONT | \ + CORGI_SCP_MIC_BIAS ) +#define CORGI_SCOOP_IO_OUT ( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R ) + +#define CORGI_SCOOP_GPIO_BASE (PXA_NR_BUILTIN_GPIO) +#define CORGI_GPIO_LED_GREEN (CORGI_SCOOP_GPIO_BASE + 0) +#define CORGI_GPIO_SWA (CORGI_SCOOP_GPIO_BASE + 1) /* Hinge Switch A */ +#define CORGI_GPIO_SWB (CORGI_SCOOP_GPIO_BASE + 2) /* Hinge Switch B */ +#define CORGI_GPIO_MUTE_L (CORGI_SCOOP_GPIO_BASE + 3) +#define CORGI_GPIO_MUTE_R (CORGI_SCOOP_GPIO_BASE + 4) +#define CORGI_GPIO_AKIN_PULLUP (CORGI_SCOOP_GPIO_BASE + 5) +#define CORGI_GPIO_APM_ON (CORGI_SCOOP_GPIO_BASE + 6) +#define CORGI_GPIO_BACKLIGHT_CONT (CORGI_SCOOP_GPIO_BASE + 7) +#define CORGI_GPIO_MIC_BIAS (CORGI_SCOOP_GPIO_BASE + 8) + +#endif /* __ASM_ARCH_CORGI_H */ + diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h new file mode 100644 index 00000000000..2628e7b7211 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/csb726.h @@ -0,0 +1,26 @@ +/* + * Support for Cogent CSB726 + * + * Copyright (c) 2008 Dmitry Baryshkov + * + * 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 CSB726_H +#define CSB726_H + +#define CSB726_GPIO_IRQ_LAN 52 +#define CSB726_GPIO_IRQ_SM501 53 +#define CSB726_GPIO_MMC_DETECT 100 +#define CSB726_GPIO_MMC_RO 101 + +#define CSB726_FLASH_SIZE (64 * 1024 * 1024) +#define CSB726_FLASH_uMON (8 * 1024 * 1024) + +#define CSB726_IRQ_LAN PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_LAN) +#define CSB726_IRQ_SM501 PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_SM501) + +#endif + diff --git a/arch/arm/mach-pxa/include/mach/debug-macro.S b/arch/arm/mach-pxa/include/mach/debug-macro.S new file mode 100644 index 00000000000..70b112e8ef6 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/debug-macro.S @@ -0,0 +1,23 @@ +/* arch/arm/mach-pxa/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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 "hardware.h" + + .macro addruart, rp, rv, tmp + mov \rp, #0x00100000 + orr \rv, \rp, #io_p2v(0x40000000) @ virtual + orr \rp, \rp, #0x40000000 @ physical + .endm + +#define UART_SHIFT 2 +#include <asm/hardware/debug-8250.S> diff --git a/arch/arm/mach-pxa/include/mach/dma.h b/arch/arm/mach-pxa/include/mach/dma.h new file mode 100644 index 00000000000..5bd55894a48 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/dma.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-pxa/include/mach/dma.h + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software, 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. + */ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#include <mach/hardware.h> + +/* DMA Controller Registers Definitions */ +#define DMAC_REGS_VIRT io_p2v(0x40000000) + +#include <plat/dma.h> +#endif /* _ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S new file mode 100644 index 00000000000..260c0c17692 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/entry-macro.S @@ -0,0 +1,15 @@ +/* + * arch/arm/mach-pxa/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for PXA-based platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm diff --git a/arch/arm/mach-pxa/include/mach/eseries-gpio.h b/arch/arm/mach-pxa/include/mach/eseries-gpio.h new file mode 100644 index 00000000000..f3e5509820d --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/eseries-gpio.h @@ -0,0 +1,67 @@ +/* + * eseries-gpio.h + * + * Copyright (C) Ian Molton <spyro@f2s.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. + * + */ + +/* e-series power button */ +#define GPIO_ESERIES_POWERBTN 0 + +/* UDC GPIO definitions */ +#define GPIO_E7XX_USB_DISC 13 +#define GPIO_E7XX_USB_PULLUP 3 + +#define GPIO_E800_USB_DISC 4 +#define GPIO_E800_USB_PULLUP 84 + +/* e740 PCMCIA GPIO definitions */ +/* Note: PWR1 seems to be inverted */ +#define GPIO_E740_PCMCIA_CD0 8 +#define GPIO_E740_PCMCIA_CD1 44 +#define GPIO_E740_PCMCIA_RDY0 11 +#define GPIO_E740_PCMCIA_RDY1 6 +#define GPIO_E740_PCMCIA_RST0 27 +#define GPIO_E740_PCMCIA_RST1 24 +#define GPIO_E740_PCMCIA_PWR0 20 +#define GPIO_E740_PCMCIA_PWR1 23 + +/* e750 PCMCIA GPIO definitions */ +#define GPIO_E750_PCMCIA_CD0 8 +#define GPIO_E750_PCMCIA_RDY0 12 +#define GPIO_E750_PCMCIA_RST0 27 +#define GPIO_E750_PCMCIA_PWR0 20 + +/* e800 PCMCIA GPIO definitions */ +#define GPIO_E800_PCMCIA_RST0 69 +#define GPIO_E800_PCMCIA_RST1 72 +#define GPIO_E800_PCMCIA_PWR0 20 +#define GPIO_E800_PCMCIA_PWR1 73 + +/* e7xx IrDA power control */ +#define GPIO_E7XX_IR_OFF 38 + +/* e740 audio control GPIOs */ +#define GPIO_E740_WM9705_nAVDD2 16 +#define GPIO_E740_MIC_ON 40 +#define GPIO_E740_AMP_ON 41 + +/* e750 audio control GPIOs */ +#define GPIO_E750_HP_AMP_OFF 4 +#define GPIO_E750_SPK_AMP_OFF 7 +#define GPIO_E750_HP_DETECT 37 + +/* e800 audio control GPIOs */ +#define GPIO_E800_HP_DETECT 81 +#define GPIO_E800_HP_AMP_OFF 82 +#define GPIO_E800_SPK_AMP_ON 83 + +/* ASIC related GPIOs */ +#define GPIO_ESERIES_TMIO_IRQ 5 +#define GPIO_ESERIES_TMIO_PCLR 19 +#define GPIO_ESERIES_TMIO_SUSPEND 45 +#define GPIO_E800_ANGELX_IRQ 8 diff --git a/arch/arm/mach-pxa/include/mach/eseries-irq.h b/arch/arm/mach-pxa/include/mach/eseries-irq.h new file mode 100644 index 00000000000..de292b269c6 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/eseries-irq.h @@ -0,0 +1,28 @@ +/* + * eseries-irq.h + * + * Copyright (C) Ian Molton <spyro@f2s.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. + * + */ + +#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8) +#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n)) + +#define ANGELX_RDY0_IRQ IRQ_ANGELX(0) +#define ANGELX_ST0_IRQ IRQ_ANGELX(1) +#define ANGELX_CD0_IRQ IRQ_ANGELX(2) +#define ANGELX_RDY1_IRQ IRQ_ANGELX(3) +#define ANGELX_ST1_IRQ IRQ_ANGELX(4) +#define ANGELX_CD1_IRQ IRQ_ANGELX(5) + +#define TMIO_IRQ_BASE (IRQ_BOARD_START+0) +#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n)) + +#define TMIO_SD_IRQ IRQ_TMIO(1) +#define TMIO_USB_IRQ IRQ_TMIO(2) + +#define ESERIES_NR_IRQS (IRQ_BOARD_START + 16) diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h new file mode 100644 index 00000000000..0248e433bc9 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-pxa/include/mach/gpio.h + * + * PXA GPIO wrappers for arch-neutral GPIO calls + * + * Written by Philipp Zabel <philipp.zabel@gmail.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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_PXA_GPIO_H +#define __ASM_ARCH_PXA_GPIO_H + +#include <asm-generic/gpio.h> + +#include <mach/irqs.h> +#include <mach/hardware.h> + +#endif diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h new file mode 100644 index 00000000000..dba14b6503a --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/gumstix.h @@ -0,0 +1,91 @@ +/* + * arch/arm/mach-pxa/include/mach/gumstix.h + * + * 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. + */ + + +/* BTRESET - Reset line to Bluetooth module, active low signal. */ +#define GPIO_GUMSTIX_BTRESET 7 +#define GPIO_GUMSTIX_BTRESET_MD (GPIO_GUMSTIX_BTRESET | GPIO_OUT) + + +/* +GPIOn - Input from MAX823 (or equiv), normalizing USB +5V into a clean +interrupt signal for determining cable presence. On the gumstix F, +this moves to GPIO17 and GPIO37. */ + +/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn +has detected a cable insertion; driven low otherwise. */ + +#define GPIO_GUMSTIX_USB_GPIOn 35 +#define GPIO_GUMSTIX_USB_GPIOx 41 + +/* usb state change */ +#define GUMSTIX_USB_INTR_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_USB_GPIOn) + +#define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN) +#define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT) +#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN) + +/* + * SD/MMC definitions + */ +#define GUMSTIX_GPIO_nSD_WP 22 /* SD Write Protect */ +#define GUMSTIX_GPIO_nSD_DETECT 11 /* MMC/SD Card Detect */ +#define GUMSTIX_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT) + +/* + * SMC Ethernet definitions + * ETH_RST provides a hardware reset line to the ethernet chip + * ETH is the IRQ line in from the ethernet chip to the PXA + */ +#define GPIO_GUMSTIX_ETH0_RST 80 +#define GPIO_GUMSTIX_ETH0_RST_MD (GPIO_GUMSTIX_ETH0_RST | GPIO_OUT) +#define GPIO_GUMSTIX_ETH1_RST 52 +#define GPIO_GUMSTIX_ETH1_RST_MD (GPIO_GUMSTIX_ETH1_RST | GPIO_OUT) + +#define GPIO_GUMSTIX_ETH0 36 +#define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN) +#define GUMSTIX_ETH0_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0) +#define GPIO_GUMSTIX_ETH1 27 +#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN) +#define GUMSTIX_ETH1_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1) + + +/* CF reset line */ +#define GPIO8_RESET 8 + +/* CF slot 0 */ +#define GPIO4_nBVD1 4 +#define GPIO4_nSTSCHG GPIO4_nBVD1 +#define GPIO11_nCD 11 +#define GPIO26_PRDY_nBSY 26 +#define GUMSTIX_S0_nSTSCHG_IRQ PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG) +#define GUMSTIX_S0_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO11_nCD) +#define GUMSTIX_S0_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(GPIO26_PRDY_nBSY) + +/* CF slot 1 */ +#define GPIO18_nBVD1 18 +#define GPIO18_nSTSCHG GPIO18_nBVD1 +#define GPIO36_nCD 36 +#define GPIO27_PRDY_nBSY 27 +#define GUMSTIX_S1_nSTSCHG_IRQ PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG) +#define GUMSTIX_S1_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO36_nCD) +#define GUMSTIX_S1_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(GPIO27_PRDY_nBSY) + +/* CF GPIO line modes */ +#define GPIO4_nSTSCHG_MD (GPIO4_nSTSCHG | GPIO_IN) +#define GPIO8_RESET_MD (GPIO8_RESET | GPIO_OUT) +#define GPIO11_nCD_MD (GPIO11_nCD | GPIO_IN) +#define GPIO18_nSTSCHG_MD (GPIO18_nSTSCHG | GPIO_IN) +#define GPIO26_PRDY_nBSY_MD (GPIO26_PRDY_nBSY | GPIO_IN) +#define GPIO27_PRDY_nBSY_MD (GPIO27_PRDY_nBSY | GPIO_IN) +#define GPIO36_nCD_MD (GPIO36_nCD | GPIO_IN) + +/* for expansion boards that can't be programatically detected */ +extern int am200_init(void); +extern int am300_init(void); + diff --git a/arch/arm/mach-pxa/include/mach/h5000.h b/arch/arm/mach-pxa/include/mach/h5000.h new file mode 100644 index 00000000000..2a5ae380278 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/h5000.h @@ -0,0 +1,113 @@ +/* + * Hardware definitions for HP iPAQ h5xxx Handheld Computers + * + * Copyright(20)02 Hewlett-Packard Company. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, + * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS + * FITNESS FOR ANY PARTICULAR PURPOSE. + * + * Author: Jamey Hicks + */ + +#ifndef __ASM_ARCH_H5000_H +#define __ASM_ARCH_H5000_H + +#include <mach/mfp-pxa25x.h> + +/* + * CPU GPIOs + */ + +#define H5000_GPIO_POWER_BUTTON (0) +#define H5000_GPIO_RESET_BUTTON_N (1) +#define H5000_GPIO_OPT_INT (2) +#define H5000_GPIO_BACKUP_POWER (3) +#define H5000_GPIO_ACTION_BUTTON (4) +#define H5000_GPIO_COM_DCD_SOMETHING (5) /* what is this really ? */ +/* 6 not connected */ +#define H5000_GPIO_RESET_BUTTON_AGAIN_N (7) /* connected to gpio 1 as well */ +/* 8 not connected */ +#define H5000_GPIO_RSO_N (9) /* reset output from max1702 which regulates 3.3 and 2.5 */ +#define H5000_GPIO_ASIC_INT_N (10) /* from companion asic */ +#define H5000_GPIO_BT_ENV_0 (11) /* to LMX9814, set to 1 according to regdump */ +/*(12) not connected */ +#define H5000_GPIO_BT_ENV_1 (13) /* to LMX9814, set to 1 according to regdump */ +#define H5000_GPIO_BT_WU (14) /* from LMX9814, Defined as HOST_WAKEUP in the LMX9820 data sheet */ +/*(15) is CS1# */ +/*(16) not connected */ +/*(17) not connected */ +/*(18) is pcmcia ready */ +/*(19) is dreq1 */ +/*(20) is dreq0 */ +#define H5000_GPIO_OE_RD_NWR (21) /* output enable on rd/nwr signal to companion asic */ +/*(22) is not connected */ +#define H5000_GPIO_OPT_SPI_CLK (23) /* to extension pack */ +#define H5000_GPIO_OPT_SPI_CS_N (24) /* to extension pack */ +#define H5000_GPIO_OPT_SPI_DOUT (25) /* to extension pack */ +#define H5000_GPIO_OPT_SPI_DIN (26) /* to extension pack */ +/*(27) not connected */ +#define H5000_GPIO_I2S_BITCLK (28) /* connected to AC97 codec */ +#define H5000_GPIO_I2S_DATAOUT (29) /* connected to AC97 codec */ +#define H5000_GPIO_I2S_DATAIN (30) /* connected to AC97 codec */ +#define H5000_GPIO_I2S_LRCLK (31) /* connected to AC97 codec */ +#define H5000_GPIO_I2S_SYSCLK (32) /* connected to AC97 codec */ +/*(33) is CS5# */ +#define H5000_GPIO_COM_RXD (34) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_CTS (35) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_DCD (36) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_DSR (37) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_RI (38) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_TXD (39) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_DTR (40) /* connected to cradle/cable connector */ +#define H5000_GPIO_COM_RTS (41) /* connected to cradle/cable connector */ + +#define H5000_GPIO_BT_RXD (42) /* connected to BT (LMX9814) */ +#define H5000_GPIO_BT_TXD (43) /* connected to BT (LMX9814) */ +#define H5000_GPIO_BT_CTS (44) /* connected to BT (LMX9814) */ +#define H5000_GPIO_BT_RTS (45) /* connected to BT (LMX9814) */ + +#define H5000_GPIO_IRDA_RXD (46) +#define H5000_GPIO_IRDA_TXD (47) + +#define H5000_GPIO_POE_N (48) /* used for pcmcia */ +#define H5000_GPIO_PWE_N (49) /* used for pcmcia */ +#define H5000_GPIO_PIOR_N (50) /* used for pcmcia */ +#define H5000_GPIO_PIOW_N (51) /* used for pcmcia */ +#define H5000_GPIO_PCE1_N (52) /* used for pcmcia */ +#define H5000_GPIO_PCE2_N (53) /* used for pcmcia */ +#define H5000_GPIO_PSKTSEL (54) /* used for pcmcia */ +#define H5000_GPIO_PREG_N (55) /* used for pcmcia */ +#define H5000_GPIO_PWAIT_N (56) /* used for pcmcia */ +#define H5000_GPIO_IOIS16_N (57) /* used for pcmcia */ + +#define H5000_GPIO_IRDA_SD (58) /* to hsdl3002 sd */ +/*(59) not connected */ +#define H5000_GPIO_POWER_SD_N (60) /* controls power to SD */ +#define H5000_GPIO_POWER_RS232_N (61) /* inverted FORCEON to rs232 transceiver */ +#define H5000_GPIO_POWER_ACCEL_N (62) /* controls power to accel */ +/*(63) is not connected */ +#define H5000_GPIO_OPT_NVRAM (64) /* controls power to expansion pack */ +#define H5000_GPIO_CHG_EN (65) /* to sc801 en */ +#define H5000_GPIO_USB_PULLUP (66) /* USB d+ pullup via 1.5K resistor */ +#define H5000_GPIO_BT_2V8_N (67) /* 2.8V used by bluetooth */ +#define H5000_GPIO_EXT_CHG_RATE (68) /* enables external charging rate */ +/*(69) is not connected */ +#define H5000_GPIO_CIR_RESET (70) /* consumer IR reset */ +#define H5000_GPIO_POWER_LIGHT_SENSOR_N (71) +#define H5000_GPIO_BT_M_RESET (72) +#define H5000_GPIO_STD_CHG_RATE (73) +#define H5000_GPIO_SD_WP_N (74) +#define H5000_GPIO_MOTOR_ON_N (75) /* external pullup on this */ +#define H5000_GPIO_HEADPHONE_DETECT (76) +#define H5000_GPIO_USB_CHG_RATE (77) /* select rate for charging via usb */ +/*(78) is CS2# */ +/*(79) is CS3# */ +/*(80) is CS4# */ + +#endif /* __ASM_ARCH_H5000_H */ diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h new file mode 100644 index 00000000000..8184669dde2 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -0,0 +1,344 @@ +/* + * arch/arm/mach-pxa/include/mach/hardware.h + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software 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. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include <mach/addr-map.h> + +/* + * Workarounds for at least 2 errata so far require this. + * The mapping is set in mach-pxa/generic.c. + */ +#define UNCACHED_PHYS_0 0xff000000 +#define UNCACHED_ADDR UNCACHED_PHYS_0 + +/* + * Intel PXA2xx internal register mapping: + * + * 0x40000000 - 0x41ffffff <--> 0xf2000000 - 0xf3ffffff + * 0x44000000 - 0x45ffffff <--> 0xf4000000 - 0xf5ffffff + * 0x48000000 - 0x49ffffff <--> 0xf6000000 - 0xf7ffffff + * 0x4c000000 - 0x4dffffff <--> 0xf8000000 - 0xf9ffffff + * 0x50000000 - 0x51ffffff <--> 0xfa000000 - 0xfbffffff + * 0x54000000 - 0x55ffffff <--> 0xfc000000 - 0xfdffffff + * 0x58000000 - 0x59ffffff <--> 0xfe000000 - 0xffffffff + * + * Note that not all PXA2xx chips implement all those addresses, and the + * kernel only maps the minimum needed range of this mapping. + */ +#define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1)) +#define io_p2v(x) IOMEM(0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) + +#ifndef __ASSEMBLY__ +# define IOMEM(x) ((void __iomem *)(x)) +# define __REG(x) (*((volatile u32 __iomem *)io_p2v(x))) + +/* With indexed regs we don't want to feed the index through io_p2v() + especially if it is a variable, otherwise horrible code will result. */ +# define __REG2(x,y) \ + (*(volatile u32 __iomem*)((u32)&__REG(x) + (y))) + +# define __PREG(x) (io_v2p((u32)&(x))) + +#else + +# define IOMEM(x) x +# define __REG(x) io_p2v(x) +# define __PREG(x) io_v2p(x) + +#endif + +#ifndef __ASSEMBLY__ + +#include <asm/cputype.h> + +/* + * CPU Stepping CPU_ID JTAG_ID + * + * PXA210 B0 0x69052922 0x2926C013 + * PXA210 B1 0x69052923 0x3926C013 + * PXA210 B2 0x69052924 0x4926C013 + * PXA210 C0 0x69052D25 0x5926C013 + * + * PXA250 A0 0x69052100 0x09264013 + * PXA250 A1 0x69052101 0x19264013 + * PXA250 B0 0x69052902 0x29264013 + * PXA250 B1 0x69052903 0x39264013 + * PXA250 B2 0x69052904 0x49264013 + * PXA250 C0 0x69052D05 0x59264013 + * + * PXA255 A0 0x69052D06 0x69264013 + * + * PXA26x A0 0x69052903 0x39264013 + * PXA26x B0 0x69052D05 0x59264013 + * + * PXA27x A0 0x69054110 0x09265013 + * PXA27x A1 0x69054111 0x19265013 + * PXA27x B0 0x69054112 0x29265013 + * PXA27x B1 0x69054113 0x39265013 + * PXA27x C0 0x69054114 0x49265013 + * PXA27x C5 0x69054117 0x79265013 + * + * PXA30x A0 0x69056880 0x0E648013 + * PXA30x A1 0x69056881 0x1E648013 + * PXA31x A0 0x69056890 0x0E649013 + * PXA31x A1 0x69056891 0x1E649013 + * PXA31x A2 0x69056892 0x2E649013 + * PXA32x B1 0x69056825 0x5E642013 + * PXA32x B2 0x69056826 0x6E642013 + * + * PXA930 B0 0x69056835 0x5E643013 + * PXA930 B1 0x69056837 0x7E643013 + * PXA930 B2 0x69056838 0x8E643013 + * + * PXA935 A0 0x56056931 0x1E653013 + * PXA935 B0 0x56056936 0x6E653013 + * PXA935 B1 0x56056938 0x8E653013 + */ +#ifdef CONFIG_PXA25x +#define __cpu_is_pxa210(id) \ + ({ \ + unsigned int _id = (id) & 0xf3f0; \ + _id == 0x2120; \ + }) + +#define __cpu_is_pxa250(id) \ + ({ \ + unsigned int _id = (id) & 0xf3ff; \ + _id <= 0x2105; \ + }) + +#define __cpu_is_pxa255(id) \ + ({ \ + unsigned int _id = (id) & 0xffff; \ + _id == 0x2d06; \ + }) + +#define __cpu_is_pxa25x(id) \ + ({ \ + unsigned int _id = (id) & 0xf300; \ + _id == 0x2100; \ + }) +#else +#define __cpu_is_pxa210(id) (0) +#define __cpu_is_pxa250(id) (0) +#define __cpu_is_pxa255(id) (0) +#define __cpu_is_pxa25x(id) (0) +#endif + +#ifdef CONFIG_PXA27x +#define __cpu_is_pxa27x(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x411; \ + }) +#else +#define __cpu_is_pxa27x(id) (0) +#endif + +#ifdef CONFIG_CPU_PXA300 +#define __cpu_is_pxa300(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x688; \ + }) +#else +#define __cpu_is_pxa300(id) (0) +#endif + +#ifdef CONFIG_CPU_PXA310 +#define __cpu_is_pxa310(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x689; \ + }) +#else +#define __cpu_is_pxa310(id) (0) +#endif + +#ifdef CONFIG_CPU_PXA320 +#define __cpu_is_pxa320(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x603 || _id == 0x682; \ + }) +#else +#define __cpu_is_pxa320(id) (0) +#endif + +#ifdef CONFIG_CPU_PXA930 +#define __cpu_is_pxa930(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x683; \ + }) +#else +#define __cpu_is_pxa930(id) (0) +#endif + +#ifdef CONFIG_CPU_PXA935 +#define __cpu_is_pxa935(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x693; \ + }) +#else +#define __cpu_is_pxa935(id) (0) +#endif + +#ifdef CONFIG_CPU_PXA955 +#define __cpu_is_pxa955(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x581 || _id == 0xc08 \ + || _id == 0xb76; \ + }) +#else +#define __cpu_is_pxa955(id) (0) +#endif + +#define cpu_is_pxa210() \ + ({ \ + __cpu_is_pxa210(read_cpuid_id()); \ + }) + +#define cpu_is_pxa250() \ + ({ \ + __cpu_is_pxa250(read_cpuid_id()); \ + }) + +#define cpu_is_pxa255() \ + ({ \ + __cpu_is_pxa255(read_cpuid_id()); \ + }) + +#define cpu_is_pxa25x() \ + ({ \ + __cpu_is_pxa25x(read_cpuid_id()); \ + }) + +#define cpu_is_pxa27x() \ + ({ \ + __cpu_is_pxa27x(read_cpuid_id()); \ + }) + +#define cpu_is_pxa300() \ + ({ \ + __cpu_is_pxa300(read_cpuid_id()); \ + }) + +#define cpu_is_pxa310() \ + ({ \ + __cpu_is_pxa310(read_cpuid_id()); \ + }) + +#define cpu_is_pxa320() \ + ({ \ + __cpu_is_pxa320(read_cpuid_id()); \ + }) + +#define cpu_is_pxa930() \ + ({ \ + __cpu_is_pxa930(read_cpuid_id()); \ + }) + +#define cpu_is_pxa935() \ + ({ \ + __cpu_is_pxa935(read_cpuid_id()); \ + }) + +#define cpu_is_pxa955() \ + ({ \ + __cpu_is_pxa955(read_cpuid_id()); \ + }) + + +/* + * CPUID Core Generation Bit + * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x + */ +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) +#define __cpu_is_pxa2xx(id) \ + ({ \ + unsigned int _id = (id) >> 13 & 0x7; \ + _id <= 0x2; \ + }) +#else +#define __cpu_is_pxa2xx(id) (0) +#endif + +#ifdef CONFIG_PXA3xx +#define __cpu_is_pxa3xx(id) \ + ({ \ + __cpu_is_pxa300(id) \ + || __cpu_is_pxa310(id) \ + || __cpu_is_pxa320(id) \ + || __cpu_is_pxa93x(id); \ + }) +#else +#define __cpu_is_pxa3xx(id) (0) +#endif + +#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) +#define __cpu_is_pxa93x(id) \ + ({ \ + __cpu_is_pxa930(id) \ + || __cpu_is_pxa935(id); \ + }) +#else +#define __cpu_is_pxa93x(id) (0) +#endif + +#ifdef CONFIG_PXA95x +#define __cpu_is_pxa95x(id) \ + ({ \ + __cpu_is_pxa955(id); \ + }) +#else +#define __cpu_is_pxa95x(id) (0) +#endif + +#define cpu_is_pxa2xx() \ + ({ \ + __cpu_is_pxa2xx(read_cpuid_id()); \ + }) + +#define cpu_is_pxa3xx() \ + ({ \ + __cpu_is_pxa3xx(read_cpuid_id()); \ + }) + +#define cpu_is_pxa93x() \ + ({ \ + __cpu_is_pxa93x(read_cpuid_id()); \ + }) + +#define cpu_is_pxa95x() \ + ({ \ + __cpu_is_pxa95x(read_cpuid_id()); \ + }) + +/* + * return current memory and LCD clock frequency in units of 10kHz + */ +extern unsigned int get_memclk_frequency_10khz(void); + +/* return the clock tick rate of the OS timer */ +extern unsigned long get_clock_tick_rate(void); +#endif + +#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) +#define ARCH_HAS_DMA_SET_COHERENT_MASK +#endif + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h new file mode 100644 index 00000000000..8bc02913517 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/hx4700.h @@ -0,0 +1,132 @@ +/* + * GPIO and IRQ definitions for HP iPAQ hx4700 + * + * Copyright (c) 2008 Philipp Zabel + * + * 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 _HX4700_H_ +#define _HX4700_H_ + +#include <linux/gpio.h> +#include <linux/mfd/asic3.h> + +#define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO +#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS) +#define HX4700_NR_IRQS (IRQ_BOARD_START + 70) + +/* + * PXA GPIOs + */ + +#define GPIO0_HX4700_nKEY_POWER 0 +#define GPIO12_HX4700_ASIC3_IRQ 12 +#define GPIO13_HX4700_W3220_IRQ 13 +#define GPIO14_HX4700_nWLAN_IRQ 14 +#define GPIO18_HX4700_RDY 18 +#define GPIO22_HX4700_LCD_RL 22 +#define GPIO27_HX4700_CODEC_ON 27 +#define GPIO32_HX4700_RS232_ON 32 +#define GPIO52_HX4700_CPU_nBATT_FAULT 52 +#define GPIO58_HX4700_TSC2046_nPENIRQ 58 +#define GPIO59_HX4700_LCD_PC1 59 +#define GPIO60_HX4700_CF_RNB 60 +#define GPIO61_HX4700_W3220_nRESET 61 +#define GPIO62_HX4700_LCD_nRESET 62 +#define GPIO63_HX4700_CPU_SS_nRESET 63 +#define GPIO65_HX4700_TSC2046_PEN_PU 65 +#define GPIO66_HX4700_ASIC3_nSDIO_IRQ 66 +#define GPIO67_HX4700_EUART_PS 67 +#define GPIO70_HX4700_LCD_SLIN1 70 +#define GPIO71_HX4700_ASIC3_nRESET 71 +#define GPIO72_HX4700_BQ24022_nCHARGE_EN 72 +#define GPIO73_HX4700_LCD_UD_1 73 +#define GPIO75_HX4700_EARPHONE_nDET 75 +#define GPIO76_HX4700_USBC_PUEN 76 +#define GPIO81_HX4700_CPU_GP_nRESET 81 +#define GPIO82_HX4700_EUART_RESET 82 +#define GPIO83_HX4700_WLAN_nRESET 83 +#define GPIO84_HX4700_LCD_SQN 84 +#define GPIO85_HX4700_nPCE1 85 +#define GPIO88_HX4700_TSC2046_CS 88 +#define GPIO91_HX4700_FLASH_VPEN 91 +#define GPIO92_HX4700_HP_DRIVER 92 +#define GPIO93_HX4700_EUART_INT 93 +#define GPIO94_HX4700_KEY_MAIL 94 +#define GPIO95_HX4700_BATT_OFF 95 +#define GPIO96_HX4700_BQ24022_ISET2 96 +#define GPIO97_HX4700_nBL_DETECT 97 +#define GPIO99_HX4700_KEY_CONTACTS 99 +#define GPIO100_HX4700_AUTO_SENSE 100 /* BL auto brightness */ +#define GPIO102_HX4700_SYNAPTICS_POWER_ON 102 +#define GPIO103_HX4700_SYNAPTICS_INT 103 +#define GPIO105_HX4700_nIR_ON 105 +#define GPIO106_HX4700_CPU_BT_nRESET 106 +#define GPIO107_HX4700_SPK_nSD 107 +#define GPIO109_HX4700_CODEC_nPDN 109 +#define GPIO110_HX4700_LCD_LVDD_3V3_ON 110 +#define GPIO111_HX4700_LCD_AVDD_3V3_ON 111 +#define GPIO112_HX4700_LCD_N2V7_7V3_ON 112 +#define GPIO114_HX4700_CF_RESET 114 +#define GPIO116_HX4700_CPU_HW_nRESET 116 + +/* + * ASIC3 GPIOs + */ + +#define GPIOC_BASE (HX4700_ASIC3_GPIO_BASE + 32) +#define GPIOD_BASE (HX4700_ASIC3_GPIO_BASE + 48) + +#define GPIOC0_LED_RED (GPIOC_BASE + 0) +#define GPIOC1_LED_GREEN (GPIOC_BASE + 1) +#define GPIOC2_LED_BLUE (GPIOC_BASE + 2) +#define GPIOC3_nSD_CS (GPIOC_BASE + 3) +#define GPIOC4_CF_nCD (GPIOC_BASE + 4) /* Input */ +#define GPIOC5_nCIOW (GPIOC_BASE + 5) /* Output, to CF */ +#define GPIOC6_nCIOR (GPIOC_BASE + 6) /* Output, to CF */ +#define GPIOC7_nPCE1 (GPIOC_BASE + 7) /* Input, from CPU */ +#define GPIOC8_nPCE2 (GPIOC_BASE + 8) /* Input, from CPU */ +#define GPIOC9_nPOE (GPIOC_BASE + 9) /* Input, from CPU */ +#define GPIOC10_CF_nPWE (GPIOC_BASE + 10) /* Input */ +#define GPIOC11_PSKTSEL (GPIOC_BASE + 11) /* Input, from CPU */ +#define GPIOC12_nPREG (GPIOC_BASE + 12) /* Input, from CPU */ +#define GPIOC13_nPWAIT (GPIOC_BASE + 13) /* Output, to CPU */ +#define GPIOC14_nPIOIS16 (GPIOC_BASE + 14) /* Output, to CPU */ +#define GPIOC15_nPIOR (GPIOC_BASE + 15) /* Input, from CPU */ + +#define GPIOD0_CPU_SS_INT (GPIOD_BASE + 0) /* Input */ +#define GPIOD1_nKEY_CALENDAR (GPIOD_BASE + 1) +#define GPIOD2_BLUETOOTH_WAKEUP (GPIOD_BASE + 2) +#define GPIOD3_nKEY_HOME (GPIOD_BASE + 3) +#define GPIOD4_CF_nCD (GPIOD_BASE + 4) /* Input, from CF */ +#define GPIOD5_nPIO (GPIOD_BASE + 5) /* Input */ +#define GPIOD6_nKEY_RECORD (GPIOD_BASE + 6) +#define GPIOD7_nSDIO_DETECT (GPIOD_BASE + 7) +#define GPIOD8_COM_DCD (GPIOD_BASE + 8) /* Input */ +#define GPIOD9_nAC_IN (GPIOD_BASE + 9) +#define GPIOD10_nSDIO_IRQ (GPIOD_BASE + 10) /* Input */ +#define GPIOD11_nCIOIS16 (GPIOD_BASE + 11) /* Input, from CF */ +#define GPIOD12_nCWAIT (GPIOD_BASE + 12) /* Input, from CF */ +#define GPIOD13_CF_RNB (GPIOD_BASE + 13) /* Input */ +#define GPIOD14_nUSBC_DETECT (GPIOD_BASE + 14) +#define GPIOD15_nPIOW (GPIOD_BASE + 15) /* Input, from CPU */ + +/* + * EGPIOs + */ + +#define EGPIO0_VCC_3V3_EN (HX4700_EGPIO_BASE + 0) /* WLAN support chip */ +#define EGPIO1_WL_VREG_EN (HX4700_EGPIO_BASE + 1) /* WLAN power */ +#define EGPIO2_VCC_2V1_WL_EN (HX4700_EGPIO_BASE + 2) /* unused */ +#define EGPIO3_SS_PWR_ON (HX4700_EGPIO_BASE + 3) /* smart slot power */ +#define EGPIO4_CF_3V3_ON (HX4700_EGPIO_BASE + 4) /* CF 3.3V enable */ +#define EGPIO5_BT_3V3_ON (HX4700_EGPIO_BASE + 5) /* BT 3.3V enable */ +#define EGPIO6_WL1V8_EN (HX4700_EGPIO_BASE + 6) /* WLAN 1.8V enable */ +#define EGPIO7_VCC_3V3_WL_EN (HX4700_EGPIO_BASE + 7) /* WLAN 3.3V enable */ +#define EGPIO8_USB_3V3_ON (HX4700_EGPIO_BASE + 8) /* unused */ + +#endif /* _HX4700_H_ */ diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h new file mode 100644 index 00000000000..22a96f87232 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/idp.h @@ -0,0 +1,197 @@ +/* + * arch/arm/mach-pxa/include/mach/idp.h + * + * 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. + * + * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc. + * + * 2001-09-13: Cliff Brake <cbrake@accelent.com> + * Initial code + * + * 2005-02-15: Cliff Brake <cliff.brake@gmail.com> + * <http://www.vibren.com> <http://bec-systems.com> + * Changes for 2.6 kernel. + */ + + +/* + * Note: this file must be safe to include in assembly files + * + * Support for the Vibren PXA255 IDP requires rev04 or later + * IDP hardware. + */ + + +#define IDP_FLASH_PHYS (PXA_CS0_PHYS) +#define IDP_ALT_FLASH_PHYS (PXA_CS1_PHYS) +#define IDP_MEDIAQ_PHYS (PXA_CS3_PHYS) +#define IDP_IDE_PHYS (PXA_CS5_PHYS + 0x03000000) +#define IDP_ETH_PHYS (PXA_CS5_PHYS + 0x03400000) +#define IDP_COREVOLT_PHYS (PXA_CS5_PHYS + 0x03800000) +#define IDP_CPLD_PHYS (PXA_CS5_PHYS + 0x03C00000) + + +/* + * virtual memory map + */ + +#define IDP_COREVOLT_VIRT (0xf0000000) +#define IDP_COREVOLT_SIZE (1*1024*1024) + +#define IDP_CPLD_VIRT (IDP_COREVOLT_VIRT + IDP_COREVOLT_SIZE) +#define IDP_CPLD_SIZE (1*1024*1024) + +#if (IDP_CPLD_VIRT + IDP_CPLD_SIZE) > 0xfc000000 +#error Your custom IO space is getting a bit large !! +#endif + +#define CPLD_P2V(x) ((x) - IDP_CPLD_PHYS + IDP_CPLD_VIRT) +#define CPLD_V2P(x) ((x) - IDP_CPLD_VIRT + IDP_CPLD_PHYS) + +#ifndef __ASSEMBLY__ +# define __CPLD_REG(x) (*((volatile unsigned long *)CPLD_P2V(x))) +#else +# define __CPLD_REG(x) CPLD_P2V(x) +#endif + +/* board level registers in the CPLD: (offsets from CPLD_VIRT) */ + +#define _IDP_CPLD_REV (IDP_CPLD_PHYS + 0x00) +#define _IDP_CPLD_PERIPH_PWR (IDP_CPLD_PHYS + 0x04) +#define _IDP_CPLD_LED_CONTROL (IDP_CPLD_PHYS + 0x08) +#define _IDP_CPLD_KB_COL_HIGH (IDP_CPLD_PHYS + 0x0C) +#define _IDP_CPLD_KB_COL_LOW (IDP_CPLD_PHYS + 0x10) +#define _IDP_CPLD_PCCARD_EN (IDP_CPLD_PHYS + 0x14) +#define _IDP_CPLD_GPIOH_DIR (IDP_CPLD_PHYS + 0x18) +#define _IDP_CPLD_GPIOH_VALUE (IDP_CPLD_PHYS + 0x1C) +#define _IDP_CPLD_GPIOL_DIR (IDP_CPLD_PHYS + 0x20) +#define _IDP_CPLD_GPIOL_VALUE (IDP_CPLD_PHYS + 0x24) +#define _IDP_CPLD_PCCARD_PWR (IDP_CPLD_PHYS + 0x28) +#define _IDP_CPLD_MISC_CTRL (IDP_CPLD_PHYS + 0x2C) +#define _IDP_CPLD_LCD (IDP_CPLD_PHYS + 0x30) +#define _IDP_CPLD_FLASH_WE (IDP_CPLD_PHYS + 0x34) + +#define _IDP_CPLD_KB_ROW (IDP_CPLD_PHYS + 0x50) +#define _IDP_CPLD_PCCARD0_STATUS (IDP_CPLD_PHYS + 0x54) +#define _IDP_CPLD_PCCARD1_STATUS (IDP_CPLD_PHYS + 0x58) +#define _IDP_CPLD_MISC_STATUS (IDP_CPLD_PHYS + 0x5C) + +/* FPGA register virtual addresses */ + +#define IDP_CPLD_REV __CPLD_REG(_IDP_CPLD_REV) +#define IDP_CPLD_PERIPH_PWR __CPLD_REG(_IDP_CPLD_PERIPH_PWR) +#define IDP_CPLD_LED_CONTROL __CPLD_REG(_IDP_CPLD_LED_CONTROL) +#define IDP_CPLD_KB_COL_HIGH __CPLD_REG(_IDP_CPLD_KB_COL_HIGH) +#define IDP_CPLD_KB_COL_LOW __CPLD_REG(_IDP_CPLD_KB_COL_LOW) +#define IDP_CPLD_PCCARD_EN __CPLD_REG(_IDP_CPLD_PCCARD_EN) +#define IDP_CPLD_GPIOH_DIR __CPLD_REG(_IDP_CPLD_GPIOH_DIR) +#define IDP_CPLD_GPIOH_VALUE __CPLD_REG(_IDP_CPLD_GPIOH_VALUE) +#define IDP_CPLD_GPIOL_DIR __CPLD_REG(_IDP_CPLD_GPIOL_DIR) +#define IDP_CPLD_GPIOL_VALUE __CPLD_REG(_IDP_CPLD_GPIOL_VALUE) +#define IDP_CPLD_PCCARD_PWR __CPLD_REG(_IDP_CPLD_PCCARD_PWR) +#define IDP_CPLD_MISC_CTRL __CPLD_REG(_IDP_CPLD_MISC_CTRL) +#define IDP_CPLD_LCD __CPLD_REG(_IDP_CPLD_LCD) +#define IDP_CPLD_FLASH_WE __CPLD_REG(_IDP_CPLD_FLASH_WE) + +#define IDP_CPLD_KB_ROW __CPLD_REG(_IDP_CPLD_KB_ROW) +#define IDP_CPLD_PCCARD0_STATUS __CPLD_REG(_IDP_CPLD_PCCARD0_STATUS) +#define IDP_CPLD_PCCARD1_STATUS __CPLD_REG(_IDP_CPLD_PCCARD1_STATUS) +#define IDP_CPLD_MISC_STATUS __CPLD_REG(_IDP_CPLD_MISC_STATUS) + + +/* + * Bit masks for various registers + */ + +// IDP_CPLD_PCCARD_PWR +#define PCC0_PWR0 (1 << 0) +#define PCC0_PWR1 (1 << 1) +#define PCC0_PWR2 (1 << 2) +#define PCC0_PWR3 (1 << 3) +#define PCC1_PWR0 (1 << 4) +#define PCC1_PWR1 (1 << 5) +#define PCC1_PWR2 (1 << 6) +#define PCC1_PWR3 (1 << 7) + +// IDP_CPLD_PCCARD_EN +#define PCC0_RESET (1 << 6) +#define PCC1_RESET (1 << 7) +#define PCC0_ENABLE (1 << 0) +#define PCC1_ENABLE (1 << 1) + +// IDP_CPLD_PCCARDx_STATUS +#define _PCC_WRPROT (1 << 7) // 7-4 read as low true +#define _PCC_RESET (1 << 6) +#define _PCC_IRQ (1 << 5) +#define _PCC_INPACK (1 << 4) +#define PCC_BVD2 (1 << 3) +#define PCC_BVD1 (1 << 2) +#define PCC_VS2 (1 << 1) +#define PCC_VS1 (1 << 0) + +/* A listing of interrupts used by external hardware devices */ + +#define TOUCH_PANEL_IRQ PXA_GPIO_TO_IRQ(5) +#define IDE_IRQ PXA_GPIO_TO_IRQ(21) + +#define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING + +#define ETHERNET_IRQ PXA_GPIO_TO_IRQ(4) +#define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING + +#define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING + +#define PCMCIA_S0_CD_VALID PXA_GPIO_TO_IRQ(7) +#define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH + +#define PCMCIA_S1_CD_VALID PXA_GPIO_TO_IRQ(8) +#define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH + +#define PCMCIA_S0_RDYINT PXA_GPIO_TO_IRQ(19) +#define PCMCIA_S1_RDYINT PXA_GPIO_TO_IRQ(22) + + +/* + * Macros for LED Driver + */ + +/* leds 0 = ON */ +#define IDP_HB_LED (1<<5) +#define IDP_BUSY_LED (1<<6) + +#define IDP_LEDS_MASK (IDP_HB_LED | IDP_BUSY_LED) + +/* + * macros for MTD driver + */ + +#define FLASH_WRITE_PROTECT_DISABLE() ((IDP_CPLD_FLASH_WE) &= ~(0x1)) +#define FLASH_WRITE_PROTECT_ENABLE() ((IDP_CPLD_FLASH_WE) |= (0x1)) + +/* + * macros for matrix keyboard driver + */ + +#define KEYBD_MATRIX_NUMBER_INPUTS 7 +#define KEYBD_MATRIX_NUMBER_OUTPUTS 14 + +#define KEYBD_MATRIX_INVERT_OUTPUT_LOGIC FALSE +#define KEYBD_MATRIX_INVERT_INPUT_LOGIC FALSE + +#define KEYBD_MATRIX_SETTLING_TIME_US 100 +#define KEYBD_MATRIX_KEYSTATE_DEBOUNCE_CONSTANT 2 + +#define KEYBD_MATRIX_SET_OUTPUTS(outputs) \ +{\ + IDP_CPLD_KB_COL_LOW = outputs;\ + IDP_CPLD_KB_COL_HIGH = outputs >> 7;\ +} + +#define KEYBD_MATRIX_GET_INPUTS(inputs) \ +{\ + inputs = (IDP_CPLD_KB_ROW & 0x7f);\ +} + + diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h new file mode 100644 index 00000000000..fdca3be47d9 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/io.h @@ -0,0 +1,20 @@ +/* + * arch/arm/mach-pxa/include/mach/io.h + * + * Copied from asm/arch/sa1100/io.h + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#include <mach/hardware.h> + +#define IO_SPACE_LIMIT 0xffffffff + +/* + * We don't actually have real ISA nor PCI buses, but there is so many + * drivers out there that might just work if we fake them... + */ +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-pxa/include/mach/irda.h b/arch/arm/mach-pxa/include/mach/irda.h new file mode 100644 index 00000000000..3cd41f77dda --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/irda.h @@ -0,0 +1,25 @@ +#ifndef ASMARM_ARCH_IRDA_H +#define ASMARM_ARCH_IRDA_H + +/* board specific transceiver capabilities */ + +#define IR_OFF 1 +#define IR_SIRMODE 2 +#define IR_FIRMODE 4 + +struct pxaficp_platform_data { + int transceiver_cap; + void (*transceiver_mode)(struct device *dev, int mode); + int (*startup)(struct device *dev); + void (*shutdown)(struct device *dev); + int gpio_pwdown; /* powerdown GPIO for the IrDA chip */ + bool gpio_pwdown_inverted; /* gpio_pwdown is inverted */ +}; + +extern void pxa_set_ficp_info(struct pxaficp_platform_data *info); + +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) +void pxa2xx_transceiver_mode(struct device *dev, int mode); +#endif + +#endif diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h new file mode 100644 index 00000000000..32975adf3ca --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -0,0 +1,117 @@ +/* + * arch/arm/mach-pxa/include/mach/irqs.h + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software 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. + */ +#ifndef __ASM_MACH_IRQS_H +#define __ASM_MACH_IRQS_H + +#ifdef CONFIG_PXA_HAVE_ISA_IRQS +#define PXA_ISA_IRQ(x) (x) +#define PXA_ISA_IRQ_NUM (16) +#else +#define PXA_ISA_IRQ_NUM (0) +#endif + +#define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x)) + +#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */ +#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */ +#define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI,PXA27x) */ +#define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI,PXA27x) */ +#define IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */ +#define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt (PXA27x) */ +#define IRQ_ACIPC0 PXA_IRQ(5) /* AP-CP Communication (PXA930) */ +#define IRQ_PWRI2C PXA_IRQ(6) /* Power I2C interrupt */ +#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error (PXA26x) */ +#define IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4-11 matches (PXA27x) */ +#define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */ +#define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */ +#define IRQ_GPIO_2_x PXA_IRQ(10) /* GPIO[2-x] Edge Detect */ +#define IRQ_USB PXA_IRQ(11) /* USB Service */ +#define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */ +#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt (PXA27x) */ +#define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request (PXA3xx) */ +#define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */ +#define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request (PXA25x) */ +#define IRQ_USIM PXA_IRQ(15) /* Smart Card interface interrupt (PXA27x) */ +#define IRQ_NSSP PXA_IRQ(16) /* Network SSP Service Request (PXA25x) */ +#define IRQ_SSP2 PXA_IRQ(16) /* SSP2 interrupt (PXA27x) */ +#define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */ +#define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */ +#define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */ +#define IRQ_ACIPC2 PXA_IRQ(19) /* AP-CP Communication (PXA930) */ +#define IRQ_STUART PXA_IRQ(20) /* STUART Transmit/Receive/Error */ +#define IRQ_BTUART PXA_IRQ(21) /* BTUART Transmit/Receive/Error */ +#define IRQ_FFUART PXA_IRQ(22) /* FFUART Transmit/Receive/Error*/ +#define IRQ_MMC PXA_IRQ(23) /* MMC Status/Error Detection */ +#define IRQ_SSP PXA_IRQ(24) /* SSP Service Request */ +#define IRQ_DMA PXA_IRQ(25) /* DMA Channel Service Request */ +#define IRQ_OST0 PXA_IRQ(26) /* OS Timer match 0 */ +#define IRQ_OST1 PXA_IRQ(27) /* OS Timer match 1 */ +#define IRQ_OST2 PXA_IRQ(28) /* OS Timer match 2 */ +#define IRQ_OST3 PXA_IRQ(29) /* OS Timer match 3 */ +#define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */ +#define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */ + +#define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */ +#define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */ +#define IRQ_CIR PXA_IRQ(34) /* Consumer IR */ +#define IRQ_COMM_WDT PXA_IRQ(35) /* Comm WDT interrupt */ +#define IRQ_TSI PXA_IRQ(36) /* Touch Screen Interface (PXA320) */ +#define IRQ_ENHROT PXA_IRQ(37) /* Enhanced Rotary (PXA930) */ +#define IRQ_USIM2 PXA_IRQ(38) /* USIM2 Controller */ +#define IRQ_GCU PXA_IRQ(39) /* Graphics Controller (PXA3xx) */ +#define IRQ_ACIPC1 PXA_IRQ(40) /* AP-CP Communication (PXA930) */ +#define IRQ_MMC2 PXA_IRQ(41) /* MMC2 Controller */ +#define IRQ_TRKBALL PXA_IRQ(43) /* Track Ball (PXA930) */ +#define IRQ_1WIRE PXA_IRQ(44) /* 1-Wire Controller */ +#define IRQ_NAND PXA_IRQ(45) /* NAND Controller */ +#define IRQ_USB2 PXA_IRQ(46) /* USB 2.0 Device Controller */ +#define IRQ_WAKEUP0 PXA_IRQ(49) /* EXT_WAKEUP0 */ +#define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */ +#define IRQ_DMEMC PXA_IRQ(51) /* Dynamic Memory Controller */ +#define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */ + +#define IRQ_U2O PXA_IRQ(64) /* USB OTG 2.0 Controller (PXA935) */ +#define IRQ_U2H PXA_IRQ(65) /* USB Host 2.0 Controller (PXA935) */ +#define IRQ_PXA935_MMC0 PXA_IRQ(72) /* MMC0 Controller (PXA935) */ +#define IRQ_PXA935_MMC1 PXA_IRQ(73) /* MMC1 Controller (PXA935) */ +#define IRQ_PXA935_MMC2 PXA_IRQ(74) /* MMC2 Controller (PXA935) */ +#define IRQ_PXA955_MMC3 PXA_IRQ(75) /* MMC3 Controller (PXA955) */ +#define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */ + +#define PXA_GPIO_IRQ_BASE PXA_IRQ(96) +#define PXA_NR_BUILTIN_GPIO (192) +#define PXA_GPIO_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x)) + +/* + * The following interrupts are for board specific purposes. Since + * the kernel can only run on one machine at a time, we can re-use + * these. + * By default, no board IRQ is reserved. It should be finished in + * custom board since sparse IRQ is already enabled. + */ +#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO) + +#define NR_IRQS (IRQ_BOARD_START) + +#ifndef __ASSEMBLY__ +struct irq_data; +struct pt_regs; + +void pxa_mask_irq(struct irq_data *); +void pxa_unmask_irq(struct irq_data *); +void icip_handle_irq(struct pt_regs *); +void ichp_handle_irq(struct pt_regs *); + +void pxa_init_irq(int irq_nr, int (*set_wake)(struct irq_data *, unsigned int)); +#endif + +#endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h new file mode 100644 index 00000000000..8066be54e9f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/littleton.h @@ -0,0 +1,13 @@ +#ifndef __ASM_ARCH_LITTLETON_H +#define __ASM_ARCH_LITTLETON_H + +#define LITTLETON_ETH_PHYS 0x30000000 + +#define LITTLETON_GPIO_LCD_CS (17) + +#define EXT0_GPIO_BASE (PXA_NR_BUILTIN_GPIO) +#define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x)) + +#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8) + +#endif /* __ASM_ARCH_LITTLETON_H */ diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/include/mach/lpd270.h new file mode 100644 index 00000000000..4edc712a2de --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/lpd270.h @@ -0,0 +1,43 @@ +/* + * arch/arm/mach-pxa/include/mach/lpd270.h + * + * Author: Lennert Buytenhek + * Created: Feb 10, 2006 + * + * 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 __ASM_ARCH_LPD270_H +#define __ASM_ARCH_LPD270_H + +#define LPD270_CPLD_PHYS PXA_CS2_PHYS +#define LPD270_CPLD_VIRT IOMEM(0xf0000000) +#define LPD270_CPLD_SIZE 0x00100000 + +#define LPD270_ETH_PHYS (PXA_CS2_PHYS + 0x01000000) + +/* CPLD registers */ +#define LPD270_CPLD_REG(x) (LPD270_CPLD_VIRT + (x)) +#define LPD270_CONTROL LPD270_CPLD_REG(0x00) +#define LPD270_PERIPHERAL0 LPD270_CPLD_REG(0x04) +#define LPD270_PERIPHERAL1 LPD270_CPLD_REG(0x08) +#define LPD270_CPLD_REVISION LPD270_CPLD_REG(0x14) +#define LPD270_EEPROM_SPI_ITF LPD270_CPLD_REG(0x20) +#define LPD270_MODE_PINS LPD270_CPLD_REG(0x24) +#define LPD270_EGPIO LPD270_CPLD_REG(0x30) +#define LPD270_INT_MASK LPD270_CPLD_REG(0x40) +#define LPD270_INT_STATUS LPD270_CPLD_REG(0x50) + +#define LPD270_INT_AC97 (1 << 4) /* AC'97 CODEC IRQ */ +#define LPD270_INT_ETHERNET (1 << 3) /* Ethernet controller IRQ */ +#define LPD270_INT_USBC (1 << 2) /* USB client cable detection IRQ */ + +#define LPD270_IRQ(x) (IRQ_BOARD_START + (x)) +#define LPD270_USBC_IRQ LPD270_IRQ(2) +#define LPD270_ETHERNET_IRQ LPD270_IRQ(3) +#define LPD270_AC97_IRQ LPD270_IRQ(4) +#define LPD270_NR_IRQS (IRQ_BOARD_START + 5) + +#endif diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h new file mode 100644 index 00000000000..2a086e8373e --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/lubbock.h @@ -0,0 +1,53 @@ +/* + * arch/arm/mach-pxa/include/mach/lubbock.h + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software 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. + */ + +#define LUBBOCK_ETH_PHYS PXA_CS3_PHYS + +#define LUBBOCK_FPGA_PHYS PXA_CS2_PHYS +#define LUBBOCK_FPGA_VIRT (0xf0000000) +#define LUB_P2V(x) ((x) - LUBBOCK_FPGA_PHYS + LUBBOCK_FPGA_VIRT) +#define LUB_V2P(x) ((x) - LUBBOCK_FPGA_VIRT + LUBBOCK_FPGA_PHYS) + +#ifndef __ASSEMBLY__ +# define __LUB_REG(x) (*((volatile unsigned long *)LUB_P2V(x))) +#else +# define __LUB_REG(x) LUB_P2V(x) +#endif + +/* FPGA register virtual addresses */ +#define LUB_WHOAMI __LUB_REG(LUBBOCK_FPGA_PHYS + 0x000) +#define LUB_DISC_BLNK_LED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x040) +#define LUB_CONF_SWITCHES __LUB_REG(LUBBOCK_FPGA_PHYS + 0x050) +#define LUB_USER_SWITCHES __LUB_REG(LUBBOCK_FPGA_PHYS + 0x060) +#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080) +#define LUB_MISC_RD __LUB_REG(LUBBOCK_FPGA_PHYS + 0x090) +#define LUB_IRQ_MASK_EN __LUB_REG(LUBBOCK_FPGA_PHYS + 0x0c0) +#define LUB_IRQ_SET_CLR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x0d0) +#define LUB_GP __LUB_REG(LUBBOCK_FPGA_PHYS + 0x100) + +/* Board specific IRQs */ +#define LUBBOCK_IRQ(x) (IRQ_BOARD_START + (x)) +#define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0) +#define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1) +#define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2) /* usb connect */ +#define LUBBOCK_ETH_IRQ LUBBOCK_IRQ(3) +#define LUBBOCK_UCB1400_IRQ LUBBOCK_IRQ(4) +#define LUBBOCK_BB_IRQ LUBBOCK_IRQ(5) +#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */ +#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6) + +#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16) +#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55) + +#ifndef __ASSEMBLY__ +extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set); +#endif diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h new file mode 100644 index 00000000000..ba6a6e1d29e --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -0,0 +1,120 @@ +/* + * GPIO and IRQ definitions for HTC Magician PDA phones + * + * Copyright (c) 2007 Philipp Zabel + * + * 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 _MAGICIAN_H_ +#define _MAGICIAN_H_ + +#include <linux/gpio.h> +#include <mach/irqs.h> + +/* + * PXA GPIOs + */ + +#define GPIO0_MAGICIAN_KEY_POWER 0 +#define GPIO9_MAGICIAN_UNKNOWN 9 +#define GPIO10_MAGICIAN_GSM_IRQ 10 +#define GPIO11_MAGICIAN_GSM_OUT1 11 +#define GPIO13_MAGICIAN_CPLD_IRQ 13 +#define GPIO18_MAGICIAN_UNKNOWN 18 +#define GPIO22_MAGICIAN_VIBRA_EN 22 +#define GPIO26_MAGICIAN_GSM_POWER 26 +#define GPIO27_MAGICIAN_USBC_PUEN 27 +#define GPIO30_MAGICIAN_BQ24022_nCHARGE_EN 30 +#define GPIO37_MAGICIAN_KEY_HANGUP 37 +#define GPIO38_MAGICIAN_KEY_CONTACTS 38 +#define GPIO40_MAGICIAN_GSM_OUT2 40 +#define GPIO48_MAGICIAN_UNKNOWN 48 +#define GPIO56_MAGICIAN_UNKNOWN 56 +#define GPIO57_MAGICIAN_CAM_RESET 57 +#define GPIO75_MAGICIAN_SAMSUNG_POWER 75 +#define GPIO83_MAGICIAN_nIR_EN 83 +#define GPIO86_MAGICIAN_GSM_RESET 86 +#define GPIO87_MAGICIAN_GSM_SELECT 87 +#define GPIO90_MAGICIAN_KEY_CALENDAR 90 +#define GPIO91_MAGICIAN_KEY_CAMERA 91 +#define GPIO93_MAGICIAN_KEY_UP 93 +#define GPIO94_MAGICIAN_KEY_DOWN 94 +#define GPIO95_MAGICIAN_KEY_LEFT 95 +#define GPIO96_MAGICIAN_KEY_RIGHT 96 +#define GPIO97_MAGICIAN_KEY_ENTER 97 +#define GPIO98_MAGICIAN_KEY_RECORD 98 +#define GPIO99_MAGICIAN_HEADPHONE_IN 99 +#define GPIO100_MAGICIAN_KEY_VOL_UP 100 +#define GPIO101_MAGICIAN_KEY_VOL_DOWN 101 +#define GPIO102_MAGICIAN_KEY_PHONE 102 +#define GPIO103_MAGICIAN_LED_KP 103 +#define GPIO104_MAGICIAN_LCD_POWER_1 104 +#define GPIO105_MAGICIAN_LCD_POWER_2 105 +#define GPIO106_MAGICIAN_LCD_POWER_3 106 +#define GPIO107_MAGICIAN_DS1WM_IRQ 107 +#define GPIO108_MAGICIAN_GSM_READY 108 +#define GPIO114_MAGICIAN_UNKNOWN 114 +#define GPIO115_MAGICIAN_nPEN_IRQ 115 +#define GPIO116_MAGICIAN_nCAM_EN 116 +#define GPIO119_MAGICIAN_UNKNOWN 119 +#define GPIO120_MAGICIAN_UNKNOWN 120 + +/* + * CPLD IRQs + */ + +#define IRQ_MAGICIAN_SD (IRQ_BOARD_START + 0) +#define IRQ_MAGICIAN_EP (IRQ_BOARD_START + 1) +#define IRQ_MAGICIAN_BT (IRQ_BOARD_START + 2) +#define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3) + +#define MAGICIAN_NR_IRQS (IRQ_BOARD_START + 8) + +/* + * CPLD EGPIOs + */ + +#define MAGICIAN_EGPIO_BASE PXA_NR_BUILTIN_GPIO +#define MAGICIAN_EGPIO(reg,bit) \ + (MAGICIAN_EGPIO_BASE + 8*reg + bit) + +/* output */ + +#define EGPIO_MAGICIAN_TOPPOLY_POWER MAGICIAN_EGPIO(0, 2) +#define EGPIO_MAGICIAN_LED_POWER MAGICIAN_EGPIO(0, 5) +#define EGPIO_MAGICIAN_GSM_RESET MAGICIAN_EGPIO(0, 6) +#define EGPIO_MAGICIAN_LCD_POWER MAGICIAN_EGPIO(0, 7) +#define EGPIO_MAGICIAN_SPK_POWER MAGICIAN_EGPIO(1, 0) +#define EGPIO_MAGICIAN_EP_POWER MAGICIAN_EGPIO(1, 1) +#define EGPIO_MAGICIAN_IN_SEL0 MAGICIAN_EGPIO(1, 2) +#define EGPIO_MAGICIAN_IN_SEL1 MAGICIAN_EGPIO(1, 3) +#define EGPIO_MAGICIAN_MIC_POWER MAGICIAN_EGPIO(1, 4) +#define EGPIO_MAGICIAN_CODEC_RESET MAGICIAN_EGPIO(1, 5) +#define EGPIO_MAGICIAN_CODEC_POWER MAGICIAN_EGPIO(1, 6) +#define EGPIO_MAGICIAN_BL_POWER MAGICIAN_EGPIO(1, 7) +#define EGPIO_MAGICIAN_SD_POWER MAGICIAN_EGPIO(2, 0) +#define EGPIO_MAGICIAN_CARKIT_MIC MAGICIAN_EGPIO(2, 1) +#define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL MAGICIAN_EGPIO(2, 2) +#define EGPIO_MAGICIAN_FLASH_VPP MAGICIAN_EGPIO(2, 3) +#define EGPIO_MAGICIAN_BL_POWER2 MAGICIAN_EGPIO(2, 4) +#define EGPIO_MAGICIAN_BQ24022_ISET2 MAGICIAN_EGPIO(2, 5) +#define EGPIO_MAGICIAN_GSM_POWER MAGICIAN_EGPIO(2, 7) + +/* input */ + +#define EGPIO_MAGICIAN_CABLE_STATE_AC MAGICIAN_EGPIO(4, 0) +#define EGPIO_MAGICIAN_CABLE_STATE_USB MAGICIAN_EGPIO(4, 1) + +#define EGPIO_MAGICIAN_BOARD_ID0 MAGICIAN_EGPIO(5, 0) +#define EGPIO_MAGICIAN_BOARD_ID1 MAGICIAN_EGPIO(5, 1) +#define EGPIO_MAGICIAN_BOARD_ID2 MAGICIAN_EGPIO(5, 2) +#define EGPIO_MAGICIAN_LCD_SELECT MAGICIAN_EGPIO(5, 3) +#define EGPIO_MAGICIAN_nSD_READONLY MAGICIAN_EGPIO(5, 4) + +#define EGPIO_MAGICIAN_EP_INSERT MAGICIAN_EGPIO(6, 1) + +#endif /* _MAGICIAN_H_ */ diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h new file mode 100644 index 00000000000..4c2d11cd824 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -0,0 +1,139 @@ +/* + * arch/arm/mach-pxa/include/mach/mainstone.h + * + * Author: Nicolas Pitre + * Created: Nov 14, 2002 + * Copyright: MontaVista Software 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. + */ + +#ifndef ASM_ARCH_MAINSTONE_H +#define ASM_ARCH_MAINSTONE_H + +#define MST_ETH_PHYS PXA_CS4_PHYS + +#define MST_FPGA_PHYS PXA_CS2_PHYS +#define MST_FPGA_VIRT (0xf0000000) +#define MST_P2V(x) ((x) - MST_FPGA_PHYS + MST_FPGA_VIRT) +#define MST_V2P(x) ((x) - MST_FPGA_VIRT + MST_FPGA_PHYS) + +#ifndef __ASSEMBLY__ +# define __MST_REG(x) (*((volatile unsigned long *)MST_P2V(x))) +#else +# define __MST_REG(x) MST_P2V(x) +#endif + +/* board level registers in the FPGA */ + +#define MST_LEDDAT1 __MST_REG(0x08000010) +#define MST_LEDDAT2 __MST_REG(0x08000014) +#define MST_LEDCTRL __MST_REG(0x08000040) +#define MST_GPSWR __MST_REG(0x08000060) +#define MST_MSCWR1 __MST_REG(0x08000080) +#define MST_MSCWR2 __MST_REG(0x08000084) +#define MST_MSCWR3 __MST_REG(0x08000088) +#define MST_MSCRD __MST_REG(0x08000090) +#define MST_INTMSKENA __MST_REG(0x080000c0) +#define MST_INTSETCLR __MST_REG(0x080000d0) +#define MST_PCMCIA0 __MST_REG(0x080000e0) +#define MST_PCMCIA1 __MST_REG(0x080000e4) + +#define MST_MSCWR1_CAMERA_ON (1 << 15) /* Camera interface power control */ +#define MST_MSCWR1_CAMERA_SEL (1 << 14) /* Camera interface mux control */ +#define MST_MSCWR1_LCD_CTL (1 << 13) /* General-purpose LCD control */ +#define MST_MSCWR1_MS_ON (1 << 12) /* Memory Stick power control */ +#define MST_MSCWR1_MMC_ON (1 << 11) /* MultiMediaCard* power control */ +#define MST_MSCWR1_MS_SEL (1 << 10) /* SD/MS multiplexer control */ +#define MST_MSCWR1_BB_SEL (1 << 9) /* PCMCIA/Baseband multiplexer */ +#define MST_MSCWR1_BT_ON (1 << 8) /* Bluetooth UART transceiver */ +#define MST_MSCWR1_BTDTR (1 << 7) /* Bluetooth UART DTR */ + +#define MST_MSCWR1_IRDA_MASK (3 << 5) /* IrDA transceiver mode */ +#define MST_MSCWR1_IRDA_FULL (0 << 5) /* full distance power */ +#define MST_MSCWR1_IRDA_OFF (1 << 5) /* shutdown */ +#define MST_MSCWR1_IRDA_MED (2 << 5) /* 2/3 distance power */ +#define MST_MSCWR1_IRDA_LOW (3 << 5) /* 1/3 distance power */ + +#define MST_MSCWR1_IRDA_FIR (1 << 4) /* IrDA transceiver SIR/FIR */ +#define MST_MSCWR1_GREENLED (1 << 3) /* LED D1 control */ +#define MST_MSCWR1_PDC_CTL (1 << 2) /* reserved */ +#define MST_MSCWR1_MTR_ON (1 << 1) /* Silent alert motor */ +#define MST_MSCWR1_SYSRESET (1 << 0) /* System reset */ + +#define MST_MSCWR2_USB_OTG_RST (1 << 6) /* USB On The Go reset */ +#define MST_MSCWR2_USB_OTG_SEL (1 << 5) /* USB On The Go control */ +#define MST_MSCWR2_nUSBC_SC (1 << 4) /* USB client soft connect control */ +#define MST_MSCWR2_I2S_SPKROFF (1 << 3) /* I2S CODEC amplifier control */ +#define MST_MSCWR2_AC97_SPKROFF (1 << 2) /* AC97 CODEC amplifier control */ +#define MST_MSCWR2_RADIO_PWR (1 << 1) /* Radio module power control */ +#define MST_MSCWR2_RADIO_WAKE (1 << 0) /* Radio module wake-up signal */ + +#define MST_MSCWR3_GPIO_RESET_EN (1 << 2) /* Enable GPIO Reset */ +#define MST_MSCWR3_GPIO_RESET (1 << 1) /* Initiate a GPIO Reset */ +#define MST_MSCWR3_COMMS_SW_RESET (1 << 0) /* Communications Processor Reset Control */ + +#define MST_MSCRD_nPENIRQ (1 << 9) /* ADI7873* nPENIRQ signal */ +#define MST_MSCRD_nMEMSTK_CD (1 << 8) /* Memory Stick detection signal */ +#define MST_MSCRD_nMMC_CD (1 << 7) /* SD/MMC card detection signal */ +#define MST_MSCRD_nUSIM_CD (1 << 6) /* USIM card detection signal */ +#define MST_MSCRD_USB_CBL (1 << 5) /* USB client cable status */ +#define MST_MSCRD_TS_BUSY (1 << 4) /* ADI7873 busy */ +#define MST_MSCRD_BTDSR (1 << 3) /* Bluetooth UART DSR */ +#define MST_MSCRD_BTRI (1 << 2) /* Bluetooth UART Ring Indicator */ +#define MST_MSCRD_BTDCD (1 << 1) /* Bluetooth UART DCD */ +#define MST_MSCRD_nMMC_WP (1 << 0) /* SD/MMC write-protect status */ + +#define MST_INT_S1_IRQ (1 << 15) /* PCMCIA socket 1 IRQ */ +#define MST_INT_S1_STSCHG (1 << 14) /* PCMCIA socket 1 status changed */ +#define MST_INT_S1_CD (1 << 13) /* PCMCIA socket 1 card detection */ +#define MST_INT_S0_IRQ (1 << 11) /* PCMCIA socket 0 IRQ */ +#define MST_INT_S0_STSCHG (1 << 10) /* PCMCIA socket 0 status changed */ +#define MST_INT_S0_CD (1 << 9) /* PCMCIA socket 0 card detection */ +#define MST_INT_nEXBRD_INT (1 << 7) /* Expansion board IRQ */ +#define MST_INT_MSINS (1 << 6) /* Memory Stick* detection */ +#define MST_INT_PENIRQ (1 << 5) /* ADI7873* touch-screen IRQ */ +#define MST_INT_AC97 (1 << 4) /* AC'97 CODEC IRQ */ +#define MST_INT_ETHERNET (1 << 3) /* Ethernet controller IRQ */ +#define MST_INT_USBC (1 << 2) /* USB client cable detection IRQ */ +#define MST_INT_USIM (1 << 1) /* USIM card detection IRQ */ +#define MST_INT_MMC (1 << 0) /* MMC/SD card detection IRQ */ + +#define MST_PCMCIA_nIRQ (1 << 10) /* IRQ / ready signal */ +#define MST_PCMCIA_nSPKR_BVD2 (1 << 9) /* VDD sense / digital speaker */ +#define MST_PCMCIA_nSTSCHG_BVD1 (1 << 8) /* VDD sense / card status changed */ +#define MST_PCMCIA_nVS2 (1 << 7) /* VSS voltage sense */ +#define MST_PCMCIA_nVS1 (1 << 6) /* VSS voltage sense */ +#define MST_PCMCIA_nCD (1 << 5) /* Card detection signal */ +#define MST_PCMCIA_RESET (1 << 4) /* Card reset signal */ +#define MST_PCMCIA_PWR_MASK (0x000f) /* MAX1602 power-supply controls */ + +#define MST_PCMCIA_PWR_VPP_0 0x0 /* voltage VPP = 0V */ +#define MST_PCMCIA_PWR_VPP_120 0x2 /* voltage VPP = 12V*/ +#define MST_PCMCIA_PWR_VPP_VCC 0x1 /* voltage VPP = VCC */ +#define MST_PCMCIA_PWR_VCC_0 0x0 /* voltage VCC = 0V */ +#define MST_PCMCIA_PWR_VCC_33 0x8 /* voltage VCC = 3.3V */ +#define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */ + +/* board specific IRQs */ +#define MAINSTONE_IRQ(x) (IRQ_BOARD_START + (x)) +#define MAINSTONE_MMC_IRQ MAINSTONE_IRQ(0) +#define MAINSTONE_USIM_IRQ MAINSTONE_IRQ(1) +#define MAINSTONE_USBC_IRQ MAINSTONE_IRQ(2) +#define MAINSTONE_ETHERNET_IRQ MAINSTONE_IRQ(3) +#define MAINSTONE_AC97_IRQ MAINSTONE_IRQ(4) +#define MAINSTONE_PEN_IRQ MAINSTONE_IRQ(5) +#define MAINSTONE_MSINS_IRQ MAINSTONE_IRQ(6) +#define MAINSTONE_EXBRD_IRQ MAINSTONE_IRQ(7) +#define MAINSTONE_S0_CD_IRQ MAINSTONE_IRQ(9) +#define MAINSTONE_S0_STSCHG_IRQ MAINSTONE_IRQ(10) +#define MAINSTONE_S0_IRQ MAINSTONE_IRQ(11) +#define MAINSTONE_S1_CD_IRQ MAINSTONE_IRQ(13) +#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14) +#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15) + +#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16) + +#endif diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h new file mode 100644 index 00000000000..cafadc33dfd --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h @@ -0,0 +1,225 @@ +#ifndef __ASM_ARCH_MFP_PXA25X_H +#define __ASM_ARCH_MFP_PXA25X_H + +#include <mach/mfp-pxa2xx.h> + +/* GPIO */ +#define GPIO2_GPIO MFP_CFG_IN(GPIO2, AF0) +#define GPIO3_GPIO MFP_CFG_IN(GPIO3, AF0) +#define GPIO4_GPIO MFP_CFG_IN(GPIO4, AF0) +#define GPIO5_GPIO MFP_CFG_IN(GPIO5, AF0) +#define GPIO6_GPIO MFP_CFG_IN(GPIO6, AF0) +#define GPIO7_GPIO MFP_CFG_IN(GPIO7, AF0) +#define GPIO8_GPIO MFP_CFG_IN(GPIO8, AF0) + +#define GPIO1_RST MFP_CFG_IN(GPIO1, AF1) + +/* Crystal and Clock Signals */ +#define GPIO10_RTCCLK MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW) +#define GPIO70_RTCCLK MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW) +#define GPIO7_48MHz MFP_CFG_OUT(GPIO7, AF1, DRIVE_LOW) +#define GPIO11_3_6MHz MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW) +#define GPIO71_3_6MHz MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW) +#define GPIO12_32KHz MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW) +#define GPIO72_32kHz MFP_CFG_OUT(GPIO72, AF1, DRIVE_LOW) + +/* SDRAM and Static Memory I/O Signals */ +#define GPIO15_nCS_1 MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH) +#define GPIO78_nCS_2 MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH) +#define GPIO79_nCS_3 MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH) +#define GPIO80_nCS_4 MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH) +#define GPIO33_nCS_5 MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH) + +/* Miscellaneous I/O and DMA Signals */ +#define GPIO18_RDY MFP_CFG_IN(GPIO18, AF1) +#define GPIO20_DREQ_0 MFP_CFG_IN(GPIO20, AF1) +#define GPIO19_DREQ_1 MFP_CFG_IN(GPIO19, AF1) + +/* Alternate Bus Master Mode I/O Signals */ +#define GPIO13_MBGNT MFP_CFG_OUT(GPIO13, AF2, DRIVE_LOW) +#define GPIO73_MBGNT MFP_CFG_OUT(GPIO73, AF1, DRIVE_LOW) +#define GPIO14_MBREQ MFP_CFG_IN(GPIO14, AF1) +#define GPIO66_MBREQ MFP_CFG_IN(GPIO66, AF1) + +/* PC CARD */ +#define GPIO52_nPCE_1 MFP_CFG_OUT(GPIO52, AF2, DRIVE_HIGH) +#define GPIO53_nPCE_2 MFP_CFG_OUT(GPIO53, AF2, DRIVE_HIGH) +#define GPIO55_nPREG MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH) +#define GPIO50_nPIOR MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH) +#define GPIO51_nPIOW MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH) +#define GPIO49_nPWE MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH) +#define GPIO48_nPOE MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH) +#define GPIO57_nIOIS16 MFP_CFG_IN(GPIO57, AF1) +#define GPIO56_nPWAIT MFP_CFG_IN(GPIO56, AF1) +#define GPIO54_nPSKTSEL MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH) + +/* FFUART */ +#define GPIO34_FFUART_RXD MFP_CFG_IN(GPIO34, AF1) +#define GPIO35_FFUART_CTS MFP_CFG_IN(GPIO35, AF1) +#define GPIO36_FFUART_DCD MFP_CFG_IN(GPIO36, AF1) +#define GPIO37_FFUART_DSR MFP_CFG_IN(GPIO37, AF1) +#define GPIO38_FFUART_RI MFP_CFG_IN(GPIO38, AF1) +#define GPIO39_FFUART_TXD MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH) +#define GPIO40_FFUART_DTR MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH) +#define GPIO41_FFUART_RTS MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH) + +/* BTUART */ +#define GPIO42_BTUART_RXD MFP_CFG_IN(GPIO42, AF1) +#define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH) +#define GPIO44_BTUART_CTS MFP_CFG_IN(GPIO44, AF1) +#define GPIO45_BTUART_RTS MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH) + +/* STUART */ +#define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2) +#define GPIO47_STUART_TXD MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH) + +/* HWUART */ +#define GPIO42_HWUART_RXD MFP_CFG_IN(GPIO42, AF3) +#define GPIO43_HWUART_TXD MFP_CFG_OUT(GPIO43, AF3, DRIVE_HIGH) +#define GPIO44_HWUART_CTS MFP_CFG_IN(GPIO44, AF3) +#define GPIO45_HWUART_RTS MFP_CFG_OUT(GPIO45, AF3, DRIVE_HIGH) +#define GPIO48_HWUART_TXD MFP_CFG_OUT(GPIO48, AF1, DRIVE_HIGH) +#define GPIO49_HWUART_RXD MFP_CFG_IN(GPIO49, AF1) +#define GPIO50_HWUART_CTS MFP_CFG_IN(GPIO50, AF1) +#define GPIO51_HWUART_RTS MFP_CFG_OUT(GPIO51, AF1, DRIVE_HIGH) + +/* FICP */ +#define GPIO46_FICP_RXD MFP_CFG_IN(GPIO46, AF1) +#define GPIO47_FICP_TXD MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH) + +/* PWM 0/1 */ +#define GPIO16_PWM0_OUT MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW) +#define GPIO17_PWM1_OUT MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW) + +/* AC97 */ +#define GPIO28_AC97_BITCLK MFP_CFG_IN(GPIO28, AF1) +#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1) +#define GPIO30_AC97_SDATA_OUT MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW) +#define GPIO31_AC97_SYNC MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW) +#define GPIO32_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO32, AF1) + +/* I2S */ +#define GPIO28_I2S_BITCLK_IN MFP_CFG_IN(GPIO28, AF2) +#define GPIO28_I2S_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW) +#define GPIO29_I2S_SDATA_IN MFP_CFG_IN(GPIO29, AF2) +#define GPIO30_I2S_SDATA_OUT MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW) +#define GPIO31_I2S_SYNC MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW) +#define GPIO32_I2S_SYSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW) + +/* SSP 1 */ +#define GPIO23_SSP1_SCLK MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW) +#define GPIO24_SSP1_SFRM MFP_CFG_OUT(GPIO24, AF2, DRIVE_LOW) +#define GPIO25_SSP1_TXD MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW) +#define GPIO26_SSP1_RXD MFP_CFG_IN(GPIO26, AF1) +#define GPIO27_SSP1_EXTCLK MFP_CFG_IN(GPIO27, AF1) + +/* SSP 2 - NSSP */ +#define GPIO81_SSP2_CLK_OUT MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW) +#define GPIO81_SSP2_CLK_IN MFP_CFG_IN(GPIO81, AF1) +#define GPIO82_SSP2_FRM_OUT MFP_CFG_OUT(GPIO82, AF1, DRIVE_LOW) +#define GPIO82_SSP2_FRM_IN MFP_CFG_IN(GPIO82, AF1) +#define GPIO83_SSP2_TXD MFP_CFG_OUT(GPIO83, AF1, DRIVE_LOW) +#define GPIO83_SSP2_RXD MFP_CFG_IN(GPIO83, AF2) +#define GPIO84_SSP2_TXD MFP_CFG_OUT(GPIO84, AF1, DRIVE_LOW) +#define GPIO84_SSP2_RXD MFP_CFG_IN(GPIO84, AF2) + +/* MMC */ +#define GPIO6_MMC_CLK MFP_CFG_OUT(GPIO6, AF1, DRIVE_LOW) +#define GPIO8_MMC_CS0 MFP_CFG_OUT(GPIO8, AF1, DRIVE_LOW) +#define GPIO9_MMC_CS1 MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW) +#define GPIO34_MMC_CS0 MFP_CFG_OUT(GPIO34, AF2, DRIVE_LOW) +#define GPIO39_MMC_CS1 MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW) +#define GPIO53_MMC_CLK MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW) +#define GPIO54_MMC_CLK MFP_CFG_OUT(GPIO54, AF1, DRIVE_LOW) +#define GPIO69_MMC_CLK MFP_CFG_OUT(GPIO69, AF1, DRIVE_LOW) +#define GPIO67_MMC_CS0 MFP_CFG_OUT(GPIO67, AF1, DRIVE_LOW) +#define GPIO68_MMC_CS1 MFP_CFG_OUT(GPIO68, AF1, DRIVE_LOW) + +/* LCD */ +#define GPIO58_LCD_LDD_0 MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW) +#define GPIO59_LCD_LDD_1 MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW) +#define GPIO60_LCD_LDD_2 MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW) +#define GPIO61_LCD_LDD_3 MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW) +#define GPIO62_LCD_LDD_4 MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW) +#define GPIO63_LCD_LDD_5 MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW) +#define GPIO64_LCD_LDD_6 MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW) +#define GPIO65_LCD_LDD_7 MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW) +#define GPIO66_LCD_LDD_8 MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW) +#define GPIO67_LCD_LDD_9 MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW) +#define GPIO68_LCD_LDD_10 MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW) +#define GPIO69_LCD_LDD_11 MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW) +#define GPIO70_LCD_LDD_12 MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW) +#define GPIO71_LCD_LDD_13 MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW) +#define GPIO72_LCD_LDD_14 MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW) +#define GPIO73_LCD_LDD_15 MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW) +#define GPIO74_LCD_FCLK MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW) +#define GPIO75_LCD_LCLK MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW) +#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW) +#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW) + +#ifdef CONFIG_CPU_PXA26x +/* GPIO */ +#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0) +#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF1) +#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF1) +#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF1) +#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF1) + +/* SDRAM */ +#define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH) +#define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH) +#define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH) + +/* USB */ +#define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1) +#define GPIO32_USB_VP MFP_CFG_IN(GPIO32, AF2) +#define GPIO34_USB_VM MFP_CFG_IN(GPIO34, AF2) +#define GPIO39_USB_VPO MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW) +#define GPIO56_USB_VMO MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW) +#define GPIO57_USB_nOE MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH) + +/* ASSP */ +#define GPIO28_ASSP_BITCLK_IN MFP_CFG_IN(GPIO28, AF3) +#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW) +#define GPIO29_ASSP_RXD MFP_CFG_IN(GPIO29, AF3) +#define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW) +#define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1) +#define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW) + +/* AC97 */ +#define GPIO89_AC97_nRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH) +#endif /* CONFIG_CPU_PXA26x */ + +/* commonly used pin configurations */ +#define GPIOxx_LCD_16BPP \ + GPIO58_LCD_LDD_0, \ + GPIO59_LCD_LDD_1, \ + GPIO60_LCD_LDD_2, \ + GPIO61_LCD_LDD_3, \ + GPIO62_LCD_LDD_4, \ + GPIO63_LCD_LDD_5, \ + GPIO64_LCD_LDD_6, \ + GPIO65_LCD_LDD_7, \ + GPIO66_LCD_LDD_8, \ + GPIO67_LCD_LDD_9, \ + GPIO68_LCD_LDD_10, \ + GPIO69_LCD_LDD_11, \ + GPIO70_LCD_LDD_12, \ + GPIO71_LCD_LDD_13, \ + GPIO72_LCD_LDD_14, \ + GPIO73_LCD_LDD_15 + +#define GPIOxx_LCD_DSTN_16BPP \ + GPIOxx_LCD_16BPP, \ + GPIO74_LCD_FCLK, \ + GPIO75_LCD_LCLK, \ + GPIO76_LCD_PCLK + +#define GPIOxx_LCD_TFT_16BPP \ + GPIOxx_LCD_16BPP, \ + GPIO74_LCD_FCLK, \ + GPIO75_LCD_LCLK, \ + GPIO76_LCD_PCLK, \ + GPIO77_LCD_BIAS + +#endif /* __ASM_ARCH_MFP_PXA25X_H */ diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h new file mode 100644 index 00000000000..ec0f0b0b674 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h @@ -0,0 +1,465 @@ +#ifndef __ASM_ARCH_MFP_PXA27X_H +#define __ASM_ARCH_MFP_PXA27X_H + +/* + * NOTE: for those special-function bidirectional GPIOs, as described + * in the "PXA27x Developer's Manual" Section 24.4.2.1, only its input + * alternative is preserved, the direction is actually selected by the + * specific controller, and this should work in most cases. + */ + +#include <mach/mfp-pxa2xx.h> + +/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN + * bit is set, regardless of the GPIO configuration + */ +#define GPIO3_GPIO MFP_CFG_IN(GPIO3, AF0) +#define GPIO4_GPIO MFP_CFG_IN(GPIO4, AF0) + +/* GPIO */ +#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0) +#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF0) +#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF0) +#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF0) +#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF0) +#define GPIO90_GPIO MFP_CFG_IN(GPIO90, AF0) +#define GPIO91_GPIO MFP_CFG_IN(GPIO91, AF0) +#define GPIO92_GPIO MFP_CFG_IN(GPIO92, AF0) +#define GPIO93_GPIO MFP_CFG_IN(GPIO93, AF0) +#define GPIO94_GPIO MFP_CFG_IN(GPIO94, AF0) +#define GPIO95_GPIO MFP_CFG_IN(GPIO95, AF0) +#define GPIO96_GPIO MFP_CFG_IN(GPIO96, AF0) +#define GPIO97_GPIO MFP_CFG_IN(GPIO97, AF0) +#define GPIO98_GPIO MFP_CFG_IN(GPIO98, AF0) +#define GPIO99_GPIO MFP_CFG_IN(GPIO99, AF0) +#define GPIO100_GPIO MFP_CFG_IN(GPIO100, AF0) +#define GPIO101_GPIO MFP_CFG_IN(GPIO101, AF0) +#define GPIO102_GPIO MFP_CFG_IN(GPIO102, AF0) +#define GPIO103_GPIO MFP_CFG_IN(GPIO103, AF0) +#define GPIO104_GPIO MFP_CFG_IN(GPIO104, AF0) +#define GPIO105_GPIO MFP_CFG_IN(GPIO105, AF0) +#define GPIO106_GPIO MFP_CFG_IN(GPIO106, AF0) +#define GPIO107_GPIO MFP_CFG_IN(GPIO107, AF0) +#define GPIO108_GPIO MFP_CFG_IN(GPIO108, AF0) +#define GPIO109_GPIO MFP_CFG_IN(GPIO109, AF0) +#define GPIO110_GPIO MFP_CFG_IN(GPIO110, AF0) +#define GPIO111_GPIO MFP_CFG_IN(GPIO111, AF0) +#define GPIO112_GPIO MFP_CFG_IN(GPIO112, AF0) +#define GPIO113_GPIO MFP_CFG_IN(GPIO113, AF0) +#define GPIO114_GPIO MFP_CFG_IN(GPIO114, AF0) +#define GPIO115_GPIO MFP_CFG_IN(GPIO115, AF0) +#define GPIO116_GPIO MFP_CFG_IN(GPIO116, AF0) +#define GPIO117_GPIO MFP_CFG_IN(GPIO117, AF0) +#define GPIO118_GPIO MFP_CFG_IN(GPIO118, AF0) +#define GPIO119_GPIO MFP_CFG_IN(GPIO119, AF0) +#define GPIO120_GPIO MFP_CFG_IN(GPIO120, AF0) + +/* Crystal and Clock Signals */ +#define GPIO9_HZ_CLK MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW) +#define GPIO10_HZ_CLK MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW) +#define GPIO11_48_MHz MFP_CFG_OUT(GPIO11, AF3, DRIVE_LOW) +#define GPIO12_48_MHz MFP_CFG_OUT(GPIO12, AF3, DRIVE_LOW) +#define GPIO13_CLK_EXT MFP_CFG_IN(GPIO13, AF1) + +/* OS Timer Signals */ +#define GPIO11_EXT_SYNC_0 MFP_CFG_IN(GPIO11, AF1) +#define GPIO12_EXT_SYNC_1 MFP_CFG_IN(GPIO12, AF1) +#define GPIO9_CHOUT_0 MFP_CFG_OUT(GPIO9, AF3, DRIVE_LOW) +#define GPIO10_CHOUT_1 MFP_CFG_OUT(GPIO10, AF3, DRIVE_LOW) +#define GPIO11_CHOUT_0 MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW) +#define GPIO12_CHOUT_1 MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW) + +/* SDRAM and Static Memory I/O Signals */ +#define GPIO20_nSDCS_2 MFP_CFG_OUT(GPIO20, AF1, DRIVE_HIGH) +#define GPIO21_nSDCS_3 MFP_CFG_OUT(GPIO21, AF1, DRIVE_HIGH) +#define GPIO15_nCS_1 MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH) +#define GPIO78_nCS_2 MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH) +#define GPIO79_nCS_3 MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH) +#define GPIO80_nCS_4 MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH) +#define GPIO33_nCS_5 MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH) + +/* Miscellaneous I/O and DMA Signals */ +#define GPIO21_DVAL_0 MFP_CFG_OUT(GPIO21, AF2, DRIVE_HIGH) +#define GPIO116_DVAL_0 MFP_CFG_OUT(GPIO116, AF1, DRIVE_HIGH) +#define GPIO33_DVAL_1 MFP_CFG_OUT(GPIO33, AF1, DRIVE_HIGH) +#define GPIO96_DVAL_1 MFP_CFG_OUT(GPIO96, AF2, DRIVE_HIGH) +#define GPIO18_RDY MFP_CFG_IN(GPIO18, AF1) +#define GPIO20_DREQ_0 MFP_CFG_IN(GPIO20, AF1) +#define GPIO115_DREQ_0 MFP_CFG_IN(GPIO115, AF1) +#define GPIO80_DREQ_1 MFP_CFG_IN(GPIO80, AF1) +#define GPIO97_DREQ_1 MFP_CFG_IN(GPIO97, AF2) +#define GPIO85_DREQ_2 MFP_CFG_IN(GPIO85, AF2) +#define GPIO100_DREQ_2 MFP_CFG_IN(GPIO100, AF2) + +/* Alternate Bus Master Mode I/O Signals */ +#define GPIO20_MBREQ MFP_CFG_IN(GPIO20, AF2) +#define GPIO80_MBREQ MFP_CFG_IN(GPIO80, AF2) +#define GPIO96_MBREQ MFP_CFG_IN(GPIO96, AF2) +#define GPIO115_MBREQ MFP_CFG_IN(GPIO115, AF3) +#define GPIO21_MBGNT MFP_CFG_OUT(GPIO21, AF3, DRIVE_LOW) +#define GPIO33_MBGNT MFP_CFG_OUT(GPIO33, AF3, DRIVE_LOW) +#define GPIO97_MBGNT MFP_CFG_OUT(GPIO97, AF2, DRIVE_LOW) +#define GPIO116_MBGNT MFP_CFG_OUT(GPIO116, AF3, DRIVE_LOW) + +/* PC CARD */ +#define GPIO15_nPCE_1 MFP_CFG_OUT(GPIO15, AF1, DRIVE_HIGH) +#define GPIO85_nPCE_1 MFP_CFG_OUT(GPIO85, AF1, DRIVE_HIGH) +#define GPIO86_nPCE_1 MFP_CFG_OUT(GPIO86, AF1, DRIVE_HIGH) +#define GPIO102_nPCE_1 MFP_CFG_OUT(GPIO102, AF1, DRIVE_HIGH) +#define GPIO54_nPCE_2 MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH) +#define GPIO78_nPCE_2 MFP_CFG_OUT(GPIO78, AF1, DRIVE_HIGH) +#define GPIO87_nPCE_2 MFP_CFG_IN(GPIO87, AF1) +#define GPIO55_nPREG MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH) +#define GPIO50_nPIOR MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH) +#define GPIO51_nPIOW MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH) +#define GPIO49_nPWE MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH) +#define GPIO48_nPOE MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH) +#define GPIO57_nIOIS16 MFP_CFG_IN(GPIO57, AF1) +#define GPIO56_nPWAIT MFP_CFG_IN(GPIO56, AF1) +#define GPIO79_PSKTSEL MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH) +#define GPIO104_PSKTSEL MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH) + +/* I2C */ +#define GPIO117_I2C_SCL MFP_CFG_IN(GPIO117, AF1) +#define GPIO118_I2C_SDA MFP_CFG_IN(GPIO118, AF1) + +/* FFUART */ +#define GPIO9_FFUART_CTS MFP_CFG_IN(GPIO9, AF3) +#define GPIO26_FFUART_CTS MFP_CFG_IN(GPIO26, AF3) +#define GPIO35_FFUART_CTS MFP_CFG_IN(GPIO35, AF1) +#define GPIO100_FFUART_CTS MFP_CFG_IN(GPIO100, AF3) +#define GPIO10_FFUART_DCD MFP_CFG_IN(GPIO10, AF1) +#define GPIO36_FFUART_DCD MFP_CFG_IN(GPIO36, AF1) +#define GPIO33_FFUART_DSR MFP_CFG_IN(GPIO33, AF2) +#define GPIO37_FFUART_DSR MFP_CFG_IN(GPIO37, AF1) +#define GPIO38_FFUART_RI MFP_CFG_IN(GPIO38, AF1) +#define GPIO89_FFUART_RI MFP_CFG_IN(GPIO89, AF3) +#define GPIO19_FFUART_RXD MFP_CFG_IN(GPIO19, AF3) +#define GPIO33_FFUART_RXD MFP_CFG_IN(GPIO33, AF1) +#define GPIO34_FFUART_RXD MFP_CFG_IN(GPIO34, AF1) +#define GPIO41_FFUART_RXD MFP_CFG_IN(GPIO41, AF1) +#define GPIO53_FFUART_RXD MFP_CFG_IN(GPIO53, AF1) +#define GPIO85_FFUART_RXD MFP_CFG_IN(GPIO85, AF1) +#define GPIO96_FFUART_RXD MFP_CFG_IN(GPIO96, AF3) +#define GPIO102_FFUART_RXD MFP_CFG_IN(GPIO102, AF3) +#define GPIO16_FFUART_TXD MFP_CFG_OUT(GPIO16, AF3, DRIVE_HIGH) +#define GPIO37_FFUART_TXD MFP_CFG_OUT(GPIO37, AF3, DRIVE_HIGH) +#define GPIO39_FFUART_TXD MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH) +#define GPIO83_FFUART_TXD MFP_CFG_OUT(GPIO83, AF2, DRIVE_HIGH) +#define GPIO99_FFUART_TXD MFP_CFG_OUT(GPIO99, AF3, DRIVE_HIGH) +#define GPIO27_FFUART_RTS MFP_CFG_OUT(GPIO27, AF3, DRIVE_HIGH) +#define GPIO41_FFUART_RTS MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH) +#define GPIO83_FFUART_RTS MFP_CFG_OUT(GPIO83, AF3, DRIVE_HIGH) +#define GPIO98_FFUART_RTS MFP_CFG_OUT(GPIO98, AF3, DRIVE_HIGH) +#define GPIO40_FFUART_DTR MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH) +#define GPIO82_FFUART_DTR MFP_CFG_OUT(GPIO82, AF3, DRIVE_HIGH) + +/* BTUART */ +#define GPIO44_BTUART_CTS MFP_CFG_IN(GPIO44, AF1) +#define GPIO42_BTUART_RXD MFP_CFG_IN(GPIO42, AF1) +#define GPIO45_BTUART_RTS MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH) +#define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH) + +/* STUART */ +#define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2) +#define GPIO47_STUART_TXD MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH) + +/* FICP */ +#define GPIO42_FICP_RXD MFP_CFG_IN(GPIO42, AF2) +#define GPIO46_FICP_RXD MFP_CFG_IN(GPIO46, AF1) +#define GPIO43_FICP_TXD MFP_CFG_OUT(GPIO43, AF1, DRIVE_HIGH) +#define GPIO47_FICP_TXD MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH) + +/* PWM 0/1/2/3 */ +#define GPIO11_PWM2_OUT MFP_CFG_OUT(GPIO11, AF2, DRIVE_LOW) +#define GPIO12_PWM3_OUT MFP_CFG_OUT(GPIO12, AF2, DRIVE_LOW) +#define GPIO16_PWM0_OUT MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW) +#define GPIO17_PWM1_OUT MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW) +#define GPIO38_PWM1_OUT MFP_CFG_OUT(GPIO38, AF3, DRIVE_LOW) +#define GPIO46_PWM2_OUT MFP_CFG_OUT(GPIO46, AF2, DRIVE_LOW) +#define GPIO47_PWM3_OUT MFP_CFG_OUT(GPIO47, AF3, DRIVE_LOW) +#define GPIO79_PWM2_OUT MFP_CFG_OUT(GPIO79, AF3, DRIVE_LOW) +#define GPIO80_PWM3_OUT MFP_CFG_OUT(GPIO80, AF3, DRIVE_LOW) +#define GPIO115_PWM1_OUT MFP_CFG_OUT(GPIO115, AF3, DRIVE_LOW) + +/* AC97 */ +#define GPIO31_AC97_SYNC MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW) +#define GPIO94_AC97_SYNC MFP_CFG_OUT(GPIO94, AF1, DRIVE_LOW) +#define GPIO30_AC97_SDATA_OUT MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW) +#define GPIO93_AC97_SDATA_OUT MFP_CFG_OUT(GPIO93, AF1, DRIVE_LOW) +#define GPIO45_AC97_SYSCLK MFP_CFG_OUT(GPIO45, AF1, DRIVE_LOW) +#define GPIO89_AC97_SYSCLK MFP_CFG_OUT(GPIO89, AF1, DRIVE_LOW) +#define GPIO98_AC97_SYSCLK MFP_CFG_OUT(GPIO98, AF1, DRIVE_LOW) +#define GPIO95_AC97_nRESET MFP_CFG_OUT(GPIO95, AF1, DRIVE_LOW) +#define GPIO113_AC97_nRESET MFP_CFG_OUT(GPIO113, AF2, DRIVE_LOW) +#define GPIO28_AC97_BITCLK MFP_CFG_IN(GPIO28, AF1) +#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1) +#define GPIO116_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO116, AF2) +#define GPIO99_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO99, AF2) + +/* I2S */ +#define GPIO28_I2S_BITCLK_IN MFP_CFG_IN(GPIO28, AF2) +#define GPIO28_I2S_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW) +#define GPIO29_I2S_SDATA_IN MFP_CFG_IN(GPIO29, AF2) +#define GPIO30_I2S_SDATA_OUT MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW) +#define GPIO31_I2S_SYNC MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW) +#define GPIO113_I2S_SYSCLK MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW) + +/* SSP 1 */ +#define GPIO23_SSP1_SCLK MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW) +#define GPIO29_SSP1_SCLK MFP_CFG_IN(GPIO29, AF3) +#define GPIO27_SSP1_SYSCLK MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW) +#define GPIO53_SSP1_SYSCLK MFP_CFG_OUT(GPIO53, AF3, DRIVE_LOW) +#define GPIO24_SSP1_SFRM MFP_CFG_IN(GPIO24, AF2) +#define GPIO28_SSP1_SFRM MFP_CFG_IN(GPIO28, AF3) +#define GPIO25_SSP1_TXD MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW) +#define GPIO57_SSP1_TXD MFP_CFG_OUT(GPIO57, AF3, DRIVE_LOW) +#define GPIO26_SSP1_RXD MFP_CFG_IN(GPIO26, AF1) +#define GPIO27_SSP1_SCLKEN MFP_CFG_IN(GPIO27, AF2) + +/* SSP 2 */ +#define GPIO19_SSP2_SCLK MFP_CFG_IN(GPIO19, AF1) +#define GPIO22_SSP2_SCLK MFP_CFG_IN(GPIO22, AF3) +#define GPIO29_SSP2_SCLK MFP_CFG_OUT(GPIO29, AF3, DRIVE_LOW) +#define GPIO36_SSP2_SCLK MFP_CFG_IN(GPIO36, AF2) +#define GPIO50_SSP2_SCLK MFP_CFG_IN(GPIO50, AF3) +#define GPIO22_SSP2_SYSCLK MFP_CFG_OUT(GPIO22, AF2, DRIVE_LOW) +#define GPIO14_SSP2_SFRM MFP_CFG_IN(GPIO14, AF2) +#define GPIO37_SSP2_SFRM MFP_CFG_IN(GPIO37, AF2) +#define GPIO87_SSP2_SFRM MFP_CFG_OUT(GPIO87, AF3, DRIVE_LOW) +#define GPIO88_SSP2_SFRM MFP_CFG_IN(GPIO88, AF3) +#define GPIO13_SSP2_TXD MFP_CFG_OUT(GPIO13, AF1, DRIVE_LOW) +#define GPIO38_SSP2_TXD MFP_CFG_OUT(GPIO38, AF2, DRIVE_LOW) +#define GPIO87_SSP2_TXD MFP_CFG_OUT(GPIO87, AF1, DRIVE_LOW) +#define GPIO89_SSP2_TXD MFP_CFG_OUT(GPIO89, AF3, DRIVE_LOW) +#define GPIO11_SSP2_RXD MFP_CFG_IN(GPIO11, AF2) +#define GPIO29_SSP2_RXD MFP_CFG_OUT(GPIO29, AF1, DRIVE_LOW) +#define GPIO40_SSP2_RXD MFP_CFG_IN(GPIO40, AF1) +#define GPIO86_SSP2_RXD MFP_CFG_IN(GPIO86, AF1) +#define GPIO88_SSP2_RXD MFP_CFG_IN(GPIO88, AF2) +#define GPIO22_SSP2_EXTCLK MFP_CFG_IN(GPIO22, AF1) +#define GPIO27_SSP2_EXTCLK MFP_CFG_IN(GPIO27, AF1) +#define GPIO22_SSP2_SCLKEN MFP_CFG_IN(GPIO22, AF2) +#define GPIO23_SSP2_SCLKEN MFP_CFG_IN(GPIO23, AF2) + +/* SSP 3 */ +#define GPIO34_SSP3_SCLK MFP_CFG_IN(GPIO34, AF3) +#define GPIO40_SSP3_SCLK MFP_CFG_OUT(GPIO40, AF3, DRIVE_LOW) +#define GPIO52_SSP3_SCLK MFP_CFG_IN(GPIO52, AF2) +#define GPIO84_SSP3_SCLK MFP_CFG_IN(GPIO84, AF1) +#define GPIO45_SSP3_SYSCLK MFP_CFG_OUT(GPIO45, AF3, DRIVE_LOW) +#define GPIO35_SSP3_SFRM MFP_CFG_IN(GPIO35, AF3) +#define GPIO39_SSP3_SFRM MFP_CFG_IN(GPIO39, AF3) +#define GPIO83_SSP3_SFRM MFP_CFG_IN(GPIO83, AF1) +#define GPIO35_SSP3_TXD MFP_CFG_OUT(GPIO35, AF3, DRIVE_LOW) +#define GPIO38_SSP3_TXD MFP_CFG_OUT(GPIO38, AF1, DRIVE_LOW) +#define GPIO81_SSP3_TXD MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW) +#define GPIO41_SSP3_RXD MFP_CFG_IN(GPIO41, AF3) +#define GPIO82_SSP3_RXD MFP_CFG_IN(GPIO82, AF1) +#define GPIO89_SSP3_RXD MFP_CFG_IN(GPIO89, AF1) + +/* MMC */ +#define GPIO32_MMC_CLK MFP_CFG_OUT(GPIO32, AF2, DRIVE_LOW) +#define GPIO92_MMC_DAT_0 MFP_CFG_IN(GPIO92, AF1) +#define GPIO109_MMC_DAT_1 MFP_CFG_IN(GPIO109, AF1) +#define GPIO110_MMC_DAT_2 MFP_CFG_IN(GPIO110, AF1) +#define GPIO111_MMC_DAT_3 MFP_CFG_IN(GPIO111, AF1) +#define GPIO112_MMC_CMD MFP_CFG_IN(GPIO112, AF1) + +/* LCD */ +#define GPIO58_LCD_LDD_0 MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW) +#define GPIO59_LCD_LDD_1 MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW) +#define GPIO60_LCD_LDD_2 MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW) +#define GPIO61_LCD_LDD_3 MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW) +#define GPIO62_LCD_LDD_4 MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW) +#define GPIO63_LCD_LDD_5 MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW) +#define GPIO64_LCD_LDD_6 MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW) +#define GPIO65_LCD_LDD_7 MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW) +#define GPIO66_LCD_LDD_8 MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW) +#define GPIO67_LCD_LDD_9 MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW) +#define GPIO68_LCD_LDD_10 MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW) +#define GPIO69_LCD_LDD_11 MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW) +#define GPIO70_LCD_LDD_12 MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW) +#define GPIO71_LCD_LDD_13 MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW) +#define GPIO72_LCD_LDD_14 MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW) +#define GPIO73_LCD_LDD_15 MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW) +#define GPIO86_LCD_LDD_16 MFP_CFG_OUT(GPIO86, AF2, DRIVE_LOW) +#define GPIO87_LCD_LDD_17 MFP_CFG_OUT(GPIO87, AF2, DRIVE_LOW) +#define GPIO74_LCD_FCLK MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW) +#define GPIO75_LCD_LCLK MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW) +#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW) +#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW) +#define GPIO14_LCD_VSYNC MFP_CFG_IN(GPIO14, AF1) +#define GPIO19_LCD_CS MFP_CFG_OUT(GPIO19, AF2, DRIVE_LOW) + +/* Keypad */ +#define GPIO93_KP_DKIN_0 MFP_CFG_IN(GPIO93, AF1) +#define GPIO94_KP_DKIN_1 MFP_CFG_IN(GPIO94, AF1) +#define GPIO95_KP_DKIN_2 MFP_CFG_IN(GPIO95, AF1) +#define GPIO96_KP_DKIN_3 MFP_CFG_IN(GPIO96, AF1) +#define GPIO97_KP_DKIN_4 MFP_CFG_IN(GPIO97, AF1) +#define GPIO98_KP_DKIN_5 MFP_CFG_IN(GPIO98, AF1) +#define GPIO99_KP_DKIN_6 MFP_CFG_IN(GPIO99, AF1) +#define GPIO13_KP_KDIN_7 MFP_CFG_IN(GPIO13, AF2) +#define GPIO100_KP_MKIN_0 MFP_CFG_IN(GPIO100, AF1) +#define GPIO101_KP_MKIN_1 MFP_CFG_IN(GPIO101, AF1) +#define GPIO102_KP_MKIN_2 MFP_CFG_IN(GPIO102, AF1) +#define GPIO34_KP_MKIN_3 MFP_CFG_IN(GPIO34, AF2) +#define GPIO37_KP_MKIN_3 MFP_CFG_IN(GPIO37, AF3) +#define GPIO97_KP_MKIN_3 MFP_CFG_IN(GPIO97, AF3) +#define GPIO98_KP_MKIN_4 MFP_CFG_IN(GPIO98, AF3) +#define GPIO38_KP_MKIN_4 MFP_CFG_IN(GPIO38, AF2) +#define GPIO39_KP_MKIN_4 MFP_CFG_IN(GPIO39, AF1) +#define GPIO16_KP_MKIN_5 MFP_CFG_IN(GPIO16, AF1) +#define GPIO90_KP_MKIN_5 MFP_CFG_IN(GPIO90, AF1) +#define GPIO99_KP_MKIN_5 MFP_CFG_IN(GPIO99, AF3) +#define GPIO17_KP_MKIN_6 MFP_CFG_IN(GPIO17, AF1) +#define GPIO91_KP_MKIN_6 MFP_CFG_IN(GPIO91, AF1) +#define GPIO95_KP_MKIN_6 MFP_CFG_IN(GPIO95, AF3) +#define GPIO13_KP_MKIN_7 MFP_CFG_IN(GPIO13, AF3) +#define GPIO36_KP_MKIN_7 MFP_CFG_IN(GPIO36, AF3) +#define GPIO103_KP_MKOUT_0 MFP_CFG_OUT(GPIO103, AF2, DRIVE_HIGH) +#define GPIO104_KP_MKOUT_1 MFP_CFG_OUT(GPIO104, AF2, DRIVE_HIGH) +#define GPIO105_KP_MKOUT_2 MFP_CFG_OUT(GPIO105, AF2, DRIVE_HIGH) +#define GPIO106_KP_MKOUT_3 MFP_CFG_OUT(GPIO106, AF2, DRIVE_HIGH) +#define GPIO107_KP_MKOUT_4 MFP_CFG_OUT(GPIO107, AF2, DRIVE_HIGH) +#define GPIO108_KP_MKOUT_5 MFP_CFG_OUT(GPIO108, AF2, DRIVE_HIGH) +#define GPIO35_KP_MKOUT_6 MFP_CFG_OUT(GPIO35, AF2, DRIVE_HIGH) +#define GPIO22_KP_MKOUT_7 MFP_CFG_OUT(GPIO22, AF1, DRIVE_HIGH) +#define GPIO40_KP_MKOUT_6 MFP_CFG_OUT(GPIO40, AF1, DRIVE_HIGH) +#define GPIO41_KP_MKOUT_7 MFP_CFG_OUT(GPIO41, AF1, DRIVE_HIGH) +#define GPIO96_KP_MKOUT_6 MFP_CFG_OUT(GPIO96, AF3, DRIVE_HIGH) + +/* USB P3 */ +#define GPIO10_USB_P3_5 MFP_CFG_IN(GPIO10, AF3) +#define GPIO11_USB_P3_1 MFP_CFG_IN(GPIO11, AF3) +#define GPIO30_USB_P3_2 MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW) +#define GPIO31_USB_P3_6 MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW) +#define GPIO56_USB_P3_4 MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW) +#define GPIO86_USB_P3_5 MFP_CFG_IN(GPIO86, AF3) +#define GPIO87_USB_P3_1 MFP_CFG_IN(GPIO87, AF3) +#define GPIO90_USB_P3_5 MFP_CFG_IN(GPIO90, AF2) +#define GPIO91_USB_P3_1 MFP_CFG_IN(GPIO91, AF2) +#define GPIO113_USB_P3_3 MFP_CFG_IN(GPIO113, AF3) + +/* USB P2 */ +#define GPIO34_USB_P2_2 MFP_CFG_OUT(GPIO34, AF1, DRIVE_LOW) +#define GPIO35_USB_P2_1 MFP_CFG_IN(GPIO35, AF2) +#define GPIO36_USB_P2_4 MFP_CFG_OUT(GPIO36, AF1, DRIVE_LOW) +#define GPIO37_USB_P2_8 MFP_CFG_OUT(GPIO37, AF1, DRIVE_LOW) +#define GPIO38_USB_P2_3 MFP_CFG_IN(GPIO38, AF3) +#define GPIO39_USB_P2_6 MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW) +#define GPIO40_USB_P2_5 MFP_CFG_IN(GPIO40, AF3) +#define GPIO41_USB_P2_7 MFP_CFG_IN(GPIO41, AF2) +#define GPIO53_USB_P2_3 MFP_CFG_IN(GPIO53, AF2) + +/* USB Host Port 1/2 */ +#define GPIO88_USBH1_PWR MFP_CFG_IN(GPIO88, AF1) +#define GPIO89_USBH1_PEN MFP_CFG_OUT(GPIO89, AF2, DRIVE_LOW) +#define GPIO119_USBH2_PWR MFP_CFG_IN(GPIO119, AF1) +#define GPIO120_USBH2_PEN MFP_CFG_OUT(GPIO120, AF2, DRIVE_LOW) + +/* QCI - default to Master Mode: CIF_FV/CIF_LV Direction In */ +#define GPIO115_CIF_DD_3 MFP_CFG_IN(GPIO115, AF2) +#define GPIO116_CIF_DD_2 MFP_CFG_IN(GPIO116, AF1) +#define GPIO12_CIF_DD_7 MFP_CFG_IN(GPIO12, AF2) +#define GPIO17_CIF_DD_6 MFP_CFG_IN(GPIO17, AF2) +#define GPIO23_CIF_MCLK MFP_CFG_OUT(GPIO23, AF1, DRIVE_LOW) +#define GPIO24_CIF_FV MFP_CFG_IN(GPIO24, AF1) +#define GPIO25_CIF_LV MFP_CFG_IN(GPIO25, AF1) +#define GPIO26_CIF_PCLK MFP_CFG_IN(GPIO26, AF2) +#define GPIO27_CIF_DD_0 MFP_CFG_IN(GPIO27, AF3) +#define GPIO42_CIF_MCLK MFP_CFG_OUT(GPIO42, AF3, DRIVE_LOW) +#define GPIO43_CIF_FV MFP_CFG_IN(GPIO43, AF3) +#define GPIO44_CIF_LV MFP_CFG_IN(GPIO44, AF3) +#define GPIO45_CIF_PCLK MFP_CFG_IN(GPIO45, AF3) +#define GPIO47_CIF_DD_0 MFP_CFG_IN(GPIO47, AF1) +#define GPIO48_CIF_DD_5 MFP_CFG_IN(GPIO48, AF1) +#define GPIO50_CIF_DD_3 MFP_CFG_IN(GPIO50, AF1) +#define GPIO51_CIF_DD_2 MFP_CFG_IN(GPIO51, AF1) +#define GPIO52_CIF_DD_4 MFP_CFG_IN(GPIO52, AF1) +#define GPIO53_CIF_MCLK MFP_CFG_OUT(GPIO53, AF2, DRIVE_LOW) +#define GPIO54_CIF_PCLK MFP_CFG_IN(GPIO54, AF3) +#define GPIO55_CIF_DD_1 MFP_CFG_IN(GPIO55, AF1) +#define GPIO81_CIF_DD_0 MFP_CFG_IN(GPIO81, AF2) +#define GPIO82_CIF_DD_5 MFP_CFG_IN(GPIO82, AF3) +#define GPIO83_CIF_DD_4 MFP_CFG_IN(GPIO83, AF3) +#define GPIO84_CIF_FV MFP_CFG_IN(GPIO84, AF3) +#define GPIO85_CIF_LV MFP_CFG_IN(GPIO85, AF3) +#define GPIO90_CIF_DD_4 MFP_CFG_IN(GPIO90, AF3) +#define GPIO91_CIF_DD_5 MFP_CFG_IN(GPIO91, AF3) +#define GPIO93_CIF_DD_6 MFP_CFG_IN(GPIO93, AF2) +#define GPIO94_CIF_DD_5 MFP_CFG_IN(GPIO94, AF2) +#define GPIO95_CIF_DD_4 MFP_CFG_IN(GPIO95, AF2) +#define GPIO98_CIF_DD_0 MFP_CFG_IN(GPIO98, AF2) +#define GPIO103_CIF_DD_3 MFP_CFG_IN(GPIO103, AF1) +#define GPIO104_CIF_DD_2 MFP_CFG_IN(GPIO104, AF1) +#define GPIO105_CIF_DD_1 MFP_CFG_IN(GPIO105, AF1) +#define GPIO106_CIF_DD_9 MFP_CFG_IN(GPIO106, AF1) +#define GPIO107_CIF_DD_8 MFP_CFG_IN(GPIO107, AF1) +#define GPIO108_CIF_DD_7 MFP_CFG_IN(GPIO108, AF1) +#define GPIO114_CIF_DD_1 MFP_CFG_IN(GPIO114, AF1) + +/* Universal Subscriber ID Interface */ +#define GPIO114_UVS0 MFP_CFG_OUT(GPIO114, AF2, DRIVE_LOW) +#define GPIO115_nUVS1 MFP_CFG_OUT(GPIO115, AF2, DRIVE_LOW) +#define GPIO116_nUVS2 MFP_CFG_OUT(GPIO116, AF2, DRIVE_LOW) +#define GPIO14_UCLK MFP_CFG_OUT(GPIO14, AF3, DRIVE_LOW) +#define GPIO91_UCLK MFP_CFG_OUT(GPIO91, AF2, DRIVE_LOW) +#define GPIO19_nURST MFP_CFG_OUT(GPIO19, AF3, DRIVE_LOW) +#define GPIO90_nURST MFP_CFG_OUT(GPIO90, AF2, DRIVE_LOW) +#define GPIO116_UDET MFP_CFG_IN(GPIO116, AF3) +#define GPIO114_UEN MFP_CFG_OUT(GPIO114, AF1, DRIVE_LOW) +#define GPIO115_UEN MFP_CFG_OUT(GPIO115, AF1, DRIVE_LOW) + +/* Mobile Scalable Link (MSL) Interface */ +#define GPIO81_BB_OB_DAT_0 MFP_CFG_OUT(GPIO81, AF2, DRIVE_LOW) +#define GPIO48_BB_OB_DAT_1 MFP_CFG_OUT(GPIO48, AF1, DRIVE_LOW) +#define GPIO50_BB_OB_DAT_2 MFP_CFG_OUT(GPIO50, AF1, DRIVE_LOW) +#define GPIO51_BB_OB_DAT_3 MFP_CFG_OUT(GPIO51, AF1, DRIVE_LOW) +#define GPIO52_BB_OB_CLK MFP_CFG_OUT(GPIO52, AF1, DRIVE_LOW) +#define GPIO53_BB_OB_STB MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW) +#define GPIO54_BB_OB_WAIT MFP_CFG_IN(GPIO54, AF2) +#define GPIO82_BB_IB_DAT_0 MFP_CFG_IN(GPIO82, AF2) +#define GPIO55_BB_IB_DAT_1 MFP_CFG_IN(GPIO55, AF2) +#define GPIO56_BB_IB_DAT_2 MFP_CFG_IN(GPIO56, AF2) +#define GPIO57_BB_IB_DAT_3 MFP_CFG_IN(GPIO57, AF2) +#define GPIO83_BB_IB_CLK MFP_CFG_IN(GPIO83, AF2) +#define GPIO84_BB_IB_STB MFP_CFG_IN(GPIO84, AF2) +#define GPIO85_BB_IB_WAIT MFP_CFG_OUT(GPIO85, AF2, DRIVE_LOW) + +/* Memory Stick Host Controller */ +#define GPIO92_MSBS MFP_CFG_OUT(GPIO92, AF2, DRIVE_LOW) +#define GPIO109_MSSDIO MFP_CFG_IN(GPIO109, AF2) +#define GPIO112_nMSINS MFP_CFG_IN(GPIO112, AF2) +#define GPIO32_MSSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW) + +/* commonly used pin configurations */ +#define GPIOxx_LCD_16BPP \ + GPIO58_LCD_LDD_0, \ + GPIO59_LCD_LDD_1, \ + GPIO60_LCD_LDD_2, \ + GPIO61_LCD_LDD_3, \ + GPIO62_LCD_LDD_4, \ + GPIO63_LCD_LDD_5, \ + GPIO64_LCD_LDD_6, \ + GPIO65_LCD_LDD_7, \ + GPIO66_LCD_LDD_8, \ + GPIO67_LCD_LDD_9, \ + GPIO68_LCD_LDD_10, \ + GPIO69_LCD_LDD_11, \ + GPIO70_LCD_LDD_12, \ + GPIO71_LCD_LDD_13, \ + GPIO72_LCD_LDD_14, \ + GPIO73_LCD_LDD_15 + +#define GPIOxx_LCD_TFT_16BPP \ + GPIOxx_LCD_16BPP, \ + GPIO74_LCD_FCLK, \ + GPIO75_LCD_LCLK, \ + GPIO76_LCD_PCLK, \ + GPIO77_LCD_BIAS + + +extern int keypad_set_wake(unsigned int on); +#endif /* __ASM_ARCH_MFP_PXA27X_H */ diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h new file mode 100644 index 00000000000..c54cef25895 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h @@ -0,0 +1,135 @@ +#ifndef __ASM_ARCH_MFP_PXA2XX_H +#define __ASM_ARCH_MFP_PXA2XX_H + +#include <plat/mfp.h> + +/* + * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx: + * + * MFP_PIN(x) + * MFP_AFx + * MFP_LPM_DRIVE_{LOW, HIGH} + * MFP_LPM_EDGE_x + * + * other MFP_x bit definitions will be ignored + * + * and adds the below two bits specifically for pxa2xx: + * + * bit 23 - Input/Output (PXA2xx specific) + * bit 24 - Wakeup Enable(PXA2xx specific) + */ + +#define MFP_DIR_IN (0x0 << 23) +#define MFP_DIR_OUT (0x1 << 23) +#define MFP_DIR_MASK (0x1 << 23) +#define MFP_DIR(x) (((x) >> 23) & 0x1) + +#define MFP_LPM_CAN_WAKEUP (0x1 << 24) +#define MFP_LPM_KEEP_OUTPUT (0x1 << 25) + +#define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE) +#define WAKEUP_ON_EDGE_FALL (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL) +#define WAKEUP_ON_EDGE_BOTH (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH) + +/* specifically for enabling wakeup on keypad GPIOs */ +#define WAKEUP_ON_LEVEL_HIGH (MFP_LPM_CAN_WAKEUP) + +#define MFP_CFG_IN(pin, af) \ + ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\ + (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_IN)) + +/* NOTE: pins configured as output _must_ provide a low power state, + * and this state should help to minimize the power dissipation. + */ +#define MFP_CFG_OUT(pin, af, state) \ + ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\ + (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state)) + +/* Common configurations for pxa25x and pxa27x + * + * Note: pins configured as GPIO are always initialized to input + * so not to cause any side effect + */ +#define GPIO0_GPIO MFP_CFG_IN(GPIO0, AF0) +#define GPIO1_GPIO MFP_CFG_IN(GPIO1, AF0) +#define GPIO9_GPIO MFP_CFG_IN(GPIO9, AF0) +#define GPIO10_GPIO MFP_CFG_IN(GPIO10, AF0) +#define GPIO11_GPIO MFP_CFG_IN(GPIO11, AF0) +#define GPIO12_GPIO MFP_CFG_IN(GPIO12, AF0) +#define GPIO13_GPIO MFP_CFG_IN(GPIO13, AF0) +#define GPIO14_GPIO MFP_CFG_IN(GPIO14, AF0) +#define GPIO15_GPIO MFP_CFG_IN(GPIO15, AF0) +#define GPIO16_GPIO MFP_CFG_IN(GPIO16, AF0) +#define GPIO17_GPIO MFP_CFG_IN(GPIO17, AF0) +#define GPIO18_GPIO MFP_CFG_IN(GPIO18, AF0) +#define GPIO19_GPIO MFP_CFG_IN(GPIO19, AF0) +#define GPIO20_GPIO MFP_CFG_IN(GPIO20, AF0) +#define GPIO21_GPIO MFP_CFG_IN(GPIO21, AF0) +#define GPIO22_GPIO MFP_CFG_IN(GPIO22, AF0) +#define GPIO23_GPIO MFP_CFG_IN(GPIO23, AF0) +#define GPIO24_GPIO MFP_CFG_IN(GPIO24, AF0) +#define GPIO25_GPIO MFP_CFG_IN(GPIO25, AF0) +#define GPIO26_GPIO MFP_CFG_IN(GPIO26, AF0) +#define GPIO27_GPIO MFP_CFG_IN(GPIO27, AF0) +#define GPIO28_GPIO MFP_CFG_IN(GPIO28, AF0) +#define GPIO29_GPIO MFP_CFG_IN(GPIO29, AF0) +#define GPIO30_GPIO MFP_CFG_IN(GPIO30, AF0) +#define GPIO31_GPIO MFP_CFG_IN(GPIO31, AF0) +#define GPIO32_GPIO MFP_CFG_IN(GPIO32, AF0) +#define GPIO33_GPIO MFP_CFG_IN(GPIO33, AF0) +#define GPIO34_GPIO MFP_CFG_IN(GPIO34, AF0) +#define GPIO35_GPIO MFP_CFG_IN(GPIO35, AF0) +#define GPIO36_GPIO MFP_CFG_IN(GPIO36, AF0) +#define GPIO37_GPIO MFP_CFG_IN(GPIO37, AF0) +#define GPIO38_GPIO MFP_CFG_IN(GPIO38, AF0) +#define GPIO39_GPIO MFP_CFG_IN(GPIO39, AF0) +#define GPIO40_GPIO MFP_CFG_IN(GPIO40, AF0) +#define GPIO41_GPIO MFP_CFG_IN(GPIO41, AF0) +#define GPIO42_GPIO MFP_CFG_IN(GPIO42, AF0) +#define GPIO43_GPIO MFP_CFG_IN(GPIO43, AF0) +#define GPIO44_GPIO MFP_CFG_IN(GPIO44, AF0) +#define GPIO45_GPIO MFP_CFG_IN(GPIO45, AF0) +#define GPIO46_GPIO MFP_CFG_IN(GPIO46, AF0) +#define GPIO47_GPIO MFP_CFG_IN(GPIO47, AF0) +#define GPIO48_GPIO MFP_CFG_IN(GPIO48, AF0) +#define GPIO49_GPIO MFP_CFG_IN(GPIO49, AF0) +#define GPIO50_GPIO MFP_CFG_IN(GPIO50, AF0) +#define GPIO51_GPIO MFP_CFG_IN(GPIO51, AF0) +#define GPIO52_GPIO MFP_CFG_IN(GPIO52, AF0) +#define GPIO53_GPIO MFP_CFG_IN(GPIO53, AF0) +#define GPIO54_GPIO MFP_CFG_IN(GPIO54, AF0) +#define GPIO55_GPIO MFP_CFG_IN(GPIO55, AF0) +#define GPIO56_GPIO MFP_CFG_IN(GPIO56, AF0) +#define GPIO57_GPIO MFP_CFG_IN(GPIO57, AF0) +#define GPIO58_GPIO MFP_CFG_IN(GPIO58, AF0) +#define GPIO59_GPIO MFP_CFG_IN(GPIO59, AF0) +#define GPIO60_GPIO MFP_CFG_IN(GPIO60, AF0) +#define GPIO61_GPIO MFP_CFG_IN(GPIO61, AF0) +#define GPIO62_GPIO MFP_CFG_IN(GPIO62, AF0) +#define GPIO63_GPIO MFP_CFG_IN(GPIO63, AF0) +#define GPIO64_GPIO MFP_CFG_IN(GPIO64, AF0) +#define GPIO65_GPIO MFP_CFG_IN(GPIO65, AF0) +#define GPIO66_GPIO MFP_CFG_IN(GPIO66, AF0) +#define GPIO67_GPIO MFP_CFG_IN(GPIO67, AF0) +#define GPIO68_GPIO MFP_CFG_IN(GPIO68, AF0) +#define GPIO69_GPIO MFP_CFG_IN(GPIO69, AF0) +#define GPIO70_GPIO MFP_CFG_IN(GPIO70, AF0) +#define GPIO71_GPIO MFP_CFG_IN(GPIO71, AF0) +#define GPIO72_GPIO MFP_CFG_IN(GPIO72, AF0) +#define GPIO73_GPIO MFP_CFG_IN(GPIO73, AF0) +#define GPIO74_GPIO MFP_CFG_IN(GPIO74, AF0) +#define GPIO75_GPIO MFP_CFG_IN(GPIO75, AF0) +#define GPIO76_GPIO MFP_CFG_IN(GPIO76, AF0) +#define GPIO77_GPIO MFP_CFG_IN(GPIO77, AF0) +#define GPIO78_GPIO MFP_CFG_IN(GPIO78, AF0) +#define GPIO79_GPIO MFP_CFG_IN(GPIO79, AF0) +#define GPIO80_GPIO MFP_CFG_IN(GPIO80, AF0) +#define GPIO81_GPIO MFP_CFG_IN(GPIO81, AF0) +#define GPIO82_GPIO MFP_CFG_IN(GPIO82, AF0) +#define GPIO83_GPIO MFP_CFG_IN(GPIO83, AF0) +#define GPIO84_GPIO MFP_CFG_IN(GPIO84, AF0) + +extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num); +extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm); +extern int gpio_set_wake(unsigned int gpio, unsigned int on); +#endif /* __ASM_ARCH_MFP_PXA2XX_H */ diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h new file mode 100644 index 00000000000..4e1287070d2 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h @@ -0,0 +1,575 @@ +/* + * arch/arm/mach-pxa/include/mach/mfp-pxa300.h + * + * PXA300/PXA310 specific MFP configuration definitions + * + * Copyright (C) 2007 Marvell International Ltd. + * 2007-08-21: eric miao <eric.miao@marvell.com> + * initial version + * + * 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 __ASM_ARCH_MFP_PXA300_H +#define __ASM_ARCH_MFP_PXA300_H + +#include <mach/mfp-pxa3xx.h> + +/* GPIO */ +#define GPIO46_GPIO MFP_CFG(GPIO46, AF1) +#define GPIO49_GPIO MFP_CFG(GPIO49, AF3) +#define GPIO50_GPIO MFP_CFG(GPIO50, AF2) +#define GPIO51_GPIO MFP_CFG(GPIO51, AF3) +#define GPIO52_GPIO MFP_CFG(GPIO52, AF3) +#define GPIO56_GPIO MFP_CFG(GPIO56, AF0) +#define GPIO58_GPIO MFP_CFG(GPIO58, AF0) +#define GPIO59_GPIO MFP_CFG(GPIO59, AF0) +#define GPIO60_GPIO MFP_CFG(GPIO60, AF0) +#define GPIO61_GPIO MFP_CFG(GPIO61, AF0) +#define GPIO62_GPIO MFP_CFG(GPIO62, AF0) + +#ifdef CONFIG_CPU_PXA310 +#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0) +#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0) +#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0) +#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0) +#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0) +#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0) +#endif + +/* Chip Select */ +#define GPIO1_nCS2 MFP_CFG(GPIO1, AF1) +#define GPIO2_nCS3 MFP_CFG(GPIO2, AF1) + +/* AC97 */ +#define GPIO23_AC97_nACRESET MFP_CFG(GPIO23, AF1) +#define GPIO24_AC97_SYSCLK MFP_CFG(GPIO24, AF1) +#define GPIO29_AC97_BITCLK MFP_CFG(GPIO29, AF1) +#define GPIO25_AC97_SDATA_IN_0 MFP_CFG(GPIO25, AF1) +#define GPIO26_AC97_SDATA_IN_1 MFP_CFG(GPIO26, AF1) +#define GPIO17_AC97_SDATA_IN_2 MFP_CFG(GPIO17, AF3) +#define GPIO21_AC97_SDATA_IN_2 MFP_CFG(GPIO21, AF2) +#define GPIO18_AC97_SDATA_IN_3 MFP_CFG(GPIO18, AF3) +#define GPIO22_AC97_SDATA_IN_3 MFP_CFG(GPIO22, AF2) +#define GPIO27_AC97_SDATA_OUT MFP_CFG(GPIO27, AF1) +#define GPIO28_AC97_SYNC MFP_CFG(GPIO28, AF1) + +/* I2C */ +#define GPIO21_I2C_SCL MFP_CFG_LPM(GPIO21, AF1, PULL_HIGH) +#define GPIO22_I2C_SDA MFP_CFG_LPM(GPIO22, AF1, PULL_HIGH) + +/* QCI */ +#define GPIO39_CI_DD_0 MFP_CFG_DRV(GPIO39, AF1, DS04X) +#define GPIO40_CI_DD_1 MFP_CFG_DRV(GPIO40, AF1, DS04X) +#define GPIO41_CI_DD_2 MFP_CFG_DRV(GPIO41, AF1, DS04X) +#define GPIO42_CI_DD_3 MFP_CFG_DRV(GPIO42, AF1, DS04X) +#define GPIO43_CI_DD_4 MFP_CFG_DRV(GPIO43, AF1, DS04X) +#define GPIO44_CI_DD_5 MFP_CFG_DRV(GPIO44, AF1, DS04X) +#define GPIO45_CI_DD_6 MFP_CFG_DRV(GPIO45, AF1, DS04X) +#define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X) +#define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X) +#define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X) +#define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X) +#define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X) +#define GPIO51_CI_HSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X) +#define GPIO52_CI_VSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X) + +/* KEYPAD */ +#define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT) +#define GPIO4_KP_DKIN_7 MFP_CFG_LPM(GPIO4, AF2, FLOAT) +#define GPIO16_KP_DKIN_6 MFP_CFG_LPM(GPIO16, AF6, FLOAT) +#define GPIO83_KP_DKIN_2 MFP_CFG_LPM(GPIO83, AF5, FLOAT) +#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF5, FLOAT) +#define GPIO85_KP_DKIN_0 MFP_CFG_LPM(GPIO85, AF3, FLOAT) +#define GPIO86_KP_DKIN_1 MFP_CFG_LPM(GPIO86, AF3, FLOAT) +#define GPIO87_KP_DKIN_2 MFP_CFG_LPM(GPIO87, AF3, FLOAT) +#define GPIO88_KP_DKIN_3 MFP_CFG_LPM(GPIO88, AF3, FLOAT) +#define GPIO89_KP_DKIN_3 MFP_CFG_LPM(GPIO89, AF3, FLOAT) +#define GPIO107_KP_DKIN_0 MFP_CFG_LPM(GPIO107, AF2, FLOAT) +#define GPIO108_KP_DKIN_1 MFP_CFG_LPM(GPIO108, AF2, FLOAT) +#define GPIO109_KP_DKIN_2 MFP_CFG_LPM(GPIO109, AF2, FLOAT) +#define GPIO110_KP_DKIN_3 MFP_CFG_LPM(GPIO110, AF2, FLOAT) +#define GPIO111_KP_DKIN_4 MFP_CFG_LPM(GPIO111, AF2, FLOAT) +#define GPIO112_KP_DKIN_5 MFP_CFG_LPM(GPIO112, AF2, FLOAT) +#define GPIO113_KP_DKIN_6 MFP_CFG_LPM(GPIO113, AF2, FLOAT) +#define GPIO114_KP_DKIN_7 MFP_CFG_LPM(GPIO114, AF2, FLOAT) +#define GPIO115_KP_DKIN_0 MFP_CFG_LPM(GPIO115, AF2, FLOAT) +#define GPIO116_KP_DKIN_1 MFP_CFG_LPM(GPIO116, AF2, FLOAT) +#define GPIO117_KP_DKIN_2 MFP_CFG_LPM(GPIO117, AF2, FLOAT) +#define GPIO118_KP_DKIN_3 MFP_CFG_LPM(GPIO118, AF2, FLOAT) +#define GPIO119_KP_DKIN_4 MFP_CFG_LPM(GPIO119, AF2, FLOAT) +#define GPIO120_KP_DKIN_5 MFP_CFG_LPM(GPIO120, AF2, FLOAT) +#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT) +#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT) +#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT) +#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT) +#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF5, FLOAT) +#define GPIO0_2_KP_DKIN_0 MFP_CFG_LPM(GPIO0_2, AF2, FLOAT) +#define GPIO1_2_KP_DKIN_1 MFP_CFG_LPM(GPIO1_2, AF2, FLOAT) +#define GPIO2_2_KP_DKIN_6 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT) +#define GPIO3_2_KP_DKIN_7 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT) +#define GPIO4_2_KP_DKIN_1 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT) +#define GPIO5_2_KP_DKIN_0 MFP_CFG_LPM(GPIO5_2, AF2, FLOAT) + +#define GPIO5_KP_MKIN_0 MFP_CFG_LPM(GPIO5, AF2, FLOAT) +#define GPIO6_KP_MKIN_1 MFP_CFG_LPM(GPIO6, AF2, FLOAT) +#define GPIO9_KP_MKIN_6 MFP_CFG_LPM(GPIO9, AF3, FLOAT) +#define GPIO10_KP_MKIN_7 MFP_CFG_LPM(GPIO10, AF3, FLOAT) +#define GPIO70_KP_MKIN_6 MFP_CFG_LPM(GPIO70, AF3, FLOAT) +#define GPIO71_KP_MKIN_7 MFP_CFG_LPM(GPIO71, AF3, FLOAT) +#define GPIO100_KP_MKIN_6 MFP_CFG_LPM(GPIO100, AF7, FLOAT) +#define GPIO101_KP_MKIN_7 MFP_CFG_LPM(GPIO101, AF7, FLOAT) +#define GPIO112_KP_MKIN_6 MFP_CFG_LPM(GPIO112, AF4, FLOAT) +#define GPIO113_KP_MKIN_7 MFP_CFG_LPM(GPIO113, AF4, FLOAT) +#define GPIO115_KP_MKIN_0 MFP_CFG_LPM(GPIO115, AF1, FLOAT) +#define GPIO116_KP_MKIN_1 MFP_CFG_LPM(GPIO116, AF1, FLOAT) +#define GPIO117_KP_MKIN_2 MFP_CFG_LPM(GPIO117, AF1, FLOAT) +#define GPIO118_KP_MKIN_3 MFP_CFG_LPM(GPIO118, AF1, FLOAT) +#define GPIO119_KP_MKIN_4 MFP_CFG_LPM(GPIO119, AF1, FLOAT) +#define GPIO120_KP_MKIN_5 MFP_CFG_LPM(GPIO120, AF1, FLOAT) +#define GPIO125_KP_MKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT) +#define GPIO2_2_KP_MKIN_6 MFP_CFG_LPM(GPIO2_2, AF1, FLOAT) +#define GPIO3_2_KP_MKIN_7 MFP_CFG_LPM(GPIO3_2, AF1, FLOAT) + |