diff options
Diffstat (limited to 'arch/arm/mach-pxa')
213 files changed, 31374 insertions, 12806 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index e8ee7ec9ff6..e6690a44917 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -2,61 +2,458 @@ if ARCH_PXA menu "Intel PXA2xx/PXA3xx Implementations" -if PXA3xx +comment "Intel/Marvell Dev Platforms (sorted by hardware release time)" -menu "Supported PXA3xx Processor Variants" +config MACH_PXA3XX_DT + bool "Support PXA3xx platforms from device tree" + select CPU_PXA300 + select POWER_SUPPLY + select PXA3xx + select USE_OF + help + Include support for Marvell PXA3xx based platforms using + the device tree. Needn't select any other machine while + MACH_PXA3XX_DT is enabled. -config CPU_PXA300 - bool "PXA300 (codename Monahans-L)" +config ARCH_LUBBOCK + bool "Intel DBPXA250 Development Platform (aka Lubbock)" + select PXA25x + select SA1111 -config CPU_PXA310 - bool "PXA310 (codename Monahans-LV)" +config MACH_MAINSTONE + bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)" + select PXA27x + +config MACH_ZYLONITE + bool + select PXA3xx + +config MACH_ZYLONITE300 + bool "PXA3xx Development Platform (aka Zylonite) PXA300/310" select CPU_PXA300 + select CPU_PXA310 + select MACH_ZYLONITE -config CPU_PXA320 - bool "PXA320 (codename Monahans-P)" +config MACH_ZYLONITE320 + bool "PXA3xx Development Platform (aka Zylonite) PXA320" + select CPU_PXA320 + select MACH_ZYLONITE -config CPU_PXA930 - bool "PXA930 (codename Tavor-P)" +config MACH_LITTLETON + bool "PXA3xx Form Factor Platform (aka Littleton)" + select CPU_PXA300 + select CPU_PXA310 + select PXA3xx -endmenu +config MACH_TAVOREVB + bool "PXA930 Evaluation Board (aka TavorEVB)" + select CPU_PXA930 + select CPU_PXA935 + select PXA3xx + select FB + select FB_PXA -endif +config MACH_SAAR + bool "PXA930 Handheld Platform (aka SAAR)" + select CPU_PXA930 + select CPU_PXA935 + select PXA3xx + select FB + select FB_PXA + +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 ARCOM_PCMCIA + select I2C_GPIO if I2C=y + select ISA + select PXA25x + select PXA_HAVE_ISA_IRQS + +config MACH_ARCOM_ZEUS + bool "Arcom/Eurotech ZEUS SBC" + select ARCOM_PCMCIA + select ISA + select PXA27x + select PXA_HAVE_ISA_IRQS + +config MACH_BALLOON3 + bool "Balloon 3 board" + select IWMMXT + select PXA27x + +config MACH_CSB726 + bool "Enable Cogent CSB726 System On a Module" + select IWMMXT + select PXA27x + 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 ARCH_HAS_DMA_SET_COHERENT_MASK if PCI + select IWMMXT + select MIGHT_HAVE_PCI + select NEED_MACH_IO_H if PCI + select PXA25x + select PXA27x + +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 CPU_PXA300 + select CPU_PXA310 + select PXA3xx + +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 boards" + bool "Gumstix XScale 255 boards" + select PXA25x help - Say Y here if you intend to run this kernel on a - Gumstix Full Function Minature Computer. + Say Y here if you intend to run this kernel on + Basix, Connex, ws-200ax, ws-400ax systems -config MACH_GUMSTIX_F - bool "Basix, Connex, ws-200ax, ws-400ax systems" +choice + prompt "Gumstix Carrier/Expansion Board" depends on ARCH_GUMSTIX - select PXA25x -config ARCH_LUBBOCK - bool "Intel DBPXA250 Development Platform" +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 IWMMXT + select PXA27x + +config MACH_STARGATE2 + bool "Intel Stargate 2 Platform" + select IWMMXT + select PXA27x + +config MACH_XCEP + bool "Iskratel Electronics XCEP" + select MTD + select MTD_CFI + select MTD_CFI_INTELEXT + select MTD_PHYSMAP select PXA25x - select SA1111 + 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 PXA27x + select TRIZEPS_PCMCIA + +config MACH_TRIZEPS4WL + bool "Keith und Koep Trizeps4-WL DIMM-Module" + depends on TRIZEPS_PXA + select MACH_TRIZEPS4 + select PXA27x + select TRIZEPS_PCMCIA + +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_MAINSTONE - bool "Intel HCDDBBVA0 Development Platform" +config MACH_PCM027 + bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" + select IWMMXT select PXA27x - select HAVE_PWM -config ARCH_PXA_IDP - bool "Accelent Xscale IDP" +config MACH_PCM990_BASEBOARD + bool "PHYTEC PCM-990 development board" + 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 + +config MACH_COLIBRI300 + bool "Toradex Colibri PXA300/310" + select CPU_PXA300 + select CPU_PXA310 + select PXA3xx + +config MACH_COLIBRI320 + bool "Toradex Colibri PXA320" + select CPU_PXA320 + select PXA3xx + +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 HAVE_PATA_PLATFORM + select PXA27x + help + PXA270 based Single Board Computer. + +comment "End-user Products (sorted by vendor name)" + +config MACH_H4700 + bool "HP iPAQ hx4700" + select IWMMXT + select PXA27x + +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 IWMMXT + select PXA27x + +config MACH_MIOA701 + bool "Mitac Mio A701 Support" + select GPIO_SYSFS + select IWMMXT + select PXA27x + 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 IWMMXT + select PXA27x + +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" + +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 IWMMXT + select MACH_PALM27X + select PXA27x + 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 IWMMXT + select MACH_PALM27X + select PXA27x + 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 IWMMXT + select MACH_PALM27X + select PXA27x + 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 IWMMXT + select MACH_PALM27X + select PXA27x + 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 IWMMXT + select MACH_PALM27X + select PALM_TREO + select PXA27x + 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 IWMMXT + select MACH_PALM27X + select PALM_TREO + select PXA27x + help + Say Y here if you intend to run this kernel on Palm Treo 680 + smartphone. + +config MACH_RAUMFELD_RC + bool "Raumfeld Controller" + select CPU_PXA300 + select POWER_SUPPLY + select PXA3xx + +config MACH_RAUMFELD_CONNECTOR + bool "Raumfeld Connector" + select CPU_PXA300 + select POWER_SUPPLY + select PXA3xx + +config MACH_RAUMFELD_SPEAKER + bool "Raumfeld Speaker" + select CPU_PXA300 + select POWER_SUPPLY + select PXA3xx + config PXA_SHARPSL bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models" - select SHARP_SCOOP select SHARP_PARAM + select SHARP_SCOOP help Say Y here if you intend to run this kernel on a Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi), @@ -64,12 +461,19 @@ config PXA_SHARPSL 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 - select PXA_SSP config MACH_CORGI bool "Enable Sharp SL-C700 (Corgi) Support" @@ -92,11 +496,11 @@ config MACH_HUSKY 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 + select MACH_SPITZ + select PXA27x + select PXA_SHARP_Cxx00 config MACH_SPITZ bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" @@ -115,8 +519,33 @@ config MACH_TOSA 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 FB_W100 select PXA25x config MACH_E330 @@ -139,7 +568,6 @@ config MACH_E740 bool "Toshiba e740" default y depends on ARCH_PXA_ESERIES - select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e740 family PDA. @@ -148,7 +576,6 @@ config MACH_E750 bool "Toshiba e750" default y depends on ARCH_PXA_ESERIES - select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e750 family PDA. @@ -165,182 +592,98 @@ config MACH_E800 bool "Toshiba e800" default y depends on ARCH_PXA_ESERIES - select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e800 family PDA. -config MACH_TRIZEPS4 - bool "Keith und Koep Trizeps4 DIMM-Module" - select PXA27x - -config MACH_TRIZEPS4_CONXS - bool "ConXS Eval Board" - depends on MACH_TRIZEPS4 - -config MACH_EM_X270 - bool "CompuLab EM-x270 platform" +config MACH_ZIPIT2 + bool "Zipit Z2 Handheld" select PXA27x +endmenu -config MACH_COLIBRI - bool "Toradex Colibri PX27x" - select PXA27x +config PXA25x + bool + select CPU_XSCALE + help + Select code specific to PXA21x/25x/26x variants -config MACH_ZYLONITE - bool "PXA3xx Development Platform (aka Zylonite)" - select PXA3xx - select HAVE_PWM +config PXA27x + bool + select CPU_XSCALE + help + Select code specific to PXA27x variants -config MACH_LITTLETON - bool "PXA3xx Form Factor Platform (aka Littleton)" - select PXA3xx - select PXA_SSP +config CPU_PXA26x + bool + select PXA25x + help + Select code specific to PXA26x (codename Dalhart) -config MACH_TAVOREVB - bool "PXA930 Evaluation Board (aka TavorEVB)" - select PXA3xx - select PXA930 +config PXA3xx + bool + select CPU_XSC3 + help + Select code specific to PXA3xx variants -config MACH_SAAR - bool "PXA930 Handheld Platform (aka SAAR)" +config CPU_PXA300 + bool select PXA3xx - select PXA930 - -config MACH_ARMCORE - bool "CompuLab CM-X270 modules" - select PXA27x - select IWMMXT - -config MACH_MAGICIAN - bool "Enable HTC Magician Support" - select PXA27x - select IWMMXT - -config MACH_PCM027 - bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" - select PXA27x - select IWMMXT - select PXA_SSP - -config ARCH_PXA_PALM - bool "PXA based Palm PDAs" - select HAVE_PWM - -config MACH_PALMTX - bool "Palm T|X" - default y - depends on ARCH_PXA_PALM - select PXA27x - select IWMMXT help - Say Y here if you intend to run this kernel on a Palm T|X - handheld computer. - -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 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 + PXA300 (codename Monahans-L) -config MACH_EZX_E2 - bool "Motorola EZX E2" - default y - depends on PXA_EZX - -endmenu +config CPU_PXA310 + bool + select CPU_PXA300 + select PXA310_ULPI if USB_ULPI + help + PXA310 (codename Monahans-LV) -config PXA25x +config CPU_PXA320 bool + select PXA3xx help - Select code specific to PXA21x/25x/26x variants + PXA320 (codename Monahans-P) -config PXA27x +config CPU_PXA930 bool + select PXA3xx help - Select code specific to PXA27x variants + PXA930 (codename Tavor-P) -config PXA3xx +config CPU_PXA935 bool + select CPU_PXA930 help - Select code specific to PXA3xx variants + PXA935 (codename Tavor-P65) config PXA_SHARP_C7xx bool - select PXA_SSP select SHARPSL_PM help Enable support for all Sharp C7xx models config PXA_SHARP_Cxx00 bool - select PXA_SSP select SHARPSL_PM help Enable common support for Sharp Cxx00 models -config PXA_SSP - tristate - help - Enable support for PXA2xx SSP ports +config SHARPSL_PM + bool + select APM_EMULATION + select SHARPSL_PM_MAX1111 -config PXA_PWM - tristate - default BACKLIGHT_PWM - help - Enable support for PXA2xx/PXA3xx PWM controllers +config SHARPSL_PM_MAX1111 + bool + select HWMON + select SENSORS_MAX1111 + select SPI + select SPI_MASTER -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 PXA_HAVE_ISA_IRQS + bool + +config PXA310_ULPI + bool endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 99ecbe7f850..648867a8caa 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -3,70 +3,90 @@ # # Common support (must be linked before board specific support) -obj-y += clock.o devices.o generic.o irq.o dma.o \ - time.o gpio.o reset.o +obj-y += clock.o devices.o generic.o irq.o \ + time.o reset.o obj-$(CONFIG_PM) += pm.o sleep.o standby.o -obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o # Generic drivers that other drivers may depend upon -obj-$(CONFIG_PXA_SSP) += ssp.o -obj-$(CONFIG_PXA_PWM) += pwm.o # SoC-specific code -obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o -obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o -obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o +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_CPU_PXA300) += pxa300.o obj-$(CONFIG_CPU_PXA320) += pxa320.o obj-$(CONFIG_CPU_PXA930) += pxa930.o -# Specific board support -obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o +# NOTE: keep the order of boards in accordance to their order in Kconfig + +# Device Tree support +obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o + +# Intel/Marvell Dev Platforms obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o -obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o -obj-$(CONFIG_ARCH_PXA_IDP) += idp.o -obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o -obj-$(CONFIG_MACH_COLIBRI) += colibri.o -obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o -obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o -obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o -obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o -obj-$(CONFIG_MACH_PCM027) += pcm027.o -obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o -obj-$(CONFIG_MACH_TOSA) += tosa.o -obj-$(CONFIG_MACH_EM_X270) += em-x270.o -obj-$(CONFIG_MACH_MAGICIAN) += magician.o -obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o eseries_udc.o -obj-$(CONFIG_MACH_E740) += e740_lcd.o -obj-$(CONFIG_MACH_E750) += e750_lcd.o -obj-$(CONFIG_MACH_E400) += e400_lcd.o -obj-$(CONFIG_MACH_E800) += e800_lcd.o -obj-$(CONFIG_MACH_PALMTX) += palmtx.o - -ifeq ($(CONFIG_MACH_ZYLONITE),y) - obj-y += zylonite.o - obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o - obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o -endif +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_SAAR) += saar.o -obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o -obj-$(CONFIG_PXA_EZX) += ezx.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 -led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o - -obj-$(CONFIG_LEDS) += $(led-y) - +# 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-x270-pci.o +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 obj-$(CONFIG_TOSA_BT) += tosa-bt.o diff --git a/arch/arm/mach-pxa/Makefile.boot b/arch/arm/mach-pxa/Makefile.boot index 1ead67178ec..2c1ae92f210 100644 --- a/arch/arm/mach-pxa/Makefile.boot +++ b/arch/arm/mach-pxa/Makefile.boot @@ -1,2 +1,2 @@ - zreladdr-y := 0xa0008000 + zreladdr-y += 0xa0008000 diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c deleted file mode 100644 index 5c67b188a3b..00000000000 --- a/arch/arm/mach-pxa/akita-ioexp.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita) - * (uses a Maxim MAX7310 8 Port IO Expander) - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie <richard@openedhand.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/slab.h> -#include <linux/workqueue.h> -#include <mach/akita.h> - -/* MAX7310 Regiser Map */ -#define MAX7310_INPUT 0x00 -#define MAX7310_OUTPUT 0x01 -#define MAX7310_POLINV 0x02 -#define MAX7310_IODIR 0x03 /* 1 = Input, 0 = Output */ -#define MAX7310_TIMEOUT 0x04 - -/* Addresses to scan */ -static const unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END }; - -/* I2C Magic */ -I2C_CLIENT_INSMOD; - -static int max7310_write(struct i2c_client *client, int address, int data); -static struct i2c_client max7310_template; -static void akita_ioexp_work(struct work_struct *private_); - -static struct device *akita_ioexp_device; -static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT; -DECLARE_WORK(akita_ioexp, akita_ioexp_work); - - -/* - * MAX7310 Access - */ -static int max7310_config(struct device *dev, int iomode, int polarity) -{ - int ret; - struct i2c_client *client = to_i2c_client(dev); - - ret = max7310_write(client, MAX7310_POLINV, polarity); - if (ret < 0) - return ret; - ret = max7310_write(client, MAX7310_IODIR, iomode); - return ret; -} - -static int max7310_set_ouputs(struct device *dev, int outputs) -{ - struct i2c_client *client = to_i2c_client(dev); - - return max7310_write(client, MAX7310_OUTPUT, outputs); -} - -/* - * I2C Functions - */ -static int max7310_write(struct i2c_client *client, int address, int value) -{ - u8 data[2]; - - data[0] = address & 0xff; - data[1] = value & 0xff; - - if (i2c_master_send(client, data, 2) == 2) - return 0; - return -1; -} - -static int max7310_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *new_client; - int err; - - if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) - return -ENOMEM; - - max7310_template.adapter = adapter; - max7310_template.addr = address; - - memcpy(new_client, &max7310_template, sizeof(struct i2c_client)); - - if ((err = i2c_attach_client(new_client))) { - kfree(new_client); - return err; - } - - max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0); - akita_ioexp_device = &new_client->dev; - schedule_work(&akita_ioexp); - - return 0; -} - -static int max7310_attach_adapter(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, max7310_detect); -} - -static int max7310_detach_client(struct i2c_client *client) -{ - int err; - - akita_ioexp_device = NULL; - - if ((err = i2c_detach_client(client))) - return err; - - kfree(client); - return 0; -} - -static struct i2c_driver max7310_i2c_driver = { - .driver = { - .name = "akita-max7310", - }, - .id = I2C_DRIVERID_AKITAIOEXP, - .attach_adapter = max7310_attach_adapter, - .detach_client = max7310_detach_client, -}; - -static struct i2c_client max7310_template = { - name: "akita-max7310", - driver: &max7310_i2c_driver, -}; - -void akita_set_ioexp(struct device *dev, unsigned char bit) -{ - ioexp_output_value |= bit; - - if (akita_ioexp_device) - schedule_work(&akita_ioexp); - return; -} - -void akita_reset_ioexp(struct device *dev, unsigned char bit) -{ - ioexp_output_value &= ~bit; - - if (akita_ioexp_device) - schedule_work(&akita_ioexp); - return; -} - -EXPORT_SYMBOL(akita_set_ioexp); -EXPORT_SYMBOL(akita_reset_ioexp); - -static void akita_ioexp_work(struct work_struct *private_) -{ - if (akita_ioexp_device) - max7310_set_ouputs(akita_ioexp_device, ioexp_output_value); -} - - -#ifdef CONFIG_PM -static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state) -{ - flush_scheduled_work(); - return 0; -} - -static int akita_ioexp_resume(struct platform_device *pdev) -{ - schedule_work(&akita_ioexp); - return 0; -} -#else -#define akita_ioexp_suspend NULL -#define akita_ioexp_resume NULL -#endif - -static int __init akita_ioexp_probe(struct platform_device *pdev) -{ - return i2c_add_driver(&max7310_i2c_driver); -} - -static int akita_ioexp_remove(struct platform_device *pdev) -{ - i2c_del_driver(&max7310_i2c_driver); - return 0; -} - -static struct platform_driver akita_ioexp_driver = { - .probe = akita_ioexp_probe, - .remove = akita_ioexp_remove, - .suspend = akita_ioexp_suspend, - .resume = akita_ioexp_resume, - .driver = { - .name = "akita-ioexp", - }, -}; - -static int __init akita_ioexp_init(void) -{ - return platform_driver_register(&akita_ioexp_driver); -} - -static void __exit akita_ioexp_exit(void) -{ - platform_driver_unregister(&akita_ioexp_driver); -} - -MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); -MODULE_DESCRIPTION("Akita IO-Expander driver"); -MODULE_LICENSE("GPL"); - -fs_initcall(akita_ioexp_init); -module_exit(akita_ioexp_exit); - diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c new file mode 100644 index 00000000000..12fb0f4ae35 --- /dev/null +++ b/arch/arm/mach-pxa/am200epd.c @@ -0,0 +1,386 @@ +/* + * 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 <linux/platform_data/video-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_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..8b90c4f2d43 --- /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/irqs.h> +#include <linux/platform_data/video-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_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..43596e0ed05 --- /dev/null +++ b/arch/arm/mach-pxa/balloon3.c @@ -0,0 +1,828 @@ +/* + * 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 <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <mach/udc.h> +#include <mach/pxa27x-udc.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/usb-ohci-pxa27x.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); +} +#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 + }, +}; + +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, + }, + .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[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +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, + .init_time = pxa_timer_init, + .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..c092730749b --- /dev/null +++ b/arch/arm/mach-pxa/capc7117.c @@ -0,0 +1,159 @@ +/* + * 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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .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..9ee2ad6a0a0 --- /dev/null +++ b/arch/arm/mach-pxa/clock-pxa2xx.c @@ -0,0 +1,55 @@ +/* + * 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/io.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..d4e9499832d --- /dev/null +++ b/arch/arm/mach-pxa/clock-pxa3xx.c @@ -0,0 +1,212 @@ +/* + * 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 if (clk->cken < 64) + CKENB |= mask; + else + CKENC |= mask; +} + +void clk_pxa3xx_cken_disable(struct clk *clk) +{ + unsigned long mask = 1ul << (clk->cken & 0x1f); + + if (clk->cken < 32) + CKENA &= ~mask; + else if (clk->cken < 64) + CKENB &= ~mask; + else + CKENC &= ~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 index ca8e2053815..4d466102a02 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -3,62 +3,15 @@ */ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/string.h> #include <linux/clk.h> #include <linux/spinlock.h> -#include <linux/platform_device.h> #include <linux/delay.h> +#include <linux/clkdev.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/hardware.h> - -#include "devices.h" -#include "generic.h" #include "clock.h" -static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); -static struct clk *clk_lookup(struct device *dev, const char *id) -{ - struct clk *p; - - list_for_each_entry(p, &clocks, node) - if (strcmp(id, p->name) == 0 && p->dev == dev) - return p; - - return NULL; -} - -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *p, *clk = ERR_PTR(-ENOENT); - - mutex_lock(&clocks_mutex); - p = clk_lookup(dev, id); - if (!p) - p = clk_lookup(NULL, id); - if (p) - clk = p; - mutex_unlock(&clocks_mutex); - - if (!IS_ERR(clk) && clk->ops == NULL) - clk = clk->other; - - return clk; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - int clk_enable(struct clk *clk) { unsigned long flags; @@ -100,53 +53,34 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); - -void clk_cken_enable(struct clk *clk) +int clk_set_rate(struct clk *clk, unsigned long rate) { - CKEN |= 1 << clk->cken; -} + unsigned long flags; + int ret = -EINVAL; -void clk_cken_disable(struct clk *clk) -{ - CKEN &= ~(1 << clk->cken); -} + if (clk->ops->setrate) { + spin_lock_irqsave(&clocks_lock, flags); + ret = clk->ops->setrate(clk, rate); + spin_unlock_irqrestore(&clocks_lock, flags); + } -const struct clkops clk_cken_ops = { - .enable = clk_cken_enable, - .disable = clk_cken_disable, -}; + return ret; +} +EXPORT_SYMBOL(clk_set_rate); -void clks_register(struct clk *clks, size_t num) +void clk_dummy_enable(struct clk *clk) { - int i; - - mutex_lock(&clocks_mutex); - for (i = 0; i < num; i++) - list_add(&clks[i].node, &clocks); - mutex_unlock(&clocks_mutex); } -int clk_add_alias(char *alias, struct device *alias_dev, char *id, - struct device *dev) +void clk_dummy_disable(struct clk *clk) { - struct clk *r = clk_lookup(dev, id); - struct clk *new; - - if (!r) - return -ENODEV; - - new = kzalloc(sizeof(struct clk), GFP_KERNEL); - - if (!new) - return -ENOMEM; - - new->name = alias; - new->dev = alias_dev; - new->other = r; +} - mutex_lock(&clocks_mutex); - list_add(&new->node, &clocks); - mutex_unlock(&clocks_mutex); +const struct clkops clk_dummy_ops = { + .enable = clk_dummy_enable, + .disable = clk_dummy_disable, +}; - return 0; -} +struct clk clk_dummy = { + .ops = &clk_dummy_ops, +}; diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index 73be795fe3b..1f65d32c8d5 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -1,93 +1,80 @@ -#include <linux/list.h> - -struct clk; +#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 { - struct list_head node; - const char *name; - struct device *dev; const struct clkops *ops; unsigned long rate; unsigned int cken; unsigned int delay; unsigned int enabled; - struct clk *other; }; -#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ +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) \ { \ - .name = _name, \ - .dev = _dev, \ - .ops = &clk_cken_ops, \ - .rate = _rate, \ - .cken = CKEN_##_cken, \ - .delay = _delay, \ + .clk = _clk, \ + .dev_id = _devname, \ + .con_id = _conname, \ } -#define INIT_CK(_name, _cken, _ops, _dev) \ - { \ - .name = _name, \ - .dev = _dev, \ +#define DEFINE_CK(_name, _cken, _ops) \ +struct clk clk_##_name = { \ .ops = _ops, \ .cken = CKEN_##_cken, \ } -/* - * This is a placeholder to alias one clock device+name pair - * to another struct clk. - */ -#define INIT_CKOTHER(_name, _other, _dev) \ - { \ - .name = _name, \ - .dev = _dev, \ - .other = _other, \ +#define DEFINE_CLK(_name, _ops, _rate, _delay) \ +struct clk clk_##_name = { \ + .ops = _ops, \ + .rate = _rate, \ + .delay = _delay, \ } -#define INIT_CLK(_name, _ops, _rate, _delay, _dev) \ - { \ - .name = _name, \ - .dev = _dev, \ - .ops = _ops, \ - .rate = _rate, \ +#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_cken_ops; +extern const struct clkops clk_pxa2xx_cken_ops; -void clk_cken_enable(struct clk *clk); -void clk_cken_disable(struct clk *clk); +void clk_pxa2xx_cken_enable(struct clk *clk); +void clk_pxa2xx_cken_disable(struct clk *clk); -#ifdef CONFIG_PXA3xx -#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \ - { \ - .name = _name, \ - .dev = _dev, \ +extern struct syscore_ops pxa2xx_clock_syscore_ops; + +#if defined(CONFIG_PXA3xx) +#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \ +struct clk clk_##_name = { \ .ops = &clk_pxa3xx_cken_ops, \ .rate = _rate, \ .cken = CKEN_##_cken, \ .delay = _delay, \ } -#define PXA3xx_CK(_name, _cken, _ops, _dev) \ - { \ - .name = _name, \ - .dev = _dev, \ - .ops = _ops, \ - .cken = CKEN_##_cken, \ - } - 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 *); -#endif -void clks_register(struct clk *clks, size_t num); -int clk_add_alias(char *alias, struct device *alias_dev, char *id, - struct device *dev); +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-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h deleted file mode 100644 index 48f532f4cb5..00000000000 --- a/arch/arm/mach-pxa/cm-x270-pci.h +++ /dev/null @@ -1,13 +0,0 @@ -extern void __cmx270_pci_init_irq(int irq_gpio); -extern void __cmx270_pci_suspend(void); -extern void __cmx270_pci_resume(void); - -#ifdef CONFIG_PCI -#define cmx270_pci_init_irq(x) __cmx270_pci_init_irq(x) -#define cmx270_pci_suspend(x) __cmx270_pci_suspend(x) -#define cmx270_pci_resume(x) __cmx270_pci_resume(x) -#else -#define cmx270_pci_init_irq(x) do {} while (0) -#define cmx270_pci_suspend(x) do {} while (0) -#define cmx270_pci_resume(x) do {} while (0) -#endif diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index af003a26953..2503db9e325 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -10,54 +10,38 @@ */ #include <linux/platform_device.h> -#include <linux/sysdev.h> #include <linux/irq.h> #include <linux/gpio.h> +#include <linux/delay.h> -#include <linux/dm9000.h> #include <linux/rtc-v3020.h> #include <video/mbxfb.h> -#include <linux/leds.h> -#include <asm/mach/arch.h> -#include <asm/mach-types.h> -#include <asm/mach/map.h> +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/spi/libertas_spi.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa27x.h> -#include <mach/pxa-regs.h> -#include <mach/audio.h> -#include <mach/pxafb.h> -#include <mach/ohci.h> -#include <mach/mmc.h> -#include <mach/bitfield.h> - -#include <asm/hardware/it8152.h> +#include <mach/pxa27x.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/mmc-pxamci.h> #include "generic.h" -#include "cm-x270-pci.h" - -/* virtual addresses for statically mapped regions */ -#define CMX270_VIRT_BASE (0xe8000000) -#define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) +/* physical address if local-bus attached devices */ #define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) -#define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) /* GPIO IRQ usage */ -#define GPIO10_ETHIRQ (10) -#define GPIO22_IT8152_IRQ (22) #define GPIO83_MMC_IRQ (83) -#define GPIO95_GFXIRQ (95) -#define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ) -#define CMX270_IT8152_IRQ IRQ_GPIO(GPIO22_IT8152_IRQ) -#define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) -#define CMX270_GFXIRQ IRQ_GPIO(GPIO95_GFXIRQ) +#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, @@ -86,26 +70,7 @@ static unsigned long cmx270_pin_config[] = { GPIO111_MMC_DAT_3, /* LCD */ - 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, - GPIO74_LCD_FCLK, - GPIO75_LCD_LCLK, - GPIO76_LCD_PCLK, - GPIO77_LCD_BIAS, + GPIOxx_LCD_TFT_16BPP, /* I2C */ GPIO117_I2C_SCL, @@ -118,8 +83,8 @@ static unsigned long cmx270_pin_config[] = { GPIO26_SSP1_RXD, /* SSP2 */ - GPIO19_SSP2_SCLK, - GPIO14_SSP2_SFRM, + GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */ + GPIO14_GPIO, GPIO87_SSP2_TXD, GPIO88_SSP2_RXD, @@ -147,6 +112,7 @@ static unsigned long cmx270_pin_config[] = { 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# */ @@ -155,64 +121,9 @@ static unsigned long cmx270_pin_config[] = { /* interrupts */ GPIO10_GPIO, /* DM9000 interrupt */ GPIO83_GPIO, /* MMC card detect */ + GPIO95_GPIO, /* WLAN interrupt */ }; -#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) -static struct resource cmx270_dm9000_resource[] = { - [0] = { - .start = DM9000_PHYS_BASE, - .end = DM9000_PHYS_BASE + 4, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DM9000_PHYS_BASE + 8, - .end = 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, -}; - -static struct platform_device cmx270_dm9000_device = { - .name = "dm9000", - .id = 0, - .num_resources = ARRAY_SIZE(cmx270_dm9000_resource), - .resource = cmx270_dm9000_resource, - .dev = { - .platform_data = &cmx270_dm9000_platdata, - } -}; - -static void __init cmx270_init_dm9000(void) -{ - platform_device_register(&cmx270_dm9000_device); -} -#else -static inline void cmx270_init_dm9000(void) {} -#endif - -/* UCB1400 touchscreen controller */ -#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) -static struct platform_device cmx270_ts_device = { - .name = "ucb1400_ts", - .id = -1, -}; - -static void __init cmx270_init_touchscreen(void) -{ - platform_device_register(&cmx270_ts_device); -} -#else -static inline void cmx270_init_touchscreen(void) {} -#endif - /* V3020 RTC */ #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) static struct resource cmx270_v3020_resource[] = { @@ -245,44 +156,6 @@ static void __init cmx270_init_rtc(void) static inline void cmx270_init_rtc(void) {} #endif -/* CM-X270 LEDs */ -#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) -static struct gpio_led cmx270_leds[] = { - [0] = { - .name = "cm-x270:red", - .default_trigger = "nand-disk", - .gpio = 93, - .active_low = 1, - }, - [1] = { - .name = "cm-x270:green", - .default_trigger = "heartbeat", - .gpio = 94, - .active_low = 1, - }, -}; - -static struct gpio_led_platform_data cmx270_gpio_led_pdata = { - .num_leds = ARRAY_SIZE(cmx270_leds), - .leds = cmx270_leds, -}; - -static struct platform_device cmx270_led_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &cmx270_gpio_led_pdata, - }, -}; - -static void __init cmx270_init_leds(void) -{ - platform_device_register(&cmx270_led_device); -} -#else -static inline void cmx270_init_leds(void) {} -#endif - /* 2700G graphics */ #if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE) static u64 fb_dma_mask = ~(u64)0; @@ -302,33 +175,57 @@ static struct resource cmx270_2700G_resource[] = { }, }; -static unsigned long save_lcd_regs[10]; +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) { - /* save PXA-270 pin settings before enabling 2700G */ - save_lcd_regs[0] = GPDR1; - save_lcd_regs[1] = GPDR2; - save_lcd_regs[2] = GAFR1_U; - save_lcd_regs[3] = GAFR2_L; - save_lcd_regs[4] = GAFR2_U; - - /* Disable PXA-270 on-chip controller driving pins */ - GPDR1 &= ~(0xfc000000); - GPDR2 &= ~(0x00c03fff); - GAFR1_U &= ~(0xfff00000); - GAFR2_L &= ~(0x0fffffff); - GAFR2_U &= ~(0x0000f000); + 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) { - GPDR1 = save_lcd_regs[0]; - GPDR2 = save_lcd_regs[1]; - GAFR1_U = save_lcd_regs[2]; - GAFR2_L = save_lcd_regs[3]; - GAFR2_U = save_lcd_regs[4]; + int gpio; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_off)); + + for (gpio = 58; gpio <= 77; gpio++) + gpio_free(gpio); + return 0; } @@ -373,238 +270,11 @@ static void __init cmx270_init_2700G(void) static inline void cmx270_init_2700G(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, - .lccr0 = 0, - .lccr3 = (LCCR3_PixClkDiv(0x03) | - LCCR3_Acb(0xff) | - LCCR3_PCP), - .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, - .lccr0 = (LCCR0_PAS), - .lccr3 = (LCCR3_PixClkDiv(0x01) | - LCCR3_Acb(0xff) | - LCCR3_PCP), - .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, - .lccr0 = (LCCR0_PAS), - .lccr3 = (LCCR3_PixClkDiv(0x01) | - LCCR3_Acb(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, - .lccr0 = (LCCR0_PAS), - .lccr3 = (LCCR3_PixClkDiv(0x02) | - LCCR3_Acb(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, - .lccr0 = (LCCR0_PAS), - .lccr3 = (LCCR3_PixClkDiv(0x06) | - LCCR3_Acb(0xff) | - LCCR3_PCP), - .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, - .lccr0 = 0, - .lccr3 = (LCCR3_PixClkDiv(0x02) | - LCCR3_Acb(0xff)), - .cmap_inverse = 0, - .cmap_static = 0, -}; - -static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480; - -static int __init cmx270_set_display(char *str) -{ - int disp_type = simple_strtol(str, NULL, 0); - switch (disp_type) { - case MTYPE_STN320x240: - cmx270_display = &generic_stn_320x240; - break; - case MTYPE_TFT640x480: - cmx270_display = &generic_tft_640x480; - break; - case MTYPE_CRT640x480: - cmx270_display = &generic_crt_640x480; - break; - case MTYPE_CRT800x600: - cmx270_display = &generic_crt_800x600; - break; - case MTYPE_TFT320x240: - cmx270_display = &generic_tft_320x240; - break; - case MTYPE_STN640x480: - cmx270_display = &generic_stn_640x480; - break; - default: /* fallback to CRT 640x480 */ - cmx270_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-X270 bootloader - has limitied line length for kernel command line, and also it will - break compatibitlty with proprietary releases already in field. -*/ -__setup("monitor=", cmx270_set_display); - -static void __init cmx270_init_display(void) -{ - set_pxa_fb_info(cmx270_display); -} -#else -static inline void cmx270_init_display(void) {} -#endif - /* PXA27x OHCI controller setup */ #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static int cmx270_ohci_init(struct device *dev) -{ - /* Set the Power Control Polarity Low */ - UHCHR = (UHCHR | UHCHR_PCPL) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); - - return 0; -} - static struct pxaohci_platform_data cmx270_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, - .init = cmx270_ohci_init, + .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW, }; static void __init cmx270_init_ohci(void) @@ -616,56 +286,12 @@ static inline void cmx270_init_ohci(void) {} #endif #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) -static int cmx270_mci_init(struct device *dev, - irq_handler_t cmx270_detect_int, - void *data) -{ - int err; - - err = gpio_request(GPIO105_MMC_POWER, "MMC/SD power"); - if (err) { - dev_warn(dev, "power gpio unavailable\n"); - return err; - } - - gpio_direction_output(GPIO105_MMC_POWER, 0); - - err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_FALLING, - "MMC card detect", data); - if (err) { - gpio_free(GPIO105_MMC_POWER); - dev_err(dev, "cmx270_mci_init: MMC/SD: can't" - " request MMC card detect IRQ\n"); - } - - return err; -} - -static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) -{ - struct pxamci_platform_data *p_d = dev->platform_data; - - if ((1 << vdd) & p_d->ocr_mask) { - dev_dbg(dev, "power on\n"); - gpio_set_value(GPIO105_MMC_POWER, 0); - } else { - gpio_set_value(GPIO105_MMC_POWER, 1); - dev_dbg(dev, "power off\n"); - } -} - -static void cmx270_mci_exit(struct device *dev, void *data) -{ - free_irq(CMX270_MMC_IRQ, data); - gpio_free(GPIO105_MMC_POWER); -} - static struct pxamci_platform_data cmx270_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = cmx270_mci_init, - .setpower = cmx270_mci_setpower, - .exit = cmx270_mci_exit, + .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) @@ -676,131 +302,111 @@ static void __init cmx270_init_mmc(void) static inline void cmx270_init_mmc(void) {} #endif -#ifdef CONFIG_PM -static unsigned long sleep_save_msc[10]; +#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 int cmx270_suspend(struct sys_device *dev, pm_message_t state) -{ - cmx270_pci_suspend(); - - /* save MSC registers */ - sleep_save_msc[0] = MSC0; - sleep_save_msc[1] = MSC1; - sleep_save_msc[2] = 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; +static struct pxa2xx_spi_chip cm_x270_libertas_chip = { + .rx_threshold = 1, + .tx_threshold = 1, + .timeout = 1000, + .gpio_cs = 14, +}; - return 0; -} +static unsigned long cm_x270_libertas_pin_config[] = { + /* SSP2 */ + GPIO19_SSP2_SCLK, + GPIO14_GPIO, + GPIO87_SSP2_TXD, + GPIO88_SSP2_RXD, -static int cmx270_resume(struct sys_device *dev) +}; + +static int cm_x270_libertas_setup(struct spi_device *spi) { - cmx270_pci_resume(); + int err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP"); + if (err) + return err; - /* restore MSC registers */ - MSC0 = sleep_save_msc[0]; - MSC1 = sleep_save_msc[1]; - MSC2 = sleep_save_msc[2]; + err = gpio_request(GPIO102_WLAN_RST, "WLAN RST"); + if (err) + goto err_free_strap; - return 0; -} + err = gpio_direction_output(GPIO102_WLAN_RST, 0); + if (err) + goto err_free_strap; + msleep(100); -static struct sysdev_class cmx270_pm_sysclass = { - .name = "pm", - .resume = cmx270_resume, - .suspend = cmx270_suspend, -}; + err = gpio_direction_output(GPIO19_WLAN_STRAP, 1); + if (err) + goto err_free_strap; + msleep(100); -static struct sys_device cmx270_pm_device = { - .cls = &cmx270_pm_sysclass, -}; + pxa2xx_mfp_config(ARRAY_AND_SIZE(cm_x270_libertas_pin_config)); -static int __init cmx270_pm_init(void) -{ - int error; - error = sysdev_class_register(&cmx270_pm_sysclass); - if (error == 0) - error = sysdev_register(&cmx270_pm_device); - return error; -} -#else -static int __init cmx270_pm_init(void) { return 0; } -#endif + gpio_set_value(GPIO102_WLAN_RST, 1); + msleep(100); -#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) -static void __init cmx270_init_ac97(void) -{ - pxa_set_ac97_info(NULL); -} -#else -static inline void cmx270_init_ac97(void) {} -#endif + spi->bits_per_word = 16; + spi_setup(spi); -static void __init cmx270_init(void) -{ - cmx270_pm_init(); + return 0; - pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); +err_free_strap: + gpio_free(GPIO19_WLAN_STRAP); - cmx270_init_dm9000(); - cmx270_init_rtc(); - cmx270_init_display(); - cmx270_init_mmc(); - cmx270_init_ohci(); - cmx270_init_ac97(); - cmx270_init_touchscreen(); - cmx270_init_leds(); - cmx270_init_2700G(); + return err; } -static void __init cmx270_init_irq(void) +static int cm_x270_libertas_teardown(struct spi_device *spi) { - pxa27x_init_irq(); + gpio_set_value(GPIO102_WLAN_RST, 0); + gpio_free(GPIO102_WLAN_RST); + gpio_free(GPIO19_WLAN_STRAP); - cmx270_pci_init_irq(GPIO22_IT8152_IRQ); + return 0; } -#ifdef CONFIG_PCI -/* Map PCI companion statically */ -static struct map_desc cmx270_io_desc[] __initdata = { - [0] = { /* PCI bridge */ - .virtual = CMX270_IT8152_VIRT, - .pfn = __phys_to_pfn(PXA_CS4_PHYS), - .length = SZ_64M, - .type = MT_DEVICE +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_map_io(void) +static void __init cmx270_init_spi(void) { - pxa_map_io(); - iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); - - it8152_base_address = CMX270_IT8152_VIRT; + pxa2xx_set_spi_info(2, &cm_x270_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(cm_x270_spi_devices)); } #else -static void __init cmx270_map_io(void) +static inline void cmx270_init_spi(void) {} +#endif + +void __init cmx270_init(void) { - pxa_map_io(); -} + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); + +#ifdef CONFIG_PM + pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP); #endif -MACHINE_START(ARMCORE, "Compulab CM-x270") - .boot_params = 0xa0000100, - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = cmx270_map_io, - .init_irq = cmx270_init_irq, - .timer = &pxa_timer, - .init_machine = cmx270_init, -MACHINE_END + cmx270_init_rtc(); + cmx270_init_mmc(); + cmx270_init_ohci(); + cmx270_init_2700G(); + cmx270_init_spi(); +} diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c index 2d5bcea1e52..d8f816c24a2 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-pxa/cm-x270-pci.c + * linux/arch/arm/mach-pxa/cm-x2xx-pci.c * * PCI bios-type initialisation for PCI machines * @@ -22,64 +22,37 @@ #include <linux/gpio.h> #include <asm/mach/pci.h> -#include <mach/pxa-regs.h> #include <asm/mach-types.h> #include <asm/hardware/it8152.h> -unsigned long it8152_base_address; -static int cmx270_it8152_irq_gpio; +void __iomem *it8152_base_address; +static int cmx2xx_it8152_irq_gpio; -/* - * Only first 64MB of memory can be accessed via PCI. - * We use GFP_DMA to allocate safe buffers to do map/unmap. - * This is really ugly and we need a better way of specifying - * DMA-capable regions of memory. - */ -void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, - unsigned long *zhole_size) -{ - unsigned int sz = SZ_64M >> PAGE_SHIFT; - - if (machine_is_armcore()) { - pr_info("Adjusting zones for CM-X270\n"); - - /* - * Only adjust if > 64M on current system - */ - if (node || (zone_size[0] <= sz)) - return; - - zone_size[1] = zone_size[0] - sz; - zone_size[0] = sz; - zhole_size[1] = zhole_size[0]; - zhole_size[0] = 0; - } -} - -static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) +static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) { /* clear our parent irq */ - GEDR(cmx270_it8152_irq_gpio) = GPIO_bit(cmx270_it8152_irq_gpio); + desc->irq_data.chip->irq_ack(&desc->irq_data); it8152_irq_demux(irq, desc); } -void __cmx270_pci_init_irq(int irq_gpio) +void __cmx2xx_pci_init_irq(int irq_gpio) { it8152_init_irq(); - cmx270_it8152_irq_gpio = irq_gpio; + cmx2xx_it8152_irq_gpio = irq_gpio; - set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); - set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux); + irq_set_chained_handler(gpio_to_irq(irq_gpio), + cmx2xx_it8152_irq_demux); } #ifdef CONFIG_PM static unsigned long sleep_save_ite[10]; -void __cmx270_pci_suspend(void) +void __cmx2xx_pci_suspend(void) { /* save ITE state */ sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR); @@ -91,7 +64,7 @@ void __cmx270_pci_suspend(void) __raw_writel((0), IT8152_INTC_LPCNIRR); } -void __cmx270_pci_resume(void) +void __cmx2xx_pci_resume(void) { /* restore IT8152 state */ __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR); @@ -99,12 +72,12 @@ void __cmx270_pci_resume(void) __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR); } #else -void cmx270_pci_suspend(void) {} -void cmx270_pci_resume(void) {} +void cmx2xx_pci_suspend(void) {} +void cmx2xx_pci_resume(void) {} #endif /* PCI IRQ mapping*/ -static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init cmx2xx_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; @@ -116,14 +89,14 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) /* Here comes the ugly part. The routing is baseboard specific, - but defining a platform for each possible base of CM-X270 is - unrealistic. Here we keep mapping for ATXBase and SB-X270. + 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-x270 CardBus */ + /* ATXBase/SB-X2XX CardBus */ if (slot == 8 || slot == 0) return IT8152_PCI_INTB; @@ -131,7 +104,11 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) if (slot == 9) return IT8152_PCI_INTA; - /* SB-x270 Ethernet */ + /* CM-x255 Onboard Ethernet */ + if (slot == 15) + return IT8152_PCI_INTC; + + /* SB-x2xx Ethernet */ if (slot == 16) return IT8152_PCI_INTA; @@ -144,9 +121,12 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) return(0); } -static void cmx270_pci_preinit(void) +static void cmx2xx_pci_preinit(void) { - pr_info("Initializing CM-X270 PCI subsystem\n"); + 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) { @@ -200,21 +180,20 @@ static void cmx270_pci_preinit(void) } } -static struct hw_pci cmx270_pci __initdata = { - .swizzle = pci_std_swizzle, - .map_irq = cmx270_pci_map_irq, +static struct hw_pci cmx2xx_pci __initdata = { + .map_irq = cmx2xx_pci_map_irq, .nr_controllers = 1, + .ops = &it8152_ops, .setup = it8152_pci_setup, - .scan = it8152_pci_scan_bus, - .preinit = cmx270_pci_preinit, + .preinit = cmx2xx_pci_preinit, }; -static int __init cmx270_init_pci(void) +static int __init cmx2xx_init_pci(void) { if (machine_is_armcore()) - pci_common_init(&cmx270_pci); + pci_common_init(&cmx2xx_pci); return 0; } -subsys_initcall(cmx270_init_pci); +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..bb99f59a36d --- /dev/null +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -0,0 +1,529 @@ +/* + * 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> +#undef GPIO24_SSP1_SFRM +#include <mach/pxa27x.h> +#include <mach/audio.h> +#include <linux/platform_data/video-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, + .init_time = pxa_timer_init, + .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..4d3588d26c2 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x300.c @@ -0,0 +1,861 @@ +/* + * 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/platform_data/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 <asm/system_info.h> + +#include <mach/pxa300.h> +#include <mach/pxa27x-udc.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/mtd-nand-pxa3xx.h> +#include <mach/audio.h> +#include <linux/platform_data/usb-pxa3xx-ulpi.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, + .enable_gpio = -1, +}; + +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[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +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) +{ + /* 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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .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..638b0bb8842 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-evalboard.c @@ -0,0 +1,120 @@ +/* + * 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 <asm/io.h> + +#include <mach/pxa27x.h> +#include <mach/colibri.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.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..3aa264640c9 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -0,0 +1,224 @@ +/* + * 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 <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/pxa27x.h> +#include <mach/pxa27x-udc.h> +#include <linux/platform_data/video-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, + .enable_gpio = -1, +}; + +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..5f9d9303b34 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -0,0 +1,330 @@ +/* + * 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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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..f1a1ac1fbd8 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -0,0 +1,195 @@ +/* + * 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 <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/video-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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .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..f6cc8b0ab82 --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -0,0 +1,265 @@ +/* + * 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 <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/usb-ohci-pxa27x.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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .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..8240291ab8c --- /dev/null +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -0,0 +1,153 @@ +/* + * 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/system_info.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 <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mtd-nand-pxa3xx.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/colibri.c b/arch/arm/mach-pxa/colibri.c deleted file mode 100644 index abce13c846c..00000000000 --- a/arch/arm/mach-pxa/colibri.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/colibri.c - * - * Support for Toradex PXA27x based Colibri module - * 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/sysdev.h> -#include <linux/interrupt.h> -#include <linux/bitops.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.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/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/colibri.h> - -#include "generic.h" -#include "devices.h" - -/* - * Flash - */ -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 flash_resource = { - .start = PXA_CS0_PHYS, - .end = PXA_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = colibri_flash_data, - }, - .resource = &flash_resource, - .num_resources = 1, -}; - -/* - * DM9000 Ethernet - */ -static struct resource dm9000_resources[] = { - [0] = { - .start = COLIBRI_ETH_PHYS, - .end = COLIBRI_ETH_PHYS + 3, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = COLIBRI_ETH_PHYS + 4, - .end = COLIBRI_ETH_PHYS + 4 + 500, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = COLIBRI_ETH_IRQ, - .end = COLIBRI_ETH_IRQ, - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, - }, -}; - -static struct platform_device dm9000_device = { - .name = "dm9000", - .id = -1, - .num_resources = ARRAY_SIZE(dm9000_resources), - .resource = dm9000_resources, -}; - -static struct platform_device *colibri_devices[] __initdata = { - &flash_device, - &dm9000_device, -}; - -static void __init colibri_init(void) -{ - /* DM9000 LAN */ - pxa_gpio_mode(GPIO78_nCS_2_MD); - pxa_gpio_mode(GPIO_DM9000 | GPIO_IN); - - platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices)); -} - -MACHINE_START(COLIBRI, "Toradex Colibri PXA27x") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = COLIBRI_SDRAM_BASE + 0x100, - .init_machine = colibri_init, - .map_io = pxa_map_io, - .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, -MACHINE_END diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index e703a8d209e..91dd1c7cdbc 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -19,8 +19,22 @@ #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/gpio_keys.h> +#include <linux/module.h> +#include <linux/memblock.h> #include <video/w100fb.h> #include <asm/setup.h> @@ -28,30 +42,108 @@ #include <asm/mach-types.h> #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/io.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/i2c.h> -#include <mach/irda.h> -#include <mach/mmc.h> +#include <mach/pxa25x.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/mmc-pxamci.h> #include <mach/udc.h> #include <mach/corgi.h> -#include <mach/sharpsl.h> +#include <mach/sharpsl_pm.h> #include <asm/mach/sharpsl_param.h> #include <asm/hardware/scoop.h> #include "generic.h" #include "devices.h" -#include "sharpsl.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 @@ -67,6 +159,7 @@ static struct resource corgi_scoop_resources[] = { 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 = { @@ -79,27 +172,6 @@ struct platform_device corgiscoop_device = { .resource = corgi_scoop_resources, }; -static void corgi_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); -} - static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { { .dev = &corgiscoop_device.dev, @@ -112,56 +184,6 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { static struct scoop_pcmcia_config corgi_pcmcia_config = { .devs = &corgi_pcmcia_scoop[0], .num_devs = 1, - .pcmcia_init = corgi_pcmcia_init, -}; - -EXPORT_SYMBOL(corgiscoop_device); - - -/* - * Corgi SSP Device - * - * Set the parent as the scoop device because a lot of SSP devices - * also use scoop functions and this makes the power up/down order - * work correctly. - */ -struct platform_device corgissp_device = { - .name = "corgi-ssp", - .dev = { - .parent = &corgiscoop_device.dev, - }, - .id = -1, -}; - -struct corgissp_machinfo corgi_ssp_machinfo = { - .port = 1, - .cs_lcdcon = CORGI_GPIO_LCDCON_CS, - .cs_ads7846 = CORGI_GPIO_ADS7846_CS, - .cs_max1111 = CORGI_GPIO_MAX1111_CS, - .clk_lcdcon = 76, - .clk_ads7846 = 2, - .clk_max1111 = 8, -}; - - -/* - * LCD/Framebuffer - */ -static void w100_lcdtg_suspend(struct w100fb_par *par) -{ - corgi_lcdtg_suspend(); -} - -static void w100_lcdtg_init(struct w100fb_par *par) -{ - corgi_lcdtg_hw_init(par->xres); -} - - -static struct w100_tg_info corgi_lcdtg_info = { - .change = w100_lcdtg_init, - .suspend = w100_lcdtg_suspend, - .resume = w100_lcdtg_init, }; static struct w100_mem_info corgi_fb_mem = { @@ -242,7 +264,6 @@ static struct w100_mode corgi_fb_modes[] = { }; static struct w100fb_mach_info corgi_fb_info = { - .tg = &corgi_lcdtg_info, .init_mode = INIT_MODE_ROTATED, .mem = &corgi_fb_mem, .regs = &corgi_fb_regs, @@ -268,136 +289,198 @@ static struct platform_device corgifb_device = { .resource = corgi_fb_resources, .dev = { .platform_data = &corgi_fb_info, - .parent = &corgissp_device.dev, }, }; - /* - * Corgi Backlight Device + * Corgi Keyboard Device */ -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 void corgi_bl_set_intensity(int intensity) -{ - if (intensity > 0x10) - intensity += 0x10; - - /* Bits 0-4 are accessed via the SSP interface */ - corgi_ssp_blduty_set(intensity & 0x1f); - - /* Bit 5 is via SCOOP */ - if (intensity & 0x0020) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); -} - -static struct generic_bl_info corgi_bl_machinfo = { - .name = "corgi-bl", - .max_intensity = 0x2f, - .default_intensity = 0x1f, - .limit_mask = 0x0b, - .set_bl_intensity = corgi_bl_set_intensity, - .kick_battery = corgi_bl_kick_battery, +#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 platform_device corgibl_device = { - .name = "generic-bl", - .dev = { - .parent = &corgifb_device.dev, - .platform_data = &corgi_bl_machinfo, - }, - .id = -1, +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, +}; -/* - * Corgi Keyboard Device - */ static struct platform_device corgikbd_device = { - .name = "corgi-keyboard", + .name = "matrix-keypad", .id = -1, + .dev = { + .platform_data = &corgikbd_pdata, + }, }; +static struct gpio_keys_button corgi_gpio_keys[] = { + { + .type = EV_SW, + .code = SW_LID, + .gpio = CORGI_GPIO_SWA, + .desc = "Lid close switch", + .debounce_interval = 500, + }, + { + .type = EV_SW, + .code = SW_TABLET_MODE, + .gpio = CORGI_GPIO_SWB, + .desc = "Tablet mode switch", + .debounce_interval = 500, + }, + { + .type = EV_SW, + .code = SW_HEADPHONE_INSERT, + .gpio = CORGI_GPIO_AK_INT, + .desc = "HeadPhone insert", + .debounce_interval = 500, + }, +}; -/* - * Corgi LEDs - */ -static struct platform_device corgiled_device = { - .name = "corgi-led", - .id = -1, +static struct gpio_keys_platform_data corgi_gpio_keys_platform_data = { + .buttons = corgi_gpio_keys, + .nbuttons = ARRAY_SIZE(corgi_gpio_keys), + .poll_interval = 250, }; +static struct platform_device corgi_gpio_keys_device = { + .name = "gpio-keys-polled", + .id = -1, + .dev = { + .platform_data = &corgi_gpio_keys_platform_data, + }, +}; /* - * Corgi Touch Screen Device + * Corgi LEDs */ -static unsigned long (*get_hsync_invperiod)(struct device *dev); - -static void inline sharpsl_wait_sync(int gpio) -{ - while((GPLR(gpio) & GPIO_bit(gpio)) == 0); - while((GPLR(gpio) & GPIO_bit(gpio)) != 0); -} - -static unsigned long corgi_get_hsync_invperiod(void) -{ - if (!get_hsync_invperiod) - get_hsync_invperiod = symbol_get(w100fb_get_hsynclen); - if (!get_hsync_invperiod) - return 0; - - return get_hsync_invperiod(&corgifb_device.dev); -} - -static void corgi_put_hsync(void) -{ - if (get_hsync_invperiod) - symbol_put(w100fb_get_hsynclen); - get_hsync_invperiod = NULL; -} - -static void corgi_wait_hsync(void) -{ - sharpsl_wait_sync(CORGI_GPIO_HSYNC); -} - -static struct resource corgits_resources[] = { - [0] = { - .start = CORGI_IRQ_GPIO_TP_INT, - .end = CORGI_IRQ_GPIO_TP_INT, - .flags = IORESOURCE_IRQ, +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 corgits_machinfo corgi_ts_machinfo = { - .get_hsync_invperiod = corgi_get_hsync_invperiod, - .put_hsync = corgi_put_hsync, - .wait_hsync = corgi_wait_hsync, +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 corgits_device = { - .name = "corgi-ts", +static struct platform_device corgiled_device = { + .name = "leds-gpio", + .id = -1, .dev = { - .parent = &corgissp_device.dev, - .platform_data = &corgi_ts_machinfo, + .platform_data = &corgi_gpio_leds_info, }, - .id = -1, - .num_resources = ARRAY_SIZE(corgits_resources), - .resource = corgits_resources, }; +/* + * Corgi Audio + */ +static struct platform_device corgi_audio_device = { + .name = "corgi-audio", + .id = -1, +}; /* * MMC/SD Device @@ -405,187 +488,317 @@ static struct platform_device corgits_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; +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, +}; -static int corgi_mci_init(struct device *dev, irq_handler_t corgi_detect_int, void *data) -{ - int err; - /* setup GPIO for PXA25x MMC controller */ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN); - pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT); +/* + * Irda + */ +static struct pxaficp_platform_data corgi_ficp_platform_data = { + .gpio_pwdown = CORGI_GPIO_IR_ON, + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; - corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250); - err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC card detect", data); - if (err) - printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); +/* + * 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, +}; - return err; -} +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MASTER) +static struct pxa2xx_spi_master corgi_spi_info = { + .num_chipselect = 3, +}; -static void corgi_mci_setpower(struct device *dev, unsigned int vdd) +static void corgi_wait_for_hsync(void) { - struct pxamci_platform_data* p_d = dev->platform_data; + while (gpio_get_value(CORGI_GPIO_HSYNC)) + cpu_relax(); - if (( 1 << vdd) & p_d->ocr_mask) - GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR); - else - GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR); + while (!gpio_get_value(CORGI_GPIO_HSYNC)) + cpu_relax(); } -static int corgi_mci_get_ro(struct device *dev) -{ - return GPLR(CORGI_GPIO_nSD_WP) & GPIO_bit(CORGI_GPIO_nSD_WP); -} +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_mci_exit(struct device *dev, void *data) +static void corgi_bl_kick_battery(void) { - free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data); + void (*kick_batt)(void); + + kick_batt = symbol_get(sharpsl_battery_kick); + if (kick_batt) { + kick_batt(); + symbol_put(sharpsl_battery_kick); + } } -static struct pxamci_platform_data corgi_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = corgi_mci_init, - .get_ro = corgi_mci_get_ro, - .setpower = corgi_mci_setpower, - .exit = corgi_mci_exit, +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, +}; -/* - * Irda - */ -static void corgi_irda_transceiver_mode(struct device *dev, int mode) +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) { - if (mode & IR_OFF) - GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON); - else - GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON); - pxa2xx_transceiver_mode(dev, mode); + 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 pxaficp_platform_data corgi_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_OFF, - .transceiver_mode = corgi_irda_transceiver_mode, +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 }; -/* - * 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, +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, - &corgissp_device, &corgifb_device, + &corgi_gpio_keys_device, &corgikbd_device, - &corgibl_device, - &corgits_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 */ - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); - arm_machine_restart('h'); + gpio_set_value(CORGI_GPIO_LED_GREEN, 0); + + pxa_restart(REBOOT_HARD, NULL); } -static void corgi_restart(char mode) +static void corgi_restart(enum reboot_mode mode, const char *cmd) { if (!machine_is_corgi()) /* Green LED on tells the bootloader to reboot */ - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); - arm_machine_restart('h'); + gpio_set_value(CORGI_GPIO_LED_GREEN, 1); + + pxa_restart(REBOOT_HARD, cmd); } static void __init corgi_init(void) { pm_power_off = corgi_poweroff; - arm_pm_restart = corgi_restart; - - /* setup sleep mode values */ - PWER = 0x00000002; - PFER = 0x00000000; - PRER = 0x00000002; - PGSR0 = 0x0158C000; - PGSR1 = 0x00FF0080; - PGSR2 = 0x0001C004; + /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ PCFR |= PCFR_OPDE; - corgi_ssp_set_machinfo(&corgi_ssp_machinfo); + pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); - pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN); + /* 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 machine_desc *desc, - struct tag *tags, char **cmdline, struct meminfo *mi) +static void __init fixup_corgi(struct tag *tags, char **cmdline) { sharpsl_save_param(); - mi->nr_banks=1; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; if (machine_is_corgi()) - mi->bank[0].size = (32*1024*1024); + memblock_add(0xa0000000, SZ_32M); else - mi->bank[0].size = (64*1024*1024); + memblock_add(0xa0000000, SZ_64M); } #ifdef CONFIG_MACH_CORGI MACHINE_START(CORGI, "SHARP Corgi") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_corgi, - .map_io = pxa_map_io, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = corgi_restart, MACHINE_END #endif #ifdef CONFIG_MACH_SHEPHERD MACHINE_START(SHEPHERD, "SHARP Shepherd") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_corgi, - .map_io = pxa_map_io, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = corgi_restart, MACHINE_END #endif #ifdef CONFIG_MACH_HUSKY MACHINE_START(HUSKY, "SHARP Husky") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_corgi, - .map_io = pxa_map_io, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = corgi_restart, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c deleted file mode 100644 index 311baf149b0..00000000000 --- a/arch/arm/mach-pxa/corgi_lcd.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/corgi_lcd.c - * - * Corgi/Spitz LCD Specific Code - * - * Copyright (C) 2005 Richard Purdie - * - * Connectivity: - * Corgi - LCD to ATI Imageon w100 (Wallaby) - * Spitz - LCD to PXA Framebuffer - * - * 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/delay.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/string.h> -#include <mach/akita.h> -#include <mach/corgi.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> -#include <mach/sharpsl.h> -#include <mach/spitz.h> -#include <asm/hardware/scoop.h> -#include <asm/mach/sharpsl_param.h> -#include "generic.h" - -/* Register Addresses */ -#define RESCTL_ADRS 0x00 -#define PHACTRL_ADRS 0x01 -#define DUTYCTRL_ADRS 0x02 -#define POWERREG0_ADRS 0x03 -#define POWERREG1_ADRS 0x04 -#define GPOR3_ADRS 0x05 -#define PICTRL_ADRS 0x06 -#define POLCTRL_ADRS 0x07 - -/* Register Bit Definitions */ -#define RESCTL_QVGA 0x01 -#define RESCTL_VGA 0x00 - -#define POWER1_VW_ON 0x01 /* VW Supply FET ON */ -#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */ -#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */ - -#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */ -#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */ -#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */ - -#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */ -#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */ -#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */ -#define POWER0_COM_ON 0x08 /* COM Power Supply ON */ -#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */ - -#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */ -#define POWER0_COM_OFF 0x00 /* COM Power Supply OFF */ -#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */ - -#define PICTRL_INIT_STATE 0x01 -#define PICTRL_INIOFF 0x02 -#define PICTRL_POWER_DOWN 0x04 -#define PICTRL_COM_SIGNAL_OFF 0x08 -#define PICTRL_DAC_SIGNAL_OFF 0x10 - -#define POLCTRL_SYNC_POL_FALL 0x01 -#define POLCTRL_EN_POL_FALL 0x02 -#define POLCTRL_DATA_POL_FALL 0x04 -#define POLCTRL_SYNC_ACT_H 0x08 -#define POLCTRL_EN_ACT_L 0x10 - -#define POLCTRL_SYNC_POL_RISE 0x00 -#define POLCTRL_EN_POL_RISE 0x00 -#define POLCTRL_DATA_POL_RISE 0x00 -#define POLCTRL_SYNC_ACT_L 0x00 -#define POLCTRL_EN_ACT_H 0x00 - -#define PHACTRL_PHASE_MANUAL 0x01 -#define DEFAULT_PHAD_QVGA (9) -#define DEFAULT_COMADJ (125) - -/* - * This is only a psuedo I2C interface. We can't use the standard kernel - * routines as the interface is write only. We just assume the data is acked... - */ -static void lcdtg_ssp_i2c_send(u8 data) -{ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, data); - udelay(10); -} - -static void lcdtg_i2c_send_bit(u8 data) -{ - lcdtg_ssp_i2c_send(data); - lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK); - lcdtg_ssp_i2c_send(data); -} - -static void lcdtg_i2c_send_start(u8 base) -{ - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT); - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK); - lcdtg_ssp_i2c_send(base); -} - -static void lcdtg_i2c_send_stop(u8 base) -{ - lcdtg_ssp_i2c_send(base); - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK); - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT); -} - -static void lcdtg_i2c_send_byte(u8 base, u8 data) -{ - int i; - for (i = 0; i < 8; i++) { - if (data & 0x80) - lcdtg_i2c_send_bit(base | POWER0_COM_DOUT); - else - lcdtg_i2c_send_bit(base); - data <<= 1; - } -} - -static void lcdtg_i2c_wait_ack(u8 base) -{ - lcdtg_i2c_send_bit(base); -} - -static void lcdtg_set_common_voltage(u8 base_data, u8 data) -{ - /* Set Common Voltage to M62332FP via I2C */ - lcdtg_i2c_send_start(base_data); - lcdtg_i2c_send_byte(base_data, 0x9c); - lcdtg_i2c_wait_ack(base_data); - lcdtg_i2c_send_byte(base_data, 0x00); - lcdtg_i2c_wait_ack(base_data); - lcdtg_i2c_send_byte(base_data, data); - lcdtg_i2c_wait_ack(base_data); - lcdtg_i2c_send_stop(base_data); -} - -/* Set Phase Adjust */ -static void lcdtg_set_phadadj(int mode) -{ - int adj; - switch(mode) { - case 480: - case 640: - /* Setting for VGA */ - adj = sharpsl_param.phadadj; - if (adj < 0) { - adj = PHACTRL_PHASE_MANUAL; - } else { - adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL; - } - break; - case 240: - case 320: - default: - /* Setting for QVGA */ - adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL; - break; - } - - corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj); -} - -static int lcd_inited; - -void corgi_lcdtg_hw_init(int mode) -{ - if (!lcd_inited) { - int comadj; - - /* Initialize Internal Logic & Port */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE - | PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF); - - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF - | POWER0_COM_OFF | POWER0_VCC5_OFF); - - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); - - /* VDD(+8V), SVSS(-4V) ON */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); - mdelay(3); - - /* DAC ON */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON - | POWER0_COM_OFF | POWER0_VCC5_OFF); - - /* INIB = H, INI = L */ - /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF); - - /* Set Common Voltage */ - comadj = sharpsl_param.comadj; - if (comadj < 0) - comadj = DEFAULT_COMADJ; - lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj); - - /* VCC5 ON, DAC ON */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | - POWER0_COM_OFF | POWER0_VCC5_ON); - - /* GVSS(-8V) ON, VDD ON */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); - mdelay(2); - - /* COM SIGNAL ON (PICTL[3] = L) */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE); - - /* COM ON, DAC ON, VCC5_ON */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON - | POWER0_COM_ON | POWER0_VCC5_ON); - - /* VW ON, GVSS ON, VDD ON */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON); - - /* Signals output enable */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, 0); - - /* Set Phase Adjust */ - lcdtg_set_phadadj(mode); - - /* Initialize for Input Signals from ATI */ - corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE - | POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H); - udelay(1000); - - lcd_inited=1; - } else { - lcdtg_set_phadadj(mode); - } - - switch(mode) { - case 480: - case 640: - /* Set Lcd Resolution (VGA) */ - corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA); - break; - case 240: - case 320: - default: - /* Set Lcd Resolution (QVGA) */ - corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA); - break; - } -} - -void corgi_lcdtg_suspend(void) -{ - /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ - mdelay(34); - - /* (1)VW OFF */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); - - /* (2)COM OFF */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF); - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON); - - /* (3)Set Common Voltage Bias 0V */ - lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0); - - /* (4)GVSS OFF */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); - - /* (5)VCC5 OFF */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF); - - /* (6)Set PDWN, INIOFF, DACOFF */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF | - PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF); - - /* (7)DAC OFF */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF); - - /* (8)VDD OFF */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); - - lcd_inited = 0; -} - diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 35bbfccd2df..7a39efc5086 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -14,21 +14,22 @@ #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 <linux/io.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <mach/hardware.h> -#include <asm/hardware/scoop.h> -#include <mach/sharpsl.h> #include <mach/corgi.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> -#include "sharpsl.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 */ @@ -37,88 +38,48 @@ #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) { - pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN); - sharpsl_pm_pxa_init(); + gpio_request_array(ARRAY_AND_SIZE(charger_gpios)); } static void corgi_measure_temp(int on) { - if (on) - GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON); - else - GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_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)) { - GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); - GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); + gpio_set_value(CORGI_GPIO_CHRG_ON, 0); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 1); } else { - GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); - GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); + gpio_set_value(CORGI_GPIO_CHRG_ON, 1); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); } } else { - GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); - GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); + gpio_set_value(CORGI_GPIO_CHRG_ON, 0); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); } } static void corgi_discharge(int on) { - if (on) - GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON); - else - GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON); + gpio_set_value(CORGI_GPIO_DISCHARGE_ON, on); } static void corgi_presuspend(void) { - int i; - unsigned long wakeup_mask; - - /* charging , so CHARGE_ON bit is HIGH during OFF. */ - if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON)) - PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON); - else - PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON); - - if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE)) - PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE); - else - PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE); - - if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN)) - PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN); - else - PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN); - - /* Resume on keyboard power key */ - PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0); - - wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL); - - if (!machine_is_corgi()) - wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW); - - PWER = wakeup_mask | PWER_RTC; - PRER = wakeup_mask; - PFER = wakeup_mask; - - for (i = 0; i <=15; i++) { - if (PRER & PFER & GPIO_bit(i)) { - if (GPLR0 & GPIO_bit(i) ) - PRER &= ~GPIO_bit(i); - else - PFER &= ~GPIO_bit(i); - } - } } static void corgi_postsuspend(void) @@ -133,7 +94,12 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm) { int is_resume = 0; - dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR); + 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)) { @@ -167,20 +133,27 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm) static unsigned long corgi_charger_wakeup(void) { - return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) ); + 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 ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0); + return !gpio_get_value(CORGI_GPIO_AC_IN); case SHARPSL_STATUS_LOCK: - return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock); + return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); case SHARPSL_STATUS_CHRGFULL: - return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull); + return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull); case SHARPSL_STATUS_FATAL: - return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_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: @@ -193,7 +166,7 @@ unsigned long corgipm_read_devdata(int type) static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .init = corgi_charger_init, - .exit = sharpsl_pm_pxa_remove, + .exit = NULL, .gpio_batlock = CORGI_GPIO_BAT_COVER, .gpio_acin = CORGI_GPIO_AC_IN, .gpio_batfull = CORGI_GPIO_CHRG_FULL, @@ -205,8 +178,8 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .read_devdata = corgipm_read_devdata, .charger_wakeup = corgi_charger_wakeup, .should_wakeup = corgi_should_wakeup, -#ifdef CONFIG_BACKLIGHT_CORGI - .backlight_limit = corgibl_limit_intensity, +#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, @@ -215,8 +188,8 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .fatal_acin_volt = SHARPSL_FATAL_ACIN_VOLT, .fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT, .bat_levels = 40, - .bat_levels_noac = spitz_battery_levels_noac, - .bat_levels_acin = spitz_battery_levels_acin, + .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, @@ -225,7 +198,7 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = { static struct platform_device *corgipm_device; -static int __devinit corgipm_init(void) +static int corgipm_init(void) { int ret; diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c deleted file mode 100644 index 8e2f2215c4b..00000000000 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * SSP control code for Sharp Corgi devices - * - * Copyright (c) 2004-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/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <mach/hardware.h> -#include <asm/mach-types.h> - -#include <mach/ssp.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/regs-ssp.h> -#include "sharpsl.h" - -static DEFINE_SPINLOCK(corgi_ssp_lock); -static struct ssp_dev corgi_ssp_dev; -static struct ssp_state corgi_ssp_state; -static struct corgissp_machinfo *ssp_machinfo; - -/* - * There are three devices connected to the SSP interface: - * 1. A touchscreen controller (TI ADS7846 compatible) - * 2. An LCD controller (with some Backlight functionality) - * 3. A battery monitoring IC (Maxim MAX1111) - * - * Each device uses a different speed/mode of communication. - * - * The touchscreen is very sensitive and the most frequently used - * so the port is left configured for this. - * - * Devices are selected using Chip Selects on GPIOs. - */ - -/* - * ADS7846 Routines - */ -unsigned long corgi_ssp_ads7846_putget(ulong data) -{ - unsigned long flag; - u32 ret = 0; - - spin_lock_irqsave(&corgi_ssp_lock, flag); - if (ssp_machinfo->cs_ads7846 >= 0) - GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); - - ssp_write_word(&corgi_ssp_dev,data); - ssp_read_word(&corgi_ssp_dev, &ret); - - if (ssp_machinfo->cs_ads7846 >= 0) - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); - spin_unlock_irqrestore(&corgi_ssp_lock, flag); - - return ret; -} - -/* - * NOTE: These functions should always be called in interrupt context - * and use the _lock and _unlock functions. They are very time sensitive. - */ -void corgi_ssp_ads7846_lock(void) -{ - spin_lock(&corgi_ssp_lock); - if (ssp_machinfo->cs_ads7846 >= 0) - GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); -} - -void corgi_ssp_ads7846_unlock(void) -{ - if (ssp_machinfo->cs_ads7846 >= 0) - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); - spin_unlock(&corgi_ssp_lock); -} - -void corgi_ssp_ads7846_put(ulong data) -{ - ssp_write_word(&corgi_ssp_dev,data); -} - -unsigned long corgi_ssp_ads7846_get(void) -{ - u32 ret = 0; - ssp_read_word(&corgi_ssp_dev, &ret); - return ret; -} - -EXPORT_SYMBOL(corgi_ssp_ads7846_putget); -EXPORT_SYMBOL(corgi_ssp_ads7846_lock); -EXPORT_SYMBOL(corgi_ssp_ads7846_unlock); -EXPORT_SYMBOL(corgi_ssp_ads7846_put); -EXPORT_SYMBOL(corgi_ssp_ads7846_get); - - -/* - * LCD/Backlight Routines - */ -unsigned long corgi_ssp_dac_put(ulong data) -{ - unsigned long flag, sscr1 = SSCR1_SPH; - u32 tmp; - - spin_lock_irqsave(&corgi_ssp_lock, flag); - - if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) - sscr1 = 0; - - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon)); - ssp_enable(&corgi_ssp_dev); - - if (ssp_machinfo->cs_lcdcon >= 0) - GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); - ssp_write_word(&corgi_ssp_dev,data); - /* Read null data back from device to prevent SSP overflow */ - ssp_read_word(&corgi_ssp_dev, &tmp); - if (ssp_machinfo->cs_lcdcon >= 0) - GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); - - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); - ssp_enable(&corgi_ssp_dev); - - spin_unlock_irqrestore(&corgi_ssp_lock, flag); - - return 0; -} - -void corgi_ssp_lcdtg_send(u8 adrs, u8 data) -{ - corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f)); -} - -void corgi_ssp_blduty_set(int duty) -{ - corgi_ssp_lcdtg_send(0x02,duty); -} - -EXPORT_SYMBOL(corgi_ssp_lcdtg_send); -EXPORT_SYMBOL(corgi_ssp_blduty_set); - -/* - * Max1111 Routines - */ -int corgi_ssp_max1111_get(ulong data) -{ - unsigned long flag; - long voltage = 0, voltage1 = 0, voltage2 = 0; - - spin_lock_irqsave(&corgi_ssp_lock, flag); - if (ssp_machinfo->cs_max1111 >= 0) - GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111)); - ssp_enable(&corgi_ssp_dev); - - udelay(1); - - /* TB1/RB1 */ - ssp_write_word(&corgi_ssp_dev,data); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */ - - /* TB12/RB2 */ - ssp_write_word(&corgi_ssp_dev,0); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); - - /* TB13/RB3*/ - ssp_write_word(&corgi_ssp_dev,0); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2); - - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); - ssp_enable(&corgi_ssp_dev); - if (ssp_machinfo->cs_max1111 >= 0) - GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); - spin_unlock_irqrestore(&corgi_ssp_lock, flag); - - if (voltage1 & 0xc0 || voltage2 & 0x3f) - voltage = -1; - else - voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03); - - return voltage; -} - -EXPORT_SYMBOL(corgi_ssp_max1111_get); - -/* - * Support Routines - */ - -void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo) -{ - ssp_machinfo = machinfo; -} - -static int __init corgi_ssp_probe(struct platform_device *dev) -{ - int ret; - - /* Chip Select - Disable All */ - if (ssp_machinfo->cs_lcdcon >= 0) - pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH); - if (ssp_machinfo->cs_max1111 >= 0) - pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH); - if (ssp_machinfo->cs_ads7846 >= 0) - pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH); - - ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); - - if (ret) - printk(KERN_ERR "Unable to register SSP handler!\n"); - else { - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); - ssp_enable(&corgi_ssp_dev); - } - - return ret; -} - -static int corgi_ssp_remove(struct platform_device *dev) -{ - ssp_exit(&corgi_ssp_dev); - return 0; -} - -static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state) -{ - ssp_flush(&corgi_ssp_dev); - ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state); - - return 0; -} - -static int corgi_ssp_resume(struct platform_device *dev) -{ - if (ssp_machinfo->cs_lcdcon >= 0) - GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ - if (ssp_machinfo->cs_max1111 >= 0) - GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ - if (ssp_machinfo->cs_ads7846 >= 0) - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ - ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); - ssp_enable(&corgi_ssp_dev); - - return 0; -} - -static struct platform_driver corgissp_driver = { - .probe = corgi_ssp_probe, - .remove = corgi_ssp_remove, - .suspend = corgi_ssp_suspend, - .resume = corgi_ssp_resume, - .driver = { - .name = "corgi-ssp", - }, -}; - -int __init corgi_ssp_init(void) -{ - return platform_driver_register(&corgissp_driver); -} - -arch_initcall(corgi_ssp_init); diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c deleted file mode 100644 index 6f5569bac13..00000000000 --- a/arch/arm/mach-pxa/cpu-pxa.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/cpu-pxa.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 <mach/hardware.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.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 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; -} pxa_freqs_t; - -/* Define the refresh period in mSec for the SDRAM and the number of rows */ -#define SDRAM_TREF 64 /* standard 64ms SDRAM */ -#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ - -#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 - -/* - * 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}, /* 99, 99, 50, 50 */ - {132700, 132700, 0x123, 1, CCLKCFG}, /* 133, 133, 66, 66 */ - {199100, 99500, 0x141, 0, CCLKCFG}, /* 199, 199, 99, 99 */ - {265400, 132700, 0x143, 1, CCLKCFG}, /* 265, 265, 133, 66 */ - {331800, 165900, 0x145, 1, CCLKCFG}, /* 331, 331, 166, 83 */ - {398100, 99500, 0x161, 0, CCLKCFG}, /* 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}, /* 99, 99, 50, 50 */ - {199100, 99500, 0x221, 0, CCLKCFG}, /* 99, 199, 50, 99 */ - {298500, 99500, 0x321, 0, CCLKCFG}, /* 99, 287, 50, 99 */ - {298600, 99500, 0x1c1, 0, CCLKCFG}, /* 199, 287, 99, 99 */ - {398100, 99500, 0x241, 0, CCLKCFG}, /* 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]; - -/* - * 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)}, - {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1)}, - {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)}, - {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)}, - {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)}, - {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)}, - {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)} -}; - -#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); - -static void find_freq_tables(struct cpufreq_policy *policy, - struct cpufreq_frequency_table **freq_table, - pxa_freqs_t **pxa_freqs) -{ - if (cpu_is_pxa25x()) { - if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { - *pxa_freqs = pxa255_run_freqs; - *freq_table = pxa255_run_freq_table; - } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { - *pxa_freqs = pxa255_turbo_freqs; - *freq_table = pxa255_turbo_freq_table; - } else { - printk("CPU PXA: Unknown policy found. " - "Using CPUFREQ_POLICY_PERFORMANCE\n"); - *pxa_freqs = pxa255_run_freqs; - *freq_table = pxa255_run_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 u32 mdrefr_dri(unsigned int freq) -{ - u32 dri = 0; - - if (cpu_is_pxa25x()) - dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32)); - if (cpu_is_pxa27x()) - dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32; - return dri; -} - -/* 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(policy, &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; - - /* Get the current policy */ - find_freq_tables(policy, &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(KERN_INFO "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)); - - /* - * 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 = MDREFR; - if ((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); - - return 0; -} - -static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) -{ - int i; - unsigned int freq; - - /* try to guess pxa27x cpu */ - if (cpu_is_pxa27x()) - pxa27x_guess_max_freq(); - - /* set default policy and cpuinfo */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - if (cpu_is_pxa25x()) - policy->policy = CPUFREQ_POLICY_PERFORMANCE; - 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; - - /* 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].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()) - cpufreq_frequency_table_cpuinfo(policy, pxa255_run_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/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..fadfff8feae --- /dev/null +++ b/arch/arm/mach-pxa/csb726.c @@ -0,0 +1,283 @@ +/* + * 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 <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_machine = csb726_init, + .init_time = pxa_timer_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 35736fc0863..666094315ab 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -3,20 +3,21 @@ #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 <mach/gpio.h> #include <mach/udc.h> -#include <mach/pxafb.h> -#include <mach/mmc.h> -#include <mach/irda.h> -#include <mach/i2c.h> -#include <mach/mfp-pxa27x.h> -#include <mach/ohci.h> -#include <mach/pxa27x_keypad.h> -#include <mach/pxa2xx_spi.h> -#include <mach/camera.h> +#include <linux/platform_data/usb-pxa3xx-ulpi.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <mach/irqs.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <linux/platform_data/camera-pxa.h> #include <mach/audio.h> -#include <mach/pxa3xx_nand.h> +#include <mach/hardware.h> +#include <linux/platform_data/mtd-nand-pxa3xx.h> #include "devices.h" #include "generic.h" @@ -32,6 +33,19 @@ void __init pxa_register_device(struct platform_device *dev, void *data) 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 = -1, + .resource = &pxa_resource_pmu, + .num_resources = 1, +}; + static struct resource pxamci_resources[] = { [0] = { .start = 0x41100000, @@ -74,7 +88,9 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info) } -static struct pxa2xx_udc_mach_info pxa_udc_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) { @@ -118,6 +134,33 @@ struct platform_device pxa27x_device_udc = { } }; +#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, @@ -144,20 +187,16 @@ struct platform_device pxa_device_fb = { .resource = pxafb_resources, }; -void __init set_pxa_fb_info(struct pxafb_mach_info *info) +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); } -void __init set_pxa_fb_parent(struct device *parent_dev) -{ - pxa_device_fb.dev.parent = parent_dev; -} - static struct resource pxa_resource_ffuart[] = { { - .start = __PREG(FFUART), - .end = __PREG(FFUART) + 35, + .start = 0x40100000, + .end = 0x40100023, .flags = IORESOURCE_MEM, }, { .start = IRQ_FFUART, @@ -166,17 +205,22 @@ static struct resource pxa_resource_ffuart[] = { } }; -struct platform_device pxa_device_ffuart= { +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 = __PREG(BTUART), - .end = __PREG(BTUART) + 35, + .start = 0x40200000, + .end = 0x40200023, .flags = IORESOURCE_MEM, }, { .start = IRQ_BTUART, @@ -192,10 +236,15 @@ struct platform_device pxa_device_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 = __PREG(STUART), - .end = __PREG(STUART) + 35, + .start = 0x40700000, + .end = 0x40700023, .flags = IORESOURCE_MEM, }, { .start = IRQ_STUART, @@ -211,10 +260,15 @@ struct platform_device pxa_device_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 = __PREG(HWUART), - .end = __PREG(HWUART) + 47, + .start = 0x41600000, + .end = 0x4160002F, .flags = IORESOURCE_MEM, }, { .start = IRQ_HWUART, @@ -230,6 +284,14 @@ struct platform_device pxa_device_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, @@ -249,18 +311,32 @@ struct platform_device pxa_device_i2c = { .num_resources = ARRAY_SIZE(pxai2c_resources), }; -static unsigned long pxa27x_i2c_mfp_cfg[] = { - GPIO117_I2C_SCL, - GPIO118_I2C_SDA, -}; - void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) { - if (cpu_is_pxa27x()) - pxa2xx_mfp_config(ARRAY_AND_SIZE(pxa27x_i2c_mfp_cfg)); 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, @@ -280,11 +356,51 @@ struct platform_device pxa_device_i2s = { .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; +static struct resource pxa_ir_resources[] = { + [0] = { + .start = IRQ_STUART, + .end = IRQ_STUART, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_ICP, + .end = IRQ_ICP, + .flags = IORESOURCE_IRQ, + }, +}; + struct platform_device pxa_device_ficp = { .name = "pxa2xx-ir", .id = -1, + .num_resources = ARRAY_SIZE(pxa_ir_resources), + .resource = pxa_ir_resources, .dev = { .dma_mask = &pxaficp_dmamask, .coherent_dma_mask = 0xffffffff, @@ -296,9 +412,52 @@ 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, + .name = "rtc 1Hz", + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .name = "rtc alarm", + .flags = IORESOURCE_IRQ, + }, +}; + 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 sa1100_rtc_resources[] = { + { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .name = "rtc 1Hz", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .name = "rtc alarm", + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device sa1100_device_rtc = { .name = "sa1100-rtc", .id = -1, + .num_resources = ARRAY_SIZE(sa1100_rtc_resources), + .resource = sa1100_rtc_resources, }; static struct resource pxa_ac97_resources[] = { @@ -481,30 +640,35 @@ struct platform_device pxa25x_device_assp = { #endif /* CONFIG_PXA25x */ #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) - -static struct resource pxa27x_resource_keypad[] = { +static struct resource pxa27x_resource_camera[] = { [0] = { - .start = 0x41500000, - .end = 0x4150004c, + .start = 0x50000000, + .end = 0x50000fff, .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_KEYPAD, - .end = IRQ_KEYPAD, + .start = IRQ_CAMERA, + .end = IRQ_CAMERA, .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), +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_keypad_info(struct pxa27x_keypad_platform_data *info) +void __init pxa_set_camera_info(struct pxacamera_platform_data *info) { - pxa_register_device(&pxa27x_device_keypad, info); + pxa_register_device(&pxa27x_device_camera, info); } static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32); @@ -537,6 +701,33 @@ 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) +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); @@ -681,79 +872,9 @@ struct platform_device pxa27x_device_pwm1 = { .resource = pxa27x_resource_pwm1, .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), }; - -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); -} #endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ #ifdef CONFIG_PXA3xx -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), -}; - static struct resource pxa3xx_resources_mci2[] = { [0] = { .start = 0x42000000, @@ -832,6 +953,54 @@ 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) +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, @@ -874,8 +1043,102 @@ 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 */ +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 pxa25x_device_gpio = { +#ifdef CONFIG_CPU_PXA26x + .name = "pxa26x-gpio", +#else + .name = "pxa25x-gpio", +#endif + .id = -1, + .num_resources = ARRAY_SIZE(pxa_resource_gpio), + .resource = pxa_resource_gpio, +}; + +struct platform_device pxa27x_device_gpio = { + .name = "pxa27x-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(pxa_resource_gpio), + .resource = pxa_resource_gpio, +}; + +struct platform_device pxa3xx_device_gpio = { + .name = "pxa3xx-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(pxa_resource_gpio), + .resource = pxa_resource_gpio, +}; + +struct platform_device pxa93x_device_gpio = { + .name = "pxa93x-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) diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 887c738f591..0f3fd0d65b1 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -1,8 +1,10 @@ +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; @@ -11,6 +13,7 @@ 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; @@ -32,5 +35,19 @@ 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; + +extern struct platform_device pxa25x_device_gpio; +extern struct platform_device pxa27x_device_gpio; +extern struct platform_device pxa3xx_device_gpio; +extern struct platform_device pxa93x_device_gpio; void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c deleted file mode 100644 index c0be17e0ab8..00000000000 --- a/arch/arm/mach-pxa/dma.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/dma.c - * - * PXA DMA registration and IRQ dispatching - * - * Author: Nicolas Pitre - * Created: Nov 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. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/errno.h> - -#include <asm/system.h> -#include <asm/irq.h> -#include <mach/hardware.h> -#include <asm/dma.h> - -#include <mach/pxa-regs.h> - -struct dma_channel { - char *name; - pxa_dma_prio prio; - void (*irq_handler)(int, void *); - void *data; -}; - -static struct dma_channel *dma_channels; -static int num_dma_channels; - -int pxa_request_dma (char *name, pxa_dma_prio prio, - void (*irq_handler)(int, void *), - void *data) -{ - unsigned long flags; - int i, found = 0; - - /* basic sanity checks */ - if (!name || !irq_handler) - return -EINVAL; - - local_irq_save(flags); - - do { - /* try grabbing a DMA channel with the requested priority */ - for (i = 0; i < num_dma_channels; i++) { - if ((dma_channels[i].prio == prio) && - !dma_channels[i].name) { - found = 1; - break; - } - } - /* if requested prio group is full, try a hier priority */ - } while (!found && prio--); - - if (found) { - DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; - dma_channels[i].name = name; - dma_channels[i].irq_handler = irq_handler; - dma_channels[i].data = data; - } else { - printk (KERN_WARNING "No more available DMA channels for %s\n", name); - i = -ENODEV; - } - - local_irq_restore(flags); - return i; -} - -void pxa_free_dma (int dma_ch) -{ - unsigned long flags; - - if (!dma_channels[dma_ch].name) { - printk (KERN_CRIT - "%s: trying to free channel %d which is already freed\n", - __func__, dma_ch); - return; - } - - local_irq_save(flags); - DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; - dma_channels[dma_ch].name = NULL; - local_irq_restore(flags); -} - -static irqreturn_t dma_irq_handler(int irq, void *dev_id) -{ - int i, dint = DINT; - - for (i = 0; i < num_dma_channels; i++) { - if (dint & (1 << i)) { - struct dma_channel *channel = &dma_channels[i]; - if (channel->name && channel->irq_handler) { - channel->irq_handler(i, channel->data); - } else { - /* - * IRQ for an unregistered DMA channel: - * let's clear the interrupts and disable it. - */ - printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i); - DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; - } - } - } - return IRQ_HANDLED; -} - -int __init pxa_init_dma(int num_ch) -{ - int i, ret; - - dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL); - if (dma_channels == NULL) - return -ENOMEM; - - ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL); - if (ret) { - printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); - kfree(dma_channels); - return ret; - } - - /* dma channel priorities on pxa2xx processors: - * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH - * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM - * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW - */ - for (i = 0; i < num_ch; i++) - dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); - - num_dma_channels = num_ch; - return 0; -} - -EXPORT_SYMBOL(pxa_request_dma); -EXPORT_SYMBOL(pxa_free_dma); diff --git a/arch/arm/mach-pxa/e400_lcd.c b/arch/arm/mach-pxa/e400_lcd.c deleted file mode 100644 index 263884165f5..00000000000 --- a/arch/arm/mach-pxa/e400_lcd.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * e400_lcd.c - * - * (c) 2005 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. - * - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> - -#include <asm/mach-types.h> -#include <mach/pxa-regs.h> -#include <mach/pxafb.h> - -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, - .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, - .lccr3 = 0, - .pxafb_backlight_power = NULL, -}; - -static int __init e400_lcd_init(void) -{ - if (!machine_is_e400()) - return -ENODEV; - - set_pxa_fb_info(&e400_pxafb_mach_info); - return 0; -} - -module_init(e400_lcd_init); - -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("e400 lcd driver"); -MODULE_LICENSE("GPLv2"); - diff --git a/arch/arm/mach-pxa/e740_lcd.c b/arch/arm/mach-pxa/e740_lcd.c deleted file mode 100644 index 26bd599af17..00000000000 --- a/arch/arm/mach-pxa/e740_lcd.c +++ /dev/null @@ -1,123 +0,0 @@ -/* e740_lcd.c - * - * This file contains the definitions for the LCD timings and functions - * to control the LCD power / frontlighting via the w100fb driver. - * - * (c) 2005 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. - * - */ - -#include <linux/module.h> -#include <linux/device.h> -#include <linux/fb.h> -#include <linux/err.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> - -#include <video/w100fb.h> - -/* -**potential** shutdown routine - to be investigated -devmem2 0x0c010528 w 0xff3fff00 -devmem2 0x0c010190 w 0x7FFF8000 -devmem2 0x0c0101b0 w 0x00FF0000 -devmem2 0x0c01008c w 0x00000000 -devmem2 0x0c010080 w 0x000000bf -devmem2 0x0c010098 w 0x00000015 -devmem2 0x0c010088 w 0x4b000204 -devmem2 0x0c010098 w 0x0000001d -*/ - -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, - }, -}; - -/* ----------------------- device declarations -------------------------- */ - - -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, -}; - -static int e740_lcd_init(void) -{ - int ret; - - if (!machine_is_e740()) - return -ENODEV; - - return platform_device_register(&e740_fb_device); -} - -module_init(e740_lcd_init); - -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("e740 lcd driver"); -MODULE_LICENSE("GPLv2"); diff --git a/arch/arm/mach-pxa/e750_lcd.c b/arch/arm/mach-pxa/e750_lcd.c deleted file mode 100644 index 75edc3b5390..00000000000 --- a/arch/arm/mach-pxa/e750_lcd.c +++ /dev/null @@ -1,109 +0,0 @@ -/* e750_lcd.c - * - * This file contains the definitions for the LCD timings and functions - * to control the LCD power / frontlighting via the w100fb driver. - * - * (c) 2005 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. - * - */ - -#include <linux/module.h> -#include <linux/device.h> -#include <linux/fb.h> -#include <linux/err.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> - -#include <video/w100fb.h> - -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, - }, -}; - -/* ----------------------- device declarations -------------------------- */ - - -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, -}; - -static int e750_lcd_init(void) -{ - if (!machine_is_e750()) - return -ENODEV; - - return platform_device_register(&e750_fb_device); -} - -module_init(e750_lcd_init); - -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("e750 lcd driver"); -MODULE_LICENSE("GPLv2"); diff --git a/arch/arm/mach-pxa/e800_lcd.c b/arch/arm/mach-pxa/e800_lcd.c deleted file mode 100644 index e6aeab0ebc2..00000000000 --- a/arch/arm/mach-pxa/e800_lcd.c +++ /dev/null @@ -1,159 +0,0 @@ -/* e800_lcd.c - * - * This file contains the definitions for the LCD timings and functions - * to control the LCD power / frontlighting via the w100fb driver. - * - * (c) 2005 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. - * - */ - -#include <linux/module.h> -#include <linux/device.h> -#include <linux/fb.h> -#include <linux/err.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> - -#include <video/w100fb.h> - -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 7MHz pclk. */ - .pixclk_divider_rotated = 6, /* we want a 14MHz one (much nicer to look at) */ - .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, - }, -}; - -/* ----------------------- device declarations -------------------------- */ - - -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, -}; - -static int e800_lcd_init(void) -{ - if (!machine_is_e800()) - return -ENODEV; - - return platform_device_register(&e800_fb_device); -} - -module_init(e800_lcd_init); - -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("e800 lcd driver"); -MODULE_LICENSE("GPLv2"); diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 7a0a681a584..6915a9f6b3a 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -11,40 +11,77 @@ #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/platform_data/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/mfp-pxa27x.h> -#include <mach/pxa-regs.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 <mach/pxa27x_keypad.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <linux/platform_data/camera-pxa.h> #include "generic.h" +#include "devices.h" -/* GPIO IRQ usage */ -#define GPIO41_ETHIRQ (41) +/* EM-X270 specific GPIOs */ #define GPIO13_MMC_CD (13) -#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) -#define EM_X270_MMC_CD IRQ_GPIO(GPIO13_MMC_CD) - -/* NAND control GPIOs */ -#define GPIO11_NAND_CS (11) -#define GPIO56_NAND_RB (56) - -static unsigned long em_x270_pin_config[] = { +#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, @@ -72,26 +109,7 @@ static unsigned long em_x270_pin_config[] = { GPIO111_MMC_DAT_3, /* LCD */ - 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, - GPIO74_LCD_FCLK, - GPIO75_LCD_LCLK, - GPIO76_LCD_PCLK, - GPIO77_LCD_BIAS, + GPIOxx_LCD_TFT_16BPP, /* QCI */ GPIO84_CIF_FV, @@ -136,8 +154,8 @@ static unsigned long em_x270_pin_config[] = { GPIO57_SSP1_TXD, /* SSP2 */ - GPIO19_SSP2_SCLK, - GPIO14_SSP2_SFRM, + GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */ + GPIO14_GPIO, GPIO89_SSP2_TXD, GPIO88_SSP2_RXD, @@ -150,7 +168,7 @@ static unsigned long em_x270_pin_config[] = { GPIO18_RDY, /* GPIO */ - GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, + GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */ /* power controls */ GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ @@ -158,13 +176,27 @@ static unsigned long em_x270_pin_config[] = { /* NAND controls */ GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ - GPIO56_GPIO, /* NAND Ready/Busy */ /* interrupts */ - GPIO13_GPIO, /* MMC card detect */ 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] = { @@ -185,7 +217,7 @@ static struct resource em_x270_dm9000_resource[] = { }; static struct dm9000_plat_data em_x270_dm9000_platdata = { - .flags = DM9000_PLATF_32BITONLY, + .flags = DM9000_PLATF_NO_EEPROM, }; static struct platform_device em_x270_dm9000 = { @@ -200,6 +232,7 @@ static struct platform_device em_x270_dm9000 = { static void __init em_x270_init_dm9000(void) { + em_x270_dm9000_platdata.flags |= dm9000_flags; platform_device_register(&em_x270_dm9000); } #else @@ -289,7 +322,7 @@ static int em_x270_nand_device_ready(struct mtd_info *mtd) { dsb(); - return gpio_get_value(GPIO56_NAND_RB); + return gpio_get_value(nand_rb); } static struct mtd_partition em_x270_partition_info[] = { @@ -305,8 +338,6 @@ static struct mtd_partition em_x270_partition_info[] = { }, }; -static const char *em_x270_part_probes[] = { "cmdlinepart", NULL }; - struct platform_nand_data em_x270_nand_platdata = { .chip = { .nr_chips = 1, @@ -314,7 +345,6 @@ struct platform_nand_data em_x270_nand_platdata = { .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, @@ -354,14 +384,14 @@ static void __init em_x270_init_nand(void) gpio_direction_output(GPIO11_NAND_CS, 1); - err = gpio_request(GPIO56_NAND_RB, "NAND R/B"); + 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(GPIO56_NAND_RB); + gpio_direction_input(nand_rb); platform_device_register(&em_x270_nand); } @@ -369,13 +399,118 @@ static void __init em_x270_init_nand(void) 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); + err = regulator_enable(em_x270_usb_ldo); + if (err) + goto err_free_rst_gpio; + + gpio_set_value(usb_hub_reset, 0); + gpio_set_value(usb_hub_reset, 1); + regulator_disable(em_x270_usb_ldo); + err = regulator_enable(em_x270_usb_ldo); + if (err) + goto err_free_rst_gpio; + + gpio_set_value(usb_hub_reset, 0); + gpio_set_value(GPIO9_USB_VBUS_EN, 1); + + return 0; + +err_free_rst_gpio: + gpio_free(usb_hub_reset); +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) { - /* Set the Power Control Polarity Low */ - UHCHR = (UHCHR | UHCHR_PCPL) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); + 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; @@ -383,9 +518,24 @@ static int em_x270_ohci_init(struct device *dev) 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) @@ -398,109 +548,377 @@ static inline void em_x270_init_ohci(void) {} /* 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 = request_irq(EM_X270_MMC_CD, em_x270_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_FALLING, + 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_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC card detect", data); if (err) { - printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n", - __func__, err); - return 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) +static int em_x270_mci_setpower(struct device *dev, unsigned int vdd) { - /* - FIXME: current hardware implementation does not allow to - enable/disable MMC power. This will be fixed in next HW releases, - and we'll need to add implmentation here. - */ - return; + 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); + return regulator_enable(em_x270_sdio_ldo); + } else { + regulator_disable(em_x270_sdio_ldo); + } + return 0; } static void em_x270_mci_exit(struct device *dev, void *data) { - int irq = gpio_to_irq(GPIO13_MMC_CD); - free_irq(irq, 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 = { - .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31, - .init = em_x270_mci_init, - .setpower = em_x270_mci_setpower, - .exit = em_x270_mci_exit, + .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 480x640 */ +/* LCD */ #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) -static struct pxafb_mode_info em_x270_lcd_mode = { - .pixclock = 50000, - .bpp = 16, - .xres = 480, - .yres = 640, - .hsync_len = 8, - .vsync_len = 2, - .left_margin = 8, - .upper_margin = 0, - .right_margin = 24, - .lower_margin = 4, - .cmap_greyscale = 0, +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_mode, - .num_modes = 1, + .modes = em_x270_lcd_modes, + .num_modes = 2, .lcd_conn = LCD_COLOR_TFT_16BPP, }; + static void __init em_x270_init_lcd(void) { - set_pxa_fb_info(&em_x270_lcd); + pxa_set_fb_info(NULL, &em_x270_lcd); } #else static inline void em_x270_init_lcd(void) {} #endif -#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) +#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(NULL); + 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_matrix_keys[] = { +static const 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_keypad_info = { +static struct matrix_keymap_data em_x270_matrix_keymap_data = { + .keymap = em_x270_module_matrix_keys, + .keymap_size = ARRAY_SIZE(em_x270_module_matrix_keys), +}; + +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_matrix_keys, - .matrix_key_map_size = ARRAY_SIZE(em_x270_matrix_keys), + .matrix_keymap_data = &em_x270_matrix_keymap_data, +}; + +static const 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), +}; + +static struct matrix_keymap_data em_x270_exeda_matrix_keymap_data = { + .keymap = em_x270_exeda_matrix_keys, + .keymap_size = ARRAY_SIZE(em_x270_exeda_matrix_keys), +}; + +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_keymap_data = &em_x270_exeda_matrix_keymap_data, }; static void __init em_x270_init_keypad(void) { - pxa_set_keypad_info(&em_x270_keypad_info); + 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) {} @@ -538,27 +956,376 @@ static void __init em_x270_init_gpio_keys(void) static inline void em_x270_init_gpio_keys(void) {} #endif -static void __init em_x270_init(void) +/* 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_name, _supply) \ + static struct regulator_consumer_supply _name##_consumers[] = { \ + REGULATOR_SUPPLY(_supply, _dev_name), \ + } + +REGULATOR_CONSUMER(ldo3, "reg-userspace-consumer.0", "vcc gps"); +REGULATOR_CONSUMER(ldo5, NULL, "vcc cam"); +REGULATOR_CONSUMER(ldo10, "pxa2xx-mci", "vcc sdio"); +REGULATOR_CONSUMER(ldo12, NULL, "vcc usb"); +REGULATOR_CONSUMER(ldo19, "reg-userspace-consumer.1", "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") - .boot_params = 0xa0000100, - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = em_x270_init, + .restart = pxa_restart, +MACHINE_END + +MACHINE_START(EXEDA, "Compulab eXeda") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, .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 index 001a252bd51..cfb864173ce 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -12,15 +12,441 @@ #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 <linux/memblock.h> + +#include <video/w100fb.h> #include <asm/setup.h> #include <asm/mach/arch.h> #include <asm/mach-types.h> -#include <mach/mfp-pxa25x.h> -#include <mach/hardware.h> +#include <mach/pxa25x.h> +#include <mach/eseries-gpio.h> +#include <mach/eseries-irq.h> +#include <mach/audio.h> +#include <linux/platform_data/video-pxafb.h> +#include <mach/udc.h> +#include <linux/platform_data/irda-pxaficp.h> +#include "devices.h" #include "generic.h" +#include "clock.h" + +/* Only e800 has 128MB RAM */ +void __init eseries_fixup(struct tag *tags, char **cmdline) +{ + if (machine_is_e800()) + memblock_add(0xa0000000, SZ_128M); + else + memblock_add(0xa0000000, SZ_64M); +} + +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, + .init_time = pxa_timer_init, + .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, + .init_time = pxa_timer_init, + .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, + .init_time = pxa_timer_init, + .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 */ @@ -35,7 +461,28 @@ static unsigned long e740_pin_config[] __initdata = { GPIO42_BTUART_RXD, GPIO43_BTUART_TXD, GPIO44_BTUART_CTS, - GPIO45_GPIO, /* Used by TMIO for #SUSPEND */ + + /* 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 */ @@ -61,126 +508,475 @@ static unsigned long e740_pin_config[] __initdata = { GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, }; -static unsigned long e400_pin_config[] __initdata = { +/* -------------------- 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, + .init_time = pxa_timer_init, + .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 */ - GPIO12_32KHz, + GPIO11_3_6MHz, /* BTUART */ GPIO42_BTUART_RXD, GPIO43_BTUART_TXD, GPIO44_BTUART_CTS, - GPIO45_GPIO, /* Used by TMIO for #SUSPEND */ + + /* 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, }; -/* Only e800 has 128MB RAM */ -static void __init eseries_fixup(struct machine_desc *desc, - struct tag *tags, char **cmdline, struct meminfo *mi) -{ - mi->nr_banks=1; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - if (machine_is_e800()) - mi->bank[0].size = (128*1024*1024); - else - mi->bank[0].size = (64*1024*1024); -} +/* ----------------- e750 tc6393xb parameters ------------------ */ -static void __init e740_init(void) -{ - pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config)); -} +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 void __init e400_init(void) -{ - pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config)); -} +static struct platform_device e750_tc6393xb_device = { + .name = "tc6393xb", + .id = -1, + .dev = { + .platform_data = &e750_tc6393xb_info, + }, + .num_resources = 2, + .resource = eseries_tmio_resources, +}; -/* e-series machine definitions */ +static struct platform_device e750_audio_device = { + .name = "e750-audio", + .id = -1, +}; -#ifdef CONFIG_MACH_E330 -MACHINE_START(E330, "Toshiba e330") - /* Maintainer: Ian Molton (spyro@f2s.com) */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, - .init_irq = pxa25x_init_irq, - .fixup = eseries_fixup, - .timer = &pxa_timer, -MACHINE_END -#endif +/* ------------------------------------------------------------- */ -#ifdef CONFIG_MACH_E350 -MACHINE_START(E350, "Toshiba e350") - /* Maintainer: Ian Molton (spyro@f2s.com) */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, - .init_irq = pxa25x_init_irq, - .fixup = eseries_fixup, - .timer = &pxa_timer, -MACHINE_END -#endif +static struct platform_device *e750_devices[] __initdata = { + &e750_fb_device, + &e750_tc6393xb_device, + &e7xx_gpio_vbus, + &e750_audio_device, +}; -#ifdef CONFIG_MACH_E740 -MACHINE_START(E740, "Toshiba e740") - /* Maintainer: Ian Molton (spyro@f2s.com) */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, - .init_irq = pxa25x_init_irq, - .fixup = eseries_fixup, - .init_machine = e740_init, - .timer = &pxa_timer, -MACHINE_END -#endif +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); +} -#ifdef CONFIG_MACH_E750 MACHINE_START(E750, "Toshiba e750") /* Maintainer: Ian Molton (spyro@f2s.com) */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, - .init_irq = pxa25x_init_irq, - .fixup = eseries_fixup, - .timer = &pxa_timer, -MACHINE_END -#endif - -#ifdef CONFIG_MACH_E400 -MACHINE_START(E400, "Toshiba e400") - /* Maintainer: Ian Molton (spyro@f2s.com) */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .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, + .init_machine = e750_init, + .init_time = pxa_timer_init, + .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) */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .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, - .timer = &pxa_timer, + .init_machine = e800_init, + .init_time = pxa_timer_init, + .restart = pxa_restart, MACHINE_END #endif - diff --git a/arch/arm/mach-pxa/eseries_udc.c b/arch/arm/mach-pxa/eseries_udc.c deleted file mode 100644 index d622c04c0d4..00000000000 --- a/arch/arm/mach-pxa/eseries_udc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * UDC functions for the Toshiba e-series PDAs - * - * Copyright (c) Ian Molton 2003 - * - * 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/device.h> - -#include <mach/udc.h> -#include <mach/eseries-gpio.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> -#include <asm/mach/arch.h> -#include <asm/mach-types.h> -#include <asm/mach/map.h> -#include <asm/domain.h> - -/* local PXA generic code */ -#include "generic.h" - -static struct pxa2xx_udc_mach_info e7xx_udc_mach_info = { - .gpio_vbus = GPIO_E7XX_USB_DISC, - .gpio_pullup = GPIO_E7XX_USB_PULLUP, - .gpio_pullup_inverted = 1 -}; - -static struct pxa2xx_udc_mach_info e800_udc_mach_info = { - .gpio_vbus = GPIO_E800_USB_DISC, - .gpio_pullup = GPIO_E800_USB_PULLUP, - .gpio_pullup_inverted = 1 -}; - -static int __init eseries_udc_init(void) -{ - if (machine_is_e330() || machine_is_e350() || - machine_is_e740() || machine_is_e750() || - machine_is_e400()) - pxa_set_udc_info(&e7xx_udc_mach_info); - else if (machine_is_e800()) - pxa_set_udc_info(&e800_udc_mach_info); - - return 0; -} - -module_init(eseries_udc_init); - -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("eseries UDC support"); -MODULE_LICENSE("GPLv2"); diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index cc3d850cc0b..ab93441e596 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -16,26 +16,45 @@ #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 <asm/setup.h> -#include <mach/pxafb.h> -#include <mach/ohci.h> -#include <mach/i2c.h> +#include <media/soc_camera.h> -#include <mach/mfp-pxa27x.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> +#include <asm/setup.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <mach/pxa27x.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/hardware.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <linux/platform_data/camera-pxa.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, + .enable_gpio = -1, }; static struct platform_device ezx_backlight_device = { @@ -87,7 +106,7 @@ static struct pxafb_mach_info ezx_fb_info_2 = { .lcd_conn = LCD_COLOR_TFT_18BPP, }; -static struct platform_device *devices[] __initdata = { +static struct platform_device *ezx_devices[] __initdata = { &ezx_backlight_device, }; @@ -101,120 +120,1149 @@ static unsigned long ezx_pin_config[] __initdata = { GPIO44_BTUART_CTS, GPIO45_BTUART_RTS, - /* STUART */ - GPIO46_STUART_RXD, - GPIO47_STUART_TXD, + /* 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 const 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 matrix_keymap_data a780_matrix_keymap_data = { + .keymap = a780_key_map, + .keymap_size = ARRAY_SIZE(a780_key_map), +}; + +static struct pxa27x_keypad_platform_data a780_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 5, + .matrix_keymap_data = &a780_matrix_keymap_data, + + .direct_key_map = { KEY_CAMERA }, + .direct_key_num = 1, + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_A780 */ + +#ifdef CONFIG_MACH_EZX_E680 +static const 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 matrix_keymap_data e680_matrix_keymap_data = { + .keymap = e680_key_map, + .keymap_size = ARRAY_SIZE(e680_key_map), +}; + +static struct pxa27x_keypad_platform_data e680_keypad_platform_data = { + .matrix_key_rows = 3, + .matrix_key_cols = 4, + .matrix_keymap_data = &e680_matrix_keymap_data, + + .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 const 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 matrix_keymap_data a1200_matrix_keymap_data = { + .keymap = a1200_key_map, + .keymap_size = ARRAY_SIZE(a1200_key_map), +}; + +static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_keymap_data = &a1200_matrix_keymap_data, + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_A1200 */ + +#ifdef CONFIG_MACH_EZX_E6 +static const 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 matrix_keymap_data e6_keymap_data = { + .keymap = e6_key_map, + .keymap_size = ARRAY_SIZE(e6_key_map), +}; + +static struct pxa27x_keypad_platform_data e6_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_keymap_data = &e6_keymap_data, + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_E6 */ + +#ifdef CONFIG_MACH_EZX_A910 +static const 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 matrix_keymap_data a910_matrix_keymap_data = { + .keymap = a910_key_map, + .keymap_size = ARRAY_SIZE(a910_key_map), +}; + +static struct pxa27x_keypad_platform_data a910_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_keymap_data = &a910_matrix_keymap_data, + + .debounce_interval = 30, +}; +#endif /* CONFIG_MACH_EZX_A910 */ + +#ifdef CONFIG_MACH_EZX_E2 +static const 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 matrix_keymap_data e2_matrix_keymap_data = { + .keymap = e2_key_map, + .keymap_size = ARRAY_SIZE(e2_key_map), +}; + +static struct pxa27x_keypad_platform_data e2_keypad_platform_data = { + .matrix_key_rows = 5, + .matrix_key_cols = 6, + .matrix_keymap_data = &e2_matrix_keymap_data, + + .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, + }, +}; - /* For A780 support (connected with Neptune GSM chip) */ - GPIO30_USB_P3_2, /* ICL_TXENB */ - GPIO31_USB_P3_6, /* ICL_VPOUT */ - GPIO90_USB_P3_5, /* ICL_VPIN */ - GPIO91_USB_P3_1, /* ICL_XRXD */ - GPIO56_USB_P3_4, /* ICL_VMOUT */ - GPIO113_USB_P3_3, /* /ICL_VMIN */ +static struct gpio_keys_platform_data a780_gpio_keys_platform_data = { + .buttons = a780_buttons, + .nbuttons = ARRAY_SIZE(a780_buttons), }; -static void __init ezx_init(void) +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) { - pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); - pxa_set_i2c_info(NULL); - if (machine_is_ezx_a780() || machine_is_ezx_e680()) - set_pxa_fb_info(&ezx_fb_info_1); - else - set_pxa_fb_info(&ezx_fb_info_2); + 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); - platform_add_devices(devices, ARRAY_SIZE(devices)); + return 0; + +fail_gpio_cam_rst: + gpio_free(GPIO50_nCAM_EN); +fail: + return err; } -static void __init ezx_fixup(struct machine_desc *desc, struct tag *tags, - char **cmdline, struct meminfo *mi) +static int a780_camera_power(struct device *dev, int on) { - /* We have two ram chips. First one with 32MB at 0xA0000000 and a second - * 16MB one at 0xAC000000 - */ - mi->nr_banks = 2; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (32*1024*1024); - mi->bank[1].start = 0xac000000; - mi->bank[1].node = 1; - mi->bank[1].size = (16*1024*1024); + 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)); } -#ifdef CONFIG_MACH_EZX_A780 MACHINE_START(EZX_A780, "Motorola EZX A780") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = ezx_fixup, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = &ezx_init, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = ezx_fixup, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = &ezx_init, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = ezx_fixup, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = &ezx_init, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = ezx_fixup, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = &ezx_init, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = ezx_fixup, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = &ezx_init, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = ezx_fixup, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = &ezx_init, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .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 index ceaed007636..42254175fcf 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -16,17 +16,18 @@ * 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/pgtable.h> #include <asm/mach/map.h> +#include <asm/mach-types.h> -#include <mach/pxa-regs.h> #include <mach/reset.h> +#include <mach/smemc.h> +#include <mach/pxa3xx-regs.h> #include "generic.h" @@ -34,10 +35,26 @@ 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; - if (cpu_is_pxa3xx()) - pxa3xx_clear_reset_status(mask); + return clock_tick_rate; } +EXPORT_SYMBOL(get_clock_tick_rate); /* * Get the clock frequency as reflected by CCCR and the turbo flag. @@ -46,63 +63,26 @@ void clear_reset_status(unsigned int mask) */ unsigned int get_clk_frequency_khz(int info) { - if (cpu_is_pxa21x() || cpu_is_pxa25x()) + if (cpu_is_pxa25x()) return pxa25x_get_clk_frequency_khz(info); else if (cpu_is_pxa27x()) return pxa27x_get_clk_frequency_khz(info); - else - return pxa3xx_get_clk_frequency_khz(info); + return 0; } EXPORT_SYMBOL(get_clk_frequency_khz); /* - * Return the current memory clock frequency in units of 10kHz - */ -unsigned int get_memclk_frequency_10khz(void) -{ - if (cpu_is_pxa21x() || cpu_is_pxa25x()) - return pxa25x_get_memclk_frequency_10khz(); - else if (cpu_is_pxa27x()) - return pxa27x_get_memclk_frequency_10khz(); - else - return pxa3xx_get_memclk_frequency_10khz(); -} -EXPORT_SYMBOL(get_memclk_frequency_10khz); - -/* * Intel PXA2xx internal register mapping. * - * Note 1: not all PXA2xx variants implement all those addresses. - * - * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table - * and cache flush area. + * Note: virtual 0xfffe0000-0xffffffff is reserved for the vector table + * and cache flush area. */ -static struct map_desc standard_io_desc[] __initdata = { +static struct map_desc common_io_desc[] __initdata = { { /* Devs */ .virtual = 0xf2000000, .pfn = __phys_to_pfn(0x40000000), .length = 0x02000000, .type = MT_DEVICE - }, { /* Mem Ctl */ - .virtual = 0xf6000000, - .pfn = __phys_to_pfn(0x48000000), - .length = 0x00200000, - .type = MT_DEVICE - }, { /* USB host */ - .virtual = 0xf8000000, - .pfn = __phys_to_pfn(0x4c000000), - .length = 0x00100000, - .type = MT_DEVICE - }, { /* Camera */ - .virtual = 0xfa000000, - .pfn = __phys_to_pfn(0x50000000), - .length = 0x00100000, - .type = MT_DEVICE - }, { /* IMem ctl */ - .virtual = 0xfe000000, - .pfn = __phys_to_pfn(0x58000000), - .length = 0x00100000, - .type = MT_DEVICE }, { /* UNCACHED_PHYS_0 */ .virtual = 0xff000000, .pfn = __phys_to_pfn(0x00000000), @@ -113,6 +93,5 @@ static struct map_desc standard_io_desc[] __initdata = { void __init pxa_map_io(void) { - iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); - get_clk_frequency_khz(1); + iotable_init(ARRAY_AND_SIZE(common_io_desc)); } diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 041c048320e..8963984d1f4 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -9,42 +9,32 @@ * published by the Free Software Foundation. */ -typedef int (*set_wake_t)(unsigned int, unsigned int); +#include <linux/reboot.h> -struct sys_timer; +struct irq_data; + +extern void pxa_timer_init(void); -extern struct sys_timer pxa_timer; -extern void __init pxa_init_irq(int irq_nr, set_wake_t fn); -extern void __init pxa_init_gpio(int gpio_nr, set_wake_t fn); -extern void __init pxa25x_init_irq(void); -extern void __init pxa27x_init_irq(void); -extern void __init pxa3xx_init_irq(void); extern void __init pxa_map_io(void); extern unsigned int get_clk_frequency_khz(int info); -extern int pxa_last_gpio; #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ - mi->bank[__nr].size = (__size), \ - mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) + 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); -extern unsigned pxa25x_get_memclk_frequency_10khz(void); #else #define pxa25x_get_clk_frequency_khz(x) (0) -#define pxa25x_get_memclk_frequency_10khz() (0) #endif #ifdef CONFIG_PXA27x extern unsigned pxa27x_get_clk_frequency_khz(int); -extern unsigned pxa27x_get_memclk_frequency_10khz(void); #else #define pxa27x_get_clk_frequency_khz(x) (0) -#define pxa27x_get_memclk_frequency_10khz() (0) #endif #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) @@ -55,14 +45,17 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {} #ifdef CONFIG_PXA3xx extern unsigned pxa3xx_get_clk_frequency_khz(int); -extern unsigned pxa3xx_get_memclk_frequency_10khz(void); -extern void pxa3xx_clear_reset_status(unsigned int); #else #define pxa3xx_get_clk_frequency_khz(x) (0) -#define pxa3xx_get_memclk_frequency_10khz() (0) -static inline void pxa3xx_clear_reset_status(unsigned int mask) {} #endif -extern struct sysdev_class pxa_irq_sysclass; -extern struct sysdev_class pxa_gpio_sysclass; -extern struct sysdev_class pxa3xx_mfp_sysclass; +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(enum reboot_mode, const char *); diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c deleted file mode 100644 index 07acc1b2385..00000000000 --- a/arch/arm/mach-pxa/gpio.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/gpio.c - * - * Generic PXA GPIO handling - * - * 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. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/irq.h> -#include <linux/sysdev.h> - -#include <asm/gpio.h> -#include <mach/hardware.h> -#include <asm/io.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> - -#include "generic.h" - - -struct pxa_gpio_chip { - struct gpio_chip chip; - void __iomem *regbase; -}; - -int pxa_last_gpio; - -/* - * Configure pins for GPIO or other functions - */ -int pxa_gpio_mode(int gpio_mode) -{ - unsigned long flags; - int gpio = gpio_mode & GPIO_MD_MASK_NR; - int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; - int gafr; - - if (gpio > pxa_last_gpio) - return -EINVAL; - - local_irq_save(flags); - if (gpio_mode & GPIO_DFLT_LOW) - GPCR(gpio) = GPIO_bit(gpio); - else if (gpio_mode & GPIO_DFLT_HIGH) - GPSR(gpio) = GPIO_bit(gpio); - if (gpio_mode & GPIO_MD_MASK_DIR) - GPDR(gpio) |= GPIO_bit(gpio); - else - GPDR(gpio) &= ~GPIO_bit(gpio); - gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); - GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); - local_irq_restore(flags); - - return 0; -} -EXPORT_SYMBOL(pxa_gpio_mode); - -static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - unsigned long flags; - u32 mask = 1 << offset; - u32 value; - struct pxa_gpio_chip *pxa; - void __iomem *gpdr; - - pxa = container_of(chip, struct pxa_gpio_chip, chip); - gpdr = pxa->regbase + GPDR_OFFSET; - local_irq_save(flags); - value = __raw_readl(gpdr); - value &= ~mask; - __raw_writel(value, gpdr); - local_irq_restore(flags); - - return 0; -} - -static int pxa_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - unsigned long flags; - u32 mask = 1 << offset; - u32 tmp; - struct pxa_gpio_chip *pxa; - void __iomem *gpdr; - - pxa = container_of(chip, struct pxa_gpio_chip, chip); - __raw_writel(mask, - pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET)); - gpdr = pxa->regbase + GPDR_OFFSET; - local_irq_save(flags); - tmp = __raw_readl(gpdr); - tmp |= mask; - __raw_writel(tmp, gpdr); - local_irq_restore(flags); - - return 0; -} - -/* - * Return GPIO level - */ -static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - u32 mask = 1 << offset; - struct pxa_gpio_chip *pxa; - - pxa = container_of(chip, struct pxa_gpio_chip, chip); - return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask; -} - -/* - * Set output GPIO level - */ -static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - u32 mask = 1 << offset; - struct pxa_gpio_chip *pxa; - - pxa = container_of(chip, struct pxa_gpio_chip, chip); - - if (value) - __raw_writel(mask, pxa->regbase + GPSR_OFFSET); - else - __raw_writel(mask, pxa->regbase + GPCR_OFFSET); -} - -#define GPIO_CHIP(_n) \ - [_n] = { \ - .regbase = GPIO##_n##_BASE, \ - .chip = { \ - .label = "gpio-" #_n, \ - .direction_input = pxa_gpio_direction_input, \ - .direction_output = pxa_gpio_direction_output, \ - .get = pxa_gpio_get, \ - .set = pxa_gpio_set, \ - .base = (_n) * 32, \ - .ngpio = 32, \ - }, \ - } - -static struct pxa_gpio_chip pxa_gpio_chip[] = { - GPIO_CHIP(0), - GPIO_CHIP(1), - GPIO_CHIP(2), -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) - GPIO_CHIP(3), -#endif -}; - -/* - * PXA GPIO edge detection for IRQs: - * IRQs are generated on Falling-Edge, Rising-Edge, or both. - * Use this instead of directly setting GRER/GFER. - */ - -static unsigned long GPIO_IRQ_rising_edge[4]; -static unsigned long GPIO_IRQ_falling_edge[4]; -static unsigned long GPIO_IRQ_mask[4]; - -/* - * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate - * function of a GPIO, and GPDRx cannot be altered once configured. It - * is attributed as "occupied" here (I know this terminology isn't - * accurate, you are welcome to propose a better one :-) - */ -static int __gpio_is_occupied(unsigned gpio) -{ - if (cpu_is_pxa25x() || cpu_is_pxa27x()) - return GAFR(gpio) & (0x3 << (((gpio) & 0xf) * 2)); - else - return 0; -} - -static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) -{ - int gpio, idx; - - gpio = IRQ_TO_GPIO(irq); - idx = gpio >> 5; - - if (type == IRQ_TYPE_PROBE) { - /* Don't mess with enabled GPIOs using preconfigured edges or - * GPIOs set to alternate function or to output during probe - */ - if ((GPIO_IRQ_rising_edge[idx] | - GPIO_IRQ_falling_edge[idx] | - GPDR(gpio)) & GPIO_bit(gpio)) - return 0; - - if (__gpio_is_occupied(gpio)) - return 0; - - type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; - } - - GPDR(gpio) &= ~GPIO_bit(gpio); - - if (type & IRQ_TYPE_EDGE_RISING) - __set_bit(gpio, GPIO_IRQ_rising_edge); - else - __clear_bit(gpio, GPIO_IRQ_rising_edge); - - if (type & IRQ_TYPE_EDGE_FALLING) - __set_bit(gpio, GPIO_IRQ_falling_edge); - else - __clear_bit(gpio, GPIO_IRQ_falling_edge); - - GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx]; - GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx]; - - pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, irq, gpio, - ((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""), - ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : "")); - return 0; -} - -/* - * GPIO IRQs must be acknowledged. This is for GPIO 0 and 1. - */ - -static void pxa_ack_low_gpio(unsigned int irq) -{ - GEDR0 = (1 << (irq - IRQ_GPIO0)); -} - -static void pxa_mask_low_gpio(unsigned int irq) -{ - ICMR &= ~(1 << (irq - PXA_IRQ(0))); -} - -static void pxa_unmask_low_gpio(unsigned int irq) -{ - ICMR |= 1 << (irq - PXA_IRQ(0)); -} - -static struct irq_chip pxa_low_gpio_chip = { - .name = "GPIO-l", - .ack = pxa_ack_low_gpio, - .mask = pxa_mask_low_gpio, - .unmask = pxa_unmask_low_gpio, - .set_type = pxa_gpio_irq_type, -}; - -/* - * Demux handler for GPIO>=2 edge detect interrupts - */ - -#define GEDR_BITS (sizeof(gedr) * BITS_PER_BYTE) - -static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) -{ - int loop, bit, n; - unsigned long gedr[4]; - - do { - gedr[0] = GEDR0 & GPIO_IRQ_mask[0] & ~3; - gedr[1] = GEDR1 & GPIO_IRQ_mask[1]; - gedr[2] = GEDR2 & GPIO_IRQ_mask[2]; - gedr[3] = GEDR3 & GPIO_IRQ_mask[3]; - - GEDR0 = gedr[0]; GEDR1 = gedr[1]; - GEDR2 = gedr[2]; GEDR3 = gedr[3]; - - loop = 0; - bit = find_first_bit(gedr, GEDR_BITS); - while (bit < GEDR_BITS) { - loop = 1; - - n = PXA_GPIO_IRQ_BASE + bit; - desc_handle_irq(n, irq_desc + n); - - bit = find_next_bit(gedr, GEDR_BITS, bit + 1); - } - } while (loop); -} - -static void pxa_ack_muxed_gpio(unsigned int irq) -{ - int gpio = irq - IRQ_GPIO(2) + 2; - GEDR(gpio) = GPIO_bit(gpio); -} - -static void pxa_mask_muxed_gpio(unsigned int irq) -{ - int gpio = irq - IRQ_GPIO(2) + 2; - __clear_bit(gpio, GPIO_IRQ_mask); - GRER(gpio) &= ~GPIO_bit(gpio); - GFER(gpio) &= ~GPIO_bit(gpio); -} - -static void pxa_unmask_muxed_gpio(unsigned int irq) -{ - int gpio = irq - IRQ_GPIO(2) + 2; - int idx = gpio >> 5; - __set_bit(gpio, GPIO_IRQ_mask); - GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx]; - GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx]; -} - -static struct irq_chip pxa_muxed_gpio_chip = { - .name = "GPIO", - .ack = pxa_ack_muxed_gpio, - .mask = pxa_mask_muxed_gpio, - .unmask = pxa_unmask_muxed_gpio, - .set_type = pxa_gpio_irq_type, -}; - -void __init pxa_init_gpio(int gpio_nr, set_wake_t fn) -{ - int irq, i, gpio; - - pxa_last_gpio = gpio_nr - 1; - - /* clear all GPIO edge detects */ - for (i = 0; i < gpio_nr; i += 32) { - GFER(i) = 0; - GRER(i) = 0; - GEDR(i) = GEDR(i); - } - - /* GPIO 0 and 1 must have their mask bit always set */ - GPIO_IRQ_mask[0] = 3; - - for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { - set_irq_chip(irq, &pxa_low_gpio_chip); - set_irq_handler(irq, handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - for (irq = IRQ_GPIO(2); irq < IRQ_GPIO(gpio_nr); irq++) { - set_irq_chip(irq, &pxa_muxed_gpio_chip); - set_irq_handler(irq, handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - /* Install handler for GPIO>=2 edge detect interrupts */ - set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); - - pxa_low_gpio_chip.set_wake = fn; - pxa_muxed_gpio_chip.set_wake = fn; - - /* add a GPIO chip for each register bank. - * the last PXA25x register only contains 21 GPIOs - */ - for (gpio = 0, i = 0; gpio < gpio_nr; gpio += 32, i++) { - if (gpio + 32 > gpio_nr) - pxa_gpio_chip[i].chip.ngpio = gpio_nr - gpio; - gpiochip_add(&pxa_gpio_chip[i].chip); - } -} - -#ifdef CONFIG_PM - -static unsigned long saved_gplr[4]; -static unsigned long saved_gpdr[4]; -static unsigned long saved_grer[4]; -static unsigned long saved_gfer[4]; - -static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state) -{ - int i, gpio; - - for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { - saved_gplr[i] = GPLR(gpio); - saved_gpdr[i] = GPDR(gpio); - saved_grer[i] = GRER(gpio); - saved_gfer[i] = GFER(gpio); - - /* Clear GPIO transition detect bits */ - GEDR(gpio) = GEDR(gpio); - } - return 0; -} - -static int pxa_gpio_resume(struct sys_device *dev) -{ - int i, gpio; - - for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { - /* restore level with set/clear */ - GPSR(gpio) = saved_gplr[i]; - GPCR(gpio) = ~saved_gplr[i]; - - GRER(gpio) = saved_grer[i]; - GFER(gpio) = saved_gfer[i]; - GPDR(gpio) = saved_gpdr[i]; - } - return 0; -} -#else -#define pxa_gpio_suspend NULL -#define pxa_gpio_resume NULL -#endif - -struct sysdev_class pxa_gpio_sysclass = { - .name = "gpio", - .suspend = pxa_gpio_suspend, - .resume = pxa_gpio_resume, -}; - -static int __init pxa_gpio_init(void) -{ - return sysdev_class_register(&pxa_gpio_sysclass); -} - -core_initcall(pxa_gpio_init); diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index c0092472fa5..00b92dad7b8 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -20,8 +20,13 @@ #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> @@ -34,14 +39,12 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> #include <asm/mach/flash.h> -#include <mach/mmc.h> + +#include <mach/pxa25x.h> +#include <linux/platform_data/mmc-pxamci.h> #include <mach/udc.h> #include <mach/gumstix.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> - #include "generic.h" static struct resource flash_resource = { @@ -85,21 +88,11 @@ static struct platform_device *devices[] __initdata = { }; #ifdef CONFIG_MMC_PXA -static struct pxamci_platform_data gumstix_mci_platform_data; - -static int gumstix_mci_init(struct device *dev, irq_handler_t detect_int, - void *data) -{ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO53_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - - return 0; -} - static struct pxamci_platform_data gumstix_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = gumstix_mci_init, + .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) @@ -109,40 +102,143 @@ static void __init gumstix_mmc_init(void) #else static void __init gumstix_mmc_init(void) { - printk(KERN_INFO "Gumstix mmc disabled\n"); + pr_debug("Gumstix mmc disabled\n"); } #endif -#ifdef CONFIG_USB_GADGET_PXA2XX -static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = { +#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) { - pxa_set_udc_info(&gumstix_udc_info); + platform_device_register(&gumstix_gpio_vbus); } #else static void gumstix_udc_init(void) { - printk(KERN_INFO "Gumstix udc is disabled\n"); + 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") - .phys_io = 0x40000000, - .boot_params = 0xa0000100, /* match u-boot bi_boot_params */ - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = pxa_map_io, + .atag_offset = 0x100, /* match u-boot bi_boot_params */ + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, .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..875ec335149 --- /dev/null +++ b/arch/arm/mach-pxa/h5000.c @@ -0,0 +1,214 @@ +/* + * 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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, + .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..7a8d749a07b --- /dev/null +++ b/arch/arm/mach-pxa/himalaya.c @@ -0,0 +1,169 @@ +/* + * 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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_machine = himalaya_init, + .init_time = pxa_timer_init, + .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..c66ad4edc5e --- /dev/null +++ b/arch/arm/mach-pxa/hx4700.c @@ -0,0 +1,907 @@ +/* + * 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/input/navpoint.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.h> +#include <linux/pwm_backlight.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/gpio-regulator.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 <linux/platform_data/irda-pxaficp.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_LPM_LOW, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS_LPM_LOW, + + /* STUART (IRDA) */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* 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_IN, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* SSP 2 (TSC2046) */ + GPIO19_SSP2_SCLK, + GPIO86_SSP2_RXD, + GPIO87_SSP2_TXD, + GPIO88_GPIO | MFP_LPM_DRIVE_HIGH, /* TSC2046_CS */ + + /* BQ24022 Regulator */ + GPIO72_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_nCHARGE_EN */ + GPIO96_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_ISET2 */ + + /* HX4700 specific input GPIOs */ + GPIO12_GPIO | WAKEUP_ON_EDGE_RISE, /* ASIC3_IRQ */ + GPIO13_GPIO, /* W3220_IRQ */ + GPIO14_GPIO, /* nWLAN_IRQ */ + + /* HX4700 specific output GPIOs */ + GPIO61_GPIO | MFP_LPM_DRIVE_HIGH, /* W3220_nRESET */ + GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* ASIC3_nRESET */ + GPIO81_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_GP_nRESET */ + GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_HW_nRESET */ + GPIO102_GPIO | MFP_LPM_DRIVE_LOW, /* SYNAPTICS_POWER_ON */ + + 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, +}; + +/* + * Synaptics NavPoint connected to SSP1 + */ + +static struct navpoint_platform_data navpoint_platform_data = { + .port = 1, + .gpio = GPIO102_HX4700_SYNAPTICS_POWER_ON, +}; + +static struct platform_device navpoint = { + .name = "navpoint", + .id = -1, + .dev = { + .platform_data = &navpoint_platform_data, + }, +}; + +/* + * 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_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_GPIOD4_CF_nCD, + ASIC3_GPIOD11_nCIOIS16, + ASIC3_GPIOD12_nCWAIT, + ASIC3_GPIOD15_nPIOW, +}; + +static struct asic3_led asic3_leds[ASIC3_NUM_LEDS] = { + [0] = { + .name = "hx4700:amber", + .default_trigger = "ds2760-battery.0-charging-blink-full-solid", + }, + [1] = { + .name = "hx4700:green", + .default_trigger = "unused", + }, + [2] = { + .name = "hx4700:blue", + .default_trigger = "hx4700-radio", + }, +}; + +static struct resource asic3_resources[] = { + /* GPIO part */ + [0] = DEFINE_RES_MEM(ASIC3_PHYS, ASIC3_MAP_SIZE_16BIT), + [1] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ)), + /* SD part */ + [2] = DEFINE_RES_MEM(ASIC3_SD_PHYS, ASIC3_MAP_SIZE_16BIT), + [3] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_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, + .clock_rate = 4000000, + .leds = asic3_leds, +}; + +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] = DEFINE_RES_MEM(PXA_CS5_PHYS, 0x4), +}; + +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] = DEFINE_RES_MEM(ATI_W3220_PHYS, SZ_16M), +}; + +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, /* Superseded by pwm_lookup */ + .max_brightness = 200, + .dft_brightness = 100, + .pwm_period_ns = 30923, + .enable_gpio = -1, +}; + +static struct platform_device backlight = { + .name = "pwm-backlight", + .id = -1, + .dev = { + .parent = &pxa27x_device_pwm1.dev, + .platform_data = &backlight_data, + }, +}; + +static struct pwm_lookup hx4700_pwm_lookup[] = { + PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL, + 30923, PWM_POLARITY_NORMAL), +}; + +/* + * 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] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), 1, "ac", + IORESOURCE_IRQ | + IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE), + [1] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), 1, "usb", + IORESOURCE_IRQ | + IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE), +}; + +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[] = { + REGULATOR_SUPPLY("vbus_draw", NULL), + REGULATOR_SUPPLY("ac_draw", NULL), +}; + +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 gpio bq24022_gpios[] = { + { GPIO96_HX4700_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" }, +}; + +static struct gpio_regulator_state bq24022_states[] = { + { .value = 100000, .gpios = (0 << 0) }, + { .value = 500000, .gpios = (1 << 0) }, +}; + +static struct gpio_regulator_config bq24022_info = { + .supply_name = "bq24022", + + .enable_gpio = GPIO72_HX4700_BQ24022_nCHARGE_EN, + .enable_high = 0, + .enabled_at_boot = 0, + + .gpios = bq24022_gpios, + .nr_gpios = ARRAY_SIZE(bq24022_gpios), + + .states = bq24022_states, + .nr_states = ARRAY_SIZE(bq24022_states), + + .type = REGULATOR_CURRENT, + .init_data = &bq24022_init_data, +}; + +static struct platform_device bq24022 = { + .name = "gpio-regulator", + .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[] = { + [0] = DEFINE_RES_MEM(PXA_CS0_PHYS, SZ_64M), + [1] = DEFINE_RES_MEM(PXA_CS0_PHYS + SZ_64M, SZ_64M), +}; + +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 = ARRAY_SIZE(strataflash_resource), + .dev = { + .platform_data = &strataflash_data, + }, +}; + +/* + * Maxim MAX1587A on PI2C + */ + +static struct regulator_consumer_supply max1587a_consumer = + REGULATOR_SUPPLY("vcc_core", NULL); + +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, +}; + + +/* + * Platform devices + */ + +static struct platform_device *devices[] __initdata = { + &asic3, + &gpio_keys, + &navpoint, + &backlight, + &w3220, + &hx4700_lcd, + &egpio, + &bq24022, + &gpio_vbus, + &power_supply, + &strataflash, + &audio, +}; + +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" }, + { GPIO61_HX4700_W3220_nRESET, GPIOF_OUT_INIT_HIGH, "W3220_nRESET" }, + { GPIO71_HX4700_ASIC3_nRESET, GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" }, + { GPIO81_HX4700_CPU_GP_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_GP_nRESET" }, + { GPIO82_HX4700_EUART_RESET, GPIOF_OUT_INIT_HIGH, "EUART_RESET" }, + { GPIO116_HX4700_CPU_HW_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_HW_nRESET" }, +}; + +static void __init hx4700_init(void) +{ + int ret; + + PCFR = PCFR_GPR_EN | PCFR_OPDE; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config)); + gpio_set_wake(GPIO12_HX4700_ASIC3_IRQ, 1); + 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)); + pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); + + 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, + .init_time = pxa_timer_init, + .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..c98511c5abd --- /dev/null +++ b/arch/arm/mach-pxa/icontrol.c @@ -0,0 +1,199 @@ +/* + * 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, +}; + +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, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .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 index 5aa0270d560..343c4e3a7c5 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -31,12 +31,11 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> +#include <mach/pxa25x.h> #include <mach/idp.h> -#include <mach/pxafb.h> +#include <linux/platform_data/video-pxafb.h> #include <mach/bitfield.h> -#include <mach/mmc.h> +#include <linux/platform_data/mmc-pxamci.h> #include "generic.h" #include "devices.h" @@ -46,6 +45,29 @@ * - 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), @@ -53,8 +75,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(4), - .end = IRQ_GPIO(4), + .start = PXA_GPIO_TO_IRQ(4), + .end = PXA_GPIO_TO_IRQ(4), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; @@ -121,44 +143,34 @@ static struct pxafb_mach_info sharp_lm8v31 = { .num_modes = 1, .cmap_inverse = 0, .cmap_static = 0, - .lccr0 = LCCR0_SDS, - .lccr3 = LCCR3_PCP | LCCR3_Acb(255), + .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 int idp_mci_init(struct device *dev, irq_handler_t idp_detect_int, void *data) -{ - /* setup GPIO for PXA25x MMC controller */ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - - return 0; -} - static struct pxamci_platform_data idp_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = idp_mci_init, + .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); - set_pxa_fb_info(&sharp_lm8v31); + pxa_set_fb_info(NULL, &sharp_lm8v31); pxa_set_mci_info(&idp_mci_platform_data); } -static void __init idp_init_irq(void) -{ - - pxa25x_init_irq(); - - set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE); -} - static struct map_desc idp_io_desc[] __initdata = { { .virtual = IDP_COREVOLT_VIRT, @@ -175,26 +187,99 @@ static struct map_desc idp_io_desc[] __initdata = { static void __init idp_map_io(void) { - pxa_map_io(); + pxa25x_map_io(); iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc)); +} + +/* LEDs */ +#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) +struct idp_led { + struct led_classdev cdev; + u8 mask; +}; + +/* + * The triggers lines up below will only be used if the + * LED triggers are compiled in. + */ +static const struct { + const char *name; + const char *trigger; +} idp_leds[] = { + { "idp:green", "heartbeat", }, + { "idp:red", "cpu0", }, +}; + +static void idp_led_set(struct led_classdev *cdev, + enum led_brightness b) +{ + struct idp_led *led = container_of(cdev, + struct idp_led, cdev); + u32 reg = IDP_CPLD_LED_CONTROL; + + if (b != LED_OFF) + reg &= ~led->mask; + else + reg |= led->mask; + + IDP_CPLD_LED_CONTROL = reg; +} + +static enum led_brightness idp_led_get(struct led_classdev *cdev) +{ + struct idp_led *led = container_of(cdev, + struct idp_led, cdev); + + return (IDP_CPLD_LED_CONTROL & led->mask) ? LED_OFF : LED_FULL; +} - // serial ports 2 & 3 - pxa_gpio_mode(GPIO42_BTRXD_MD); - pxa_gpio_mode(GPIO43_BTTXD_MD); - pxa_gpio_mode(GPIO44_BTCTS_MD); - pxa_gpio_mode(GPIO45_BTRTS_MD); - pxa_gpio_mode(GPIO46_STRXD_MD); - pxa_gpio_mode(GPIO47_STTXD_MD); +static int __init idp_leds_init(void) +{ + int i; + + if (!machine_is_pxa_idp()) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(idp_leds); i++) { + struct idp_led *led; + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (!led) + break; + + led->cdev.name = idp_leds[i].name; + led->cdev.brightness_set = idp_led_set; + led->cdev.brightness_get = idp_led_get; + led->cdev.default_trigger = idp_leds[i].trigger; + + if (i == 0) + led->mask = IDP_HB_LED; + else + led->mask = IDP_BUSY_LED; + if (led_classdev_register(NULL, &led->cdev) < 0) { + kfree(led); + break; + } + } + + return 0; } +/* + * Since we may have triggers on any subsystem, defer registration + * until after subsystem_init. + */ +fs_initcall(idp_leds_init); +#endif MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") /* Maintainer: Vibren Technologies */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = idp_map_io, - .init_irq = idp_init_irq, - .timer = &pxa_timer, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, .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/akita.h b/arch/arm/mach-pxa/include/mach/akita.h deleted file mode 100644 index 5d8cc1d9cb1..00000000000 --- a/arch/arm/mach-pxa/include/mach/akita.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Hardware specific definitions for SL-C1000 (Akita) - * - * 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. - * - */ - -/* Akita IO Expander GPIOs */ - -#define AKITA_IOEXP_RESERVED_7 (1 << 7) -#define AKITA_IOEXP_IR_ON (1 << 6) -#define AKITA_IOEXP_AKIN_PULLUP (1 << 5) -#define AKITA_IOEXP_BACKLIGHT_CONT (1 << 4) -#define AKITA_IOEXP_BACKLIGHT_ON (1 << 3) -#define AKITA_IOEXP_MIC_BIAS (1 << 2) -#define AKITA_IOEXP_RESERVED_1 (1 << 1) -#define AKITA_IOEXP_RESERVED_0 (1 << 0) - -/* Direction Bitfield 0=output 1=input */ -#define AKITA_IOEXP_IO_DIR 0 -/* Default Values */ -#define AKITA_IOEXP_IO_OUT (AKITA_IOEXP_IR_ON | AKITA_IOEXP_AKIN_PULLUP) - -extern struct platform_device akitaioexp_device; - -void akita_set_ioexp(struct device *dev, unsigned char bitmask); -void akita_reset_ioexp(struct device *dev, unsigned char bitmask); - diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h index f82f96dd105..a3449e35a6f 100644 --- a/arch/arm/mach-pxa/include/mach/audio.h +++ b/arch/arm/mach-pxa/include/mach/audio.h @@ -3,13 +3,26 @@ #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); 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..1b0825911e6 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -0,0 +1,184 @@ +/* + * 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 + +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ + +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_NR_IRQS (IRQ_BOARD_START + 16) + +extern int balloon3_has(enum balloon3_features feature); + +#endif diff --git a/arch/arm/mach-pxa/include/mach/camera.h b/arch/arm/mach-pxa/include/mach/camera.h deleted file mode 100644 index 39516ced8b1..00000000000 --- a/arch/arm/mach-pxa/include/mach/camera.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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 { - int (*init)(struct device *); - int (*power)(struct device *, int); - int (*reset)(struct device *, int); - - 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 index 2ae373fb567..cb4236e98a0 100644 --- a/arch/arm/mach-pxa/include/mach/colibri.h +++ b/arch/arm/mach-pxa/include/mach/colibri.h @@ -1,19 +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_FLASH_PHYS (PXA_CS0_PHYS) /* Flash region */ -#define COLIBRI_ETH_PHYS (PXA_CS2_PHYS) /* Ethernet DM9000 region */ #define COLIBRI_SDRAM_BASE 0xa0000000 /* SDRAM region */ -/* virtual memory regions */ -#define COLIBRI_DISK_VIRT 0xF0000000 /* Disk On Chip 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 -/* size of flash */ -#define COLIBRI_FLASH_SIZE 0x02000000 /* Flash size 32 MB */ +/* GPIO definitions for Colibri PXA300/310 */ +#define GPIO13_COLIBRI_PXA300_SD_DETECT 13 -/* Ethernet Controller Davicom DM9000 */ -#define GPIO_DM9000 114 -#define COLIBRI_ETH_IRQ IRQ_GPIO(GPIO_DM9000) +/* 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 index bf856503baf..c030d955bbd 100644 --- a/arch/arm/mach-pxa/include/mach/corgi.h +++ b/arch/arm/mach-pxa/include/mach/corgi.h @@ -13,6 +13,7 @@ #ifndef __ASM_ARCH_CORGI_H #define __ASM_ARCH_CORGI_H 1 +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ /* * Corgi (Non Standard) GPIO Definitions @@ -34,7 +35,7 @@ #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 Transciever */ +#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 */ @@ -66,18 +67,18 @@ /* * Corgi Interrupts */ -#define CORGI_IRQ_GPIO_KEY_INT IRQ_GPIO(0) -#define CORGI_IRQ_GPIO_AC_IN IRQ_GPIO(1) -#define CORGI_IRQ_GPIO_WAKEUP IRQ_GPIO(3) -#define CORGI_IRQ_GPIO_AK_INT IRQ_GPIO(4) -#define CORGI_IRQ_GPIO_TP_INT IRQ_GPIO(5) -#define CORGI_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9) -#define CORGI_IRQ_GPIO_nSD_INT IRQ_GPIO(10) -#define CORGI_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(11) -#define CORGI_IRQ_GPIO_CF_CD IRQ_GPIO(14) -#define CORGI_IRQ_GPIO_CHRG_FULL IRQ_GPIO(16) /* Battery fully charged */ -#define CORGI_IRQ_GPIO_CF_IRQ IRQ_GPIO(17) -#define CORGI_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(58+(a)) /* Keyboard Sense lines */ +#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 */ /* @@ -98,12 +99,16 @@ CORGI_SCP_MIC_BIAS ) #define CORGI_SCOOP_IO_OUT ( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R ) - -/* - * Shared data structures - */ -extern struct platform_device corgiscoop_device; -extern struct platform_device corgissp_device; +#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..00cfbbbf73f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/csb726.h @@ -0,0 +1,28 @@ +/* + * 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 + +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + +#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 deleted file mode 100644 index 55d6a175ab1..00000000000 --- a/arch/arm/mach-pxa/include/mach/debug-macro.S +++ /dev/null @@ -1,25 +0,0 @@ -/* 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,rx - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - moveq \rx, #0x40000000 @ physical - movne \rx, #io_p2v(0x40000000) @ virtual - orr \rx, \rx, #0x00100000 - .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 index 955bfe60606..5bd55894a48 100644 --- a/arch/arm/mach-pxa/include/mach/dma.h +++ b/arch/arm/mach-pxa/include/mach/dma.h @@ -12,39 +12,10 @@ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H -/* - * Descriptor structure for PXA's DMA engine - * Note: this structure must always be aligned to a 16-byte boundary. - */ - -typedef struct pxa_dma_desc { - volatile u32 ddadr; /* Points to the next descriptor + flags */ - volatile u32 dsadr; /* DSADR value for the current transfer */ - volatile u32 dtadr; /* DTADR value for the current transfer */ - volatile u32 dcmd; /* DCMD value for the current transfer */ -} pxa_dma_desc; - -typedef enum { - DMA_PRIO_HIGH = 0, - DMA_PRIO_MEDIUM = 1, - DMA_PRIO_LOW = 2 -} pxa_dma_prio; - -#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) -#define HAVE_ARCH_PCI_SET_DMA_MASK 1 -#endif - -/* - * DMA registration - */ - -int __init pxa_init_dma(int num_ch); - -int pxa_request_dma (char *name, - pxa_dma_prio prio, - void (*irq_handler)(int, void *), - void *data); +#include <mach/hardware.h> -void pxa_free_dma (int dma_ch); +/* 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 deleted file mode 100644 index de16c12d523..00000000000 --- a/arch/arm/mach-pxa/include/mach/entry-macro.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ -#include <mach/hardware.h> -#include <mach/irqs.h> - - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mrc p15, 0, \tmp, c0, c0, 0 @ CPUID - mov \tmp, \tmp, lsr #13 - and \tmp, \tmp, #0x7 @ Core G - cmp \tmp, #1 - bhi 1004f - - mov \base, #io_p2v(0x40000000) @ IIR Ctl = 0x40d00000 - add \base, \base, #0x00d00000 - ldr \irqstat, [\base, #0] @ ICIP - ldr \irqnr, [\base, #4] @ ICMR - b 1002f - -1004: - mrc p6, 0, \irqstat, c6, c0, 0 @ ICIP2 - mrc p6, 0, \irqnr, c7, c0, 0 @ ICMR2 - ands \irqnr, \irqstat, \irqnr - beq 1003f - rsb \irqstat, \irqnr, #0 - and \irqstat, \irqstat, \irqnr - clz \irqnr, \irqstat - rsb \irqnr, \irqnr, #31 - add \irqnr, \irqnr, #32 - b 1001f -1003: - mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP - mrc p6, 0, \irqnr, c1, c0, 0 @ ICMR -1002: - ands \irqnr, \irqstat, \irqnr - beq 1001f - rsb \irqstat, \irqnr, #0 - and \irqstat, \irqstat, \irqnr - clz \irqnr, \irqstat - rsb \irqnr, \irqnr, #31 -1001: - .endm diff --git a/arch/arm/mach-pxa/include/mach/eseries-gpio.h b/arch/arm/mach-pxa/include/mach/eseries-gpio.h index 4c90b131027..f3e5509820d 100644 --- a/arch/arm/mach-pxa/include/mach/eseries-gpio.h +++ b/arch/arm/mach-pxa/include/mach/eseries-gpio.h @@ -43,8 +43,25 @@ #define GPIO_E800_PCMCIA_PWR1 73 /* e7xx IrDA power control */ -#define GPIO_E7XX_IR_ON 38 +#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 index f2a93d5e31d..de292b269c6 100644 --- a/arch/arm/mach-pxa/include/mach/eseries-irq.h +++ b/arch/arm/mach-pxa/include/mach/eseries-irq.h @@ -25,3 +25,4 @@ #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/generic.h b/arch/arm/mach-pxa/include/mach/generic.h new file mode 100644 index 00000000000..665542e0c9e --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/generic.h @@ -0,0 +1 @@ +#include "../../generic.h" diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h deleted file mode 100644 index 2c538d8c362..00000000000 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 <mach/pxa-regs.h> -#include <asm/irq.h> -#include <mach/hardware.h> - -#include <asm-generic/gpio.h> - - -/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). - * Those cases currently cause holes in the GPIO number space. - */ -#define NR_BUILTIN_GPIO 128 - -static inline int gpio_get_value(unsigned gpio) -{ - if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) - return GPLR(gpio) & GPIO_bit(gpio); - else - return __gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) { - if (value) - GPSR(gpio) = GPIO_bit(gpio); - else - GPCR(gpio) = GPIO_bit(gpio); - } else { - __gpio_set_value(gpio, value); - } -} - -#define gpio_cansleep __gpio_cansleep - -#define gpio_to_irq(gpio) IRQ_GPIO(gpio) -#define irq_to_gpio(irq) IRQ_TO_GPIO(irq) - - -#endif diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h index 42ee1956750..f7df27bbb42 100644 --- a/arch/arm/mach-pxa/include/mach/gumstix.h +++ b/arch/arm/mach-pxa/include/mach/gumstix.h @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ /* BTRESET - Reset line to Bluetooth module, active low signal. */ #define GPIO_GUMSTIX_BTRESET 7 @@ -14,27 +15,17 @@ /* GPIOn - Input from MAX823 (or equiv), normalizing USB +5V into a clean -interrupt signal for determining cable presence. On the original gumstix, -this is GPIO81, and GPIO83 needs to be defined as well. On the gumstix F, +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. */ -#ifdef CONFIG_ARCH_GUMSTIX_ORIG - -#define GPIO_GUMSTIX_USB_GPIOn 81 -#define GPIO_GUMSTIX_USB_GPIOx 83 - -#else - #define GPIO_GUMSTIX_USB_GPIOn 35 #define GPIO_GUMSTIX_USB_GPIOx 41 -#endif - /* usb state change */ -#define GUMSTIX_USB_INTR_IRQ IRQ_GPIO(GPIO_GUMSTIX_USB_GPIOn) +#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) @@ -45,7 +36,7 @@ has detected a cable insertion; driven low otherwise. */ */ #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 IRQ_GPIO(GUMSTIX_GPIO_nSD_DETECT) +#define GUMSTIX_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT) /* * SMC Ethernet definitions @@ -59,10 +50,10 @@ has detected a cable insertion; driven low otherwise. */ #define GPIO_GUMSTIX_ETH0 36 #define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN) -#define GUMSTIX_ETH0_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH0) +#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 IRQ_GPIO(GPIO_GUMSTIX_ETH1) +#define GUMSTIX_ETH1_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1) /* CF reset line */ @@ -73,18 +64,18 @@ has detected a cable insertion; driven low otherwise. */ #define GPIO4_nSTSCHG GPIO4_nBVD1 #define GPIO11_nCD 11 #define GPIO26_PRDY_nBSY 26 -#define GUMSTIX_S0_nSTSCHG_IRQ IRQ_GPIO(GPIO4_nSTSCHG) -#define GUMSTIX_S0_nCD_IRQ IRQ_GPIO(GPIO11_nCD) -#define GUMSTIX_S0_PRDY_nBSY_IRQ IRQ_GPIO(GPIO26_PRDY_nBSY) +#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 IRQ_GPIO(GPIO18_nSTSCHG) -#define GUMSTIX_S1_nCD_IRQ IRQ_GPIO(GPIO36_nCD) -#define GUMSTIX_S1_PRDY_nBSY_IRQ IRQ_GPIO(GPIO27_PRDY_nBSY) +#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) @@ -94,3 +85,8 @@ has detected a cable insertion; driven low otherwise. */ #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 index e89df4d0d23..ccb06e48552 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -13,10 +13,7 @@ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H -/* - * We requires absolute addresses. - */ -#define PCIO_BASE 0 +#include <mach/addr-map.h> /* * Workarounds for at least 2 errata so far require this. @@ -39,17 +36,16 @@ * Note that not all PXA2xx chips implement all those addresses, and the * kernel only maps the minimum needed range of this mapping. */ -#define io_p2v(x) (0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) #define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1)) +#define io_p2v(x) IOMEM(0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) #ifndef __ASSEMBLY__ - -# define __REG(x) (*((volatile u32 *)io_p2v(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 *)((u32)&__REG(x) + (y))) + (*(volatile u32 __iomem*)((u32)&__REG(x) + (y))) # define __PREG(x) (io_v2p((u32)&(x))) @@ -62,26 +58,78 @@ #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_pxa21x(id) \ +#define __cpu_is_pxa210(id) \ ({ \ - unsigned int _id = (id) >> 4 & 0xf3f; \ - _id == 0x212; \ + unsigned int _id = (id) & 0xf3f0; \ + _id == 0x2120; \ }) -#define __cpu_is_pxa255(id) \ - ({ \ - unsigned int _id = (id) >> 4 & 0xfff; \ - _id == 0x2d0; \ - }) +#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) >> 4 & 0xfff; \ - _id == 0x2d0 || _id == 0x290; \ + unsigned int _id = (id) & 0xf300; \ + _id == 0x2100; \ }) #else -#define __cpu_is_pxa21x(id) (0) +#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 @@ -130,15 +178,30 @@ #define __cpu_is_pxa930(id) \ ({ \ unsigned int _id = (id) >> 4 & 0xfff; \ - _id == 0x683; \ + _id == 0x683; \ }) #else #define __cpu_is_pxa930(id) (0) #endif -#define cpu_is_pxa21x() \ +#ifdef CONFIG_CPU_PXA935 +#define __cpu_is_pxa935(id) \ ({ \ - __cpu_is_pxa21x(read_cpuid_id()); \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x693; \ + }) +#else +#define __cpu_is_pxa935(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() \ @@ -173,26 +236,51 @@ #define cpu_is_pxa930() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa930(id); \ + __cpu_is_pxa930(read_cpuid_id()); \ }) +#define cpu_is_pxa935() \ + ({ \ + __cpu_is_pxa935(read_cpuid_id()); \ + }) + + + /* * CPUID Core Generation Bit * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x - * == 0x3 for pxa300/pxa310/pxa320 */ +#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) \ ({ \ - unsigned int _id = (id) >> 13 & 0x7; \ - _id == 0x3; \ + __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 #define cpu_is_pxa2xx() \ ({ \ @@ -204,32 +292,19 @@ __cpu_is_pxa3xx(read_cpuid_id()); \ }) -/* - * Handy routine to set GPIO alternate functions - */ -extern int pxa_gpio_mode( int gpio_mode ); - -/* - * Return GPIO level, nonzero means high, zero is low - */ -extern int pxa_gpio_get_value(unsigned gpio); +#define cpu_is_pxa93x() \ + ({ \ + __cpu_is_pxa93x(read_cpuid_id()); \ + }) -/* - * Set output GPIO level - */ -extern void pxa_gpio_set_value(unsigned gpio, int value); /* * return current memory and LCD clock frequency in units of 10kHz */ extern unsigned int get_memclk_frequency_10khz(void); -#endif - -#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) -#define PCIBIOS_MIN_IO 0 -#define PCIBIOS_MIN_MEM 0 -#define pcibios_assign_all_busses() 1 +/* return the clock tick rate of the OS timer */ +extern unsigned long get_clock_tick_rate(void); #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..0e1bb46264f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/hx4700.h @@ -0,0 +1,133 @@ +/* + * 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> +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ + +#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/i2c.h b/arch/arm/mach-pxa/include/mach/i2c.h deleted file mode 100644 index 80596b01344..00000000000 --- a/arch/arm/mach-pxa/include/mach/i2c.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * i2c_pxa.h - * - * Copyright (C) 2002 Intrinsyc 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 _I2C_PXA_H_ -#define _I2C_PXA_H_ - -#if 0 -#define DEF_TIMEOUT 3 -#else -/* need a longer timeout if we're dealing with the fact we may well be - * looking at a multi-master environment -*/ -#define DEF_TIMEOUT 32 -#endif - -#define BUS_ERROR (-EREMOTEIO) -#define XFER_NAKED (-ECONNREFUSED) -#define I2C_RETRY (-2000) /* an error has occurred retry transmit */ - -/* ICR initialize bit values -* -* 15. FM 0 (100 Khz operation) -* 14. UR 0 (No unit reset) -* 13. SADIE 0 (Disables the unit from interrupting on slave addresses -* matching its slave address) -* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration -* in master mode) -* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode) -* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent) -* 9. IRFIE 1 (Enable interrupts from full buffer received) -* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty) -* 7. GCD 1 (Disables i2c unit response to general call messages as a slave) -* 6. IUE 0 (Disable unit until we change settings) -* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL) -* 4. MA 0 (Only send stop with the ICR stop bit) -* 3. TB 0 (We are not transmitting a byte initially) -* 2. ACKNAK 0 (Send an ACK after the unit receives a byte) -* 1. STOP 0 (Do not send a STOP) -* 0. START 0 (Do not send a START) -* -*/ -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) - -/* I2C status register init values - * - * 10. BED 1 (Clear bus error detected) - * 9. SAD 1 (Clear slave address detected) - * 7. IRF 1 (Clear IDBR Receive Full) - * 6. ITE 1 (Clear IDBR Transmit Empty) - * 5. ALD 1 (Clear Arbitration Loss Detected) - * 4. SSD 1 (Clear Slave Stop Detected) - */ -#define I2C_ISR_INIT 0x7FF /* status register init */ - -struct i2c_slave_client; - -struct i2c_pxa_platform_data { - unsigned int slave_addr; - struct i2c_slave_client *slave; - unsigned int class; - int use_pio; -}; - -extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); - -#ifdef CONFIG_PXA27x -extern void pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info); -#endif - -#endif diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h index 5eff96fcc94..7e63f468027 100644 --- a/arch/arm/mach-pxa/include/mach/idp.h +++ b/arch/arm/mach-pxa/include/mach/idp.h @@ -23,6 +23,7 @@ * IDP hardware. */ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ #define IDP_FLASH_PHYS (PXA_CS0_PHYS) #define IDP_ALT_FLASH_PHYS (PXA_CS1_PHYS) @@ -131,28 +132,26 @@ #define PCC_VS2 (1 << 1) #define PCC_VS1 (1 << 0) -#define PCC_DETECT(x) (GPLR(7 + (x)) & GPIO_bit(7 + (x))) - /* A listing of interrupts used by external hardware devices */ -#define TOUCH_PANEL_IRQ IRQ_GPIO(5) -#define IDE_IRQ IRQ_GPIO(21) +#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 IRQ_GPIO(4) +#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 IRQ_GPIO(7) +#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 IRQ_GPIO(8) +#define PCMCIA_S1_CD_VALID PXA_GPIO_TO_IRQ(8) #define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH -#define PCMCIA_S0_RDYINT IRQ_GPIO(19) -#define PCMCIA_S1_RDYINT IRQ_GPIO(22) +#define PCMCIA_S0_RDYINT PXA_GPIO_TO_IRQ(19) +#define PCMCIA_S1_RDYINT PXA_GPIO_TO_IRQ(22) /* diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index 600fd4f7660..cd78b7fe356 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h @@ -6,15 +6,12 @@ #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) ((void __iomem *)(a)) -#define __mem_pci(a) (a) +#define __io(a) __typesafe_io(a) #endif diff --git a/arch/arm/mach-pxa/include/mach/irda.h b/arch/arm/mach-pxa/include/mach/irda.h deleted file mode 100644 index 0a50c3c763d..00000000000 --- a/arch/arm/mach-pxa/include/mach/irda.h +++ /dev/null @@ -1,23 +0,0 @@ -#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); -}; - -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 index 108b5db9b2a..48c2fd85168 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -9,20 +9,26 @@ * 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) (x) +#define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x)) -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #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) */ -#define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI) */ +#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 */ +#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 */ -#endif - #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 */ @@ -30,7 +36,8 @@ #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 */ +#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) */ @@ -39,6 +46,7 @@ #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*/ @@ -52,18 +60,17 @@ #define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */ #define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */ -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */ #define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */ -#endif - -#ifdef CONFIG_PXA3xx -#define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request */ #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_GRPHICS PXA_IRQ(39) /* Graphics 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 */ @@ -71,195 +78,39 @@ #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) */ -#endif - -#define PXA_GPIO_IRQ_BASE (64) -#define PXA_GPIO_IRQ_NUM (128) -#define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x)) -#define IRQ_GPIO(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x)) +#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_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */ -#define IRQ_TO_GPIO_2_x(i) ((i) - PXA_GPIO_IRQ_BASE) -#define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i)) +#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 next 16 interrupts are for board specific purposes. Since + * 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. If you need more, increase IRQ_BOARD_END, but keep it - * within sensible limits. - */ -#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM) -#define IRQ_BOARD_END (IRQ_BOARD_START + 16) - -#define IRQ_SA1111_START (IRQ_BOARD_END) -#define IRQ_GPAIN0 (IRQ_BOARD_END + 0) -#define IRQ_GPAIN1 (IRQ_BOARD_END + 1) -#define IRQ_GPAIN2 (IRQ_BOARD_END + 2) -#define IRQ_GPAIN3 (IRQ_BOARD_END + 3) -#define IRQ_GPBIN0 (IRQ_BOARD_END + 4) -#define IRQ_GPBIN1 (IRQ_BOARD_END + 5) -#define IRQ_GPBIN2 (IRQ_BOARD_END + 6) -#define IRQ_GPBIN3 (IRQ_BOARD_END + 7) -#define IRQ_GPBIN4 (IRQ_BOARD_END + 8) -#define IRQ_GPBIN5 (IRQ_BOARD_END + 9) -#define IRQ_GPCIN0 (IRQ_BOARD_END + 10) -#define IRQ_GPCIN1 (IRQ_BOARD_END + 11) -#define IRQ_GPCIN2 (IRQ_BOARD_END + 12) -#define IRQ_GPCIN3 (IRQ_BOARD_END + 13) -#define IRQ_GPCIN4 (IRQ_BOARD_END + 14) -#define IRQ_GPCIN5 (IRQ_BOARD_END + 15) -#define IRQ_GPCIN6 (IRQ_BOARD_END + 16) -#define IRQ_GPCIN7 (IRQ_BOARD_END + 17) -#define IRQ_MSTXINT (IRQ_BOARD_END + 18) -#define IRQ_MSRXINT (IRQ_BOARD_END + 19) -#define IRQ_MSSTOPERRINT (IRQ_BOARD_END + 20) -#define IRQ_TPTXINT (IRQ_BOARD_END + 21) -#define IRQ_TPRXINT (IRQ_BOARD_END + 22) -#define IRQ_TPSTOPERRINT (IRQ_BOARD_END + 23) -#define SSPXMTINT (IRQ_BOARD_END + 24) -#define SSPRCVINT (IRQ_BOARD_END + 25) -#define SSPROR (IRQ_BOARD_END + 26) -#define AUDXMTDMADONEA (IRQ_BOARD_END + 32) -#define AUDRCVDMADONEA (IRQ_BOARD_END + 33) -#define AUDXMTDMADONEB (IRQ_BOARD_END + 34) -#define AUDRCVDMADONEB (IRQ_BOARD_END + 35) -#define AUDTFSR (IRQ_BOARD_END + 36) -#define AUDRFSR (IRQ_BOARD_END + 37) -#define AUDTUR (IRQ_BOARD_END + 38) -#define AUDROR (IRQ_BOARD_END + 39) -#define AUDDTS (IRQ_BOARD_END + 40) -#define AUDRDD (IRQ_BOARD_END + 41) -#define AUDSTO (IRQ_BOARD_END + 42) -#define IRQ_USBPWR (IRQ_BOARD_END + 43) -#define IRQ_HCIM (IRQ_BOARD_END + 44) -#define IRQ_HCIBUFFACC (IRQ_BOARD_END + 45) -#define IRQ_HCIRMTWKP (IRQ_BOARD_END + 46) -#define IRQ_NHCIMFCIR (IRQ_BOARD_END + 47) -#define IRQ_USB_PORT_RESUME (IRQ_BOARD_END + 48) -#define IRQ_S0_READY_NINT (IRQ_BOARD_END + 49) -#define IRQ_S1_READY_NINT (IRQ_BOARD_END + 50) -#define IRQ_S0_CD_VALID (IRQ_BOARD_END + 51) -#define IRQ_S1_CD_VALID (IRQ_BOARD_END + 52) -#define IRQ_S0_BVD1_STSCHG (IRQ_BOARD_END + 53) -#define IRQ_S1_BVD1_STSCHG (IRQ_BOARD_END + 54) - -#define IRQ_LOCOMO_START (IRQ_BOARD_END) -#define IRQ_LOCOMO_KEY (IRQ_BOARD_END + 0) -#define IRQ_LOCOMO_GPIO0 (IRQ_BOARD_END + 1) -#define IRQ_LOCOMO_GPIO1 (IRQ_BOARD_END + 2) -#define IRQ_LOCOMO_GPIO2 (IRQ_BOARD_END + 3) -#define IRQ_LOCOMO_GPIO3 (IRQ_BOARD_END + 4) -#define IRQ_LOCOMO_GPIO4 (IRQ_BOARD_END + 5) -#define IRQ_LOCOMO_GPIO5 (IRQ_BOARD_END + 6) -#define IRQ_LOCOMO_GPIO6 (IRQ_BOARD_END + 7) -#define IRQ_LOCOMO_GPIO7 (IRQ_BOARD_END + 8) -#define IRQ_LOCOMO_GPIO8 (IRQ_BOARD_END + 9) -#define IRQ_LOCOMO_GPIO9 (IRQ_BOARD_END + 10) -#define IRQ_LOCOMO_GPIO10 (IRQ_BOARD_END + 11) -#define IRQ_LOCOMO_GPIO11 (IRQ_BOARD_END + 12) -#define IRQ_LOCOMO_GPIO12 (IRQ_BOARD_END + 13) -#define IRQ_LOCOMO_GPIO13 (IRQ_BOARD_END + 14) -#define IRQ_LOCOMO_GPIO14 (IRQ_BOARD_END + 15) -#define IRQ_LOCOMO_GPIO15 (IRQ_BOARD_END + 16) -#define IRQ_LOCOMO_LT (IRQ_BOARD_END + 17) -#define IRQ_LOCOMO_SPI_RFR (IRQ_BOARD_END + 18) -#define IRQ_LOCOMO_SPI_RFW (IRQ_BOARD_END + 19) -#define IRQ_LOCOMO_SPI_OVRN (IRQ_BOARD_END + 20) -#define IRQ_LOCOMO_SPI_TEND (IRQ_BOARD_END + 21) - -/* - * Figure out the MAX IRQ number. - * - * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1. - * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1 - * Otherwise, we have the standard IRQs only. - */ -#ifdef CONFIG_SA1111 -#define NR_IRQS (IRQ_S1_BVD1_STSCHG + 1) -#elif defined(CONFIG_SHARP_LOCOMO) -#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1) -#elif defined(CONFIG_ARCH_LUBBOCK) || \ - defined(CONFIG_MACH_LOGICPD_PXA270) || \ - defined(CONFIG_MACH_TOSA) || \ - defined(CONFIG_MACH_MAINSTONE) || \ - defined(CONFIG_MACH_PCM027) || \ - defined(CONFIG_ARCH_PXA_ESERIES) || \ - defined(CONFIG_MACH_MAGICIAN) -#define NR_IRQS (IRQ_BOARD_END) -#elif defined(CONFIG_MACH_ZYLONITE) -#define NR_IRQS (IRQ_BOARD_START + 32) -#else -#define NR_IRQS (IRQ_BOARD_START) -#endif - -/* - * Board specific IRQs. Define them here. - * Do not surround them with ifdefs. + * these. + * By default, no board IRQ is reserved. It should be finished in + * custom board since sparse IRQ is already enabled. */ -#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 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 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) - -/* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */ -#define IRQ_LOCOMO_KEY_BASE (IRQ_BOARD_START + 0) -#define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1) -#define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2) -#define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3) - -/* phyCORE-PXA270 (PCM027) Interrupts */ -#define PCM027_IRQ(x) (IRQ_BOARD_START + (x)) -#define PCM027_BTDET_IRQ PCM027_IRQ(0) -#define PCM027_FF_RI_IRQ PCM027_IRQ(1) -#define PCM027_MMCDET_IRQ PCM027_IRQ(2) -#define PCM027_PM_5V_IRQ PCM027_IRQ(3) - -/* ITE8152 irqs */ -/* add IT8152 IRQs beyond BOARD_END */ -#ifdef CONFIG_PCI_HOST_ITE8152 -#define IT8152_IRQ(x) (IRQ_BOARD_END + (x)) +#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO) -/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ -#define IT8152_LD_IRQ_COUNT 9 -#define IT8152_LP_IRQ_COUNT 16 -#define IT8152_PD_IRQ_COUNT 15 +#define PXA_NR_IRQS (IRQ_BOARD_START) -/* Priorities: */ -#define IT8152_PD_IRQ(i) IT8152_IRQ(i) -#define IT8152_LP_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT) -#define IT8152_LD_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT) +#ifndef __ASSEMBLY__ +struct irq_data; +struct pt_regs; -#define IT8152_LAST_IRQ IT8152_LD_IRQ(IT8152_LD_IRQ_COUNT - 1) +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 *); -#if NR_IRQS < (IT8152_LAST_IRQ+1) -#undef NR_IRQS -#define NR_IRQS (IT8152_LAST_IRQ+1) +void pxa_init_irq(int irq_nr, int (*set_wake)(struct irq_data *, unsigned int)); #endif -#endif /* CONFIG_PCI_HOST_ITE8152 */ +#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 index 79d209b826f..8066be54e9f 100644 --- a/arch/arm/mach-pxa/include/mach/littleton.h +++ b/arch/arm/mach-pxa/include/mach/littleton.h @@ -1,6 +1,13 @@ -#ifndef __ASM_ARCH_ZYLONITE_H -#define __ASM_ARCH_ZYLONITE_H +#ifndef __ASM_ARCH_LITTLETON_H +#define __ASM_ARCH_LITTLETON_H #define LITTLETON_ETH_PHYS 0x30000000 -#endif /* __ASM_ARCH_ZYLONITE_H */ +#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 index f89fb715266..4edc712a2de 100644 --- a/arch/arm/mach-pxa/include/mach/lpd270.h +++ b/arch/arm/mach-pxa/include/mach/lpd270.h @@ -13,13 +13,13 @@ #define __ASM_ARCH_LPD270_H #define LPD270_CPLD_PHYS PXA_CS2_PHYS -#define LPD270_CPLD_VIRT 0xf0000000 +#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) ((unsigned long)(LPD270_CPLD_VIRT + (x))) +#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) @@ -34,5 +34,10 @@ #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 index 4cb24154a5a..958cd6af938 100644 --- a/arch/arm/mach-pxa/include/mach/lubbock.h +++ b/arch/arm/mach-pxa/include/mach/lubbock.h @@ -10,6 +10,8 @@ * published by the Free Software Foundation. */ +#include <mach/irqs.h> + #define LUBBOCK_ETH_PHYS PXA_CS3_PHYS #define LUBBOCK_FPGA_PHYS PXA_CS2_PHYS @@ -25,7 +27,6 @@ /* FPGA register virtual addresses */ #define LUB_WHOAMI __LUB_REG(LUBBOCK_FPGA_PHYS + 0x000) -#define LUB_HEXLED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x010) #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) @@ -35,6 +36,20 @@ #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 index 38d68d99f58..ba6a6e1d29e 100644 --- a/arch/arm/mach-pxa/include/mach/magician.h +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -12,6 +12,7 @@ #ifndef _MAGICIAN_H_ #define _MAGICIAN_H_ +#include <linux/gpio.h> #include <mach/irqs.h> /* @@ -27,7 +28,7 @@ #define GPIO22_MAGICIAN_VIBRA_EN 22 #define GPIO26_MAGICIAN_GSM_POWER 26 #define GPIO27_MAGICIAN_USBC_PUEN 27 -#define GPIO30_MAGICIAN_nCHARGE_EN 30 +#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 @@ -69,13 +70,15 @@ #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_AC (IRQ_BOARD_START + 3) +#define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3) + +#define MAGICIAN_NR_IRQS (IRQ_BOARD_START + 8) /* * CPLD EGPIOs */ -#define MAGICIAN_EGPIO_BASE 0x80 /* GPIO_BOARD_START */ +#define MAGICIAN_EGPIO_BASE PXA_NR_BUILTIN_GPIO #define MAGICIAN_EGPIO(reg,bit) \ (MAGICIAN_EGPIO_BASE + 8*reg + bit) @@ -98,7 +101,7 @@ #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_CHARGE_EN MAGICIAN_EGPIO(2, 5) +#define EGPIO_MAGICIAN_BQ24022_ISET2 MAGICIAN_EGPIO(2, 5) #define EGPIO_MAGICIAN_GSM_POWER MAGICIAN_EGPIO(2, 7) /* input */ diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index 3461c4302ff..1bfc4e822a4 100644 --- a/arch/arm/mach-pxa/include/mach/mainstone.h +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -13,6 +13,8 @@ #ifndef ASM_ARCH_MAINSTONE_H #define ASM_ARCH_MAINSTONE_H +#include <mach/irqs.h> + #define MST_ETH_PHYS PXA_CS4_PHYS #define MST_FPGA_PHYS PXA_CS2_PHYS @@ -117,4 +119,23 @@ #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/memory.h b/arch/arm/mach-pxa/include/mach/memory.h deleted file mode 100644 index 552eb7fa657..00000000000 --- a/arch/arm/mach-pxa/include/mach/memory.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/memory.h - * - * Author: Nicolas Pitre - * Copyright: (C) 2001 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_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PHYS_OFFSET UL(0xa0000000) - -/* - * Virtual view <-> DMA view memory address translations - * virt_to_bus: Used to translate the virtual address to an - * address suitable to be passed to set_dma_addr - * bus_to_virt: Used to convert an address for DMA operations - * to an address that the kernel can use. - */ -#define __virt_to_bus(x) __virt_to_phys(x) -#define __bus_to_virt(x) __phys_to_virt(x) - -/* - * The nodes are matched with the physical SDRAM banks as follows: - * - * node 0: 0xa0000000-0xa3ffffff --> 0xc0000000-0xc3ffffff - * node 1: 0xa4000000-0xa7ffffff --> 0xc4000000-0xc7ffffff - * node 2: 0xa8000000-0xabffffff --> 0xc8000000-0xcbffffff - * node 3: 0xac000000-0xafffffff --> 0xcc000000-0xcfffffff - * - * This needs a node mem size of 26 bits. - */ -#define NODE_MEM_SIZE_BITS 26 - -#if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) -void cmx270_pci_adjust_zones(int node, unsigned long *size, - unsigned long *holes); - -#define arch_adjust_zones(node, size, holes) \ - cmx270_pci_adjust_zones(node, size, holes) - -#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1) -#endif - -#endif diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h index 6c8e72238bf..cafadc33dfd 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h @@ -1,7 +1,6 @@ #ifndef __ASM_ARCH_MFP_PXA25X_H #define __ASM_ARCH_MFP_PXA25X_H -#include <mach/mfp.h> #include <mach/mfp-pxa2xx.h> /* GPIO */ @@ -17,7 +16,7 @@ /* Crystal and Clock Signals */ #define GPIO10_RTCCLK MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW) -#define GPIO70_RTC_CLK MFP_CFG_OUT(GPIO70, 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) @@ -156,6 +155,71 @@ #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_ACBIAS MFP_CFG_OUT(GPIO77, 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 index 122bdbd5318..b6132aa95dc 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h @@ -8,9 +8,14 @@ * specific controller, and this should work in most cases. */ -#include <mach/mfp.h> #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) @@ -153,7 +158,9 @@ #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 GPIO45_BTUART_RTS_LPM_LOW MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW) #define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH) +#define GPIO43_BTUART_TXD_LPM_LOW MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW) /* STUART */ #define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2) @@ -201,6 +208,7 @@ #define GPIO113_I2S_SYSCLK MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW) /* SSP 1 */ +#define GPIO23_SSP1_SCLK_IN MFP_CFG_IN(GPIO23, AF2) #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) @@ -429,5 +437,35 @@ #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 + +/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */ +#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT) +#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT) + 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 index 3e9211591e2..cbf51ae8185 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h @@ -1,7 +1,7 @@ #ifndef __ASM_ARCH_MFP_PXA2XX_H #define __ASM_ARCH_MFP_PXA2XX_H -#include <mach/mfp.h> +#include <plat/mfp.h> /* * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx: @@ -17,6 +17,7 @@ * * bit 23 - Input/Output (PXA2xx specific) * bit 24 - Wakeup Enable(PXA2xx specific) + * bit 25 - Keep Output (PXA2xx specific) */ #define MFP_DIR_IN (0x0 << 23) @@ -25,6 +26,14 @@ #define MFP_DIR(x) (((x) >> 23) & 0x1) #define MFP_LPM_CAN_WAKEUP (0x1 << 24) + +/* + * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to + * retain their last output level (low or high). + * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input. + */ +#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) diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h index bc1fb33a6e7..4e1287070d2 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h @@ -15,7 +15,6 @@ #ifndef __ASM_ARCH_MFP_PXA300_H #define __ASM_ARCH_MFP_PXA300_H -#include <mach/mfp.h> #include <mach/mfp-pxa3xx.h> /* GPIO */ @@ -41,6 +40,7 @@ #endif /* Chip Select */ +#define GPIO1_nCS2 MFP_CFG(GPIO1, AF1) #define GPIO2_nCS3 MFP_CFG(GPIO2, AF1) /* AC97 */ @@ -71,10 +71,10 @@ #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 GPIO52_CI_HSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X) -#define GPIO51_CI_VSYNC MFP_CFG_DRV(GPIO51, AF0, 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) @@ -567,9 +567,9 @@ #define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3) #define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1) -#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, MFP_AF0, MFP_DS01X) -#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, MFP_AF0, MFP_DS01X) -#define ULPI_STP MFP_CFG_DRV(ULPI_STP, MFP_AF0, MFP_DS01X) +#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, AF0, DS01X) +#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, AF0, DS01X) +#define ULPI_STP MFP_CFG_DRV(ULPI_STP, AF0, DS01X) #endif /* CONFIG_CPU_PXA310 */ #endif /* __ASM_ARCH_MFP_PXA300_H */ diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h index 74990510cf3..3ce4682eabb 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h @@ -15,7 +15,6 @@ #ifndef __ASM_ARCH_MFP_PXA320_H #define __ASM_ARCH_MFP_PXA320_H -#include <mach/mfp.h> #include <mach/mfp-pxa3xx.h> /* GPIO */ @@ -38,6 +37,7 @@ #define GPIO17_2_GPIO MFP_CFG(GPIO17_2, AF0) /* Chip Select */ +#define GPIO3_nCS2 MFP_CFG(GPIO3, AF1) #define GPIO4_nCS3 MFP_CFG(GPIO4, AF1) /* AC97 */ @@ -257,10 +257,10 @@ #define GPIO38_SSP2_RXD MFP_CFG(GPIO38, AF2) #define GPIO38_SSP2_TXD MFP_CFG(GPIO38, AF5) -#define GPIO69_SSP3_SCLK MFP_CFG(GPIO69, AF2, DS08X, FLOAT) -#define GPIO70_SSP3_FRM MFP_CFG(GPIO70, AF2, DS08X, DRIVE_LOW) -#define GPIO89_SSP3_SCLK MFP_CFG(GPIO89, AF1, DS08X, FLOAT) -#define GPIO90_SSP3_FRM MFP_CFG(GPIO90, AF1, DS08X, DRIVE_LOW) +#define GPIO69_SSP3_SCLK MFP_CFG_X(GPIO69, AF2, DS08X, FLOAT) +#define GPIO70_SSP3_FRM MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW) +#define GPIO89_SSP3_SCLK MFP_CFG_X(GPIO89, AF1, DS08X, FLOAT) +#define GPIO90_SSP3_FRM MFP_CFG_X(GPIO90, AF1, DS08X, DRIVE_LOW) #define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT) #define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW) #define GPIO72_SSP3_RXD MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT) @@ -283,6 +283,9 @@ #define GPIO41_UART1_TXD MFP_CFG_LPM(GPIO41, AF4, FLOAT) #define GPIO42_UART1_RXD MFP_CFG_LPM(GPIO42, AF4, FLOAT) #define GPIO42_UART1_TXD MFP_CFG_LPM(GPIO42, AF2, FLOAT) +#define GPIO75_UART1_RXD MFP_CFG_LPM(GPIO75, AF1, FLOAT) +#define GPIO76_UART1_RXD MFP_CFG_LPM(GPIO76, AF3, FLOAT) +#define GPIO76_UART1_TXD MFP_CFG_LPM(GPIO76, AF1, FLOAT) #define GPIO97_UART1_RXD MFP_CFG_LPM(GPIO97, AF1, FLOAT) #define GPIO97_UART1_TXD MFP_CFG_LPM(GPIO97, AF6, FLOAT) #define GPIO98_UART1_RXD MFP_CFG_LPM(GPIO98, AF6, FLOAT) @@ -291,6 +294,9 @@ #define GPIO43_UART1_RTS MFP_CFG_LPM(GPIO43, AF4, FLOAT) #define GPIO48_UART1_CTS MFP_CFG_LPM(GPIO48, AF4, FLOAT) #define GPIO48_UART1_RTS MFP_CFG_LPM(GPIO48, AF2, FLOAT) +#define GPIO77_UART1_CTS MFP_CFG_LPM(GPIO77, AF1, FLOAT) +#define GPIO82_UART1_RTS MFP_CFG_LPM(GPIO82, AF1, FLOAT) +#define GPIO82_UART1_CTS MFP_CFG_LPM(GPIO82, AF3, FLOAT) #define GPIO99_UART1_CTS MFP_CFG_LPM(GPIO99, AF1, FLOAT) #define GPIO99_UART1_RTS MFP_CFG_LPM(GPIO99, AF6, FLOAT) #define GPIO104_UART1_CTS MFP_CFG_LPM(GPIO104, AF6, FLOAT) @@ -299,13 +305,18 @@ #define GPIO45_UART1_DSR MFP_CFG_LPM(GPIO45, AF2, FLOAT) #define GPIO47_UART1_DTR MFP_CFG_LPM(GPIO47, AF2, FLOAT) #define GPIO47_UART1_DSR MFP_CFG_LPM(GPIO47, AF4, FLOAT) +#define GPIO79_UART1_DSR MFP_CFG_LPM(GPIO79, AF1, FLOAT) +#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF1, FLOAT) +#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF3, FLOAT) #define GPIO101_UART1_DTR MFP_CFG_LPM(GPIO101, AF6, FLOAT) #define GPIO101_UART1_DSR MFP_CFG_LPM(GPIO101, AF1, FLOAT) #define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF1, FLOAT) #define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF6, FLOAT) #define GPIO44_UART1_DCD MFP_CFG_LPM(GPIO44, AF2, FLOAT) +#define GPIO78_UART1_DCD MFP_CFG_LPM(GPIO78, AF1, FLOAT) #define GPIO100_UART1_DCD MFP_CFG_LPM(GPIO100, AF1, FLOAT) #define GPIO46_UART1_RI MFP_CFG_LPM(GPIO46, AF2, FLOAT) +#define GPIO80_UART1_RI MFP_CFG_LPM(GPIO80, AF1, FLOAT) #define GPIO102_UART1_RI MFP_CFG_LPM(GPIO102, AF1, FLOAT) /* UART2 */ @@ -438,6 +449,9 @@ #define GPIO2_RDY MFP_CFG(GPIO2, AF1) #define GPIO5_NPIOR MFP_CFG(GPIO5, AF3) +#define GPIO6_NPIOW MFP_CFG(GPIO6, AF3) +#define GPIO7_NPIOS16 MFP_CFG(GPIO7, AF3) +#define GPIO8_NPWAIT MFP_CFG(GPIO8, AF3) #define GPIO11_PWM0_OUT MFP_CFG(GPIO11, AF1) #define GPIO12_PWM1_OUT MFP_CFG(GPIO12, AF1) diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h index 1f6b35c015d..d375195d982 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h @@ -1,68 +1,9 @@ #ifndef __ASM_ARCH_MFP_PXA3XX_H #define __ASM_ARCH_MFP_PXA3XX_H -#define MFPR_BASE (0x40e10000) -#define MFPR_SIZE (PAGE_SIZE) - -/* MFPR register bit definitions */ -#define MFPR_PULL_SEL (0x1 << 15) -#define MFPR_PULLUP_EN (0x1 << 14) -#define MFPR_PULLDOWN_EN (0x1 << 13) -#define MFPR_SLEEP_SEL (0x1 << 9) -#define MFPR_SLEEP_OE_N (0x1 << 7) -#define MFPR_EDGE_CLEAR (0x1 << 6) -#define MFPR_EDGE_FALL_EN (0x1 << 5) -#define MFPR_EDGE_RISE_EN (0x1 << 4) - -#define MFPR_SLEEP_DATA(x) ((x) << 8) -#define MFPR_DRIVE(x) (((x) & 0x7) << 10) -#define MFPR_AF_SEL(x) (((x) & 0x7) << 0) +#include <plat/mfp.h> -#define MFPR_EDGE_NONE (0) -#define MFPR_EDGE_RISE (MFPR_EDGE_RISE_EN) -#define MFPR_EDGE_FALL (MFPR_EDGE_FALL_EN) -#define MFPR_EDGE_BOTH (MFPR_EDGE_RISE | MFPR_EDGE_FALL) - -/* - * Table that determines the low power modes outputs, with actual settings - * used in parentheses for don't-care values. Except for the float output, - * the configured driven and pulled levels match, so if there is a need for - * non-LPM pulled output, the same configuration could probably be used. - * - * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel - * (bit 7) (bit 8) (bit 14) (bit 13) (bit 15) - * - * Input 0 X(0) X(0) X(0) 0 - * Drive 0 0 0 0 X(1) 0 - * Drive 1 0 1 X(1) 0 0 - * Pull hi (1) 1 X(1) 1 0 0 - * Pull lo (0) 1 X(0) 0 1 0 - * Z (float) 1 X(0) 0 0 0 - */ -#define MFPR_LPM_INPUT (0) -#define MFPR_LPM_DRIVE_LOW (MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN) -#define MFPR_LPM_DRIVE_HIGH (MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN) -#define MFPR_LPM_PULL_LOW (MFPR_LPM_DRIVE_LOW | MFPR_SLEEP_OE_N) -#define MFPR_LPM_PULL_HIGH (MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N) -#define MFPR_LPM_FLOAT (MFPR_SLEEP_OE_N) -#define MFPR_LPM_MASK (0xe080) - -/* - * The pullup and pulldown state of the MFP pin at run mode is by default - * determined by the selected alternate function. In case that some buggy - * devices need to override this default behavior, the definitions below - * indicates the setting of corresponding MFPR bits - * - * Definition pull_sel pullup_en pulldown_en - * MFPR_PULL_NONE 0 0 0 - * MFPR_PULL_LOW 1 0 1 - * MFPR_PULL_HIGH 1 1 0 - * MFPR_PULL_BOTH 1 1 1 - */ -#define MFPR_PULL_NONE (0) -#define MFPR_PULL_LOW (MFPR_PULL_SEL | MFPR_PULLDOWN_EN) -#define MFPR_PULL_BOTH (MFPR_PULL_LOW | MFPR_PULLUP_EN) -#define MFPR_PULL_HIGH (MFPR_PULL_SEL | MFPR_PULLUP_EN) +#define MFPR_BASE (0x40e10000) /* PXA3xx common MFP configurations - processor specific ones defined * in mfp-pxa300.h and mfp-pxa320.h @@ -197,56 +138,21 @@ #define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0) #define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0) -/* - * each MFP pin will have a MFPR register, since the offset of the - * register varies between processors, the processor specific code - * should initialize the pin offsets by pxa3xx_mfp_init_addr() - * - * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map" - * structure, which represents a range of MFP pins from "start" to - * "end", with the offset begining at "offset", to define a single - * pin, let "end" = -1 - * - * use - * - * MFP_ADDR_X() to define a range of pins - * MFP_ADDR() to define a single pin - * MFP_ADDR_END to signal the end of pin offset definitions - */ -struct pxa3xx_mfp_addr_map { - unsigned int start; - unsigned int end; - unsigned long offset; -}; - -#define MFP_ADDR_X(start, end, offset) \ - { MFP_PIN_##start, MFP_PIN_##end, offset } - -#define MFP_ADDR(pin, offset) \ - { MFP_PIN_##pin, -1, offset } - -#define MFP_ADDR_END { MFP_PIN_INVALID, 0 } - -/* - * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access - * to the MFPR register - */ -unsigned long pxa3xx_mfp_read(int mfp); -void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val); - -/* - * pxa3xx_mfp_config - configure the MFPR registers - * - * used by board specific initialization code - */ -void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num); - -/* - * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin - * index and MFPR register offset - * - * used by processor specific code +/* NOTE: usage of these two functions is not recommended, + * use pxa3xx_mfp_config() instead. */ -void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *); -void __init pxa3xx_init_mfp(void); +static inline unsigned long pxa3xx_mfp_read(int mfp) +{ + return mfp_read(mfp); +} + +static inline void pxa3xx_mfp_write(int mfp, unsigned long val) +{ + mfp_write(mfp, val); +} + +static inline void pxa3xx_mfp_config(unsigned long *mfp_cfg, int num) +{ + mfp_config(mfp_cfg, num); +} #endif /* __ASM_ARCH_MFP_PXA3XX_H */ diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h index fabd9b4df82..04f7c97044f 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h @@ -13,7 +13,6 @@ #ifndef __ASM_ARCH_MFP_PXA9xx_H #define __ASM_ARCH_MFP_PXA9xx_H -#include <mach/mfp.h> #include <mach/mfp-pxa3xx.h> /* GPIO */ @@ -70,6 +69,7 @@ #define nBE0_GPIO_60 MFP_CFG(nBE0, AF0) #define nBE1_GPIO_61 MFP_CFG(nBE1, AF0) #define RDY_GPIO_62 MFP_CFG(RDY, AF0) +#define PMIC_INT_GPIO83 MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH) /* Chip Select */ #define DF_nCS0_nCS2 MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH) @@ -93,6 +93,9 @@ #define GPIO63_CI2C_SCL MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH) #define GPIO64_CI2C_SDA MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH) +#define GPIO73_CI2C_SCL MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH) +#define GPIO74_CI2C_SDA MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH) + #define GPIO77_CI2C_SCL MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH) #define GPIO78_CI2C_SDA MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH) @@ -346,6 +349,9 @@ #define GPIO69_UART1_CTS MFP_CFG(GPIO69, AF2) #define GPIO70_UART1_RTS MFP_CFG(GPIO70, AF2) +#define GPIO53_UART1_TXD MFP_CFG(GPIO53, AF2) +#define GPIO54_UART1_RXD MFP_CFG(GPIO54, AF2) + /* UART2 - BTUART */ #define GPIO91_UART2_RXD MFP_CFG(GPIO91, AF1) #define GPIO92_UART2_TXD MFP_CFG(GPIO92, AF1) @@ -421,6 +427,7 @@ #define GPIO20_PWM0 MFP_CFG_LPM(GPIO20, AF2, PULL_LOW) #define GPIO21_PWM2 MFP_CFG_LPM(GPIO21, AF3, PULL_LOW) #define GPIO22_PWM3 MFP_CFG_LPM(GPIO22, AF3, PULL_LOW) +#define GPIO32_PWM0 MFP_CFG_LPM(GPIO32, AF4, PULL_LOW) /* CIR */ #define GPIO46_CIR_OUT MFP_CFG(GPIO46, AF1) diff --git a/arch/arm/mach-pxa/include/mach/mfp.h b/arch/arm/mach-pxa/include/mach/mfp.h index 8769567b389..271e249ae34 100644 --- a/arch/arm/mach-pxa/include/mach/mfp.h +++ b/arch/arm/mach-pxa/include/mach/mfp.h @@ -16,304 +16,6 @@ #ifndef __ASM_ARCH_MFP_H #define __ASM_ARCH_MFP_H -#define mfp_to_gpio(m) ((m) % 128) - -/* list of all the configurable MFP pins */ -enum { - MFP_PIN_INVALID = -1, - - MFP_PIN_GPIO0 = 0, - MFP_PIN_GPIO1, - MFP_PIN_GPIO2, - MFP_PIN_GPIO3, - MFP_PIN_GPIO4, - MFP_PIN_GPIO5, - MFP_PIN_GPIO6, - MFP_PIN_GPIO7, - MFP_PIN_GPIO8, - MFP_PIN_GPIO9, - MFP_PIN_GPIO10, - MFP_PIN_GPIO11, - MFP_PIN_GPIO12, - MFP_PIN_GPIO13, - MFP_PIN_GPIO14, - MFP_PIN_GPIO15, - MFP_PIN_GPIO16, - MFP_PIN_GPIO17, - MFP_PIN_GPIO18, - MFP_PIN_GPIO19, - MFP_PIN_GPIO20, - MFP_PIN_GPIO21, - MFP_PIN_GPIO22, - MFP_PIN_GPIO23, - MFP_PIN_GPIO24, - MFP_PIN_GPIO25, - MFP_PIN_GPIO26, - MFP_PIN_GPIO27, - MFP_PIN_GPIO28, - MFP_PIN_GPIO29, - MFP_PIN_GPIO30, - MFP_PIN_GPIO31, - MFP_PIN_GPIO32, - MFP_PIN_GPIO33, - MFP_PIN_GPIO34, - MFP_PIN_GPIO35, - MFP_PIN_GPIO36, - MFP_PIN_GPIO37, - MFP_PIN_GPIO38, - MFP_PIN_GPIO39, - MFP_PIN_GPIO40, - MFP_PIN_GPIO41, - MFP_PIN_GPIO42, - MFP_PIN_GPIO43, - MFP_PIN_GPIO44, - MFP_PIN_GPIO45, - MFP_PIN_GPIO46, - MFP_PIN_GPIO47, - MFP_PIN_GPIO48, - MFP_PIN_GPIO49, - MFP_PIN_GPIO50, - MFP_PIN_GPIO51, - MFP_PIN_GPIO52, - MFP_PIN_GPIO53, - MFP_PIN_GPIO54, - MFP_PIN_GPIO55, - MFP_PIN_GPIO56, - MFP_PIN_GPIO57, - MFP_PIN_GPIO58, - MFP_PIN_GPIO59, - MFP_PIN_GPIO60, - MFP_PIN_GPIO61, - MFP_PIN_GPIO62, - MFP_PIN_GPIO63, - MFP_PIN_GPIO64, - MFP_PIN_GPIO65, - MFP_PIN_GPIO66, - MFP_PIN_GPIO67, - MFP_PIN_GPIO68, - MFP_PIN_GPIO69, - MFP_PIN_GPIO70, - MFP_PIN_GPIO71, - MFP_PIN_GPIO72, - MFP_PIN_GPIO73, - MFP_PIN_GPIO74, - MFP_PIN_GPIO75, - MFP_PIN_GPIO76, - MFP_PIN_GPIO77, - MFP_PIN_GPIO78, - MFP_PIN_GPIO79, - MFP_PIN_GPIO80, - MFP_PIN_GPIO81, - MFP_PIN_GPIO82, - MFP_PIN_GPIO83, - MFP_PIN_GPIO84, - MFP_PIN_GPIO85, - MFP_PIN_GPIO86, - MFP_PIN_GPIO87, - MFP_PIN_GPIO88, - MFP_PIN_GPIO89, - MFP_PIN_GPIO90, - MFP_PIN_GPIO91, - MFP_PIN_GPIO92, - MFP_PIN_GPIO93, - MFP_PIN_GPIO94, - MFP_PIN_GPIO95, - MFP_PIN_GPIO96, - MFP_PIN_GPIO97, - MFP_PIN_GPIO98, - MFP_PIN_GPIO99, - MFP_PIN_GPIO100, - MFP_PIN_GPIO101, - MFP_PIN_GPIO102, - MFP_PIN_GPIO103, - MFP_PIN_GPIO104, - MFP_PIN_GPIO105, - MFP_PIN_GPIO106, - MFP_PIN_GPIO107, - MFP_PIN_GPIO108, - MFP_PIN_GPIO109, - MFP_PIN_GPIO110, - MFP_PIN_GPIO111, - MFP_PIN_GPIO112, - MFP_PIN_GPIO113, - MFP_PIN_GPIO114, - MFP_PIN_GPIO115, - MFP_PIN_GPIO116, - MFP_PIN_GPIO117, - MFP_PIN_GPIO118, - MFP_PIN_GPIO119, - MFP_PIN_GPIO120, - MFP_PIN_GPIO121, - MFP_PIN_GPIO122, - MFP_PIN_GPIO123, - MFP_PIN_GPIO124, - MFP_PIN_GPIO125, - MFP_PIN_GPIO126, - MFP_PIN_GPIO127, - MFP_PIN_GPIO0_2, - MFP_PIN_GPIO1_2, - MFP_PIN_GPIO2_2, - MFP_PIN_GPIO3_2, - MFP_PIN_GPIO4_2, - MFP_PIN_GPIO5_2, - MFP_PIN_GPIO6_2, - MFP_PIN_GPIO7_2, - MFP_PIN_GPIO8_2, - MFP_PIN_GPIO9_2, - MFP_PIN_GPIO10_2, - MFP_PIN_GPIO11_2, - MFP_PIN_GPIO12_2, - MFP_PIN_GPIO13_2, - MFP_PIN_GPIO14_2, - MFP_PIN_GPIO15_2, - MFP_PIN_GPIO16_2, - MFP_PIN_GPIO17_2, - - MFP_PIN_ULPI_STP, - MFP_PIN_ULPI_NXT, - MFP_PIN_ULPI_DIR, - - MFP_PIN_nXCVREN, - MFP_PIN_DF_CLE_nOE, - MFP_PIN_DF_nADV1_ALE, - MFP_PIN_DF_SCLK_E, - MFP_PIN_DF_SCLK_S, - MFP_PIN_nBE0, - MFP_PIN_nBE1, - MFP_PIN_DF_nADV2_ALE, - MFP_PIN_DF_INT_RnB, - MFP_PIN_DF_nCS0, - MFP_PIN_DF_nCS1, - MFP_PIN_nLUA, - MFP_PIN_nLLA, - MFP_PIN_DF_nWE, - MFP_PIN_DF_ALE_nWE, - MFP_PIN_DF_nRE_nOE, - MFP_PIN_DF_ADDR0, - MFP_PIN_DF_ADDR1, - MFP_PIN_DF_ADDR2, - MFP_PIN_DF_ADDR3, - MFP_PIN_DF_IO0, - MFP_PIN_DF_IO1, - MFP_PIN_DF_IO2, - MFP_PIN_DF_IO3, - MFP_PIN_DF_IO4, - MFP_PIN_DF_IO5, - MFP_PIN_DF_IO6, - MFP_PIN_DF_IO7, - MFP_PIN_DF_IO8, - MFP_PIN_DF_IO9, - MFP_PIN_DF_IO10, - MFP_PIN_DF_IO11, - MFP_PIN_DF_IO12, - MFP_PIN_DF_IO13, - MFP_PIN_DF_IO14, - MFP_PIN_DF_IO15, - - /* additional pins on PXA930 */ - MFP_PIN_GSIM_UIO, - MFP_PIN_GSIM_UCLK, - MFP_PIN_GSIM_UDET, - MFP_PIN_GSIM_nURST, - MFP_PIN_PMIC_INT, - MFP_PIN_RDY, - - MFP_PIN_MAX, -}; - -/* - * a possible MFP configuration is represented by a 32-bit integer - * - * bit 0.. 9 - MFP Pin Number (1024 Pins Maximum) - * bit 10..12 - Alternate Function Selection - * bit 13..15 - Drive Strength - * bit 16..18 - Low Power Mode State - * bit 19..20 - Low Power Mode Edge Detection - * bit 21..22 - Run Mode Pull State - * - * to facilitate the definition, the following macros are provided - * - * MFP_CFG_DEFAULT - default MFP configuration value, with - * alternate function = 0, - * drive strength = fast 3mA (MFP_DS03X) - * low power mode = default - * edge detection = none - * - * MFP_CFG - default MFPR value with alternate function - * MFP_CFG_DRV - default MFPR value with alternate function and - * pin drive strength - * MFP_CFG_LPM - default MFPR value with alternate function and - * low power mode - * MFP_CFG_X - default MFPR value with alternate function, - * pin drive strength and low power mode - */ - -typedef unsigned long mfp_cfg_t; - -#define MFP_PIN(x) ((x) & 0x3ff) - -#define MFP_AF0 (0x0 << 10) -#define MFP_AF1 (0x1 << 10) -#define MFP_AF2 (0x2 << 10) -#define MFP_AF3 (0x3 << 10) -#define MFP_AF4 (0x4 << 10) -#define MFP_AF5 (0x5 << 10) -#define MFP_AF6 (0x6 << 10) -#define MFP_AF7 (0x7 << 10) -#define MFP_AF_MASK (0x7 << 10) -#define MFP_AF(x) (((x) >> 10) & 0x7) - -#define MFP_DS01X (0x0 << 13) -#define MFP_DS02X (0x1 << 13) -#define MFP_DS03X (0x2 << 13) -#define MFP_DS04X (0x3 << 13) -#define MFP_DS06X (0x4 << 13) -#define MFP_DS08X (0x5 << 13) -#define MFP_DS10X (0x6 << 13) -#define MFP_DS13X (0x7 << 13) -#define MFP_DS_MASK (0x7 << 13) -#define MFP_DS(x) (((x) >> 13) & 0x7) - -#define MFP_LPM_INPUT (0x0 << 16) -#define MFP_LPM_DRIVE_LOW (0x1 << 16) -#define MFP_LPM_DRIVE_HIGH (0x2 << 16) -#define MFP_LPM_PULL_LOW (0x3 << 16) -#define MFP_LPM_PULL_HIGH (0x4 << 16) -#define MFP_LPM_FLOAT (0x5 << 16) -#define MFP_LPM_STATE_MASK (0x7 << 16) -#define MFP_LPM_STATE(x) (((x) >> 16) & 0x7) - -#define MFP_LPM_EDGE_NONE (0x0 << 19) -#define MFP_LPM_EDGE_RISE (0x1 << 19) -#define MFP_LPM_EDGE_FALL (0x2 << 19) -#define MFP_LPM_EDGE_BOTH (0x3 << 19) -#define MFP_LPM_EDGE_MASK (0x3 << 19) -#define MFP_LPM_EDGE(x) (((x) >> 19) & 0x3) - -#define MFP_PULL_NONE (0x0 << 21) -#define MFP_PULL_LOW (0x1 << 21) -#define MFP_PULL_HIGH (0x2 << 21) -#define MFP_PULL_BOTH (0x3 << 21) -#define MFP_PULL_MASK (0x3 << 21) -#define MFP_PULL(x) (((x) >> 21) & 0x3) - -#define MFP_CFG_DEFAULT (MFP_AF0 | MFP_DS03X | MFP_LPM_INPUT |\ - MFP_LPM_EDGE_NONE | MFP_PULL_NONE) - -#define MFP_CFG(pin, af) \ - ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\ - (MFP_PIN(MFP_PIN_##pin) | MFP_##af)) - -#define MFP_CFG_DRV(pin, af, drv) \ - ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\ - (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv)) - -#define MFP_CFG_LPM(pin, af, lpm) \ - ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\ - (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm)) - -#define MFP_CFG_X(pin, af, drv, lpm) \ - ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\ - (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm)) +#include <plat/mfp.h> #endif /* __ASM_ARCH_MFP_H */ diff --git a/arch/arm/mach-pxa/include/mach/mioa701.h b/arch/arm/mach-pxa/include/mach/mioa701.h new file mode 100644 index 00000000000..e57f5c724e8 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mioa701.h @@ -0,0 +1,75 @@ +#ifndef _MIOA701_H_ +#define _MIOA701_H_ + +#define MIO_CFG_IN(pin, af) \ + ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\ + (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN)) + +#define MIO_CFG_OUT(pin, af, state) \ + ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\ + (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state)) + +/* Global GPIOs */ +#define GPIO9_CHARGE_EN 9 +#define GPIO18_POWEROFF 18 +#define GPIO87_LCD_POWER 87 +#define GPIO96_AC_DETECT 96 +#define GPIO80_MAYBE_CHARGE_VDROP 80 /* Drop of 88mV */ + +/* USB */ +#define GPIO13_nUSB_DETECT 13 +#define GPIO22_USB_ENABLE 22 + +/* SDIO bits */ +#define GPIO78_SDIO_RO 78 +#define GPIO15_SDIO_INSERT 15 +#define GPIO91_SDIO_EN 91 + +/* Bluetooth */ +#define GPIO14_BT_nACTIVITY 14 +#define GPIO83_BT_ON 83 +#define GPIO77_BT_UNKNOWN1 77 +#define GPIO86_BT_MAYBE_nRESET 86 + +/* GPS */ +#define GPIO23_GPS_UNKNOWN1 23 +#define GPIO26_GPS_ON 26 +#define GPIO27_GPS_RESET 27 +#define GPIO106_GPS_UNKNOWN2 106 +#define GPIO107_GPS_UNKNOWN3 107 + +/* GSM */ +#define GPIO24_GSM_MOD_RESET_CMD 24 +#define GPIO88_GSM_nMOD_ON_CMD 88 +#define GPIO90_GSM_nMOD_OFF_CMD 90 +#define GPIO114_GSM_nMOD_DTE_UART_STATE 114 +#define GPIO25_GSM_MOD_ON_STATE 25 +#define GPIO113_GSM_EVENT 113 + +/* SOUND */ +#define GPIO12_HPJACK_INSERT 12 + +/* LEDS */ +#define GPIO10_LED_nCharging 10 +#define GPIO97_LED_nBlue 97 +#define GPIO98_LED_nOrange 98 +#define GPIO82_LED_nVibra 82 +#define GPIO115_LED_nKeyboard 115 + +/* Keyboard */ +#define GPIO0_KEY_POWER 0 +#define GPIO93_KEY_VOLUME_UP 93 +#define GPIO94_KEY_VOLUME_DOWN 94 + +/* Camera */ +#define GPIO56_MT9M111_nOE 56 + +extern struct input_dev *mioa701_evdev; +extern void mioa701_gpio_lpm_set(unsigned long mfp_pin); + +/* Assembler externals mioa701_bootresume.S */ +extern u32 mioa701_bootstrap; +extern u32 mioa701_jumpaddr; +extern u32 mioa701_bootstrap_lg; + +#endif /* _MIOA701_H */ diff --git a/arch/arm/mach-pxa/include/mach/mmc.h b/arch/arm/mach-pxa/include/mach/mmc.h deleted file mode 100644 index 6d1304c9270..00000000000 --- a/arch/arm/mach-pxa/include/mach/mmc.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ASMARM_ARCH_MMC_H -#define ASMARM_ARCH_MMC_H - -#include <linux/mmc/host.h> -#include <linux/interrupt.h> - -struct device; -struct mmc_host; - -struct pxamci_platform_data { - unsigned int ocr_mask; /* available voltages */ - unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */ - int (*init)(struct device *, irq_handler_t , void *); - int (*get_ro)(struct device *); - void (*setpower)(struct device *, unsigned int); - void (*exit)(struct device *, void *); -}; - -extern void pxa_set_mci_info(struct pxamci_platform_data *info); -extern void pxa3xx_set_mci2_info(struct pxamci_platform_data *info); -extern void pxa3xx_set_mci3_info(struct pxamci_platform_data *info); - -#endif diff --git a/arch/arm/mach-pxa/include/mach/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h index 4d452fcb150..990d2bf2fb4 100644 --- a/arch/arm/mach-pxa/include/mach/mtd-xip.h +++ b/arch/arm/mach-pxa/include/mach/mtd-xip.h @@ -15,7 +15,7 @@ #ifndef __ARCH_PXA_MTD_XIP_H__ #define __ARCH_PXA_MTD_XIP_H__ -#include <mach/pxa-regs.h> +#include <mach/regs-ost.h> #define xip_irqpending() (ICIP & ICMR) diff --git a/arch/arm/mach-pxa/include/mach/mxm8x10.h b/arch/arm/mach-pxa/include/mach/mxm8x10.h new file mode 100644 index 00000000000..ffa15665a41 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mxm8x10.h @@ -0,0 +1,21 @@ +#ifndef __MACH_MXM_8X10_H +#define __MACH_MXM_8X10_H + +#define MXM_8X10_ETH_PHYS 0x13000000 + +#if defined(CONFIG_MMC) + +#define MXM_8X10_SD_nCD (72) +#define MXM_8X10_SD_WP (84) + +extern void mxm_8x10_mmc_init(void); +#else +static inline void mxm_8x10_mmc_init(void) {} +#endif + +extern void mxm_8x10_usb_host_init(void); +extern void mxm_8x10_ac97_init(void); + +extern void mxm_8x10_barebones_init(void); + +#endif /* __MACH_MXM_8X10_H */ diff --git a/arch/arm/mach-pxa/include/mach/ohci.h b/arch/arm/mach-pxa/include/mach/ohci.h deleted file mode 100644 index e848a47128c..00000000000 --- a/arch/arm/mach-pxa/include/mach/ohci.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef ASMARM_ARCH_OHCI_H -#define ASMARM_ARCH_OHCI_H - -struct device; - -struct pxaohci_platform_data { - int (*init)(struct device *); - void (*exit)(struct device *); - - int port_mode; -#define PMM_NPS_MODE 1 -#define PMM_GLOBAL_MODE 2 -#define PMM_PERPORT_MODE 3 - - int power_budget; -}; - -extern void pxa_set_ohci_info(struct pxaohci_platform_data *info); - -#endif diff --git a/arch/arm/mach-pxa/include/mach/palm27x.h b/arch/arm/mach-pxa/include/mach/palm27x.h new file mode 100644 index 00000000000..d4eac3d6ffb --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palm27x.h @@ -0,0 +1,81 @@ +/* + * Common functions for Palm LD, T5, TX, Z72 + * + * Copyright (C) 2010 + * 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. + * + */ +#ifndef __INCLUDE_MACH_PALM27X__ +#define __INCLUDE_MACH_PALM27X__ + +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +extern void __init palm27x_mmc_init(int detect, int ro, int power, + int power_inverted); +#else +static inline void palm27x_mmc_init(int detect, int ro, int power, + int power_inverted) +{} +#endif + +#if defined(CONFIG_SUSPEND) +extern void __init palm27x_pm_init(unsigned long str_base); +#else +static inline void palm27x_pm_init(unsigned long str_base) {} +#endif + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +extern struct pxafb_mode_info palm_320x480_lcd_mode; +extern struct pxafb_mode_info palm_320x320_lcd_mode; +extern struct pxafb_mode_info palm_320x320_new_lcd_mode; +extern void __init palm27x_lcd_init(int power, + struct pxafb_mode_info *mode); +#else +#define palm27x_lcd_init(power, mode) do {} while (0) +#endif + +#if defined(CONFIG_USB_PXA27X) || \ + defined(CONFIG_USB_PXA27X_MODULE) +extern void __init palm27x_udc_init(int vbus, int pullup, + int vbus_inverted); +#else +static inline void palm27x_udc_init(int vbus, int pullup, int vbus_inverted) {} +#endif + +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) +extern void __init palm27x_irda_init(int pwdn); +#else +static inline void palm27x_irda_init(int pwdn) {} +#endif + +#if defined(CONFIG_TOUCHSCREEN_WM97XX) || \ + defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE) +extern void __init palm27x_ac97_init(int minv, int maxv, int jack, + int reset); +#else +static inline void palm27x_ac97_init(int minv, int maxv, int jack, int reset) {} +#endif + +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +extern void __init palm27x_pwm_init(int bl, int lcd); +#else +static inline void palm27x_pwm_init(int bl, int lcd) {} +#endif + +#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE) +extern void __init palm27x_power_init(int ac, int usb); +#else +static inline void palm27x_power_init(int ac, int usb) {} +#endif + +#if defined(CONFIG_REGULATOR_MAX1586) || \ + defined(CONFIG_REGULATOR_MAX1586_MODULE) +extern void __init palm27x_pmic_init(void); +#else +static inline void palm27x_pmic_init(void) {} +#endif + +#endif /* __INCLUDE_MACH_PALM27X__ */ diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h new file mode 100644 index 00000000000..b184f296023 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmld.h @@ -0,0 +1,111 @@ +/* + * GPIOs and interrupts for Palm LifeDrive Handheld Computer + * + * Authors: Alex Osborne <ato@meshy.org> + * 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. + * + */ + +#ifndef _INCLUDE_PALMLD_H_ +#define _INCLUDE_PALMLD_H_ + +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + +/** HERE ARE GPIOs **/ + +/* GPIOs */ +#define GPIO_NR_PALMLD_GPIO_RESET 1 +#define GPIO_NR_PALMLD_POWER_DETECT 4 +#define GPIO_NR_PALMLD_HOTSYNC_BUTTON_N 10 +#define GPIO_NR_PALMLD_POWER_SWITCH 12 +#define GPIO_NR_PALMLD_EARPHONE_DETECT 13 +#define GPIO_NR_PALMLD_LOCK_SWITCH 15 + +/* SD/MMC */ +#define GPIO_NR_PALMLD_SD_DETECT_N 14 +#define GPIO_NR_PALMLD_SD_POWER 114 +#define GPIO_NR_PALMLD_SD_READONLY 116 + +/* TOUCHSCREEN */ +#define GPIO_NR_PALMLD_WM9712_IRQ 27 + +/* IRDA */ +#define GPIO_NR_PALMLD_IR_DISABLE 108 + +/* LCD/BACKLIGHT */ +#define GPIO_NR_PALMLD_BL_POWER 19 +#define GPIO_NR_PALMLD_LCD_POWER 96 + +/* LCD BORDER */ +#define GPIO_NR_PALMLD_BORDER_SWITCH 21 +#define GPIO_NR_PALMLD_BORDER_SELECT 22 + +/* BLUETOOTH */ +#define GPIO_NR_PALMLD_BT_POWER 17 +#define GPIO_NR_PALMLD_BT_RESET 83 + +/* PCMCIA (WiFi) */ +#define GPIO_NR_PALMLD_PCMCIA_READY 38 +#define GPIO_NR_PALMLD_PCMCIA_POWER 36 +#define GPIO_NR_PALMLD_PCMCIA_RESET 81 + +/* LEDs */ +#define GPIO_NR_PALMLD_LED_GREEN 52 +#define GPIO_NR_PALMLD_LED_AMBER 94 + +/* IDE */ +#define GPIO_NR_PALMLD_IDE_RESET 98 +#define GPIO_NR_PALMLD_IDE_PWEN 115 + +/* USB */ +#define GPIO_NR_PALMLD_USB_DETECT_N 3 +#define GPIO_NR_PALMLD_USB_READY 86 +#define GPIO_NR_PALMLD_USB_RESET 88 +#define GPIO_NR_PALMLD_USB_INT 106 +#define GPIO_NR_PALMLD_USB_POWER 118 +/* 20, 53 and 86 are usb related too */ + +/* INTERRUPTS */ +#define IRQ_GPIO_PALMLD_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_GPIO_RESET) +#define IRQ_GPIO_PALMLD_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_SD_DETECT_N) +#define IRQ_GPIO_PALMLD_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_WM9712_IRQ) +#define IRQ_GPIO_PALMLD_IDE_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_IDE_IRQ) + + +/** HERE ARE INIT VALUES **/ + +/* IO mappings */ +#define PALMLD_USB_PHYS PXA_CS2_PHYS +#define PALMLD_USB_VIRT 0xf0000000 +#define PALMLD_USB_SIZE 0x00100000 + +#define PALMLD_IDE_PHYS 0x20000000 +#define PALMLD_IDE_VIRT 0xf1000000 +#define PALMLD_IDE_SIZE 0x00100000 + +#define PALMLD_PHYS_IO_START 0x40000000 +#define PALMLD_STR_BASE 0xa0200000 + +/* BATTERY */ +#define PALMLD_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */ +#define PALMLD_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */ +#define PALMLD_BAT_MAX_CURRENT 0 /* unknown */ +#define PALMLD_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMLD_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMLD_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMLD_MAX_LIFE_MINS 240 /* on-life in minutes */ + +#define PALMLD_BAT_MEASURE_DELAY (HZ * 1) + +/* BACKLIGHT */ +#define PALMLD_MAX_INTENSITY 0xFE +#define PALMLD_DEFAULT_INTENSITY 0x7E +#define PALMLD_LIMIT_MASK 0x7F +#define PALMLD_PRESCALER 0x3F +#define PALMLD_PERIOD_NS 3500 + +#endif diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h new file mode 100644 index 00000000000..e342c592140 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmt5.h @@ -0,0 +1,86 @@ +/* + * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer + * + * Authors: Ales Snuparek <snuparek@atlas.cz> + * Marek Vasut <marek.vasut@gmail.com> + * Justin Kendrick <twilightsentry@gmail.com> + * RichardT5 <richard_t5@users.sourceforge.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. + * + */ + +#ifndef _INCLUDE_PALMT5_H_ +#define _INCLUDE_PALMT5_H_ + +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + +/** HERE ARE GPIOs **/ + +/* GPIOs */ +#define GPIO_NR_PALMT5_GPIO_RESET 1 + +#define GPIO_NR_PALMT5_POWER_DETECT 90 +#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N 10 +#define GPIO_NR_PALMT5_EARPHONE_DETECT 107 + +/* SD/MMC */ +#define GPIO_NR_PALMT5_SD_DETECT_N 14 +#define GPIO_NR_PALMT5_SD_POWER 114 +#define GPIO_NR_PALMT5_SD_READONLY 115 + +/* TOUCHSCREEN */ +#define GPIO_NR_PALMT5_WM9712_IRQ 27 + +/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */ +#define GPIO_NR_PALMT5_IR_DISABLE 40 + +/* USB */ +#define GPIO_NR_PALMT5_USB_DETECT_N 15 +#define GPIO_NR_PALMT5_USB_PULLUP 93 + +/* LCD/BACKLIGHT */ +#define GPIO_NR_PALMT5_BL_POWER 84 +#define GPIO_NR_PALMT5_LCD_POWER 96 + +/* BLUETOOTH */ +#define GPIO_NR_PALMT5_BT_POWER 17 +#define GPIO_NR_PALMT5_BT_RESET 83 + +/* INTERRUPTS */ +#define IRQ_GPIO_PALMT5_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N) +#define IRQ_GPIO_PALMT5_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ) +#define IRQ_GPIO_PALMT5_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT) +#define IRQ_GPIO_PALMT5_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_GPIO_RESET) + +/** HERE ARE INIT VALUES **/ + +/* Various addresses */ +#define PALMT5_PHYS_RAM_START 0xa0000000 +#define PALMT5_PHYS_IO_START 0x40000000 +#define PALMT5_STR_BASE 0xa0200000 + +/* TOUCHSCREEN */ +#define AC97_LINK_FRAME 21 + +/* BATTERY */ +#define PALMT5_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ +#define PALMT5_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ +#define PALMT5_BAT_MAX_CURRENT 0 /* unknown */ +#define PALMT5_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMT5_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMT5_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMT5_MAX_LIFE_MINS 360 /* on-life in minutes */ + +#define PALMT5_BAT_MEASURE_DELAY (HZ * 1) + +/* BACKLIGHT */ +#define PALMT5_MAX_INTENSITY 0xFE +#define PALMT5_DEFAULT_INTENSITY 0x7E +#define PALMT5_LIMIT_MASK 0x7F +#define PALMT5_PRESCALER 0x3F +#define PALMT5_PERIOD_NS 3500 + +#endif diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h new file mode 100644 index 00000000000..81c727b3cfd --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmtc.h @@ -0,0 +1,88 @@ +/* + * linux/include/asm-arm/arch-pxa/palmtc-gpio.h + * + * GPIOs and interrupts for Palm Tungsten|C Handheld Computer + * + * Authors: Alex Osborne <bobofdoom@gmail.com> + * Marek Vasut <marek.vasut@gmail.com> + * Holger Bocklet <bitz.email@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. + * + */ + +#ifndef _INCLUDE_PALMTC_H_ +#define _INCLUDE_PALMTC_H_ + +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + +/** HERE ARE GPIOs **/ + +/* GPIOs */ +#define GPIO_NR_PALMTC_EARPHONE_DETECT 2 +#define GPIO_NR_PALMTC_CRADLE_DETECT 5 +#define GPIO_NR_PALMTC_HOTSYNC_BUTTON 7 + +/* SD/MMC */ +#define GPIO_NR_PALMTC_SD_DETECT_N 12 +#define GPIO_NR_PALMTC_SD_POWER 32 +#define GPIO_NR_PALMTC_SD_READONLY 54 + +/* WLAN */ +#define GPIO_NR_PALMTC_PCMCIA_READY 13 +#define GPIO_NR_PALMTC_PCMCIA_PWRREADY 14 +#define GPIO_NR_PALMTC_PCMCIA_POWER1 15 +#define GPIO_NR_PALMTC_PCMCIA_POWER2 33 +#define GPIO_NR_PALMTC_PCMCIA_POWER3 55 +#define GPIO_NR_PALMTC_PCMCIA_RESET 78 + +/* UDC */ +#define GPIO_NR_PALMTC_USB_DETECT_N 4 +#define GPIO_NR_PALMTC_USB_POWER 36 + +/* LCD/BACKLIGHT */ +#define GPIO_NR_PALMTC_BL_POWER 16 +#define GPIO_NR_PALMTC_LCD_POWER 44 +#define GPIO_NR_PALMTC_LCD_BLANK 38 + +/* UART */ +#define GPIO_NR_PALMTC_RS232_POWER 37 + +/* IRDA */ +#define GPIO_NR_PALMTC_IR_DISABLE 45 + +/* IRQs */ +#define IRQ_GPIO_PALMTC_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_SD_DETECT_N) +#define IRQ_GPIO_PALMTC_WLAN_READY PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_WLAN_READY) + +/* UCB1400 GPIOs */ +#define GPIO_NR_PALMTC_POWER_DETECT (0x80 | 0x00) +#define GPIO_NR_PALMTC_HEADPHONE_DETECT (0x80 | 0x01) +#define GPIO_NR_PALMTC_SPEAKER_ENABLE (0x80 | 0x03) +#define GPIO_NR_PALMTC_VIBRA_POWER (0x80 | 0x05) +#define GPIO_NR_PALMTC_LED_POWER (0x80 | 0x07) + +/** HERE ARE INIT VALUES **/ +#define PALMTC_UCB1400_GPIO_OFFSET 0x80 + +/* BATTERY */ +#define PALMTC_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */ +#define PALMTC_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */ +#define PALMTC_BAT_MAX_CURRENT 0 /* unknown */ +#define PALMTC_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMTC_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMTC_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMTC_MAX_LIFE_MINS 240 /* on-life in minutes */ + +#define PALMTC_BAT_MEASURE_DELAY (HZ * 1) + +/* BACKLIGHT */ +#define PALMTC_MAX_INTENSITY 0xFE +#define PALMTC_DEFAULT_INTENSITY 0x7E +#define PALMTC_LIMIT_MASK 0x7F +#define PALMTC_PRESCALER 0x3F +#define PALMTC_PERIOD_NS 3500 + +#endif diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h new file mode 100644 index 00000000000..f89e989a763 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmte2.h @@ -0,0 +1,68 @@ +/* + * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer + * + * Author: + * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.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. + * + */ + +#ifndef _INCLUDE_PALMTE2_H_ +#define _INCLUDE_PALMTE2_H_ + +/** HERE ARE GPIOs **/ + +/* GPIOs */ +#define GPIO_NR_PALMTE2_POWER_DETECT 9 +#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N 4 +#define GPIO_NR_PALMTE2_EARPHONE_DETECT 15 + +/* SD/MMC */ +#define GPIO_NR_PALMTE2_SD_DETECT_N 10 +#define GPIO_NR_PALMTE2_SD_POWER 55 +#define GPIO_NR_PALMTE2_SD_READONLY 51 + +/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */ +#define GPIO_NR_PALMTE2_IR_DISABLE 48 + +/* USB */ +#define GPIO_NR_PALMTE2_USB_DETECT_N 35 +#define GPIO_NR_PALMTE2_USB_PULLUP 53 + +/* LCD/BACKLIGHT */ +#define GPIO_NR_PALMTE2_BL_POWER 56 +#define GPIO_NR_PALMTE2_LCD_POWER 37 + +/* KEYS */ +#define GPIO_NR_PALMTE2_KEY_NOTES 5 +#define GPIO_NR_PALMTE2_KEY_TASKS 7 +#define GPIO_NR_PALMTE2_KEY_CALENDAR 11 +#define GPIO_NR_PALMTE2_KEY_CONTACTS 13 +#define GPIO_NR_PALMTE2_KEY_CENTER 14 +#define GPIO_NR_PALMTE2_KEY_LEFT 19 +#define GPIO_NR_PALMTE2_KEY_RIGHT 20 +#define GPIO_NR_PALMTE2_KEY_DOWN 21 +#define GPIO_NR_PALMTE2_KEY_UP 22 + +/** HERE ARE INIT VALUES **/ + +/* BACKLIGHT */ +#define PALMTE2_MAX_INTENSITY 0xFE +#define PALMTE2_DEFAULT_INTENSITY 0x7E +#define PALMTE2_LIMIT_MASK 0x7F +#define PALMTE2_PRESCALER 0x3F +#define PALMTE2_PERIOD_NS 3500 + +/* BATTERY */ +#define PALMTE2_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ +#define PALMTE2_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ +#define PALMTE2_BAT_MAX_CURRENT 0 /* unknown */ +#define PALMTE2_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMTE2_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMTE2_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMTE2_MAX_LIFE_MINS 360 /* on-life in minutes */ + +#endif diff --git a/arch/arm/mach-pxa/include/mach/palmtreo.h b/arch/arm/mach-pxa/include/mach/palmtreo.h new file mode 100644 index 00000000000..714b6574393 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmtreo.h @@ -0,0 +1,68 @@ +/* + * GPIOs and interrupts for Palm Treo smartphones + * + * currently supported: + * Palm Treo 680 (GSM) + * Palm Centro 685 (GSM) + * + * Author: Tomas Cech <sleep_walker@suse.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. + * + * find more info at www.hackndev.com + * + */ + +#ifndef _INCLUDE_TREO_H_ +#define _INCLUDE_TREO_H_ + +/* GPIOs */ +#define GPIO_NR_TREO_POWER_DETECT 0 +#define GPIO_NR_TREO_AMP_EN 27 +#define GPIO_NR_TREO_GREEN_LED 20 +#define GPIO_NR_TREO_RED_LED 79 +#define GPIO_NR_TREO_SD_DETECT_N 113 +#define GPIO_NR_TREO_EP_DETECT_N 116 +#define GPIO_NR_TREO_USB_DETECT 1 +#define GPIO_NR_TREO_USB_PULLUP 114 +#define GPIO_NR_TREO_GSM_POWER 40 +#define GPIO_NR_TREO_GSM_RESET 87 +#define GPIO_NR_TREO_GSM_WAKE 57 +#define GPIO_NR_TREO_GSM_HOST_WAKE 14 +#define GPIO_NR_TREO_GSM_TRIGGER 10 +#define GPIO_NR_TREO_IR_EN 115 +#define GPIO_NR_TREO_IR_TXD 47 +#define GPIO_NR_TREO_BL_POWER 38 +#define GPIO_NR_TREO_LCD_POWER 25 + +/* Treo680 specific GPIOs */ +#define GPIO_NR_TREO680_SD_READONLY 33 +#define GPIO_NR_TREO680_SD_POWER 42 +#define GPIO_NR_TREO680_VIBRATE_EN 44 +#define GPIO_NR_TREO680_KEYB_BL 24 +#define GPIO_NR_TREO680_BT_EN 43 +#define GPIO_NR_TREO680_LCD_POWER 77 +#define GPIO_NR_TREO680_LCD_EN 86 +#define GPIO_NR_TREO680_LCD_EN_N 25 + +/* Centro685 specific GPIOs */ +#define GPIO_NR_CENTRO_SD_POWER 21 +#define GPIO_NR_CENTRO_VIBRATE_EN 22 +#define GPIO_NR_CENTRO_KEYB_BL 33 +#define GPIO_NR_CENTRO_BT_EN 80 + +/* Various addresses */ +#define TREO_PHYS_RAM_START 0xa0000000 +#define TREO_PHYS_IO_START 0x40000000 +#define TREO_STR_BASE 0xa2000000 + +/* BACKLIGHT */ +#define TREO_MAX_INTENSITY 254 +#define TREO_DEFAULT_INTENSITY 160 +#define TREO_LIMIT_MASK 0x7F +#define TREO_PRESCALER 63 +#define TREO_PERIOD_NS 3500 + +#endif diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h index 1e8bccbda51..92bc1f05300 100644 --- a/arch/arm/mach-pxa/include/mach/palmtx.h +++ b/arch/arm/mach-pxa/include/mach/palmtx.h @@ -16,6 +16,8 @@ #ifndef _INCLUDE_PALMTX_H_ #define _INCLUDE_PALMTX_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /** HERE ARE GPIOs **/ /* GPIOs */ @@ -38,7 +40,6 @@ /* USB */ #define GPIO_NR_PALMTX_USB_DETECT_N 13 -#define GPIO_NR_PALMTX_USB_POWER 95 #define GPIO_NR_PALMTX_USB_PULLUP 93 /* LCD/BACKLIGHT */ @@ -63,24 +64,31 @@ #define GPIO_NR_PALMTX_NAND_BUFFER_DIR 79 /* INTERRUPTS */ -#define IRQ_GPIO_PALMTX_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTX_SD_DETECT_N) -#define IRQ_GPIO_PALMTX_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMTX_WM9712_IRQ) -#define IRQ_GPIO_PALMTX_USB_DETECT IRQ_GPIO(GPIO_NR_PALMTX_USB_DETECT) -#define IRQ_GPIO_PALMTX_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMTX_GPIO_RESET) +#define IRQ_GPIO_PALMTX_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_SD_DETECT_N) +#define IRQ_GPIO_PALMTX_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_WM9712_IRQ) +#define IRQ_GPIO_PALMTX_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_USB_DETECT) +#define IRQ_GPIO_PALMTX_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_GPIO_RESET) /** HERE ARE INIT VALUES **/ /* Various addresses */ #define PALMTX_PCMCIA_PHYS 0x28000000 -#define PALMTX_PCMCIA_VIRT 0xf0000000 +#define PALMTX_PCMCIA_VIRT IOMEM(0xf0000000) #define PALMTX_PCMCIA_SIZE 0x100000 #define PALMTX_PHYS_RAM_START 0xa0000000 #define PALMTX_PHYS_IO_START 0x40000000 +#define PALMTX_STR_BASE 0xa0200000 + #define PALMTX_PHYS_FLASH_START PXA_CS0_PHYS /* ChipSelect 0 */ #define PALMTX_PHYS_NAND_START PXA_CS1_PHYS /* ChipSelect 1 */ +#define PALMTX_NAND_ALE_PHYS (PALMTX_PHYS_NAND_START | (1 << 24)) +#define PALMTX_NAND_CLE_PHYS (PALMTX_PHYS_NAND_START | (1 << 25)) +#define PALMTX_NAND_ALE_VIRT IOMEM(0xff100000) +#define PALMTX_NAND_CLE_VIRT IOMEM(0xff200000) + /* TOUCHSCREEN */ #define AC97_LINK_FRAME 21 @@ -88,7 +96,7 @@ /* BATTERY */ #define PALMTX_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ #define PALMTX_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ -#define PALMTX_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMTX_BAT_MAX_CURRENT 0 /* unknown */ #define PALMTX_BAT_MIN_CURRENT 0 /* unknown */ #define PALMTX_BAT_MAX_CHARGE 1 /* unknown */ #define PALMTX_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h new file mode 100644 index 00000000000..0d4700a7961 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmz72.h @@ -0,0 +1,84 @@ +/* + * GPIOs and interrupts for Palm Zire72 Handheld Computer + * + * Authors: Alex Osborne <bobofdoom@gmail.com> + * Jan Herman <2hp@seznam.cz> + * Sergey Lapin <slapin@ossfans.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. + * + */ + +#ifndef _INCLUDE_PALMZ72_H_ +#define _INCLUDE_PALMZ72_H_ + +/* Power and control */ +#define GPIO_NR_PALMZ72_GPIO_RESET 1 +#define GPIO_NR_PALMZ72_POWER_DETECT 0 + +/* SD/MMC */ +#define GPIO_NR_PALMZ72_SD_DETECT_N 14 +#define GPIO_NR_PALMZ72_SD_POWER_N 98 +#define GPIO_NR_PALMZ72_SD_RO 115 + +/* Touchscreen */ +#define GPIO_NR_PALMZ72_WM9712_IRQ 27 + +/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */ +#define GPIO_NR_PALMZ72_IR_DISABLE 49 + +/* USB */ +#define GPIO_NR_PALMZ72_USB_DETECT_N 15 +#define GPIO_NR_PALMZ72_USB_PULLUP 95 + +/* LCD/Backlight */ +#define GPIO_NR_PALMZ72_BL_POWER 20 +#define GPIO_NR_PALMZ72_LCD_POWER 96 + +/* LED */ +#define GPIO_NR_PALMZ72_LED_GREEN 88 + +/* Bluetooth */ +#define GPIO_NR_PALMZ72_BT_POWER 17 +#define GPIO_NR_PALMZ72_BT_RESET 83 + +/* Camera */ +#define GPIO_NR_PALMZ72_CAM_PWDN 56 +#define GPIO_NR_PALMZ72_CAM_RESET 57 +#define GPIO_NR_PALMZ72_CAM_POWER 91 + +/** Initial values **/ + +/* Battery */ +#define PALMZ72_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ +#define PALMZ72_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ +#define PALMZ72_BAT_MAX_CURRENT 0 /* unknown */ +#define PALMZ72_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMZ72_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMZ72_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMZ72_MAX_LIFE_MINS 360 /* on-life in minutes */ + +/* Backlight */ +#define PALMZ72_MAX_INTENSITY 0xFE +#define PALMZ72_DEFAULT_INTENSITY 0x7E +#define PALMZ72_LIMIT_MASK 0x7F +#define PALMZ72_PRESCALER 0x3F +#define PALMZ72_PERIOD_NS 3500 + +#ifdef CONFIG_PM +struct palmz72_resume_info { + u32 magic0; /* 0x0 */ + u32 magic1; /* 0x4 */ + u32 resume_addr; /* 0x8 */ + u32 pad[11]; /* 0xc..0x37 */ + u32 arm_control; /* 0x38 */ + u32 aux_control; /* 0x3c */ + u32 ttb; /* 0x40 */ + u32 domain_access; /* 0x44 */ + u32 process_id; /* 0x48 */ +}; +#endif +#endif + diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h index 4dcd2e8baa6..86ebd7b6c96 100644 --- a/arch/arm/mach-pxa/include/mach/pcm027.h +++ b/arch/arm/mach-pxa/include/mach/pcm027.h @@ -23,9 +23,20 @@ * Definitions of CPU card resources only */ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + +/* phyCORE-PXA270 (PCM027) Interrupts */ +#define PCM027_IRQ(x) (IRQ_BOARD_START + (x)) +#define PCM027_BTDET_IRQ PCM027_IRQ(0) +#define PCM027_FF_RI_IRQ PCM027_IRQ(1) +#define PCM027_MMCDET_IRQ PCM027_IRQ(2) +#define PCM027_PM_5V_IRQ PCM027_IRQ(3) + +#define PCM027_NR_IRQS (IRQ_BOARD_START + 32) + /* I2C RTC */ #define PCM027_RTC_IRQ_GPIO 0 -#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO) +#define PCM027_RTC_IRQ PXA_GPIO_TO_IRQ(PCM027_RTC_IRQ_GPIO) #define PCM027_RTC_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define ADR_PCM027_RTC 0x51 /* I2C address */ @@ -34,21 +45,21 @@ /* Ethernet chip (SMSC91C111) */ #define PCM027_ETH_IRQ_GPIO 52 -#define PCM027_ETH_IRQ IRQ_GPIO(PCM027_ETH_IRQ_GPIO) +#define PCM027_ETH_IRQ PXA_GPIO_TO_IRQ(PCM027_ETH_IRQ_GPIO) #define PCM027_ETH_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM027_ETH_PHYS PXA_CS5_PHYS #define PCM027_ETH_SIZE (1*1024*1024) /* CAN controller SJA1000 (unsupported yet) */ #define PCM027_CAN_IRQ_GPIO 114 -#define PCM027_CAN_IRQ IRQ_GPIO(PCM027_CAN_IRQ_GPIO) +#define PCM027_CAN_IRQ PXA_GPIO_TO_IRQ(PCM027_CAN_IRQ_GPIO) #define PCM027_CAN_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define PCM027_CAN_PHYS 0x22000000 #define PCM027_CAN_SIZE 0x100 /* SPI GPIO expander (unsupported yet) */ #define PCM027_EGPIO_IRQ_GPIO 27 -#define PCM027_EGPIO_IRQ IRQ_GPIO(PCM027_EGPIO_IRQ_GPIO) +#define PCM027_EGPIO_IRQ PXA_GPIO_TO_IRQ(PCM027_EGPIO_IRQ_GPIO) #define PCM027_EGPIO_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define PCM027_EGPIO_CS 24 /* diff --git a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h index 8a4383b776d..7e544c14967 100644 --- a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h +++ b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h @@ -20,6 +20,7 @@ */ #include <mach/pcm027.h> +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ /* * definitions relevant only when the PCM-990 @@ -28,14 +29,13 @@ /* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */ #define PCM990_CTRL_INT_IRQ_GPIO 9 -#define PCM990_CTRL_INT_IRQ IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO) +#define PCM990_CTRL_INT_IRQ PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO) #define PCM990_CTRL_INT_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CTRL_PHYS PXA_CS1_PHYS /* 16-Bit */ -#define PCM990_CTRL_BASE 0xea000000 #define PCM990_CTRL_SIZE (1*1024*1024) #define PCM990_CTRL_PWR_IRQ_GPIO 14 -#define PCM990_CTRL_PWR_IRQ IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO) +#define PCM990_CTRL_PWR_IRQ PXA_GPIO_TO_IRQ(PCM990_CTRL_PWR_IRQ_GPIO) #define PCM990_CTRL_PWR_IRQ_EDGE IRQ_TYPE_EDGE_RISING /* visible CPLD (U7) registers */ @@ -69,13 +69,13 @@ #define PCM990_CTRL_MMC2DE 0x0004 /* R MMC2 Card detect */ #define PCM990_CTRL_MMC2WP 0x0008 /* R MMC2 Card write protect */ -#define PCM990_CTRL_REG6 0x000C /* Interrupt Clear REGISTER */ +#define PCM990_CTRL_INTSETCLR 0x000C /* Interrupt Clear REGISTER */ #define PCM990_CTRL_INTC0 0x0001 /* Clear Reg BT Detect */ #define PCM990_CTRL_INTC1 0x0002 /* Clear Reg FR RI */ #define PCM990_CTRL_INTC2 0x0004 /* Clear Reg MMC1 Detect */ #define PCM990_CTRL_INTC3 0x0008 /* Clear Reg PM_5V off */ -#define PCM990_CTRL_REG7 0x000E /* Interrupt Enable REGISTER */ +#define PCM990_CTRL_INTMSKENA 0x000E /* Interrupt Enable REGISTER */ #define PCM990_CTRL_ENAINT0 0x0001 /* Enable Int BT Detect */ #define PCM990_CTRL_ENAINT1 0x0002 /* Enable Int FR RI */ #define PCM990_CTRL_ENAINT2 0x0004 /* Enable Int MMC1 Detect */ @@ -102,37 +102,11 @@ #define PCM990_CTRL_ACPRES 0x0004 /* DC Present */ #define PCM990_CTRL_ACALARM 0x0008 /* Error Akku */ -#define PCM990_CTRL_P2V(x) ((x) - PCM990_CTRL_PHYS + PCM990_CTRL_BASE) -#define PCM990_CTRL_V2P(x) ((x) - PCM990_CTRL_BASE + PCM990_CTRL_PHYS) - -#ifndef __ASSEMBLY__ -# define __PCM990_CTRL_REG(x) \ - (*((volatile unsigned char *)PCM990_CTRL_P2V(x))) -#else -# define __PCM990_CTRL_REG(x) PCM990_CTRL_P2V(x) -#endif - -#define PCM990_INTMSKENA __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7) -#define PCM990_INTSETCLR __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6) -#define PCM990_CTRL0 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG0) -#define PCM990_CTRL1 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG1) -#define PCM990_CTRL2 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG2) -#define PCM990_CTRL3 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) -#define PCM990_CTRL4 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG4) -#define PCM990_CTRL5 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) -#define PCM990_CTRL6 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6) -#define PCM990_CTRL7 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7) -#define PCM990_CTRL8 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG8) -#define PCM990_CTRL9 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG9) -#define PCM990_CTRL10 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG10) -#define PCM990_CTRL11 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG11) - - /* * IDE */ #define PCM990_IDE_IRQ_GPIO 13 -#define PCM990_IDE_IRQ IRQ_GPIO(PCM990_IDE_IRQ_GPIO) +#define PCM990_IDE_IRQ PXA_GPIO_TO_IRQ(PCM990_IDE_IRQ_GPIO) #define PCM990_IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_IDE_PLD_PHYS 0x20000000 /* 16 bit wide */ #define PCM990_IDE_PLD_BASE 0xee000000 @@ -166,40 +140,18 @@ #define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE) #define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS) -#ifndef __ASSEMBLY__ -# define __PCM990_IDE_PLD_REG(x) \ - (*((volatile unsigned char *)PCM990_IDE_PLD_P2V(x))) -#else -# define __PCM990_IDE_PLD_REG(x) PCM990_IDE_PLD_P2V(x) -#endif - -#define PCM990_IDE0 \ - __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG0) -#define PCM990_IDE1 \ - __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG1) -#define PCM990_IDE2 \ - __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG2) -#define PCM990_IDE3 \ - __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG3) -#define PCM990_IDE4 \ - __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG4) - /* * Compact Flash */ #define PCM990_CF_IRQ_GPIO 11 -#define PCM990_CF_IRQ IRQ_GPIO(PCM990_CF_IRQ_GPIO) +#define PCM990_CF_IRQ PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO) #define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CF_CD_GPIO 12 -#define PCM990_CF_CD IRQ_GPIO(PCM990_CF_CD_GPIO) +#define PCM990_CF_CD PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO) #define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */ -#define PCM990_CF_PLD_BASE 0xef000000 -#define PCM990_CF_PLD_SIZE (1*1024*1024) -#define PCM990_CF_PLD_P2V(x) ((x) - PCM990_CF_PLD_PHYS + PCM990_CF_PLD_BASE) -#define PCM990_CF_PLD_V2P(x) ((x) - PCM990_CF_PLD_BASE + PCM990_CF_PLD_PHYS) /* visible CPLD (U6) registers */ #define PCM990_CF_PLD_REG0 0x1000 /* OFFSET CF REGISTER 0 */ @@ -239,33 +191,18 @@ #define PCM990_CF_REG6_CD1 0x0001 /* R CF Card_Detect1 */ #define PCM990_CF_REG6_CD2 0x0002 /* R CF Card_Detect2 */ -#ifndef __ASSEMBLY__ -# define __PCM990_CF_PLD_REG(x) \ - (*((volatile unsigned char *)PCM990_CF_PLD_P2V(x))) -#else -# define __PCM990_CF_PLD_REG(x) PCM990_CF_PLD_P2V(x) -#endif - -#define PCM990_CF0 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG0) -#define PCM990_CF1 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG1) -#define PCM990_CF2 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG2) -#define PCM990_CF3 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG3) -#define PCM990_CF4 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG4) -#define PCM990_CF5 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG5) -#define PCM990_CF6 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG6) - /* * Wolfson AC97 Touch */ #define PCM990_AC97_IRQ_GPIO 10 -#define PCM990_AC97_IRQ IRQ_GPIO(PCM990_AC97_IRQ_GPIO) +#define PCM990_AC97_IRQ PXA_GPIO_TO_IRQ(PCM990_AC97_IRQ_GPIO) #define PCM990_AC97_IRQ_EDGE IRQ_TYPE_EDGE_RISING /* * MMC phyCORE */ #define PCM990_MMC0_IRQ_GPIO 9 -#define PCM990_MMC0_IRQ IRQ_GPIO(PCM990_MMC0_IRQ_GPIO) +#define PCM990_MMC0_IRQ PXA_GPIO_TO_IRQ(PCM990_MMC0_IRQ_GPIO) #define PCM990_MMC0_IRQ_EDGE IRQ_TYPE_EDGE_FALLING /* diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h index 261e5bc958d..51558bcee99 100644 --- a/arch/arm/mach-pxa/include/mach/pm.h +++ b/arch/arm/mach-pxa/include/mach/pm.h @@ -15,13 +15,26 @@ struct pxa_cpu_pm_fns { void (*restore)(unsigned long *); int (*valid)(suspend_state_t state); void (*enter)(suspend_state_t state); + int (*prepare)(void); + void (*finish)(void); }; extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; /* sleep.S */ -extern void pxa25x_cpu_suspend(unsigned int); -extern void pxa27x_cpu_suspend(unsigned int); -extern void pxa_cpu_resume(void); +extern int pxa25x_finish_suspend(unsigned long); +extern int pxa27x_finish_suspend(unsigned long); extern int pxa_pm_enter(suspend_state_t state); +extern int pxa_pm_prepare(void); +extern void pxa_pm_finish(void); + +/* NOTE: this is for PM debugging on Lubbock, it's really a big + * ugly, but let's keep the crap minimum here, instead of direct + * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c + */ +#ifdef CONFIG_ARCH_LUBBOCK +extern void lubbock_set_hexled(uint32_t value); +#else +#define lubbock_set_hexled(x) +#endif diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h index 67debc47e8c..b56b19351a0 100644 --- a/arch/arm/mach-pxa/include/mach/poodle.h +++ b/arch/arm/mach-pxa/include/mach/poodle.h @@ -15,6 +15,8 @@ #ifndef __ASM_ARCH_POODLE_H #define __ASM_ARCH_POODLE_H 1 +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /* * GPIOs */ @@ -23,6 +25,7 @@ #define POODLE_GPIO_AC_IN (1) #define POODLE_GPIO_CO 16 #define POODLE_GPIO_TP_INT (5) +#define POODLE_GPIO_TP_CS (24) #define POODLE_GPIO_WAKEUP (11) /* change battery */ #define POODLE_GPIO_GA_INT (10) #define POODLE_GPIO_IR_ON (22) @@ -46,18 +49,18 @@ #define POODLE_GPIO_DISCHARGE_ON (42) /* Enable battery discharge */ /* PXA GPIOs */ -#define POODLE_IRQ_GPIO_ON_KEY IRQ_GPIO(0) -#define POODLE_IRQ_GPIO_AC_IN IRQ_GPIO(1) -#define POODLE_IRQ_GPIO_HP_IN IRQ_GPIO(4) -#define POODLE_IRQ_GPIO_CO IRQ_GPIO(16) -#define POODLE_IRQ_GPIO_TP_INT IRQ_GPIO(5) -#define POODLE_IRQ_GPIO_WAKEUP IRQ_GPIO(11) -#define POODLE_IRQ_GPIO_GA_INT IRQ_GPIO(10) -#define POODLE_IRQ_GPIO_CF_IRQ IRQ_GPIO(17) -#define POODLE_IRQ_GPIO_CF_CD IRQ_GPIO(14) -#define POODLE_IRQ_GPIO_nSD_INT IRQ_GPIO(8) -#define POODLE_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9) -#define POODLE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(13) +#define POODLE_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(0) +#define POODLE_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1) +#define POODLE_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(4) +#define POODLE_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(16) +#define POODLE_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5) +#define POODLE_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(11) +#define POODLE_IRQ_GPIO_GA_INT PXA_GPIO_TO_IRQ(10) +#define POODLE_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17) +#define POODLE_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14) +#define POODLE_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(8) +#define POODLE_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9) +#define POODLE_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(13) /* SCOOP GPIOs */ #define POODLE_SCOOP_CHARGE_ON SCOOP_GPCR_PA11 @@ -70,12 +73,22 @@ #define POODLE_SCOOP_IO_DIR ( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT ) #define POODLE_SCOOP_IO_OUT ( 0 ) +#define POODLE_SCOOP_GPIO_BASE (PXA_NR_BUILTIN_GPIO) +#define POODLE_GPIO_CHARGE_ON (POODLE_SCOOP_GPIO_BASE + 0) +#define POODLE_GPIO_CP401 (POODLE_SCOOP_GPIO_BASE + 2) +#define POODLE_GPIO_VPEN (POODLE_SCOOP_GPIO_BASE + 7) +#define POODLE_GPIO_L_PCLK (POODLE_SCOOP_GPIO_BASE + 9) +#define POODLE_GPIO_L_LCLK (POODLE_SCOOP_GPIO_BASE + 10) +#define POODLE_GPIO_HS_OUT (POODLE_SCOOP_GPIO_BASE + 11) + #define POODLE_LOCOMO_GPIO_AMP_ON LOCOMO_GPIO(8) #define POODLE_LOCOMO_GPIO_MUTE_L LOCOMO_GPIO(10) #define POODLE_LOCOMO_GPIO_MUTE_R LOCOMO_GPIO(11) #define POODLE_LOCOMO_GPIO_232VCC_ON LOCOMO_GPIO(12) #define POODLE_LOCOMO_GPIO_JK_B LOCOMO_GPIO(13) +#define POODLE_NR_IRQS (IRQ_BOARD_START + 4) /* 4 for LoCoMo */ + extern struct platform_device poodle_locomo_device; #endif /* __ASM_ARCH_POODLE_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa-regs.h b/arch/arm/mach-pxa/include/mach/pxa-regs.h deleted file mode 100644 index 12288ca3cbb..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxa-regs.h +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/pxa-regs.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 __PXA_REGS_H -#define __PXA_REGS_H - - -/* - * PXA 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 - - -/* - * Personal Computer Memory Card International Association (PCMCIA) sockets - */ - -#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */ -#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */ -#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */ -#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */ -#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */ - -#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */ -#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */ -#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */ -#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */ - -#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */ -#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */ -#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */ -#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */ - -#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ - (0x20000000 + (Nb)*PCMCIASp) -#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */ -#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ - (_PCMCIA (Nb) + 2*PCMCIAPrtSp) -#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ - (_PCMCIA (Nb) + 3*PCMCIAPrtSp) - -#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */ -#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */ -#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */ -#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */ - -#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */ -#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */ -#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */ -#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */ - - - -/* - * DMA Controller - */ - -#define DCSR0 __REG(0x40000000) /* DMA Control / Status Register for Channel 0 */ -#define DCSR1 __REG(0x40000004) /* DMA Control / Status Register for Channel 1 */ -#define DCSR2 __REG(0x40000008) /* DMA Control / Status Register for Channel 2 */ -#define DCSR3 __REG(0x4000000c) /* DMA Control / Status Register for Channel 3 */ -#define DCSR4 __REG(0x40000010) /* DMA Control / Status Register for Channel 4 */ -#define DCSR5 __REG(0x40000014) /* DMA Control / Status Register for Channel 5 */ -#define DCSR6 __REG(0x40000018) /* DMA Control / Status Register for Channel 6 */ -#define DCSR7 __REG(0x4000001c) /* DMA Control / Status Register for Channel 7 */ -#define DCSR8 __REG(0x40000020) /* DMA Control / Status Register for Channel 8 */ -#define DCSR9 __REG(0x40000024) /* DMA Control / Status Register for Channel 9 */ -#define DCSR10 __REG(0x40000028) /* DMA Control / Status Register for Channel 10 */ -#define DCSR11 __REG(0x4000002c) /* DMA Control / Status Register for Channel 11 */ -#define DCSR12 __REG(0x40000030) /* DMA Control / Status Register for Channel 12 */ -#define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */ -#define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */ -#define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */ - -#define DCSR(x) __REG2(0x40000000, (x) << 2) - -#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */ -#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */ -#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */ -#ifdef CONFIG_PXA27x -#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */ -#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ -#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ -#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */ -#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */ -#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */ -#define DCSR_EORINTR (1 << 9) /* The end of Receive */ -#endif -#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */ -#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */ -#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */ -#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */ -#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */ - -#define DALGN __REG(0x400000a0) /* DMA Alignment Register */ -#define DINT __REG(0x400000f0) /* DMA Interrupt Register */ - -#define DRCMR(n) (*(((n) < 64) ? \ - &__REG2(0x40000100, ((n) & 0x3f) << 2) : \ - &__REG2(0x40001100, ((n) & 0x3f) << 2))) - -#define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */ -#define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */ -#define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */ -#define DRCMR3 __REG(0x4000010c) /* Request to Channel Map Register for I2S transmit Request */ -#define DRCMR4 __REG(0x40000110) /* Request to Channel Map Register for BTUART receive Request */ -#define DRCMR5 __REG(0x40000114) /* Request to Channel Map Register for BTUART transmit Request. */ -#define DRCMR6 __REG(0x40000118) /* Request to Channel Map Register for FFUART receive Request */ -#define DRCMR7 __REG(0x4000011c) /* Request to Channel Map Register for FFUART transmit Request */ -#define DRCMR8 __REG(0x40000120) /* Request to Channel Map Register for AC97 microphone Request */ -#define DRCMR9 __REG(0x40000124) /* Request to Channel Map Register for AC97 modem receive Request */ -#define DRCMR10 __REG(0x40000128) /* Request to Channel Map Register for AC97 modem transmit Request */ -#define DRCMR11 __REG(0x4000012c) /* Request to Channel Map Register for AC97 audio receive Request */ -#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */ -#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */ -#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */ -#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for SSP2 receive Request */ -#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for SSP2 transmit Request */ -#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */ -#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ -#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ -#define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */ -#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */ -#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */ -#define DRCMR23 __REG(0x4000015c) /* Reserved */ -#define DRCMR24 __REG(0x40000160) /* Reserved */ -#define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */ -#define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */ -#define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */ -#define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */ -#define DRCMR29 __REG(0x40000174) /* Reserved */ -#define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */ -#define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */ -#define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */ -#define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */ -#define DRCMR34 __REG(0x40000188) /* Reserved */ -#define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */ -#define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */ -#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ -#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */ -#define DRCMR39 __REG(0x4000019C) /* Reserved */ -#define DRCMR66 __REG(0x40001108) /* Request to Channel Map Register for SSP3 receive Request */ -#define DRCMR67 __REG(0x4000110C) /* Request to Channel Map Register for SSP3 transmit Request */ -#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ -#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ -#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ - -#define DRCMRRXSADR DRCMR2 -#define DRCMRTXSADR DRCMR3 -#define DRCMRRXBTRBR DRCMR4 -#define DRCMRTXBTTHR DRCMR5 -#define DRCMRRXFFRBR DRCMR6 -#define DRCMRTXFFTHR DRCMR7 -#define DRCMRRXMCDR DRCMR8 -#define DRCMRRXMODR DRCMR9 -#define DRCMRTXMODR DRCMR10 -#define DRCMRRXPCDR DRCMR11 -#define DRCMRTXPCDR DRCMR12 -#define DRCMRRXSSDR DRCMR13 -#define DRCMRTXSSDR DRCMR14 -#define DRCMRRXSS2DR DRCMR15 -#define DRCMRTXSS2DR DRCMR16 -#define DRCMRRXICDR DRCMR17 -#define DRCMRTXICDR DRCMR18 -#define DRCMRRXSTRBR DRCMR19 -#define DRCMRTXSTTHR DRCMR20 -#define DRCMRRXMMC DRCMR21 -#define DRCMRTXMMC DRCMR22 -#define DRCMRRXSS3DR DRCMR66 -#define DRCMRTXSS3DR DRCMR67 -#define DRCMRUDC(x) DRCMR((x) + 24) - -#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */ -#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */ - -#define DDADR0 __REG(0x40000200) /* DMA Descriptor Address Register Channel 0 */ -#define DSADR0 __REG(0x40000204) /* DMA Source Address Register Channel 0 */ -#define DTADR0 __REG(0x40000208) /* DMA Target Address Register Channel 0 */ -#define DCMD0 __REG(0x4000020c) /* DMA Command Address Register Channel 0 */ -#define DDADR1 __REG(0x40000210) /* DMA Descriptor Address Register Channel 1 */ -#define DSADR1 __REG(0x40000214) /* DMA Source Address Register Channel 1 */ -#define DTADR1 __REG(0x40000218) /* DMA Target Address Register Channel 1 */ -#define DCMD1 __REG(0x4000021c) /* DMA Command Address Register Channel 1 */ -#define DDADR2 __REG(0x40000220) /* DMA Descriptor Address Register Channel 2 */ -#define DSADR2 __REG(0x40000224) /* DMA Source Address Register Channel 2 */ -#define DTADR2 __REG(0x40000228) /* DMA Target Address Register Channel 2 */ -#define DCMD2 __REG(0x4000022c) /* DMA Command Address Register Channel 2 */ -#define DDADR3 __REG(0x40000230) /* DMA Descriptor Address Register Channel 3 */ -#define DSADR3 __REG(0x40000234) /* DMA Source Address Register Channel 3 */ -#define DTADR3 __REG(0x40000238) /* DMA Target Address Register Channel 3 */ -#define DCMD3 __REG(0x4000023c) /* DMA Command Address Register Channel 3 */ -#define DDADR4 __REG(0x40000240) /* DMA Descriptor Address Register Channel 4 */ -#define DSADR4 __REG(0x40000244) /* DMA Source Address Register Channel 4 */ -#define DTADR4 __REG(0x40000248) /* DMA Target Address Register Channel 4 */ -#define DCMD4 __REG(0x4000024c) /* DMA Command Address Register Channel 4 */ -#define DDADR5 __REG(0x40000250) /* DMA Descriptor Address Register Channel 5 */ -#define DSADR5 __REG(0x40000254) /* DMA Source Address Register Channel 5 */ -#define DTADR5 __REG(0x40000258) /* DMA Target Address Register Channel 5 */ -#define DCMD5 __REG(0x4000025c) /* DMA Command Address Register Channel 5 */ -#define DDADR6 __REG(0x40000260) /* DMA Descriptor Address Register Channel 6 */ -#define DSADR6 __REG(0x40000264) /* DMA Source Address Register Channel 6 */ -#define DTADR6 __REG(0x40000268) /* DMA Target Address Register Channel 6 */ -#define DCMD6 __REG(0x4000026c) /* DMA Command Address Register Channel 6 */ -#define DDADR7 __REG(0x40000270) /* DMA Descriptor Address Register Channel 7 */ -#define DSADR7 __REG(0x40000274) /* DMA Source Address Register Channel 7 */ -#define DTADR7 __REG(0x40000278) /* DMA Target Address Register Channel 7 */ -#define DCMD7 __REG(0x4000027c) /* DMA Command Address Register Channel 7 */ -#define DDADR8 __REG(0x40000280) /* DMA Descriptor Address Register Channel 8 */ -#define DSADR8 __REG(0x40000284) /* DMA Source Address Register Channel 8 */ -#define DTADR8 __REG(0x40000288) /* DMA Target Address Register Channel 8 */ -#define DCMD8 __REG(0x4000028c) /* DMA Command Address Register Channel 8 */ -#define DDADR9 __REG(0x40000290) /* DMA Descriptor Address Register Channel 9 */ -#define DSADR9 __REG(0x40000294) /* DMA Source Address Register Channel 9 */ -#define DTADR9 __REG(0x40000298) /* DMA Target Address Register Channel 9 */ -#define DCMD9 __REG(0x4000029c) /* DMA Command Address Register Channel 9 */ -#define DDADR10 __REG(0x400002a0) /* DMA Descriptor Address Register Channel 10 */ -#define DSADR10 __REG(0x400002a4) /* DMA Source Address Register Channel 10 */ -#define DTADR10 __REG(0x400002a8) /* DMA Target Address Register Channel 10 */ -#define DCMD10 __REG(0x400002ac) /* DMA Command Address Register Channel 10 */ -#define DDADR11 __REG(0x400002b0) /* DMA Descriptor Address Register Channel 11 */ -#define DSADR11 __REG(0x400002b4) /* DMA Source Address Register Channel 11 */ -#define DTADR11 __REG(0x400002b8) /* DMA Target Address Register Channel 11 */ -#define DCMD11 __REG(0x400002bc) /* DMA Command Address Register Channel 11 */ -#define DDADR12 __REG(0x400002c0) /* DMA Descriptor Address Register Channel 12 */ -#define DSADR12 __REG(0x400002c4) /* DMA Source Address Register Channel 12 */ -#define DTADR12 __REG(0x400002c8) /* DMA Target Address Register Channel 12 */ -#define DCMD12 __REG(0x400002cc) /* DMA Command Address Register Channel 12 */ -#define DDADR13 __REG(0x400002d0) /* DMA Descriptor Address Register Channel 13 */ -#define DSADR13 __REG(0x400002d4) /* DMA Source Address Register Channel 13 */ -#define DTADR13 __REG(0x400002d8) /* DMA Target Address Register Channel 13 */ -#define DCMD13 __REG(0x400002dc) /* DMA Command Address Register Channel 13 */ -#define DDADR14 __REG(0x400002e0) /* DMA Descriptor Address Register Channel 14 */ -#define DSADR14 __REG(0x400002e4) /* DMA Source Address Register Channel 14 */ -#define DTADR14 __REG(0x400002e8) /* DMA Target Address Register Channel 14 */ -#define DCMD14 __REG(0x400002ec) /* DMA Command Address Register Channel 14 */ -#define DDADR15 __REG(0x400002f0) /* DMA Descriptor Address Register Channel 15 */ -#define DSADR15 __REG(0x400002f4) /* DMA Source Address Register Channel 15 */ -#define DTADR15 __REG(0x400002f8) /* DMA Target Address Register Channel 15 */ -#define DCMD15 __REG(0x400002fc) /* DMA Command Address Register Channel 15 */ - -#define DDADR(x) __REG2(0x40000200, (x) << 4) -#define DSADR(x) __REG2(0x40000204, (x) << 4) -#define DTADR(x) __REG2(0x40000208, (x) << 4) -#define DCMD(x) __REG2(0x4000020c, (x) << 4) - -#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */ -#define DDADR_STOP (1 << 0) /* Stop (read / write) */ - -#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ -#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ -#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ -#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ -#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ -#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ -#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ -#define DCMD_BURST8 (1 << 16) /* 8 byte burst */ -#define DCMD_BURST16 (2 << 16) /* 16 byte burst */ -#define DCMD_BURST32 (3 << 16) /* 32 byte burst */ -#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */ -#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */ -#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */ -#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ - - -/* - * UARTs - */ - -/* Full Function UART (FFUART) */ -#define FFUART FFRBR -#define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */ -#define FFTHR __REG(0x40100000) /* Transmit Holding Register (write only) */ -#define FFIER __REG(0x40100004) /* Interrupt Enable Register (read/write) */ -#define FFIIR __REG(0x40100008) /* Interrupt ID Register (read only) */ -#define FFFCR __REG(0x40100008) /* FIFO Control Register (write only) */ -#define FFLCR __REG(0x4010000C) /* Line Control Register (read/write) */ -#define FFMCR __REG(0x40100010) /* Modem Control Register (read/write) */ -#define FFLSR __REG(0x40100014) /* Line Status Register (read only) */ -#define FFMSR __REG(0x40100018) /* Modem Status Register (read only) */ -#define FFSPR __REG(0x4010001C) /* Scratch Pad Register (read/write) */ -#define FFISR __REG(0x40100020) /* Infrared Selection Register (read/write) */ -#define FFDLL __REG(0x40100000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ -#define FFDLH __REG(0x40100004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ - -/* Bluetooth UART (BTUART) */ -#define BTUART BTRBR -#define BTRBR __REG(0x40200000) /* Receive Buffer Register (read only) */ -#define BTTHR __REG(0x40200000) /* Transmit Holding Register (write only) */ -#define BTIER __REG(0x40200004) /* Interrupt Enable Register (read/write) */ -#define BTIIR __REG(0x40200008) /* Interrupt ID Register (read only) */ -#define BTFCR __REG(0x40200008) /* FIFO Control Register (write only) */ -#define BTLCR __REG(0x4020000C) /* Line Control Register (read/write) */ -#define BTMCR __REG(0x40200010) /* Modem Control Register (read/write) */ -#define BTLSR __REG(0x40200014) /* Line Status Register (read only) */ -#define BTMSR __REG(0x40200018) /* Modem Status Register (read only) */ -#define BTSPR __REG(0x4020001C) /* Scratch Pad Register (read/write) */ -#define BTISR __REG(0x40200020) /* Infrared Selection Register (read/write) */ -#define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ -#define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ - -/* Standard UART (STUART) */ -#define STUART STRBR -#define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */ -#define STTHR __REG(0x40700000) /* Transmit Holding Register (write only) */ -#define STIER __REG(0x40700004) /* Interrupt Enable Register (read/write) */ -#define STIIR __REG(0x40700008) /* Interrupt ID Register (read only) */ -#define STFCR __REG(0x40700008) /* FIFO Control Register (write only) */ -#define STLCR __REG(0x4070000C) /* Line Control Register (read/write) */ -#define STMCR __REG(0x40700010) /* Modem Control Register (read/write) */ -#define STLSR __REG(0x40700014) /* Line Status Register (read only) */ -#define STMSR __REG(0x40700018) /* Reserved */ -#define STSPR __REG(0x4070001C) /* Scratch Pad Register (read/write) */ -#define STISR __REG(0x40700020) /* Infrared Selection Register (read/write) */ -#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ -#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ - -/* Hardware UART (HWUART) */ -#define HWUART HWRBR -#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */ -#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */ -#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */ -#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */ -#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */ -#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */ -#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */ -#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */ -#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */ -#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */ -#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */ -#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */ -#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */ -#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */ -#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ -#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ - -#define IER_DMAE (1 << 7) /* DMA Requests Enable */ -#define IER_UUE (1 << 6) /* UART Unit Enable */ -#define IER_NRZE (1 << 5) /* NRZ coding Enable */ -#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */ -#define IER_MIE (1 << 3) /* Modem Interrupt Enable */ -#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */ -#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */ -#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */ - -#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */ -#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */ -#define IIR_TOD (1 << 3) /* Time Out Detected */ -#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */ -#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */ -#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */ - -#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */ -#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */ -#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */ -#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */ -#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */ -#define FCR_ITL_1 (0) -#define FCR_ITL_8 (FCR_ITL1) -#define FCR_ITL_16 (FCR_ITL2) -#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1) - -#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */ -#define LCR_SB (1 << 6) /* Set Break */ -#define LCR_STKYP (1 << 5) /* Sticky Parity */ -#define LCR_EPS (1 << 4) /* Even Parity Select */ -#define LCR_PEN (1 << 3) /* Parity Enable */ -#define LCR_STB (1 << 2) /* Stop Bit */ -#define LCR_WLS1 (1 << 1) /* Word Length Select */ -#define LCR_WLS0 (1 << 0) /* Word Length Select */ - -#define LSR_FIFOE (1 << 7) /* FIFO Error Status */ -#define LSR_TEMT (1 << 6) /* Transmitter Empty */ -#define LSR_TDRQ (1 << 5) /* Transmit Data Request */ -#define LSR_BI (1 << 4) /* Break Interrupt */ -#define LSR_FE (1 << 3) /* Framing Error */ -#define LSR_PE (1 << 2) /* Parity Error */ -#define LSR_OE (1 << 1) /* Overrun Error */ -#define LSR_DR (1 << 0) /* Data Ready */ - -#define MCR_LOOP (1 << 4) -#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */ -#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */ -#define MCR_RTS (1 << 1) /* Request to Send */ -#define MCR_DTR (1 << 0) /* Data Terminal Ready */ - -#define MSR_DCD (1 << 7) /* Data Carrier Detect */ -#define MSR_RI (1 << 6) /* Ring Indicator */ -#define MSR_DSR (1 << 5) /* Data Set Ready */ -#define MSR_CTS (1 << 4) /* Clear To Send */ -#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */ -#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */ -#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */ -#define MSR_DCTS (1 << 0) /* Delta Clear To Send */ - -/* - * IrSR (Infrared Selection Register) - */ -#define STISR_RXPL (1 << 4) /* Receive Data Polarity */ -#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */ -#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */ -#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */ -#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */ - - -/* - * I2C registers - */ - -#define IBMR __REG(0x40301680) /* I2C Bus Monitor Register - IBMR */ -#define IDBR __REG(0x40301688) /* I2C Data Buffer Register - IDBR */ -#define ICR __REG(0x40301690) /* I2C Control Register - ICR */ -#define ISR __REG(0x40301698) /* I2C Status Register - ISR */ -#define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */ - -#define PWRIBMR __REG(0x40f00180) /* Power I2C Bus Monitor Register-IBMR */ -#define PWRIDBR __REG(0x40f00188) /* Power I2C Data Buffer Register-IDBR */ -#define PWRICR __REG(0x40f00190) /* Power I2C Control Register - ICR */ -#define PWRISR __REG(0x40f00198) /* Power I2C Status Register - ISR */ -#define PWRISAR __REG(0x40f001A0) /*Power I2C Slave Address Register-ISAR */ - -#define ICR_START (1 << 0) /* start bit */ -#define ICR_STOP (1 << 1) /* stop bit */ -#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */ -#define ICR_TB (1 << 3) /* transfer byte bit */ -#define ICR_MA (1 << 4) /* master abort */ -#define ICR_SCLE (1 << 5) /* master clock enable */ -#define ICR_IUE (1 << 6) /* unit enable */ -#define ICR_GCD (1 << 7) /* general call disable */ -#define ICR_ITEIE (1 << 8) /* enable tx interrupts */ -#define ICR_IRFIE (1 << 9) /* enable rx interrupts */ -#define ICR_BEIE (1 << 10) /* enable bus error ints */ -#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */ -#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */ -#define ICR_SADIE (1 << 13) /* slave address detected int enable */ -#define ICR_UR (1 << 14) /* unit reset */ - -#define ISR_RWM (1 << 0) /* read/write mode */ -#define ISR_ACKNAK (1 << 1) /* ack/nak status */ -#define ISR_UB (1 << 2) /* unit busy */ -#define ISR_IBB (1 << 3) /* bus busy */ -#define ISR_SSD (1 << 4) /* slave stop detected */ -#define ISR_ALD (1 << 5) /* arbitration loss detected */ -#define ISR_ITE (1 << 6) /* tx buffer empty */ -#define ISR_IRF (1 << 7) /* rx buffer full */ -#define ISR_GCAD (1 << 8) /* general call address detected */ -#define ISR_SAD (1 << 9) /* slave address detected */ -#define ISR_BED (1 << 10) /* bus error no ACK/NAK */ - - -/* - * Serial Audio Controller - */ - -#define SACR0 __REG(0x40400000) /* Global Control Register */ -#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ -#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ -#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ -#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ -#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ -#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ - -#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */ -#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */ -#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ -#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ -#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ -#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */ -#define SACR0_ENB (1 << 0) /* Enable I2S Link */ -#define SACR1_ENLBF (1 << 5) /* Enable Loopback */ -#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ -#define SACR1_DREC (1 << 3) /* Disable Recording Function */ -#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */ - -#define SASR0_I2SOFF (1 << 7) /* Controller Status */ -#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */ -#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */ -#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */ -#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */ -#define SASR0_BSY (1 << 2) /* I2S Busy */ -#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */ -#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */ - -#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */ -#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */ - -#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */ -#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */ -#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */ -#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */ - -/* - * AC97 Controller registers - */ - -#define POCR __REG(0x40500000) /* PCM Out Control Register */ -#define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ -#define POCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ - -#define PICR __REG(0x40500004) /* PCM In Control Register */ -#define PICR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ -#define PICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ - -#define MCCR __REG(0x40500008) /* Mic In Control Register */ -#define MCCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ -#define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ - -#define GCR __REG(0x4050000C) /* Global Control Register */ -#ifdef CONFIG_PXA3xx -#define GCR_CLKBPB (1 << 31) /* Internal clock enable */ -#endif -#define GCR_nDMAEN (1 << 24) /* non DMA Enable */ -#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */ -#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */ -#define GCR_SECRDY_IEN (1 << 9) /* Secondary Ready Interrupt Enable */ -#define GCR_PRIRDY_IEN (1 << 8) /* Primary Ready Interrupt Enable */ -#define GCR_SECRES_IEN (1 << 5) /* Secondary Resume Interrupt Enable */ -#define GCR_PRIRES_IEN (1 << 4) /* Primary Resume Interrupt Enable */ -#define GCR_ACLINK_OFF (1 << 3) /* AC-link Shut Off */ -#define GCR_WARM_RST (1 << 2) /* AC97 Warm Reset */ -#define GCR_COLD_RST (1 << 1) /* AC'97 Cold Reset (0 = active) */ -#define GCR_GIE (1 << 0) /* Codec GPI Interrupt Enable */ - -#define POSR __REG(0x40500010) /* PCM Out Status Register */ -#define POSR_FIFOE (1 << 4) /* FIFO error */ -#define POSR_FSR (1 << 2) /* FIFO Service Request */ - -#define PISR __REG(0x40500014) /* PCM In Status Register */ -#define PISR_FIFOE (1 << 4) /* FIFO error */ -#define PISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ -#define PISR_FSR (1 << 2) /* FIFO Service Request */ - -#define MCSR __REG(0x40500018) /* Mic In Status Register */ -#define MCSR_FIFOE (1 << 4) /* FIFO error */ -#define MCSR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ -#define MCSR_FSR (1 << 2) /* FIFO Service Request */ - -#define GSR __REG(0x4050001C) /* Global Status Register */ -#define GSR_CDONE (1 << 19) /* Command Done */ -#define GSR_SDONE (1 << 18) /* Status Done */ -#define GSR_RDCS (1 << 15) /* Read Completion Status */ -#define GSR_BIT3SLT12 (1 << 14) /* Bit 3 of slot 12 */ -#define GSR_BIT2SLT12 (1 << 13) /* Bit 2 of slot 12 */ -#define GSR_BIT1SLT12 (1 << 12) /* Bit 1 of slot 12 */ -#define GSR_SECRES (1 << 11) /* Secondary Resume Interrupt */ -#define GSR_PRIRES (1 << 10) /* Primary Resume Interrupt */ -#define GSR_SCR (1 << 9) /* Secondary Codec Ready */ -#define GSR_PCR (1 << 8) /* Primary Codec Ready */ -#define GSR_MCINT (1 << 7) /* Mic In Interrupt */ -#define GSR_POINT (1 << 6) /* PCM Out Interrupt */ -#define GSR_PIINT (1 << 5) /* PCM In Interrupt */ -#define GSR_ACOFFD (1 << 3) /* AC-link Shut Off Done */ -#define GSR_MOINT (1 << 2) /* Modem Out Interrupt */ -#define GSR_MIINT (1 << 1) /* Modem In Interrupt */ -#define GSR_GSCI (1 << 0) /* Codec GPI Status Change Interrupt */ - -#define CAR __REG(0x40500020) /* CODEC Access Register */ -#define CAR_CAIP (1 << 0) /* Codec Access In Progress */ - -#define PCDR __REG(0x40500040) /* PCM FIFO Data Register */ -#define MCDR __REG(0x40500060) /* Mic-in FIFO Data Register */ - -#define MOCR __REG(0x40500100) /* Modem Out Control Register */ -#define MOCR_FEIE (1 << 3) /* FIFO Error */ -#define MOCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ - -#define MICR __REG(0x40500108) /* Modem In Control Register */ -#define MICR_FEIE (1 << 3) /* FIFO Error */ -#define MICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ - -#define MOSR __REG(0x40500110) /* Modem Out Status Register */ -#define MOSR_FIFOE (1 << 4) /* FIFO error */ -#define MOSR_FSR (1 << 2) /* FIFO Service Request */ - -#define MISR __REG(0x40500118) /* Modem In Status Register */ -#define MISR_FIFOE (1 << 4) /* FIFO error */ -#define MISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ -#define MISR_FSR (1 << 2) /* FIFO Service Request */ - -#define MODR __REG(0x40500140) /* Modem FIFO Data Register */ - -#define PAC_REG_BASE __REG(0x40500200) /* Primary Audio Codec */ -#define SAC_REG_BASE __REG(0x40500300) /* Secondary Audio Codec */ -#define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */ -#define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ - - -/* - * Fast Infrared Communication Port - */ - -#define FICP __REG(0x40800000) /* Start of FICP area */ -#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ -#define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */ -#define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */ -#define ICDR __REG(0x4080000c) /* ICP Data Register */ -#define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */ -#define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */ - -#define ICCR0_AME (1 << 7) /* Address match enable */ -#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ -#define ICCR0_RIE (1 << 5) /* Recieve FIFO interrupt enable */ -#define ICCR0_RXE (1 << 4) /* Receive enable */ -#define ICCR0_TXE (1 << 3) /* Transmit enable */ -#define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */ -#define ICCR0_LBM (1 << 1) /* Loopback mode */ -#define ICCR0_ITR (1 << 0) /* IrDA transmission */ - -#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ -#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ -#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ -#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ -#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ -#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ - -#ifdef CONFIG_PXA27x -#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ -#endif -#define ICSR0_FRE (1 << 5) /* Framing error */ -#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */ -#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */ -#define ICSR0_RAB (1 << 2) /* Receiver abort */ -#define ICSR0_TUR (1 << 1) /* Trunsmit FIFO underun */ -#define ICSR0_EIF (1 << 0) /* End/Error in FIFO */ - -#define ICSR1_ROR (1 << 6) /* Receiver FIFO underrun */ -#define ICSR1_CRE (1 << 5) /* CRC error */ -#define ICSR1_EOF (1 << 4) /* End of frame */ -#define ICSR1_TNF (1 << 3) /* Transmit FIFO not full */ -#define ICSR1_RNE (1 << 2) /* Receive FIFO not empty */ -#define ICSR1_TBY (1 << 1) /* Tramsmiter busy flag */ -#define ICSR1_RSY (1 << 0) /* Recevier synchronized flag */ - - -/* - * Real Time Clock - */ - -#define RCNR __REG(0x40900000) /* RTC Count Register */ -#define RTAR __REG(0x40900004) /* RTC Alarm Register */ -#define RTSR __REG(0x40900008) /* RTC Status Register */ -#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */ -#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ - -#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ -#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ -#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ -#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ -#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ -#define RTSR_AL (1 << 0) /* RTC alarm detected */ - - -/* - * OS Timer & Match Registers - */ - -#define OSMR0 __REG(0x40A00000) /* */ -#define OSMR1 __REG(0x40A00004) /* */ -#define OSMR2 __REG(0x40A00008) /* */ -#define OSMR3 __REG(0x40A0000C) /* */ -#define OSMR4 __REG(0x40A00080) /* */ -#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */ -#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ -#define OMCR4 __REG(0x40A000C0) /* */ -#define OSSR __REG(0x40A00014) /* OS Timer Status Register */ -#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */ -#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */ - -#define OSSR_M3 (1 << 3) /* Match status channel 3 */ -#define OSSR_M2 (1 << 2) /* Match status channel 2 */ -#define OSSR_M1 (1 << 1) /* Match status channel 1 */ -#define OSSR_M0 (1 << 0) /* Match status channel 0 */ - -#define OWER_WME (1 << 0) /* Watchdog Match Enable */ - -#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */ -#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */ -#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */ -#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */ - - -/* - * Pulse Width Modulator - */ - -#define PWM_CTRL0 __REG(0x40B00000) /* PWM 0 Control Register */ -#define PWM_PWDUTY0 __REG(0x40B00004) /* PWM 0 Duty Cycle Register */ -#define PWM_PERVAL0 __REG(0x40B00008) /* PWM 0 Period Control Register */ - -#define PWM_CTRL1 __REG(0x40C00000) /* PWM 1Control Register */ -#define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */ -#define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */ - - -/* - * Interrupt Controller - */ - -#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */ -#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */ -#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */ -#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */ -#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ -#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ - -#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ -#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ -#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ -#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ -#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ - -/* - * General Purpose I/O - */ - -#define GPIO0_BASE ((void __iomem *)io_p2v(0x40E00000)) -#define GPIO1_BASE ((void __iomem *)io_p2v(0x40E00004)) -#define GPIO2_BASE ((void __iomem *)io_p2v(0x40E00008)) -#define GPIO3_BASE ((void __iomem *)io_p2v(0x40E00100)) - -#define GPLR_OFFSET 0x00 -#define GPDR_OFFSET 0x0C -#define GPSR_OFFSET 0x18 -#define GPCR_OFFSET 0x24 -#define GRER_OFFSET 0x30 -#define GFER_OFFSET 0x3C -#define GEDR_OFFSET 0x48 - -#define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */ -#define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */ -#define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */ - -#define GPDR0 __REG(0x40E0000C) /* GPIO Pin Direction Register GPIO<31:0> */ -#define GPDR1 __REG(0x40E00010) /* GPIO Pin Direction Register GPIO<63:32> */ -#define GPDR2 __REG(0x40E00014) /* GPIO Pin Direction Register GPIO<80:64> */ - -#define GPSR0 __REG(0x40E00018) /* GPIO Pin Output Set Register GPIO<31:0> */ -#define GPSR1 __REG(0x40E0001C) /* GPIO Pin Output Set Register GPIO<63:32> */ -#define GPSR2 __REG(0x40E00020) /* GPIO Pin Output Set Register GPIO<80:64> */ - -#define GPCR0 __REG(0x40E00024) /* GPIO Pin Output Clear Register GPIO<31:0> */ -#define GPCR1 __REG(0x40E00028) /* GPIO Pin Output Clear Register GPIO <63:32> */ -#define GPCR2 __REG(0x40E0002C) /* GPIO Pin Output Clear Register GPIO <80:64> */ - -#define GRER0 __REG(0x40E00030) /* GPIO Rising-Edge Detect Register GPIO<31:0> */ -#define GRER1 __REG(0x40E00034) /* GPIO Rising-Edge Detect Register GPIO<63:32> */ -#define GRER2 __REG(0x40E00038) /* GPIO Rising-Edge Detect Register GPIO<80:64> */ - -#define GFER0 __REG(0x40E0003C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */ -#define GFER1 __REG(0x40E00040) /* GPIO Falling-Edge Detect Register GPIO<63:32> */ -#define GFER2 __REG(0x40E00044) /* GPIO Falling-Edge Detect Register GPIO<80:64> */ - -#define GEDR0 __REG(0x40E00048) /* GPIO Edge Detect Status Register GPIO<31:0> */ -#define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */ -#define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */ - -#define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */ -#define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */ -#define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */ -#define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */ -#define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */ -#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO<95-80> */ -#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */ -#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */ - -#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ -#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ -#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ -#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO<127:96> */ -#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ -#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<127:96> */ -#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ - -/* More handy macros. The argument is a literal GPIO number. */ - -#define GPIO_bit(x) (1 << ((x) & 0x1f)) - -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) - -/* Interrupt Controller */ - -#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) -#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) -#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3) -#define _GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3) -#define _GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3) -#define _GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3) -#define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) -#define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) - -#define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3)) -#define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3)) -#define GPSR(x) (*((((x) & 0x7f) < 96) ? &_GPSR(x) : &GPSR3)) -#define GPCR(x) (*((((x) & 0x7f) < 96) ? &_GPCR(x) : &GPCR3)) -#define GRER(x) (*((((x) & 0x7f) < 96) ? &_GRER(x) : &GRER3)) -#define GFER(x) (*((((x) & 0x7f) < 96) ? &_GFER(x) : &GFER3)) -#define GEDR(x) (*((((x) & 0x7f) < 96) ? &_GEDR(x) : &GEDR3)) -#define GAFR(x) (*((((x) & 0x7f) < 96) ? &_GAFR(x) : \ - ((((x) & 0x7f) < 112) ? &GAFR3_L : &GAFR3_U))) -#else - -#define GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) -#define GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) -#define GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3) -#define GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3) -#define GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3) -#define GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3) -#define GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) -#define GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) - -#endif - -/* - * Power Manager - see pxa2xx-regs.h - */ - -/* - * SSP Serial Port Registers - see arch/arm/mach-pxa/include/mach/regs-ssp.h - */ - -/* - * MultiMediaCard (MMC) controller - see drivers/mmc/host/pxamci.h - */ - -/* - * Core Clock - see arch/arm/mach-pxa/include/mach/pxa2xx-regs.h - */ - -#ifdef CONFIG_PXA27x - -/* Camera Interface */ -#define CICR0 __REG(0x50000000) -#define CICR1 __REG(0x50000004) -#define CICR2 __REG(0x50000008) -#define CICR3 __REG(0x5000000C) -#define CICR4 __REG(0x50000010) -#define CISR __REG(0x50000014) -#define CIFR __REG(0x50000018) -#define CITOR __REG(0x5000001C) -#define CIBR0 __REG(0x50000028) -#define CIBR1 __REG(0x50000030) -#define CIBR2 __REG(0x50000038) - -#define CICR0_DMAEN (1 << 31) /* DMA request enable */ -#define CICR0_PAR_EN (1 << 30) /* Parity enable */ -#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ -#define CICR0_ENB (1 << 28) /* Camera interface enable */ -#define CICR0_DIS (1 << 27) /* Camera interface disable */ -#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ -#define CICR0_TOM (1 << 9) /* Time-out mask */ -#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ -#define CICR0_FEM (1 << 7) /* FIFO-empty mask */ -#define CICR0_EOLM (1 << 6) /* End-of-line mask */ -#define CICR0_PERRM (1 << 5) /* Parity-error mask */ -#define CICR0_QDM (1 << 4) /* Quick-disable mask */ -#define CICR0_CDM (1 << 3) /* Disable-done mask */ -#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */ -#define CICR0_EOFM (1 << 1) /* End-of-frame mask */ -#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ - -#define CICR1_TBIT (1 << 31) /* Transparency bit */ -#define CICR1_RGBT_CONV (0x3 << 29) /* RGBT conversion mask */ -#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */ -#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ -#define CICR1_RGB_F (1 << 11) /* RGB format */ -#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ -#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */ -#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */ -#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */ -#define CICR1_DW (0x7 << 0) /* Data width mask */ - -#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock - wait count mask */ -#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock - wait count mask */ -#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */ -#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock - wait count mask */ -#define CICR2_FSW (0x7 << 0) /* Frame stabilization - wait count mask */ - -#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock - wait count mask */ -#define CICR3_EFW (0xff << 16) /* End-of-frame line clock - wait count mask */ -#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ -#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock - wait count mask */ -#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */ - -#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ -#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ -#define CICR4_PCP (1 << 22) /* Pixel clock polarity */ -#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */ -#define CICR4_VSP (1 << 20) /* Vertical sync polarity */ -#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */ -#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ -#define CICR4_DIV (0xff << 0) /* Clock divisor mask */ - -#define CISR_FTO (1 << 15) /* FIFO time-out */ -#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ -#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ -#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */ -#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */ -#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */ -#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */ -#define CISR_EOL (1 << 8) /* End of line */ -#define CISR_PAR_ERR (1 << 7) /* Parity error */ -#define CISR_CQD (1 << 6) /* Camera interface quick disable */ -#define CISR_CDD (1 << 5) /* Camera interface disable done */ -#define CISR_SOF (1 << 4) /* Start of frame */ -#define CISR_EOF (1 << 3) /* End of frame */ -#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ -#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ -#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */ - -#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */ -#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */ -#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */ -#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */ -#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */ -#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */ -#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */ -#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */ - -#define SRAM_SIZE 0x40000 /* 4x64K */ - -#define SRAM_MEM_PHYS 0x5C000000 - -#define IMPMCR __REG(0x58000000) /* IM Power Management Control Reg */ -#define IMPMSR __REG(0x58000008) /* IM Power Management Status Reg */ - -#define IMPMCR_PC3 (0x3 << 22) /* Bank 3 Power Control */ -#define IMPMCR_PC3_RUN_MODE (0x0 << 22) /* Run mode */ -#define IMPMCR_PC3_STANDBY_MODE (0x1 << 22) /* Standby mode */ -#define IMPMCR_PC3_AUTO_MODE (0x3 << 22) /* Automatically controlled */ - -#define IMPMCR_PC2 (0x3 << 20) /* Bank 2 Power Control */ -#define IMPMCR_PC2_RUN_MODE (0x0 << 20) /* Run mode */ -#define IMPMCR_PC2_STANDBY_MODE (0x1 << 20) /* Standby mode */ -#define IMPMCR_PC2_AUTO_MODE (0x3 << 20) /* Automatically controlled */ - -#define IMPMCR_PC1 (0x3 << 18) /* Bank 1 Power Control */ -#define IMPMCR_PC1_RUN_MODE (0x0 << 18) /* Run mode */ -#define IMPMCR_PC1_STANDBY_MODE (0x1 << 18) /* Standby mode */ -#define IMPMCR_PC1_AUTO_MODE (0x3 << 18) /* Automatically controlled */ - -#define IMPMCR_PC0 (0x3 << 16) /* Bank 0 Power Control */ -#define IMPMCR_PC0_RUN_MODE (0x0 << 16) /* Run mode */ -#define IMPMCR_PC0_STANDBY_MODE (0x1 << 16) /* Standby mode */ -#define IMPMCR_PC0_AUTO_MODE (0x3 << 16) /* Automatically controlled */ - -#define IMPMCR_AW3 (1 << 11) /* Bank 3 Automatic Wake-up enable */ -#define IMPMCR_AW2 (1 << 10) /* Bank 2 Automatic Wake-up enable */ -#define IMPMCR_AW1 (1 << 9) /* Bank 1 Automatic Wake-up enable */ -#define IMPMCR_AW0 (1 << 8) /* Bank 0 Automatic Wake-up enable */ - -#define IMPMCR_DST (0xFF << 0) /* Delay Standby Time, ms */ - -#define IMPMSR_PS3 (0x3 << 6) /* Bank 3 Power Status: */ -#define IMPMSR_PS3_RUN_MODE (0x0 << 6) /* Run mode */ -#define IMPMSR_PS3_STANDBY_MODE (0x1 << 6) /* Standby mode */ - -#define IMPMSR_PS2 (0x3 << 4) /* Bank 2 Power Status: */ -#define IMPMSR_PS2_RUN_MODE (0x0 << 4) /* Run mode */ -#define IMPMSR_PS2_STANDBY_MODE (0x1 << 4) /* Standby mode */ - -#define IMPMSR_PS1 (0x3 << 2) /* Bank 1 Power Status: */ -#define IMPMSR_PS1_RUN_MODE (0x0 << 2) /* Run mode */ -#define IMPMSR_PS1_STANDBY_MODE (0x1 << 2) /* Standby mode */ - -#define IMPMSR_PS0 (0x3 << 0) /* Bank 0 Power Status: */ -#define IMPMSR_PS0_RUN_MODE (0x0 << 0) /* Run mode */ -#define IMPMSR_PS0_STANDBY_MODE (0x1 << 0) /* Standby mode */ - -#endif - -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -/* - * UHC: USB Host Controller (OHCI-like) register definitions - */ -#define UHC_BASE_PHYS (0x4C000000) -#define UHCREV __REG(0x4C000000) /* UHC HCI Spec Revision */ -#define UHCHCON __REG(0x4C000004) /* UHC Host Control Register */ -#define UHCCOMS __REG(0x4C000008) /* UHC Command Status Register */ -#define UHCINTS __REG(0x4C00000C) /* UHC Interrupt Status Register */ -#define UHCINTE __REG(0x4C000010) /* UHC Interrupt Enable */ -#define UHCINTD __REG(0x4C000014) /* UHC Interrupt Disable */ -#define UHCHCCA __REG(0x4C000018) /* UHC Host Controller Comm. Area */ -#define UHCPCED __REG(0x4C00001C) /* UHC Period Current Endpt Descr */ -#define UHCCHED __REG(0x4C000020) /* UHC Control Head Endpt Descr */ -#define UHCCCED __REG(0x4C000024) /* UHC Control Current Endpt Descr */ -#define UHCBHED __REG(0x4C000028) /* UHC Bulk Head Endpt Descr */ -#define UHCBCED __REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */ -#define UHCDHEAD __REG(0x4C000030) /* UHC Done Head */ -#define UHCFMI __REG(0x4C000034) /* UHC Frame Interval */ -#define UHCFMR __REG(0x4C000038) /* UHC Frame Remaining */ -#define UHCFMN __REG(0x4C00003C) /* UHC Frame Number */ -#define UHCPERS __REG(0x4C000040) /* UHC Periodic Start */ -#define UHCLS __REG(0x4C000044) /* UHC Low Speed Threshold */ - -#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */ -#define UHCRHDA_NOCP (1 << 12) /* No over current protection */ - -#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */ -#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */ -#define UHCRHPS1 __REG(0x4C000054) /* UHC Root Hub Port 1 Status */ -#define UHCRHPS2 __REG(0x4C000058) /* UHC Root Hub Port 2 Status */ -#define UHCRHPS3 __REG(0x4C00005C) /* UHC Root Hub Port 3 Status */ - -#define UHCSTAT __REG(0x4C000060) /* UHC Status Register */ -#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ -#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ -#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ -#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ -#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ -#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ -#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ -#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ -#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */ - -#define UHCHR __REG(0x4C000064) /* UHC Reset Register */ -#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ -#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ -#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ -#define UHCHR_PCPL (1 << 7) /* Power control polarity low */ -#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ -#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ -#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ -#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ -#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ -#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ -#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */ - -#define UHCHIE __REG(0x4C000068) /* UHC Interrupt Enable Register*/ -#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ -#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ -#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ -#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ -#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort - Interrupt Enable*/ -#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ -#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */ - -#define UHCHIT __REG(0x4C00006C) /* UHC Interrupt Test register */ - -#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ - -/* PWRMODE register M field values */ - -#define PWRMODE_IDLE 0x1 -#define PWRMODE_STANDBY 0x2 -#define PWRMODE_SLEEP 0x3 -#define PWRMODE_DEEPSLEEP 0x7 - -#endif diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h new file mode 100644 index 00000000000..3ac0baac735 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa25x.h @@ -0,0 +1,17 @@ +#ifndef __MACH_PXA25x_H +#define __MACH_PXA25x_H + +#include <mach/hardware.h> +#include <mach/pxa2xx-regs.h> +#include <mach/mfp-pxa25x.h> +#include <mach/irqs.h> + +extern void __init pxa25x_map_io(void); +extern void __init pxa25x_init_irq(void); +#ifdef CONFIG_CPU_PXA26x +extern void __init pxa26x_init_irq(void); +#endif + +#define pxa25x_handle_irq icip_handle_irq + +#endif /* __MACH_PXA25x_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa27x-udc.h b/arch/arm/mach-pxa/include/mach/pxa27x-udc.h index ab1443f8bd8..4cf28f67070 100644 --- a/arch/arm/mach-pxa/include/mach/pxa27x-udc.h +++ b/arch/arm/mach-pxa/include/mach/pxa27x-udc.h @@ -56,9 +56,9 @@ #define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ #define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ #define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ -#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt +#define UDCOTGICR_IEXR (1 << 17) /* Extra Transceiver Interrupt Rising Edge Interrupt Enable */ -#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt +#define UDCOTGICR_IEXF (1 << 16) /* Extra Transceiver Interrupt Falling Edge Interrupt Enable */ #define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge Interrupt Enable */ diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h new file mode 100644 index 00000000000..7cff640582b --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa27x.h @@ -0,0 +1,29 @@ +#ifndef __MACH_PXA27x_H +#define __MACH_PXA27x_H + +#include <linux/suspend.h> +#include <mach/hardware.h> +#include <mach/pxa2xx-regs.h> +#include <mach/mfp-pxa27x.h> +#include <mach/irqs.h> + +#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ + +#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */ +#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */ +#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */ +#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */ +#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */ +#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */ +#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ +#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ +#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ + +extern void __init pxa27x_map_io(void); +extern void __init pxa27x_init_irq(void); +extern int __init pxa27x_set_pwrmode(unsigned int mode); +extern void pxa27x_cpu_pm_enter(suspend_state_t state); + +#define pxa27x_handle_irq ichp_handle_irq + +#endif /* __MACH_PXA27x_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h b/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h deleted file mode 100644 index d5a48a96dea..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __ASM_ARCH_PXA27x_KEYPAD_H -#define __ASM_ARCH_PXA27x_KEYPAD_H - -#include <linux/input.h> - -#define MAX_MATRIX_KEY_ROWS (8) -#define MAX_MATRIX_KEY_COLS (8) - -/* pxa3xx keypad platform specific parameters - * - * NOTE: - * 1. direct_key_num indicates the number of keys in the direct keypad - * _plus_ the number of rotary-encoder sensor inputs, this can be - * left as 0 if only rotary encoders are enabled, the driver will - * automatically calculate this - * - * 2. direct_key_map is the key code map for the direct keys, if rotary - * encoder(s) are enabled, direct key 0/1(2/3) will be ignored - * - * 3. rotary can be either interpreted as a relative input event (e.g. - * REL_WHEEL/REL_HWHEEL) or specific keys (e.g. UP/DOWN/LEFT/RIGHT) - * - * 4. matrix key and direct key will use the same debounce_interval by - * default, which should be sufficient in most cases - */ -struct pxa27x_keypad_platform_data { - - /* code map for the matrix keys */ - unsigned int matrix_key_rows; - unsigned int matrix_key_cols; - unsigned int *matrix_key_map; - int matrix_key_map_size; - - /* direct keys */ - int direct_key_num; - unsigned int direct_key_map[8]; - - /* rotary encoders 0 */ - int enable_rotary0; - int rotary0_rel_code; - int rotary0_up_key; - int rotary0_down_key; - - /* rotary encoders 1 */ - int enable_rotary1; - int rotary1_rel_code; - int rotary1_up_key; - int rotary1_down_key; - - /* key debounce interval */ - unsigned int debounce_interval; -}; - -#define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val)) - -extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info); - -#endif /* __ASM_ARCH_PXA27x_KEYPAD_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h b/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h deleted file mode 100644 index 6ef1dd09970..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h +++ /dev/null @@ -1,368 +0,0 @@ -#ifndef __ASM_ARCH_PXA2XX_GPIO_H -#define __ASM_ARCH_PXA2XX_GPIO_H - -#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h - -/* GPIO alternate function assignments */ - -#define GPIO1_RST 1 /* reset */ -#define GPIO6_MMCCLK 6 /* MMC Clock */ -#define GPIO7_48MHz 7 /* 48 MHz clock output */ -#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ -#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ -#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ -#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */ -#define GPIO12_32KHz 12 /* 32 kHz out */ -#define GPIO12_CIF_DD_7 12 /* Camera data pin 7 */ -#define GPIO13_MBGNT 13 /* memory controller grant */ -#define GPIO14_MBREQ 14 /* alternate bus master request */ -#define GPIO15_nCS_1 15 /* chip select 1 */ -#define GPIO16_PWM0 16 /* PWM0 output */ -#define GPIO17_PWM1 17 /* PWM1 output */ -#define GPIO17_CIF_DD_6 17 /* Camera data pin 6 */ -#define GPIO18_RDY 18 /* Ext. Bus Ready */ -#define GPIO19_DREQ1 19 /* External DMA Request */ -#define GPIO20_DREQ0 20 /* External DMA Request */ -#define GPIO23_SCLK 23 /* SSP clock */ -#define GPIO23_CIF_MCLK 23 /* Camera Master Clock */ -#define GPIO24_SFRM 24 /* SSP Frame */ -#define GPIO24_CIF_FV 24 /* Camera frame start signal */ -#define GPIO25_STXD 25 /* SSP transmit */ -#define GPIO25_CIF_LV 25 /* Camera line start signal */ -#define GPIO26_SRXD 26 /* SSP receive */ -#define GPIO26_CIF_PCLK 26 /* Camera Pixel Clock */ -#define GPIO27_SEXTCLK 27 /* SSP ext_clk */ -#define GPIO27_CIF_DD_0 27 /* Camera data pin 0 */ -#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */ -#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */ -#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ -#define GPIO31_SYNC 31 /* AC97/I2S sync */ -#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ -#define GPIO32_SYSCLK 32 /* I2S System Clock */ -#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ -#define GPIO33_nCS_5 33 /* chip select 5 */ -#define GPIO34_FFRXD 34 /* FFUART receive */ -#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ -#define GPIO35_FFCTS 35 /* FFUART Clear to send */ -#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */ -#define GPIO37_FFDSR 37 /* FFUART data set ready */ -#define GPIO38_FFRI 38 /* FFUART Ring Indicator */ -#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */ -#define GPIO39_FFTXD 39 /* FFUART transmit data */ -#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */ -#define GPIO41_FFRTS 41 /* FFUART request to send */ -#define GPIO42_BTRXD 42 /* BTUART receive data */ -#define GPIO42_HWRXD 42 /* HWUART receive data */ -#define GPIO42_CIF_MCLK 42 /* Camera Master Clock */ -#define GPIO43_BTTXD 43 /* BTUART transmit data */ -#define GPIO43_HWTXD 43 /* HWUART transmit data */ -#define GPIO43_CIF_FV 43 /* Camera frame start signal */ -#define GPIO44_BTCTS 44 /* BTUART clear to send */ -#define GPIO44_HWCTS 44 /* HWUART clear to send */ -#define GPIO44_CIF_LV 44 /* Camera line start signal */ -#define GPIO45_BTRTS 45 /* BTUART request to send */ -#define GPIO45_HWRTS 45 /* HWUART request to send */ -#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ -#define GPIO45_CIF_PCLK 45 /* Camera Pixel Clock */ -#define GPIO46_ICPRXD 46 /* ICP receive data */ -#define GPIO46_STRXD 46 /* STD_UART receive data */ -#define GPIO47_ICPTXD 47 /* ICP transmit data */ -#define GPIO47_STTXD 47 /* STD_UART transmit data */ -#define GPIO47_CIF_DD_0 47 /* Camera data pin 0 */ -#define GPIO48_nPOE 48 /* Output Enable for Card Space */ -#define GPIO48_CIF_DD_5 48 /* Camera data pin 5 */ -#define GPIO49_nPWE 49 /* Write Enable for Card Space */ -#define GPIO50_nPIOR 50 /* I/O Read for Card Space */ -#define GPIO50_CIF_DD_3 50 /* Camera data pin 3 */ -#define GPIO51_nPIOW 51 /* I/O Write for Card Space */ -#define GPIO51_CIF_DD_2 51 /* Camera data pin 2 */ -#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */ -#define GPIO52_CIF_DD_4 52 /* Camera data pin 4 */ -#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */ -#define GPIO53_MMCCLK 53 /* MMC Clock */ -#define GPIO53_CIF_MCLK 53 /* Camera Master Clock */ -#define GPIO54_MMCCLK 54 /* MMC Clock */ -#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ -#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27x) */ -#define GPIO54_CIF_PCLK 54 /* Camera Pixel Clock */ -#define GPIO55_nPREG 55 /* Card Address bit 26 */ -#define GPIO55_CIF_DD_1 55 /* Camera data pin 1 */ -#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ -#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ -#define GPIO58_LDD_0 58 /* LCD data pin 0 */ -#define GPIO59_LDD_1 59 /* LCD data pin 1 */ -#define GPIO60_LDD_2 60 /* LCD data pin 2 */ -#define GPIO61_LDD_3 61 /* LCD data pin 3 */ -#define GPIO62_LDD_4 62 /* LCD data pin 4 */ -#define GPIO63_LDD_5 63 /* LCD data pin 5 */ -#define GPIO64_LDD_6 64 /* LCD data pin 6 */ -#define GPIO65_LDD_7 65 /* LCD data pin 7 */ -#define GPIO66_LDD_8 66 /* LCD data pin 8 */ -#define GPIO66_MBREQ 66 /* alternate bus master req */ -#define GPIO67_LDD_9 67 /* LCD data pin 9 */ -#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */ -#define GPIO68_LDD_10 68 /* LCD data pin 10 */ -#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */ -#define GPIO69_LDD_11 69 /* LCD data pin 11 */ -#define GPIO69_MMCCLK 69 /* MMC_CLK */ -#define GPIO70_LDD_12 70 /* LCD data pin 12 */ -#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */ -#define GPIO71_LDD_13 71 /* LCD data pin 13 */ -#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */ -#define GPIO72_LDD_14 72 /* LCD data pin 14 */ -#define GPIO72_32kHz 72 /* 32 kHz clock */ -#define GPIO73_LDD_15 73 /* LCD data pin 15 */ -#define GPIO73_MBGNT 73 /* Memory controller grant */ -#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */ -#define GPIO75_LCD_LCLK 75 /* LCD line clock */ -#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */ -#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ -#define GPIO78_nCS_2 78 /* chip select 2 */ -#define GPIO79_nCS_3 79 /* chip select 3 */ -#define GPIO80_nCS_4 80 /* chip select 4 */ -#define GPIO81_NSCLK 81 /* NSSP clock */ -#define GPIO81_CIF_DD_0 81 /* Camera data pin 0 */ -#define GPIO82_NSFRM 82 /* NSSP Frame */ -#define GPIO82_CIF_DD_5 82 /* Camera data pin 5 */ -#define GPIO83_NSTXD 83 /* NSSP transmit */ -#define GPIO83_CIF_DD_4 83 /* Camera data pin 4 */ -#define GPIO84_NSRXD 84 /* NSSP receive */ -#define GPIO84_CIF_FV 84 /* Camera frame start signal */ -#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ -#define GPIO85_CIF_LV 85 /* Camera line start signal */ -#define GPIO90_CIF_DD_4 90 /* Camera data pin 4 */ -#define GPIO91_CIF_DD_5 91 /* Camera data pin 5 */ -#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ -#define GPIO93_CIF_DD_6 93 /* Camera data pin 6 */ -#define GPIO94_CIF_DD_5 94 /* Camera data pin 5 */ -#define GPIO95_CIF_DD_4 95 /* Camera data pin 4 */ -#define GPIO96_FFRXD 96 /* FFUART recieve */ -#define GPIO98_FFRTS 98 /* FFUART request to send */ -#define GPIO98_CIF_DD_0 98 /* Camera data pin 0 */ -#define GPIO99_FFTXD 99 /* FFUART transmit data */ -#define GPIO100_FFCTS 100 /* FFUART Clear to send */ -#define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ -#define GPIO103_CIF_DD_3 103 /* Camera data pin 3 */ -#define GPIO104_CIF_DD_2 104 /* Camera data pin 2 */ -#define GPIO105_CIF_DD_1 105 /* Camera data pin 1 */ -#define GPIO106_CIF_DD_9 106 /* Camera data pin 9 */ -#define GPIO107_CIF_DD_8 107 /* Camera data pin 8 */ -#define GPIO108_CIF_DD_7 108 /* Camera data pin 7 */ -#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ -#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ -#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ -#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ -#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ -#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ -#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ -#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ -#define GPIO114_CIF_DD_1 114 /* Camera data pin 1 */ -#define GPIO115_CIF_DD_3 115 /* Camera data pin 3 */ -#define GPIO116_CIF_DD_2 116 /* Camera data pin 2 */ - -/* GPIO alternate function mode & direction */ - -#define GPIO_IN 0x000 -#define GPIO_OUT 0x080 -#define GPIO_ALT_FN_1_IN 0x100 -#define GPIO_ALT_FN_1_OUT 0x180 -#define GPIO_ALT_FN_2_IN 0x200 -#define GPIO_ALT_FN_2_OUT 0x280 -#define GPIO_ALT_FN_3_IN 0x300 -#define GPIO_ALT_FN_3_OUT 0x380 -#define GPIO_MD_MASK_NR 0x07f -#define GPIO_MD_MASK_DIR 0x080 -#define GPIO_MD_MASK_FN 0x300 -#define GPIO_DFLT_LOW 0x400 -#define GPIO_DFLT_HIGH 0x800 - -#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) -#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) -#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) -#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) -#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) -#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) -#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) -#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) -#define GPIO12_CIF_DD_7_MD (12 | GPIO_ALT_FN_2_IN) -#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) -#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN) -#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT) -#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT) -#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT) -#define GPIO17_CIF_DD_6_MD (17 | GPIO_ALT_FN_2_IN) -#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN) -#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN) -#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN) -#define GPIO23_CIF_MCLK_MD (23 | GPIO_ALT_FN_1_OUT) -#define GPIO23_SCLK_MD (23 | GPIO_ALT_FN_2_OUT) -#define GPIO24_CIF_FV_MD (24 | GPIO_ALT_FN_1_OUT) -#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT) -#define GPIO25_CIF_LV_MD (25 | GPIO_ALT_FN_1_OUT) -#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) -#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) -#define GPIO26_CIF_PCLK_MD (26 | GPIO_ALT_FN_2_IN) -#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) -#define GPIO27_CIF_DD_0_MD (27 | GPIO_ALT_FN_3_IN) -#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) -#define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) -#define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) -#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) -#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) -#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) -#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) -#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) -#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) -#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) -#define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) -#define GPIO32_MMCCLK_MD (32 | GPIO_ALT_FN_2_OUT) -#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) -#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) -#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) -#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -#define GPIO35_KP_MKOUT6_MD (35 | GPIO_ALT_FN_2_OUT) -#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN) -#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN) -#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN) -#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT) -#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) -#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) -#define GPIO41_KP_MKOUT7_MD (41 | GPIO_ALT_FN_1_OUT) -#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) -#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) -#define GPIO42_CIF_MCLK_MD (42 | GPIO_ALT_FN_3_OUT) -#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) -#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) -#define GPIO43_CIF_FV_MD (43 | GPIO_ALT_FN_3_OUT) -#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) -#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) -#define GPIO44_CIF_LV_MD (44 | GPIO_ALT_FN_3_OUT) -#define GPIO45_CIF_PCLK_MD (45 | GPIO_ALT_FN_3_IN) -#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) -#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) -#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) -#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) -#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) -#define GPIO47_CIF_DD_0_MD (47 | GPIO_ALT_FN_1_IN) -#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) -#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) -#define GPIO48_CIF_DD_5_MD (48 | GPIO_ALT_FN_1_IN) -#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) -#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) -#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) -#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) -#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) -#define GPIO50_CIF_DD_3_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) -#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO50_CIF_DD_3_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO51_CIF_DD_2_MD (51 | GPIO_ALT_FN_1_IN) -#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) -#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) -#define GPIO51_CIF_DD_2_MD (51 | GPIO_ALT_FN_1_IN) -#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) -#define GPIO52_CIF_DD_4_MD (52 | GPIO_ALT_FN_1_IN) -#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) -#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) -#define GPIO53_CIF_MCLK_MD (53 | GPIO_ALT_FN_2_OUT) -#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) -#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) -#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) -#define GPIO54_CIF_PCLK_MD (54 | GPIO_ALT_FN_3_IN) -#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) -#define GPIO55_CIF_DD_1_MD (55 | GPIO_ALT_FN_1_IN) -#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) -#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) -#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) -#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT) -#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT) -#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT) -#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT) -#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT) -#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT) -#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT) -#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT) -#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN) -#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT) -#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT) -#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT) -#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT) -#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT) -#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT) -#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT) -#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT) -#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT) -#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT) -#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT) -#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT) -#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT) -#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT) -#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT) -#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT) -#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT) -#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) -#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) -#define GPIO78_nPCE_2_MD (78 | GPIO_ALT_FN_1_OUT) -#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) -#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) -#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) -#define GPIO81_NSSP_CLK_OUT (81 | GPIO_ALT_FN_1_OUT) -#define GPIO81_NSSP_CLK_IN (81 | GPIO_ALT_FN_1_IN) -#define GPIO81_CIF_DD_0_MD (81 | GPIO_ALT_FN_2_IN) -#define GPIO82_NSSP_FRM_OUT (82 | GPIO_ALT_FN_1_OUT) -#define GPIO82_NSSP_FRM_IN (82 | GPIO_ALT_FN_1_IN) -#define GPIO82_CIF_DD_5_MD (82 | GPIO_ALT_FN_3_IN) -#define GPIO83_NSSP_TX (83 | GPIO_ALT_FN_1_OUT) -#define GPIO83_NSSP_RX (83 | GPIO_ALT_FN_2_IN) -#define GPIO83_CIF_DD_4_MD (83 | GPIO_ALT_FN_3_IN) -#define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) -#define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) -#define GPIO84_CIF_FV_MD (84 | GPIO_ALT_FN_3_IN) -#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) -#define GPIO85_CIF_LV_MD (85 | GPIO_ALT_FN_3_IN) -#define GPIO86_nPCE_1_MD (86 | GPIO_ALT_FN_1_OUT) -#define GPIO88_USBH1_PWR_MD (88 | GPIO_ALT_FN_1_IN) -#define GPIO89_USBH1_PEN_MD (89 | GPIO_ALT_FN_2_OUT) -#define GPIO90_CIF_DD_4_MD (90 | GPIO_ALT_FN_3_IN) -#define GPIO91_CIF_DD_5_MD (91 | GPIO_ALT_FN_3_IN) -#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) -#define GPIO93_CIF_DD_6_MD (93 | GPIO_ALT_FN_2_IN) -#define GPIO94_CIF_DD_5_MD (94 | GPIO_ALT_FN_2_IN) -#define GPIO95_CIF_DD_4_MD (95 | GPIO_ALT_FN_2_IN) -#define GPIO95_KP_MKIN6_MD (95 | GPIO_ALT_FN_3_IN) -#define GPIO96_KP_DKIN3_MD (96 | GPIO_ALT_FN_1_IN) -#define GPIO96_FFRXD_MD (96 | GPIO_ALT_FN_3_IN) -#define GPIO97_KP_MKIN3_MD (97 | GPIO_ALT_FN_3_IN) -#define GPIO98_CIF_DD_0_MD (98 | GPIO_ALT_FN_2_IN) -#define GPIO98_FFRTS_MD (98 | GPIO_ALT_FN_3_OUT) -#define GPIO99_FFTXD_MD (99 | GPIO_ALT_FN_3_OUT) -#define GPIO100_KP_MKIN0_MD (100 | GPIO_ALT_FN_1_IN) -#define GPIO101_KP_MKIN1_MD (101 | GPIO_ALT_FN_1_IN) -#define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) -#define GPIO102_KP_MKIN2_MD (102 | GPIO_ALT_FN_1_IN) -#define GPIO103_CIF_DD_3_MD (103 | GPIO_ALT_FN_1_IN) -#define GPIO103_KP_MKOUT0_MD (103 | GPIO_ALT_FN_2_OUT) -#define GPIO104_CIF_DD_2_MD (104 | GPIO_ALT_FN_1_IN) -#define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) -#define GPIO104_KP_MKOUT1_MD (104 | GPIO_ALT_FN_2_OUT) -#define GPIO105_CIF_DD_1_MD (105 | GPIO_ALT_FN_1_IN) -#define GPIO105_KP_MKOUT2_MD (105 | GPIO_ALT_FN_2_OUT) -#define GPIO106_CIF_DD_9_MD (106 | GPIO_ALT_FN_1_IN) -#define GPIO106_KP_MKOUT3_MD (106 | GPIO_ALT_FN_2_OUT) -#define GPIO107_CIF_DD_8_MD (107 | GPIO_ALT_FN_1_IN) -#define GPIO107_KP_MKOUT4_MD (107 | GPIO_ALT_FN_2_OUT) -#define GPIO108_CIF_DD_7_MD (108 | GPIO_ALT_FN_1_IN) -#define GPIO108_KP_MKOUT5_MD (108 | GPIO_ALT_FN_2_OUT) -#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) -#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) -#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) -#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_IN) -#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) - -#endif /* __ASM_ARCH_PXA2XX_GPIO_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h index 806ecfea44b..ee6ced1cea7 100644 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h @@ -14,73 +14,7 @@ #ifndef __PXA2XX_REGS_H #define __PXA2XX_REGS_H -/* - * Memory controller - */ - -#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */ -#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */ -#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */ -#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */ -#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */ -#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ -#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ -#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */ -#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */ -#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */ -#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */ -#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ -#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */ -#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */ -#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */ -#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */ -#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ - -/* - * More handy macros for PCMCIA - * - * Arg is socket number - */ -#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */ -#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */ -#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */ - -/* MECR register defines */ -#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ -#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ - -#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */ -#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ -#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ -#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ -#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ -#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ -#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ -#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ -#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ -#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ -#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ -#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ -#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ -#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ - - -#ifdef CONFIG_PXA27x - -#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ - -#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */ -#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */ -#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */ -#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */ -#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */ -#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */ -#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ -#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ -#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ - -#endif - +#include <mach/hardware.h> /* * Power Manager @@ -243,4 +177,11 @@ #define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */ #define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ +/* PWRMODE register M field values */ + +#define PWRMODE_IDLE 0x1 +#define PWRMODE_STANDBY 0x2 +#define PWRMODE_SLEEP 0x3 +#define PWRMODE_DEEPSLEEP 0x7 + #endif diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h b/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h deleted file mode 100644 index 2206cb61a9f..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs - * - * 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 PXA2XX_SPI_H_ -#define PXA2XX_SPI_H_ - -#define PXA2XX_CS_ASSERT (0x01) -#define PXA2XX_CS_DEASSERT (0x02) - -/* device.platform_data for SSP controller devices */ -struct pxa2xx_spi_master { - u32 clock_enable; - u16 num_chipselect; - u8 enable_dma; -}; - -/* spi_board_info.controller_data for SPI slave devices, - * copied to spi_device.platform_data ... mostly for dma tuning - */ -struct pxa2xx_spi_chip { - u8 tx_threshold; - u8 rx_threshold; - u8 dma_burst_size; - u32 timeout; - u8 enable_loopback; - void (*cs_control)(u32 command); -}; - -extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info); - -#endif /*PXA2XX_SPI_H_*/ diff --git a/arch/arm/mach-pxa/include/mach/pxa300.h b/arch/arm/mach-pxa/include/mach/pxa300.h new file mode 100644 index 00000000000..733b6412c3d --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa300.h @@ -0,0 +1,7 @@ +#ifndef __MACH_PXA300_H +#define __MACH_PXA300_H + +#include <mach/pxa3xx.h> +#include <mach/mfp-pxa300.h> + +#endif /* __MACH_PXA300_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa320.h b/arch/arm/mach-pxa/include/mach/pxa320.h new file mode 100644 index 00000000000..b6204e470d8 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa320.h @@ -0,0 +1,8 @@ +#ifndef __MACH_PXA320_H +#define __MACH_PXA320_H + +#include <mach/pxa3xx.h> +#include <mach/mfp-pxa320.h> + +#endif /* __MACH_PXA320_H */ + diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h index 39eb68319e2..f4d48d20754 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h @@ -13,6 +13,8 @@ #ifndef __ASM_ARCH_PXA3XX_REGS_H #define __ASM_ARCH_PXA3XX_REGS_H +#include <mach/hardware.h> + /* * Oscillator Configuration Register (OSCC) */ @@ -36,7 +38,7 @@ #define PCMD(x) __REG(0x40F50110 + ((x) << 2)) /* - * Slave Power Managment Unit + * Slave Power Management Unit */ #define ASCR __REG(0x40f40000) /* Application Subsystem Power Status/Configuration */ #define ARSR __REG(0x40f40004) /* Application Subsystem Reset Status */ @@ -129,8 +131,31 @@ #define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */ #define CKENA __REG(0x4134000C) /* A Clock Enable Register */ #define CKENB __REG(0x41340010) /* B Clock Enable Register */ +#define CKENC __REG(0x41340024) /* C Clock Enable Register */ #define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */ +#define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */ +#define ACCR_SPDIS (1 << 30) /* System PLL Output Disable */ +#define ACCR_D0CS (1 << 26) /* D0 Mode Clock Select */ +#define ACCR_PCCE (1 << 11) /* Power Mode Change Clock Enable */ +#define ACCR_DDR_D0CS (1 << 7) /* DDR SDRAM clock frequency in D0CS (PXA31x only) */ + +#define ACCR_SMCFS_MASK (0x7 << 23) /* Static Memory Controller Frequency Select */ +#define ACCR_SFLFS_MASK (0x3 << 18) /* Frequency Select for Internal Memory Controller */ +#define ACCR_XSPCLK_MASK (0x3 << 16) /* Core Frequency during Frequency Change */ +#define ACCR_HSS_MASK (0x3 << 14) /* System Bus-Clock Frequency Select */ +#define ACCR_DMCFS_MASK (0x3 << 12) /* Dynamic Memory Controller Clock Frequency Select */ +#define ACCR_XN_MASK (0x7 << 8) /* Core PLL Turbo-Mode-to-Run-Mode Ratio */ +#define ACCR_XL_MASK (0x1f) /* Core PLL Run-Mode-to-Oscillator Ratio */ + +#define ACCR_SMCFS(x) (((x) & 0x7) << 23) +#define ACCR_SFLFS(x) (((x) & 0x3) << 18) +#define ACCR_XSPCLK(x) (((x) & 0x3) << 16) +#define ACCR_HSS(x) (((x) & 0x3) << 14) +#define ACCR_DMCFS(x) (((x) & 0x3) << 12) +#define ACCR_XN(x) (((x) & 0x7) << 8) +#define ACCR_XL(x) ((x) & 0x1f) + /* * Clock Enable Bit */ @@ -171,13 +196,11 @@ #define CKEN_MINI_IM 48 /* < Mini-IM */ #define CKEN_MINI_LCD 49 /* < Mini LCD */ -#if defined(CONFIG_CPU_PXA310) #define CKEN_MMC3 5 /* < MMC3 Clock Enable */ #define CKEN_MVED 43 /* < MVED clock enable */ -#endif /* Note: GCU clock enable bit differs on PXA300/PXA310 and PXA320 */ -#define PXA300_CKEN_GRAPHICS 42 /* Graphics controller clock enable */ -#define PXA320_CKEN_GRAPHICS 7 /* Graphics controller clock enable */ +#define CKEN_PXA300_GCU 42 /* Graphics controller clock enable */ +#define CKEN_PXA320_GCU 7 /* Graphics controller clock enable */ #endif /* __ASM_ARCH_PXA3XX_REGS_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx.h b/arch/arm/mach-pxa/include/mach/pxa3xx.h new file mode 100644 index 00000000000..6dd7fa163e2 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa3xx.h @@ -0,0 +1,13 @@ +#ifndef __MACH_PXA3XX_H +#define __MACH_PXA3XX_H + +#include <mach/hardware.h> +#include <mach/pxa3xx-regs.h> +#include <mach/irqs.h> + +extern void __init pxa3xx_map_io(void); +extern void __init pxa3xx_init_irq(void); + +#define pxa3xx_handle_irq ichp_handle_irq + +#endif /* __MACH_PXA3XX_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h deleted file mode 100644 index eb4b190b665..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __ASM_ARCH_PXA3XX_NAND_H -#define __ASM_ARCH_PXA3XX_NAND_H - -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> - -struct pxa3xx_nand_platform_data { - - /* the data flash bus is shared between the Static Memory - * Controller and the Data Flash Controller, the arbiter - * controls the ownership of the bus - */ - int enable_arbiter; - - struct mtd_partition *parts; - unsigned int nr_parts; -}; - -extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); -#endif /* __ASM_ARCH_PXA3XX_NAND_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa930.h b/arch/arm/mach-pxa/include/mach/pxa930.h new file mode 100644 index 00000000000..190363b98d0 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa930.h @@ -0,0 +1,7 @@ +#ifndef __MACH_PXA930_H +#define __MACH_PXA930_H + +#include <mach/pxa3xx.h> +#include <mach/mfp-pxa930.h> + +#endif /* __MACH_PXA930_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h deleted file mode 100644 index 8e591118371..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxafb.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/pxafb.h - * - * Support for the xscale frame buffer. - * - * Author: Jean-Frederic Clere - * Created: Sep 22, 2003 - * Copyright: jfclere@sinix.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/fb.h> -#include <mach/regs-lcd.h> - -/* - * Supported LCD connections - * - * bits 0 - 3: for LCD panel type: - * - * STN - for passive matrix - * DSTN - for dual scan passive matrix - * TFT - for active matrix - * - * bits 4 - 9 : for bus width - * bits 10-17 : for AC Bias Pin Frequency - * bit 18 : for output enable polarity - * bit 19 : for pixel clock edge - * bit 20 : for output pixel format when base is RGBT16 - */ -#define LCD_CONN_TYPE(_x) ((_x) & 0x0f) -#define LCD_CONN_WIDTH(_x) (((_x) >> 4) & 0x1f) - -#define LCD_TYPE_UNKNOWN 0 -#define LCD_TYPE_MONO_STN 1 -#define LCD_TYPE_MONO_DSTN 2 -#define LCD_TYPE_COLOR_STN 3 -#define LCD_TYPE_COLOR_DSTN 4 -#define LCD_TYPE_COLOR_TFT 5 -#define LCD_TYPE_SMART_PANEL 6 -#define LCD_TYPE_MAX 7 - -#define LCD_MONO_STN_4BPP ((4 << 4) | LCD_TYPE_MONO_STN) -#define LCD_MONO_STN_8BPP ((8 << 4) | LCD_TYPE_MONO_STN) -#define LCD_MONO_DSTN_8BPP ((8 << 4) | LCD_TYPE_MONO_DSTN) -#define LCD_COLOR_STN_8BPP ((8 << 4) | LCD_TYPE_COLOR_STN) -#define LCD_COLOR_DSTN_16BPP ((16 << 4) | LCD_TYPE_COLOR_DSTN) -#define LCD_COLOR_TFT_16BPP ((16 << 4) | LCD_TYPE_COLOR_TFT) -#define LCD_COLOR_TFT_18BPP ((18 << 4) | LCD_TYPE_COLOR_TFT) -#define LCD_SMART_PANEL_8BPP ((8 << 4) | LCD_TYPE_SMART_PANEL) -#define LCD_SMART_PANEL_16BPP ((16 << 4) | LCD_TYPE_SMART_PANEL) -#define LCD_SMART_PANEL_18BPP ((18 << 4) | LCD_TYPE_SMART_PANEL) - -#define LCD_AC_BIAS_FREQ(x) (((x) & 0xff) << 10) -#define LCD_BIAS_ACTIVE_HIGH (0 << 18) -#define LCD_BIAS_ACTIVE_LOW (1 << 18) -#define LCD_PCLK_EDGE_RISE (0 << 19) -#define LCD_PCLK_EDGE_FALL (1 << 19) -#define LCD_ALTERNATE_MAPPING (1 << 20) - -/* - * This structure describes the machine which we are running on. - * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine - * of linux/drivers/video/pxafb.c - */ -struct pxafb_mode_info { - u_long pixclock; - - u_short xres; - u_short yres; - - u_char bpp; - u_int cmap_greyscale:1, - depth:8, - unused:23; - - /* Parallel Mode Timing */ - u_char hsync_len; - u_char left_margin; - u_char right_margin; - - u_char vsync_len; - u_char upper_margin; - u_char lower_margin; - u_char sync; - - /* Smart Panel Mode Timing - see PXA27x DM 7.4.15.0.3 for details - * Note: - * 1. all parameters in nanosecond (ns) - * 2. a0cs{rd,wr}_set_hld are controlled by the same register bits - * in pxa27x and pxa3xx, initialize them to the same value or - * the larger one will be used - * 3. same to {rd,wr}_pulse_width - */ - unsigned a0csrd_set_hld; /* A0 and CS Setup/Hold Time before/after L_FCLK_RD */ - unsigned a0cswr_set_hld; /* A0 and CS Setup/Hold Time before/after L_PCLK_WR */ - unsigned wr_pulse_width; /* L_PCLK_WR pulse width */ - unsigned rd_pulse_width; /* L_FCLK_RD pulse width */ - unsigned cmd_inh_time; /* Command Inhibit time between two writes */ - unsigned op_hold_time; /* Output Hold time from L_FCLK_RD negation */ -}; - -struct pxafb_mach_info { - struct pxafb_mode_info *modes; - unsigned int num_modes; - - unsigned int lcd_conn; - - u_int fixed_modes:1, - cmap_inverse:1, - cmap_static:1, - unused:29; - - /* The following should be defined in LCCR0 - * LCCR0_Act or LCCR0_Pas Active or Passive - * LCCR0_Sngl or LCCR0_Dual Single/Dual panel - * LCCR0_Mono or LCCR0_Color Mono/Color - * LCCR0_4PixMono or LCCR0_8PixMono (in mono single mode) - * LCCR0_DMADel(Tcpu) (optional) DMA request delay - * - * The following should not be defined in LCCR0: - * LCCR0_OUM, LCCR0_BM, LCCR0_QDM, LCCR0_DIS, LCCR0_EFM - * LCCR0_IUM, LCCR0_SFM, LCCR0_LDM, LCCR0_ENB - */ - u_int lccr0; - /* The following should be defined in LCCR3 - * LCCR3_OutEnH or LCCR3_OutEnL Output enable polarity - * LCCR3_PixRsEdg or LCCR3_PixFlEdg Pixel clock edge type - * LCCR3_Acb(X) AB Bias pin frequency - * LCCR3_DPC (optional) Double Pixel Clock mode (untested) - * - * The following should not be defined in LCCR3 - * LCCR3_HSP, LCCR3_VSP, LCCR0_Pcd(x), LCCR3_Bpp - */ - u_int lccr3; - /* The following should be defined in LCCR4 - * LCCR4_PAL_FOR_0 or LCCR4_PAL_FOR_1 or LCCR4_PAL_FOR_2 - * - * All other bits in LCCR4 should be left alone. - */ - u_int lccr4; - void (*pxafb_backlight_power)(int); - void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); - void (*smart_update)(struct fb_info *); -}; -void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info); -void set_pxa_fb_parent(struct device *parent_dev); -unsigned long pxafb_get_hsync_time(struct device *dev); - -extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int); -extern int pxafb_smart_flush(struct fb_info *info); diff --git a/arch/arm/mach-pxa/include/mach/regs-ac97.h b/arch/arm/mach-pxa/include/mach/regs-ac97.h new file mode 100644 index 00000000000..b8d14bd9ae5 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-ac97.h @@ -0,0 +1,101 @@ +#ifndef __ASM_ARCH_REGS_AC97_H +#define __ASM_ARCH_REGS_AC97_H + +#include <mach/hardware.h> + +/* + * AC97 Controller registers + */ + +#define POCR __REG(0x40500000) /* PCM Out Control Register */ +#define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ +#define POCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define PICR __REG(0x40500004) /* PCM In Control Register */ +#define PICR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ +#define PICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define MCCR __REG(0x40500008) /* Mic In Control Register */ +#define MCCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ +#define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define GCR __REG(0x4050000C) /* Global Control Register */ +#ifdef CONFIG_PXA3xx +#define GCR_CLKBPB (1 << 31) /* Internal clock enable */ +#endif +#define GCR_nDMAEN (1 << 24) /* non DMA Enable */ +#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */ +#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */ +#define GCR_SECRDY_IEN (1 << 9) /* Secondary Ready Interrupt Enable */ +#define GCR_PRIRDY_IEN (1 << 8) /* Primary Ready Interrupt Enable */ +#define GCR_SECRES_IEN (1 << 5) /* Secondary Resume Interrupt Enable */ +#define GCR_PRIRES_IEN (1 << 4) /* Primary Resume Interrupt Enable */ +#define GCR_ACLINK_OFF (1 << 3) /* AC-link Shut Off */ +#define GCR_WARM_RST (1 << 2) /* AC97 Warm Reset */ +#define GCR_COLD_RST (1 << 1) /* AC'97 Cold Reset (0 = active) */ +#define GCR_GIE (1 << 0) /* Codec GPI Interrupt Enable */ + +#define POSR __REG(0x40500010) /* PCM Out Status Register */ +#define POSR_FIFOE (1 << 4) /* FIFO error */ +#define POSR_FSR (1 << 2) /* FIFO Service Request */ + +#define PISR __REG(0x40500014) /* PCM In Status Register */ +#define PISR_FIFOE (1 << 4) /* FIFO error */ +#define PISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ +#define PISR_FSR (1 << 2) /* FIFO Service Request */ + +#define MCSR __REG(0x40500018) /* Mic In Status Register */ +#define MCSR_FIFOE (1 << 4) /* FIFO error */ +#define MCSR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ +#define MCSR_FSR (1 << 2) /* FIFO Service Request */ + +#define GSR __REG(0x4050001C) /* Global Status Register */ +#define GSR_CDONE (1 << 19) /* Command Done */ +#define GSR_SDONE (1 << 18) /* Status Done */ +#define GSR_RDCS (1 << 15) /* Read Completion Status */ +#define GSR_BIT3SLT12 (1 << 14) /* Bit 3 of slot 12 */ +#define GSR_BIT2SLT12 (1 << 13) /* Bit 2 of slot 12 */ +#define GSR_BIT1SLT12 (1 << 12) /* Bit 1 of slot 12 */ +#define GSR_SECRES (1 << 11) /* Secondary Resume Interrupt */ +#define GSR_PRIRES (1 << 10) /* Primary Resume Interrupt */ +#define GSR_SCR (1 << 9) /* Secondary Codec Ready */ +#define GSR_PCR (1 << 8) /* Primary Codec Ready */ +#define GSR_MCINT (1 << 7) /* Mic In Interrupt */ +#define GSR_POINT (1 << 6) /* PCM Out Interrupt */ +#define GSR_PIINT (1 << 5) /* PCM In Interrupt */ +#define GSR_ACOFFD (1 << 3) /* AC-link Shut Off Done */ +#define GSR_MOINT (1 << 2) /* Modem Out Interrupt */ +#define GSR_MIINT (1 << 1) /* Modem In Interrupt */ +#define GSR_GSCI (1 << 0) /* Codec GPI Status Change Interrupt */ + +#define CAR __REG(0x40500020) /* CODEC Access Register */ +#define CAR_CAIP (1 << 0) /* Codec Access In Progress */ + +#define PCDR __REG(0x40500040) /* PCM FIFO Data Register */ +#define MCDR __REG(0x40500060) /* Mic-in FIFO Data Register */ + +#define MOCR __REG(0x40500100) /* Modem Out Control Register */ +#define MOCR_FEIE (1 << 3) /* FIFO Error */ +#define MOCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define MICR __REG(0x40500108) /* Modem In Control Register */ +#define MICR_FEIE (1 << 3) /* FIFO Error */ +#define MICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define MOSR __REG(0x40500110) /* Modem Out Status Register */ +#define MOSR_FIFOE (1 << 4) /* FIFO error */ +#define MOSR_FSR (1 << 2) /* FIFO Service Request */ + +#define MISR __REG(0x40500118) /* Modem In Status Register */ +#define MISR_FIFOE (1 << 4) /* FIFO error */ +#define MISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ +#define MISR_FSR (1 << 2) /* FIFO Service Request */ + +#define MODR __REG(0x40500140) /* Modem FIFO Data Register */ + +#define PAC_REG_BASE __REG(0x40500200) /* Primary Audio Codec */ +#define SAC_REG_BASE __REG(0x40500300) /* Secondary Audio Codec */ +#define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */ +#define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ + +#endif /* __ASM_ARCH_REGS_AC97_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-lcd.h b/arch/arm/mach-pxa/include/mach/regs-lcd.h index c689c4ea769..f82dcea792d 100644 --- a/arch/arm/mach-pxa/include/mach/regs-lcd.h +++ b/arch/arm/mach-pxa/include/mach/regs-lcd.h @@ -12,27 +12,29 @@ #define LCCR3 (0x00C) /* LCD Controller Control Register 3 */ #define LCCR4 (0x010) /* LCD Controller Control Register 4 */ #define LCCR5 (0x014) /* LCD Controller Control Register 5 */ -#define DFBR0 (0x020) /* DMA Channel 0 Frame Branch Register */ -#define DFBR1 (0x024) /* DMA Channel 1 Frame Branch Register */ -#define LCSR (0x038) /* LCD Controller Status Register */ +#define LCSR (0x038) /* LCD Controller Status Register 0 */ +#define LCSR1 (0x034) /* LCD Controller Status Register 1 */ #define LIIDR (0x03C) /* LCD Controller Interrupt ID Register */ #define TMEDRGBR (0x040) /* TMED RGB Seed Register */ #define TMEDCR (0x044) /* TMED Control Register */ +#define FBR0 (0x020) /* DMA Channel 0 Frame Branch Register */ +#define FBR1 (0x024) /* DMA Channel 1 Frame Branch Register */ +#define FBR2 (0x028) /* DMA Channel 2 Frame Branch Register */ +#define FBR3 (0x02C) /* DMA Channel 2 Frame Branch Register */ +#define FBR4 (0x030) /* DMA Channel 2 Frame Branch Register */ +#define FBR5 (0x110) /* DMA Channel 2 Frame Branch Register */ +#define FBR6 (0x114) /* DMA Channel 2 Frame Branch Register */ + +#define OVL1C1 (0x050) /* Overlay 1 Control Register 1 */ +#define OVL1C2 (0x060) /* Overlay 1 Control Register 2 */ +#define OVL2C1 (0x070) /* Overlay 2 Control Register 1 */ +#define OVL2C2 (0x080) /* Overlay 2 Control Register 2 */ + #define CMDCR (0x100) /* Command Control Register */ #define PRSR (0x104) /* Panel Read Status Register */ -#define LCCR3_1BPP (0 << 24) -#define LCCR3_2BPP (1 << 24) -#define LCCR3_4BPP (2 << 24) -#define LCCR3_8BPP (3 << 24) -#define LCCR3_16BPP (4 << 24) -#define LCCR3_18BPP (5 << 24) -#define LCCR3_18BPP_P (6 << 24) -#define LCCR3_19BPP (7 << 24) -#define LCCR3_19BPP_P (1 << 29) -#define LCCR3_24BPP ((1 << 29) | (1 << 24)) -#define LCCR3_25BPP ((1 << 29) | (2 << 24)) +#define LCCR3_BPP(x) ((((x) & 0x7) << 24) | (((x) & 0x8) ? (1 << 29) : 0)) #define LCCR3_PDFOR_0 (0 << 30) #define LCCR3_PDFOR_1 (1 << 30) @@ -42,19 +44,16 @@ #define LCCR4_PAL_FOR_0 (0 << 15) #define LCCR4_PAL_FOR_1 (1 << 15) #define LCCR4_PAL_FOR_2 (2 << 15) +#define LCCR4_PAL_FOR_3 (3 << 15) #define LCCR4_PAL_FOR_MASK (3 << 15) #define FDADR0 (0x200) /* DMA Channel 0 Frame Descriptor Address Register */ -#define FSADR0 (0x204) /* DMA Channel 0 Frame Source Address Register */ -#define FIDR0 (0x208) /* DMA Channel 0 Frame ID Register */ -#define LDCMD0 (0x20C) /* DMA Channel 0 Command Register */ #define FDADR1 (0x210) /* DMA Channel 1 Frame Descriptor Address Register */ -#define FSADR1 (0x214) /* DMA Channel 1 Frame Source Address Register */ -#define FIDR1 (0x218) /* DMA Channel 1 Frame ID Register */ -#define LDCMD1 (0x21C) /* DMA Channel 1 Command Register */ +#define FDADR2 (0x220) /* DMA Channel 2 Frame Descriptor Address Register */ +#define FDADR3 (0x230) /* DMA Channel 3 Frame Descriptor Address Register */ +#define FDADR4 (0x240) /* DMA Channel 4 Frame Descriptor Address Register */ +#define FDADR5 (0x250) /* DMA Channel 5 Frame Descriptor Address Register */ #define FDADR6 (0x260) /* DMA Channel 6 Frame Descriptor Address Register */ -#define FSADR6 (0x264) /* DMA Channel 6 Frame Source Address Register */ -#define FIDR6 (0x268) /* DMA Channel 6 Frame ID Register */ #define LCCR0_ENB (1 << 0) /* LCD Controller enable */ #define LCCR0_CMS (1 << 1) /* Color/Monochrome Display Select */ @@ -126,9 +125,6 @@ #define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ #define LCCR3_PixClkDiv(Div) (((Div) << FShft (LCCR3_PCD))) -#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ -#define LCCR3_Bpp(Bpp) (((Bpp) << FShft (LCCR3_BPP))) - #define LCCR3_ACB Fld (8, 8) /* AC Bias */ #define LCCR3_Acb(Acb) (((Acb) << FShft (LCCR3_ACB))) @@ -157,8 +153,22 @@ #define LCSR_RD_ST (1 << 11) /* read status */ #define LCSR_CMD_INT (1 << 12) /* command interrupt */ +#define LCSR1_IU(x) (1 << ((x) + 23)) /* Input FIFO underrun */ +#define LCSR1_BS(x) (1 << ((x) + 15)) /* Branch Status */ +#define LCSR1_EOF(x) (1 << ((x) + 7)) /* End of Frame Status */ +#define LCSR1_SOF(x) (1 << ((x) - 1)) /* Start of Frame Status */ + #define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ +/* overlay control registers */ +#define OVLxC1_PPL(x) ((((x) - 1) & 0x3ff) << 0) /* Pixels Per Line */ +#define OVLxC1_LPO(x) ((((x) - 1) & 0x3ff) << 10) /* Number of Lines */ +#define OVLxC1_BPP(x) (((x) & 0xf) << 20) /* Bits Per Pixel */ +#define OVLxC1_OEN (1 << 31) /* Enable bit for Overlay */ +#define OVLxC2_XPOS(x) (((x) & 0x3ff) << 0) /* Horizontal Position */ +#define OVLxC2_YPOS(x) (((x) & 0x3ff) << 10) /* Vertical Position */ +#define OVL2C2_PFOR(x) (((x) & 0x7) << 20) /* Pixel Format */ + /* smartpanel related */ #define PRSR_DATA(x) ((x) & 0xff) /* Panel Data */ #define PRSR_A0 (1 << 8) /* Read Data Source */ @@ -177,4 +187,11 @@ #define SMART_CMD(x) (SMART_CMD_WRITE_COMMAND | ((x) & 0xff)) #define SMART_DAT(x) (SMART_CMD_WRITE_DATA | ((x) & 0xff)) + +/* SMART_DELAY() is introduced for software controlled delay primitive which + * can be inserted between command sequences, unused command 0x6 is used here + * and delay ranges from 0ms ~ 255ms + */ +#define SMART_CMD_DELAY (0x6 << 9) +#define SMART_DELAY(ms) (SMART_CMD_DELAY | ((ms) & 0xff)) #endif /* __ASM_ARCH_REGS_LCD_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h new file mode 100644 index 00000000000..628819995c5 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-ost.h @@ -0,0 +1,34 @@ +#ifndef __ASM_MACH_REGS_OST_H +#define __ASM_MACH_REGS_OST_H + +#include <mach/hardware.h> + +/* + * OS Timer & Match Registers + */ + +#define OSMR0 io_p2v(0x40A00000) /* */ +#define OSMR1 io_p2v(0x40A00004) /* */ +#define OSMR2 io_p2v(0x40A00008) /* */ +#define OSMR3 io_p2v(0x40A0000C) /* */ +#define OSMR4 io_p2v(0x40A00080) /* */ +#define OSCR io_p2v(0x40A00010) /* OS Timer Counter Register */ +#define OSCR4 io_p2v(0x40A00040) /* OS Timer Counter Register */ +#define OMCR4 io_p2v(0x40A000C0) /* */ +#define OSSR io_p2v(0x40A00014) /* OS Timer Status Register */ +#define OWER io_p2v(0x40A00018) /* OS Timer Watchdog Enable Register */ +#define OIER io_p2v(0x40A0001C) /* OS Timer Interrupt Enable Register */ + +#define OSSR_M3 (1 << 3) /* Match status channel 3 */ +#define OSSR_M2 (1 << 2) /* Match status channel 2 */ +#define OSSR_M1 (1 << 1) /* Match status channel 1 */ +#define OSSR_M0 (1 << 0) /* Match status channel 0 */ + +#define OWER_WME (1 << 0) /* Watchdog Match Enable */ + +#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */ +#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */ +#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */ +#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */ + +#endif /* __ASM_MACH_REGS_OST_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-rtc.h b/arch/arm/mach-pxa/include/mach/regs-rtc.h new file mode 100644 index 00000000000..f0e4a589bbe --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-rtc.h @@ -0,0 +1,23 @@ +#ifndef __ASM_MACH_REGS_RTC_H +#define __ASM_MACH_REGS_RTC_H + +#include <mach/hardware.h> + +/* + * Real Time Clock + */ + +#define RCNR __REG(0x40900000) /* RTC Count Register */ +#define RTAR __REG(0x40900004) /* RTC Alarm Register */ +#define RTSR __REG(0x40900008) /* RTC Status Register */ +#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */ +#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ + +#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ +#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ +#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ +#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ +#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ +#define RTSR_AL (1 << 0) /* RTC alarm detected */ + +#endif /* __ASM_MACH_REGS_RTC_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h deleted file mode 100644 index 3c04cde2cf1..00000000000 --- a/arch/arm/mach-pxa/include/mach/regs-ssp.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef __ASM_ARCH_REGS_SSP_H -#define __ASM_ARCH_REGS_SSP_H - -/* - * SSP Serial Port Registers - * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. - * PXA255, PXA26x and PXA27x have extra ports, registers and bits. - */ - -#define SSCR0 (0x00) /* SSP Control Register 0 */ -#define SSCR1 (0x04) /* SSP Control Register 1 */ -#define SSSR (0x08) /* SSP Status Register */ -#define SSITR (0x0C) /* SSP Interrupt Test Register */ -#define SSDR (0x10) /* SSP Data Write/Data Read Register */ - -#define SSTO (0x28) /* SSP Time Out Register */ -#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ -#define SSTSA (0x30) /* SSP Tx Timeslot Active */ -#define SSRSA (0x34) /* SSP Rx Timeslot Active */ -#define SSTSS (0x38) /* SSP Timeslot Status */ -#define SSACD (0x3C) /* SSP Audio Clock Divider */ - -#if defined(CONFIG_PXA3xx) -#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ -#endif - -/* Common PXA2xx bits first */ -#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ -#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ -#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ -#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ -#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ -#define SSCR0_National (0x2 << 4) /* National Microwire */ -#define SSCR0_ECS (1 << 6) /* External clock select */ -#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ - -#if defined(CONFIG_PXA25x) -#define SSCR0_SCR (0x0000ff00) /* Serial Clock Rate (mask) */ -#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */ - -#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -#define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */ -#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */ -#define SSCR0_EDSS (1 << 20) /* Extended data size select */ -#define SSCR0_NCS (1 << 21) /* Network clock select */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ -#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ -#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ -#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ -#define SSCR0_ADC (1 << 30) /* Audio clock select */ -#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ -#endif - -#if defined(CONFIG_PXA3xx) -#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ -#endif - -#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ -#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ -#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ -#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ -#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ -#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ -#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ -#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ -#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ -#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ - -#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ -#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ -#define SSSR_BSY (1 << 4) /* SSP Busy */ -#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ -#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ -#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ - -#define SSCR0_TIM (1 << 23) /* Transmit FIFO Under Run Interrupt Mask */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO Over Run interrupt Mask */ -#define SSCR0_NCS (1 << 21) /* Network Clock Select */ -#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */ - -/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ -#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ -#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ -#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */ -#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */ -#define SSCR1_EBCEI (1 << 29) /* Enable Bit Count Error interrupt */ -#define SSCR1_SCFR (1 << 28) /* Slave Clock free Running */ -#define SSCR1_ECRA (1 << 27) /* Enable Clock Request A */ -#define SSCR1_ECRB (1 << 26) /* Enable Clock request B */ -#define SSCR1_SCLKDIR (1 << 25) /* Serial Bit Rate Clock Direction */ -#define SSCR1_SFRMDIR (1 << 24) /* Frame Direction */ -#define SSCR1_RWOT (1 << 23) /* Receive Without Transmit */ -#define SSCR1_TRAIL (1 << 22) /* Trailing Byte */ -#define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ -#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ -#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ -#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ -#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ -#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ -#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ - -#define SSSR_BCE (1 << 23) /* Bit Count Error */ -#define SSSR_CSS (1 << 22) /* Clock Synchronisation Status */ -#define SSSR_TUR (1 << 21) /* Transmit FIFO Under Run */ -#define SSSR_EOC (1 << 20) /* End Of Chain */ -#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ -#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ - -#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ -#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ -#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ -#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ -#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ -#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ -#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ -#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ -#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ - -#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ -#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ -#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ -#if defined(CONFIG_PXA3xx) -#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ -#endif - - -#endif /* __ASM_ARCH_REGS_SSP_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-u2d.h b/arch/arm/mach-pxa/include/mach/regs-u2d.h new file mode 100644 index 00000000000..c15c0c57de0 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-u2d.h @@ -0,0 +1,200 @@ +#ifndef __ASM_ARCH_PXA3xx_U2D_H +#define __ASM_ARCH_PXA3xx_U2D_H + +#include <mach/bitfield.h> + +/* + * USB2 device controller registers and bits definitions + */ +#define U2DCR (0x0000) /* U2D Control Register */ +#define U2DCR_NDC (1 << 31) /* NAK During Config */ +#define U2DCR_HSTC (0x7 << 28) /* High Speed Timeout Calibration */ +#define U2DCR_SPEOREN (1 << 27) /* Short Packet EOR INTR generation Enable */ +#define U2DCR_FSTC (0x7 << 24) /* Full Speed Timeout Calibration */ +#define U2DCR_UCLKOVR (1 << 22) /* UTM Clock Override */ +#define U2DCR_ABP (1 << 21) /* Application Bus Power */ +#define U2DCR_ADD (1 << 20) /* Application Device Disconnect */ +#define U2DCR_CC (1 << 19) /* Configuration Change */ +#define U2DCR_HS (1 << 18) /* High Speed USB Detection */ +#define U2DCR_SMAC (1 << 17) /* Switch Endpoint Memory to Active Configuration */ +#define U2DCR_DWRE (1 << 16) /* Device Remote Wake-up Feature */ +#define U2DCR_ACN (0xf << 12) /* Active U2D Configuration Number */ +#define U2DCR_AIN (0xf << 8) /* Active U2D Interface Number */ +#define U2DCR_AAISN (0xf << 4) /* Active U2D Alternate Interface Setting Number */ +#define U2DCR_EMCE (1 << 3) /* Endpoint Memory Configuration Error */ +#define U2DCR_UDR (1 << 2) /* U2D Resume */ +#define U2DCR_UDA (1 << 1) /* U2D Active */ +#define U2DCR_UDE (1 << 0) /* U2D Enable */ + +#define U2DICR (0x0004) /* U2D Interrupt Control Register */ +#define U2DISR (0x000C) /* U2D Interrupt Status Register */ +#define U2DINT_CC (1 << 31) /* Interrupt - Configuration Change */ +#define U2DINT_SOF (1 << 30) /* Interrupt - SOF */ +#define U2DINT_USOF (1 << 29) /* Interrupt - micro SOF */ +#define U2DINT_RU (1 << 28) /* Interrupt - Resume */ +#define U2DINT_SU (1 << 27) /* Interrupt - Suspend */ +#define U2DINT_RS (1 << 26) /* Interrupt - Reset */ +#define U2DINT_DPE (1 << 25) /* Interrupt - Data Packet Error */ +#define U2DINT_FIFOERR (0x4) /* Interrupt - endpoint FIFO error */ +#define U2DINT_PACKETCMP (0x2) /* Interrupt - endpoint packet complete */ +#define U2DINT_SPACKETCMP (0x1) /* Interrupt - endpoint short packet complete */ + +#define U2DFNR (0x0014) /* U2D Frame Number Register */ + +#define U2DINT(n, intr) (((intr) & 0x07) << (((n) & 0x07) * 3)) +#define U2DICR2 (0x0008) /* U2D Interrupt Control Register 2 */ +#define U2DISR2 (0x0010) /* U2D Interrupt Status Register 2 */ + +#define U2DOTGCR (0x0020) /* U2D OTG Control Register */ +#define U2DOTGCR_OTGEN (1 << 31) /* On-The-Go Enable */ +#define U2DOTGCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation Protocal Port Support */ +#define U2DOTGCR_AHNP (1 << 29) /* A-device Host Negotiation Protocal Support */ +#define U2DOTGCR_BHNP (1 << 28) /* B-device Host Negotiation Protocal Enable */ + +#ifdef CONFIG_CPU_PXA930 +#define U2DOTGCR_LPA (1 << 15) /* ULPI low power mode active */ +#define U2DOTGCR_IESI (1 << 13) /* OTG interrupt Enable */ +#define U2DOTGCR_ISSI (1 << 12) /* OTG interrupt status */ +#endif + +#define U2DOTGCR_CKAF (1 << 5) /* Carkit Mode Alternate Function Select */ +#define U2DOTGCR_UTMID (1 << 4) /* UTMI Interface Disable */ +#define U2DOTGCR_ULAF (1 << 3) /* ULPI Mode Alternate Function Select */ +#define U2DOTGCR_SMAF (1 << 2) /* Serial Mode Alternate Function Select */ +#define U2DOTGCR_RTSM (1 << 1) /* Return to Synchronous Mode (ULPI Mode) */ +#define U2DOTGCR_ULE (1 << 0) /* ULPI Wrapper Enable */ + +#define U2DOTGICR (0x0024) /* U2D OTG Interrupt Control Register */ +#define U2DOTGISR (0x0028) /* U2D OTG Interrupt Status Register */ + +#define U2DOTGINT_SF (1 << 17) /* OTG Set Feature Command Received */ +#define U2DOTGINT_SI (1 << 16) /* OTG Interrupt */ +#define U2DOTGINT_RLS1 (1 << 14) /* RXCMD Linestate[1] Change Interrupt Rise */ +#define U2DOTGINT_RLS0 (1 << 13) /* RXCMD Linestate[0] Change Interrupt Rise */ +#define U2DOTGINT_RID (1 << 12) /* RXCMD OTG ID Change Interrupt Rise */ +#define U2DOTGINT_RSE (1 << 11) /* RXCMD OTG Session End Interrupt Rise */ +#define U2DOTGINT_RSV (1 << 10) /* RXCMD OTG Session Valid Interrupt Rise */ +#define U2DOTGINT_RVV (1 << 9) /* RXCMD OTG Vbus Valid Interrupt Rise */ +#define U2DOTGINT_RCK (1 << 8) /* RXCMD Carkit Interrupt Rise */ +#define U2DOTGINT_FLS1 (1 << 6) /* RXCMD Linestate[1] Change Interrupt Fall */ +#define U2DOTGINT_FLS0 (1 << 5) /* RXCMD Linestate[0] Change Interrupt Fall */ +#define U2DOTGINT_FID (1 << 4) /* RXCMD OTG ID Change Interrupt Fall */ +#define U2DOTGINT_FSE (1 << 3) /* RXCMD OTG Session End Interrupt Fall */ +#define U2DOTGINT_FSV (1 << 2) /* RXCMD OTG Session Valid Interrupt Fall */ +#define U2DOTGINT_FVV (1 << 1) /* RXCMD OTG Vbus Valid Interrupt Fall */ +#define U2DOTGINT_FCK (1 << 0) /* RXCMD Carkit Interrupt Fall */ + +#define U2DOTGUSR (0x002C) /* U2D OTG ULPI Status Register */ +#define U2DOTGUSR_LPA (1 << 31) /* ULPI Low Power Mode Active */ +#define U2DOTGUSR_S6A (1 << 30) /* ULPI Serial Mode (6-pin) Active */ +#define U2DOTGUSR_S3A (1 << 29) /* ULPI Serial Mode (3-pin) Active */ +#define U2DOTGUSR_CKA (1 << 28) /* ULPI Car Kit Mode Active */ +#define U2DOTGUSR_LS1 (1 << 6) /* RXCMD Linestate 1 Status */ +#define U2DOTGUSR_LS0 (1 << 5) /* RXCMD Linestate 0 Status */ +#define U2DOTGUSR_ID (1 << 4) /* OTG IDGnd Status */ +#define U2DOTGUSR_SE (1 << 3) /* OTG Session End Status */ +#define U2DOTGUSR_SV (1 << 2) /* OTG Session Valid Status */ +#define U2DOTGUSR_VV (1 << 1) /* OTG Vbus Valid Status */ +#define U2DOTGUSR_CK (1 << 0) /* Carkit Interrupt Status */ + +#define U2DOTGUCR (0x0030) /* U2D OTG ULPI Control Register */ +#define U2DOTGUCR_RUN (1 << 25) /* RUN */ +#define U2DOTGUCR_RNW (1 << 24) /* Read or Write operation */ +#define U2DOTGUCR_ADDR (0x3f << 16) /* Address of the ULPI PHY register */ +#define U2DOTGUCR_WDATA (0xff << 8) /* The data for a WRITE command */ +#define U2DOTGUCR_RDATA (0xff << 0) /* The data for a READ command */ + +#define U2DP3CR (0x0034) /* U2D Port 3 Control Register */ +#define U2DP3CR_P2SS (0x3 << 8) /* Host Port 2 Serial Mode Select */ +#define U2DP3CR_P3SS (0x7 << 4) /* Host Port 3 Serial Mode Select */ +#define U2DP3CR_VPVMBEN (0x1 << 2) /* Host Port 3 Vp/Vm Block Enable */ +#define U2DP3CR_CFG (0x3 << 0) /* Host Port 3 Configuration */ + +#define U2DCSR0 (0x0100) /* U2D Control/Status Register - Endpoint 0 */ +#define U2DCSR0_IPA (1 << 8) /* IN Packet Adjusted */ +#define U2DCSR0_SA (1 << 7) /* SETUP Active */ +#define U2DCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ +#define U2DCSR0_FST (1 << 5) /* Force Stall */ +#define U2DCSR0_SST (1 << 4) /* Send Stall */ +#define U2DCSR0_DME (1 << 3) /* DMA Enable */ +#define U2DCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ +#define U2DCSR0_IPR (1 << 1) /* IN Packet Ready */ +#define U2DCSR0_OPC (1 << 0) /* OUT Packet Complete */ + +#define U2DCSR(x) (0x0100 + ((x) << 2)) /* U2D Control/Status Register - Endpoint x */ +#define U2DCSR_BF (1 << 10) /* Buffer Full, for OUT eps */ +#define U2DCSR_BE (1 << 10) /* Buffer Empty, for IN eps */ +#define U2DCSR_DPE (1 << 9) /* Data Packet Error, for ISO eps only */ +#define U2DCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ +#define U2DCSR_SP (1 << 7) /* Short Packet Control/Status, for OUT eps only, readonly */ +#define U2DCSR_BNE (1 << 6) /* Buffer Not Empty, for OUT eps */ +#define U2DCSR_BNF (1 << 6) /* Buffer Not Full, for IN eps */ +#define U2DCSR_FST (1 << 5) /* Force STALL, write 1 set */ +#define U2DCSR_SST (1 << 4) /* Sent STALL, write 1 clear */ +#define U2DCSR_DME (1 << 3) /* DMA Enable */ +#define U2DCSR_TRN (1 << 2) /* Tx/Rx NAK, write 1 clear */ +#define U2DCSR_PC (1 << 1) /* Packet Complete, write 1 clear */ +#define U2DCSR_FS (1 << 0) /* FIFO needs Service */ + +#define U2DBCR0 (0x0200) /* U2D Byte Count Register - Endpoint 0 */ +#define U2DBCR(x) (0x0200 + ((x) << 2)) /* U2D Byte Count Register - Endpoint x */ + +#define U2DDR0 (0x0300) /* U2D Data Register - Endpoint 0 */ + +#define U2DEPCR(x) (0x0400 + ((x) << 2)) /* U2D Configuration Register - Endpoint x */ +#define U2DEPCR_EE (1 << 0) /* Endpoint Enable */ +#define U2DEPCR_BS_MASK (0x3FE) /* Buffer Size, BS*8=FIFO size, max 8184B = 8KB */ + +#define U2DSCA (0x0500) /* U2D Setup Command Address */ +#define U2DSCA_VALUE (0x0120) + +#define U2DEN0 (0x0504) /* U2D Endpoint Information Register - Endpoint 0 */ +#define U2DEN(x) (0x0504 + ((x) << 2)) /* U2D Endpoint Information Register - Endpoint x */ + +/* U2DMA registers */ +#define U2DMACSR0 (0x1000) /* U2DMA Control/Status Register - Channel 0 */ +#define U2DMACSR(x) (0x1000 + ((x) << 2)) /* U2DMA Control/Status Register - Channel x */ +#define U2DMACSR_RUN (1 << 31) /* Run Bit (read / write) */ +#define U2DMACSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */ +#define U2DMACSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */ +#define U2DMACSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ +#define U2DMACSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ +#define U2DMACSR_RASIRQEN (1 << 23) /* Request After Cnannel Stopped Interrupt Enable */ +#define U2DMACSR_MASKRUN (1 << 22) /* Mask Run */ +#define U2DMACSR_SCEMC (3 << 18) /* System Bus Split Completion Error Message Class */ +#define U2DMACSR_SCEMI (0x1f << 13) /* System Bus Split Completion Error Message Index */ +#define U2DMACSR_BUSERRTYPE (7 << 10) /* PX Bus Error Type */ +#define U2DMACSR_EORINTR (1 << 9) /* End Of Receive */ +#define U2DMACSR_REQPEND (1 << 8) /* Request Pending */ +#define U2DMACSR_RASINTR (1 << 4) /* Request After Channel Stopped (read / write 1 clear) */ +#define U2DMACSR_STOPINTR (1 << 3) /* Stop Interrupt (read only) */ +#define U2DMACSR_ENDINTR (1 << 2) /* End Interrupt (read / write 1 clear) */ +#define U2DMACSR_STARTINTR (1 << 1) /* Start Interrupt (read / write 1 clear) */ +#define U2DMACSR_BUSERRINTR (1 << 0) /* Bus Error Interrupt (read / write 1 clear) */ + +#define U2DMACR (0x1080) /* U2DMA Control Register */ +#define U2DMAINT (0x10F0) /* U2DMA Interrupt Register */ + +#define U2DMABR0 (0x1100) /* U2DMA Branch Register - Channel 0 */ +#define U2DMABR(x) (0x1100 + (x) << 2) /* U2DMA Branch Register - Channel x */ + +#define U2DMADADR0 (0x1200) /* U2DMA Descriptor Address Register - Channel 0 */ +#define U2DMADADR(x) (0x1200 + (x) * 0x10) /* U2DMA Descriptor Address Register - Channel x */ + +#define U2DMADADR_STOP (1U << 0) + +#define U2DMASADR0 (0x1204) /* U2DMA Source Address Register - Channel 0 */ +#define U2DMASADR(x) (0x1204 + (x) * 0x10) /* U2DMA Source Address Register - Channel x */ +#define U2DMATADR0 (0x1208) /* U2DMA Target Address Register - Channel 0 */ +#define U2DMATADR(x) (0x1208 + (x) * 0x10) /* U2DMA Target Address Register - Channel x */ + +#define U2DMACMDR0 (0x120C) /* U2DMA Command Address Register - Channel 0 */ +#define U2DMACMDR(x) (0x120C + (x) * 0x10) /* U2DMA Command Address Register - Channel x */ + +#define U2DMACMDR_XFRDIS (1 << 31) /* Transfer Direction */ +#define U2DMACMDR_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ +#define U2DMACMDR_ENDIRQEN (1 << 21) /* End Interrupt Enable */ +#define U2DMACMDR_PACKCOMP (1 << 13) /* Packet Complete */ +#define U2DMACMDR_LEN (0x07ff) /* length mask (max = 2K - 1) */ + +#endif /* __ASM_ARCH_PXA3xx_U2D_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-uart.h b/arch/arm/mach-pxa/include/mach/regs-uart.h new file mode 100644 index 00000000000..55aeb7fb72f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-uart.h @@ -0,0 +1,143 @@ +#ifndef __ASM_ARCH_REGS_UART_H +#define __ASM_ARCH_REGS_UART_H + +/* + * UARTs + */ + +/* Full Function UART (FFUART) */ +#define FFUART FFRBR +#define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */ +#define FFTHR __REG(0x40100000) /* Transmit Holding Register (write only) */ +#define FFIER __REG(0x40100004) /* Interrupt Enable Register (read/write) */ +#define FFIIR __REG(0x40100008) /* Interrupt ID Register (read only) */ +#define FFFCR __REG(0x40100008) /* FIFO Control Register (write only) */ +#define FFLCR __REG(0x4010000C) /* Line Control Register (read/write) */ +#define FFMCR __REG(0x40100010) /* Modem Control Register (read/write) */ +#define FFLSR __REG(0x40100014) /* Line Status Register (read only) */ +#define FFMSR __REG(0x40100018) /* Modem Status Register (read only) */ +#define FFSPR __REG(0x4010001C) /* Scratch Pad Register (read/write) */ +#define FFISR __REG(0x40100020) /* Infrared Selection Register (read/write) */ +#define FFDLL __REG(0x40100000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define FFDLH __REG(0x40100004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +/* Bluetooth UART (BTUART) */ +#define BTUART BTRBR +#define BTRBR __REG(0x40200000) /* Receive Buffer Register (read only) */ +#define BTTHR __REG(0x40200000) /* Transmit Holding Register (write only) */ +#define BTIER __REG(0x40200004) /* Interrupt Enable Register (read/write) */ +#define BTIIR __REG(0x40200008) /* Interrupt ID Register (read only) */ +#define BTFCR __REG(0x40200008) /* FIFO Control Register (write only) */ +#define BTLCR __REG(0x4020000C) /* Line Control Register (read/write) */ +#define BTMCR __REG(0x40200010) /* Modem Control Register (read/write) */ +#define BTLSR __REG(0x40200014) /* Line Status Register (read only) */ +#define BTMSR __REG(0x40200018) /* Modem Status Register (read only) */ +#define BTSPR __REG(0x4020001C) /* Scratch Pad Register (read/write) */ +#define BTISR __REG(0x40200020) /* Infrared Selection Register (read/write) */ +#define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +/* Standard UART (STUART) */ +#define STUART STRBR +#define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */ +#define STTHR __REG(0x40700000) /* Transmit Holding Register (write only) */ +#define STIER __REG(0x40700004) /* Interrupt Enable Register (read/write) */ +#define STIIR __REG(0x40700008) /* Interrupt ID Register (read only) */ +#define STFCR __REG(0x40700008) /* FIFO Control Register (write only) */ +#define STLCR __REG(0x4070000C) /* Line Control Register (read/write) */ +#define STMCR __REG(0x40700010) /* Modem Control Register (read/write) */ +#define STLSR __REG(0x40700014) /* Line Status Register (read only) */ +#define STMSR __REG(0x40700018) /* Reserved */ +#define STSPR __REG(0x4070001C) /* Scratch Pad Register (read/write) */ +#define STISR __REG(0x40700020) /* Infrared Selection Register (read/write) */ +#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +/* Hardware UART (HWUART) */ +#define HWUART HWRBR +#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */ +#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */ +#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */ +#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */ +#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */ +#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */ +#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */ +#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */ +#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */ +#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */ +#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */ +#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */ +#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */ +#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */ +#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +#define IER_DMAE (1 << 7) /* DMA Requests Enable */ +#define IER_UUE (1 << 6) /* UART Unit Enable */ +#define IER_NRZE (1 << 5) /* NRZ coding Enable */ +#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */ +#define IER_MIE (1 << 3) /* Modem Interrupt Enable */ +#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */ +#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */ +#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */ + +#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */ +#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */ +#define IIR_TOD (1 << 3) /* Time Out Detected */ +#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */ +#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */ +#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */ + +#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */ +#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */ +#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */ +#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */ +#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */ +#define FCR_ITL_1 (0) +#define FCR_ITL_8 (FCR_ITL1) +#define FCR_ITL_16 (FCR_ITL2) +#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1) + +#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */ +#define LCR_SB (1 << 6) /* Set Break */ +#define LCR_STKYP (1 << 5) /* Sticky Parity */ +#define LCR_EPS (1 << 4) /* Even Parity Select */ +#define LCR_PEN (1 << 3) /* Parity Enable */ +#define LCR_STB (1 << 2) /* Stop Bit */ +#define LCR_WLS1 (1 << 1) /* Word Length Select */ +#define LCR_WLS0 (1 << 0) /* Word Length Select */ + +#define LSR_FIFOE (1 << 7) /* FIFO Error Status */ +#define LSR_TEMT (1 << 6) /* Transmitter Empty */ +#define LSR_TDRQ (1 << 5) /* Transmit Data Request */ +#define LSR_BI (1 << 4) /* Break Interrupt */ +#define LSR_FE (1 << 3) /* Framing Error */ +#define LSR_PE (1 << 2) /* Parity Error */ +#define LSR_OE (1 << 1) /* Overrun Error */ +#define LSR_DR (1 << 0) /* Data Ready */ + +#define MCR_LOOP (1 << 4) +#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */ +#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */ +#define MCR_RTS (1 << 1) /* Request to Send */ +#define MCR_DTR (1 << 0) /* Data Terminal Ready */ + +#define MSR_DCD (1 << 7) /* Data Carrier Detect */ +#define MSR_RI (1 << 6) /* Ring Indicator */ +#define MSR_DSR (1 << 5) /* Data Set Ready */ +#define MSR_CTS (1 << 4) /* Clear To Send */ +#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */ +#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */ +#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */ +#define MSR_DCTS (1 << 0) /* Delta Clear To Send */ + +/* + * IrSR (Infrared Selection Register) + */ +#define STISR_RXPL (1 << 4) /* Receive Data Polarity */ +#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */ +#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */ +#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */ +#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */ + +#endif /* __ASM_ARCH_REGS_UART_H */ diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h index 9489a48871a..b6c10556fbc 100644 --- a/arch/arm/mach-pxa/include/mach/reset.h +++ b/arch/arm/mach-pxa/include/mach/reset.h @@ -10,9 +10,12 @@ extern unsigned int reset_status; extern void clear_reset_status(unsigned int mask); -/* - * register GPIO as reset generator +/** + * init_gpio_reset() - register GPIO as reset generator + * @gpio: gpio nr + * @output: set gpio as output instead of input during normal work + * @level: output level */ -extern int init_gpio_reset(int gpio); +extern int init_gpio_reset(int gpio, int output, int level); #endif /* __ASM_ARCH_RESET_H */ diff --git a/arch/arm/mach-pxa/include/mach/sharpsl.h b/arch/arm/mach-pxa/include/mach/sharpsl.h deleted file mode 100644 index 3b1d4a72d4d..00000000000 --- a/arch/arm/mach-pxa/include/mach/sharpsl.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SharpSL SSP Driver - */ - -unsigned long corgi_ssp_ads7846_putget(unsigned long); -unsigned long corgi_ssp_ads7846_get(void); -void corgi_ssp_ads7846_put(unsigned long data); -void corgi_ssp_ads7846_lock(void); -void corgi_ssp_ads7846_unlock(void); -void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data); -void corgi_ssp_blduty_set(int duty); -int corgi_ssp_max1111_get(unsigned long data); - -/* - * SharpSL Touchscreen Driver - */ - -struct corgits_machinfo { - unsigned long (*get_hsync_invperiod)(void); - void (*put_hsync)(void); - void (*wait_hsync)(void); -}; - - -/* - * SharpSL Backlight - */ -extern void corgibl_limit_intensity(int limit); - - -/* - * SharpSL Battery/PM Driver - */ -extern void sharpsl_battery_kick(void); diff --git a/arch/arm/mach-pxa/include/mach/sharpsl_pm.h b/arch/arm/mach-pxa/include/mach/sharpsl_pm.h new file mode 100644 index 00000000000..905be6755f0 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/sharpsl_pm.h @@ -0,0 +1,113 @@ +/* + * SharpSL Battery/PM Driver + * + * Copyright (c) 2004-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. + * + */ +#ifndef _MACH_SHARPSL_PM +#define _MACH_SHARPSL_PM + +struct sharpsl_charger_machinfo { + void (*init)(void); + void (*exit)(void); + int gpio_acin; + int gpio_batfull; + int batfull_irq; + int gpio_batlock; + int gpio_fatal; + void (*discharge)(int); + void (*discharge1)(int); + void (*charge)(int); + void (*measure_temp)(int); + void (*presuspend)(void); + void (*postsuspend)(void); + void (*earlyresume)(void); + unsigned long (*read_devdata)(int); +#define SHARPSL_BATT_VOLT 1 +#define SHARPSL_BATT_TEMP 2 +#define SHARPSL_ACIN_VOLT 3 +#define SHARPSL_STATUS_ACIN 4 +#define SHARPSL_STATUS_LOCK 5 +#define SHARPSL_STATUS_CHRGFULL 6 +#define SHARPSL_STATUS_FATAL 7 + unsigned long (*charger_wakeup)(void); + int (*should_wakeup)(unsigned int resume_on_alarm); + void (*backlight_limit)(int); + int (*backlight_get_status) (void); + int charge_on_volt; + int charge_on_temp; + int charge_acin_high; + int charge_acin_low; + int fatal_acin_volt; + int fatal_noacin_volt; + int bat_levels; + struct battery_thresh *bat_levels_noac; + struct battery_thresh *bat_levels_acin; + struct battery_thresh *bat_levels_noac_bl; + struct battery_thresh *bat_levels_acin_bl; + int status_high_acin; + int status_low_acin; + int status_high_noac; + int status_low_noac; +}; + +struct battery_thresh { + int voltage; + int percentage; +}; + +struct battery_stat { + int ac_status; /* APM AC Present/Not Present */ + int mainbat_status; /* APM Main Battery Status */ + int mainbat_percent; /* Main Battery Percentage Charge */ + int mainbat_voltage; /* Main Battery Voltage */ +}; + +struct sharpsl_pm_status { + struct device *dev; + struct timer_list ac_timer; + struct timer_list chrg_full_timer; + + int charge_mode; +#define CHRG_ERROR (-1) +#define CHRG_OFF (0) +#define CHRG_ON (1) +#define CHRG_DONE (2) + + unsigned int flags; +#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */ +#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */ +#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */ +#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */ +#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */ + + int full_count; + unsigned long charge_start_time; + struct sharpsl_charger_machinfo *machinfo; + struct battery_stat battstat; +}; + +extern struct sharpsl_pm_status sharpsl_pm; + +extern struct battery_thresh sharpsl_battery_levels_acin[]; +extern struct battery_thresh sharpsl_battery_levels_noac[]; + +#define SHARPSL_LED_ERROR 2 +#define SHARPSL_LED_ON 1 +#define SHARPSL_LED_OFF 0 + +void sharpsl_battery_kick(void); +void sharpsl_pm_led(int val); + +/* MAX1111 Channel Definitions */ +#define MAX1111_BATT_VOLT 4u +#define MAX1111_BATT_TEMP 2u +#define MAX1111_ACIN_VOLT 6u +int sharpsl_pm_pxa_read_max1111(int channel); + +void corgi_lcd_limit_intensity(int limit); +#endif diff --git a/arch/arm/mach-pxa/include/mach/smemc.h b/arch/arm/mach-pxa/include/mach/smemc.h new file mode 100644 index 00000000000..b802f285fe0 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/smemc.h @@ -0,0 +1,75 @@ +/* + * Static memory controller register definitions for PXA CPUs + * + * Copyright (C) 2010 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. + */ + +#ifndef __SMEMC_REGS_H +#define __SMEMC_REGS_H + +#define PXA2XX_SMEMC_BASE 0x48000000 +#define PXA3XX_SMEMC_BASE 0x4a000000 +#define SMEMC_VIRT IOMEM(0xf6000000) + +#define MDCNFG (SMEMC_VIRT + 0x00) /* SDRAM Configuration Register 0 */ +#define MDREFR (SMEMC_VIRT + 0x04) /* SDRAM Refresh Control Register */ +#define MSC0 (SMEMC_VIRT + 0x08) /* Static Memory Control Register 0 */ +#define MSC1 (SMEMC_VIRT + 0x0C) /* Static Memory Control Register 1 */ +#define MSC2 (SMEMC_VIRT + 0x10) /* Static Memory Control Register 2 */ +#define MECR (SMEMC_VIRT + 0x14) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ +#define SXLCR (SMEMC_VIRT + 0x18) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ +#define SXCNFG (SMEMC_VIRT + 0x1C) /* Synchronous Static Memory Control Register */ +#define SXMRS (SMEMC_VIRT + 0x24) /* MRS value to be written to Synchronous Flash or SMROM */ +#define MCMEM0 (SMEMC_VIRT + 0x28) /* Card interface Common Memory Space Socket 0 Timing */ +#define MCMEM1 (SMEMC_VIRT + 0x2C) /* Card interface Common Memory Space Socket 1 Timing */ +#define MCATT0 (SMEMC_VIRT + 0x30) /* Card interface Attribute Space Socket 0 Timing Configuration */ +#define MCATT1 (SMEMC_VIRT + 0x34) /* Card interface Attribute Space Socket 1 Timing Configuration */ +#define MCIO0 (SMEMC_VIRT + 0x38) /* Card interface I/O Space Socket 0 Timing Configuration */ +#define MCIO1 (SMEMC_VIRT + 0x3C) /* Card interface I/O Space Socket 1 Timing Configuration */ +#define MDMRS (SMEMC_VIRT + 0x40) /* MRS value to be written to SDRAM */ +#define BOOT_DEF (SMEMC_VIRT + 0x44) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ +#define MEMCLKCFG (SMEMC_VIRT + 0x68) /* Clock Configuration */ +#define CSADRCFG0 (SMEMC_VIRT + 0x80) /* Address Configuration Register for CS0 */ +#define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */ +#define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */ +#define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */ +#define CSMSADRCFG (SMEMC_VIRT + 0xA0) /* Chip Select Configuration Register */ + +/* + * More handy macros for PCMCIA + * + * Arg is socket number + */ +#define MCMEM(s) (SMEMC_VIRT + 0x28 + ((s)<<2)) /* Card interface Common Memory Space Socket s Timing */ +#define MCATT(s) (SMEMC_VIRT + 0x30 + ((s)<<2)) /* Card interface Attribute Space Socket s Timing Configuration */ +#define MCIO(s) (SMEMC_VIRT + 0x38 + ((s)<<2)) /* Card interface I/O Space Socket s Timing Configuration */ + +/* MECR register defines */ +#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ +#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ + +#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */ +#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */ +#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */ +#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */ + +#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */ +#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ +#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ +#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ +#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ +#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ +#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ +#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ +#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ +#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ +#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ +#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ +#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ +#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ + +#endif diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h index bd14365f7ed..25c9f62e46a 100644 --- a/arch/arm/mach-pxa/include/mach/spitz.h +++ b/arch/arm/mach-pxa/include/mach/spitz.h @@ -15,6 +15,7 @@ #define __ASM_ARCH_SPITZ_H 1 #endif +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO, PXA_GPIO_TO_IRQ */ #include <linux/fb.h> /* Spitz/Akita GPIOs */ @@ -100,13 +101,24 @@ #define SPITZ_SCP_JK_A SCOOP_GPCR_PA18 /* Low */ #define SPITZ_SCP_ADC_TEMP_ON SCOOP_GPCR_PA19 /* Low */ -#define SPITZ_SCP_IO_DIR (SPITZ_SCP_LED_GREEN | SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \ - SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_LED_ORANGE | \ +#define SPITZ_SCP_IO_DIR (SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \ + SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | \ SPITZ_SCP_CF_POWER | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON) #define SPITZ_SCP_IO_OUT (SPITZ_SCP_CHRG_ON | SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R) #define SPITZ_SCP_SUS_CLR (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON) #define SPITZ_SCP_SUS_SET 0 +#define SPITZ_SCP_GPIO_BASE (PXA_NR_BUILTIN_GPIO) +#define SPITZ_GPIO_LED_GREEN (SPITZ_SCP_GPIO_BASE + 0) +#define SPITZ_GPIO_JK_B (SPITZ_SCP_GPIO_BASE + 1) +#define SPITZ_GPIO_CHRG_ON (SPITZ_SCP_GPIO_BASE + 2) +#define SPITZ_GPIO_MUTE_L (SPITZ_SCP_GPIO_BASE + 3) +#define SPITZ_GPIO_MUTE_R (SPITZ_SCP_GPIO_BASE + 4) +#define SPITZ_GPIO_CF_POWER (SPITZ_SCP_GPIO_BASE + 5) +#define SPITZ_GPIO_LED_ORANGE (SPITZ_SCP_GPIO_BASE + 6) +#define SPITZ_GPIO_JK_A (SPITZ_SCP_GPIO_BASE + 7) +#define SPITZ_GPIO_ADC_TEMP_ON (SPITZ_SCP_GPIO_BASE + 8) + /* Spitz Scoop Device (No. 2) GPIOs */ /* Suspend States in comments */ #define SPITZ_SCP2_IR_ON SCOOP_GPCR_PA11 /* High */ @@ -119,40 +131,59 @@ #define SPITZ_SCP2_BACKLIGHT_ON SCOOP_GPCR_PA18 /* Low */ #define SPITZ_SCP2_MIC_BIAS SCOOP_GPCR_PA19 /* Low */ -#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \ +#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \ SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS) -#define SPITZ_SCP2_IO_OUT (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1) +#define SPITZ_SCP2_IO_OUT (SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1) #define SPITZ_SCP2_SUS_CLR (SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS) #define SPITZ_SCP2_SUS_SET (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1) +#define SPITZ_SCP2_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12) +#define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0) +#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1) +#define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2) +#define SPITZ_GPIO_RESERVED_2 (SPITZ_SCP2_GPIO_BASE + 3) +#define SPITZ_GPIO_RESERVED_3 (SPITZ_SCP2_GPIO_BASE + 4) +#define SPITZ_GPIO_RESERVED_4 (SPITZ_SCP2_GPIO_BASE + 5) +#define SPITZ_GPIO_BACKLIGHT_CONT (SPITZ_SCP2_GPIO_BASE + 6) +#define SPITZ_GPIO_BACKLIGHT_ON (SPITZ_SCP2_GPIO_BASE + 7) +#define SPITZ_GPIO_MIC_BIAS (SPITZ_SCP2_GPIO_BASE + 8) + +/* Akita IO Expander GPIOs */ +#define AKITA_IOEXP_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12) +#define AKITA_GPIO_RESERVED_0 (AKITA_IOEXP_GPIO_BASE + 0) +#define AKITA_GPIO_RESERVED_1 (AKITA_IOEXP_GPIO_BASE + 1) +#define AKITA_GPIO_MIC_BIAS (AKITA_IOEXP_GPIO_BASE + 2) +#define AKITA_GPIO_BACKLIGHT_ON (AKITA_IOEXP_GPIO_BASE + 3) +#define AKITA_GPIO_BACKLIGHT_CONT (AKITA_IOEXP_GPIO_BASE + 4) +#define AKITA_GPIO_AKIN_PULLUP (AKITA_IOEXP_GPIO_BASE + 5) +#define AKITA_GPIO_IR_ON (AKITA_IOEXP_GPIO_BASE + 6) +#define AKITA_GPIO_RESERVED_7 (AKITA_IOEXP_GPIO_BASE + 7) /* Spitz IRQ Definitions */ -#define SPITZ_IRQ_GPIO_KEY_INT IRQ_GPIO(SPITZ_GPIO_KEY_INT) -#define SPITZ_IRQ_GPIO_AC_IN IRQ_GPIO(SPITZ_GPIO_AC_IN) -#define SPITZ_IRQ_GPIO_AK_INT IRQ_GPIO(SPITZ_GPIO_AK_INT) -#define SPITZ_IRQ_GPIO_HP_IN IRQ_GPIO(SPITZ_GPIO_HP_IN) -#define SPITZ_IRQ_GPIO_TP_INT IRQ_GPIO(SPITZ_GPIO_TP_INT) -#define SPITZ_IRQ_GPIO_SYNC IRQ_GPIO(SPITZ_GPIO_SYNC) -#define SPITZ_IRQ_GPIO_ON_KEY IRQ_GPIO(SPITZ_GPIO_ON_KEY) -#define SPITZ_IRQ_GPIO_SWA IRQ_GPIO(SPITZ_GPIO_SWA) -#define SPITZ_IRQ_GPIO_SWB IRQ_GPIO(SPITZ_GPIO_SWB) -#define SPITZ_IRQ_GPIO_BAT_COVER IRQ_GPIO(SPITZ_GPIO_BAT_COVER) -#define SPITZ_IRQ_GPIO_FATAL_BAT IRQ_GPIO(SPITZ_GPIO_FATAL_BAT) -#define SPITZ_IRQ_GPIO_CO IRQ_GPIO(SPITZ_GPIO_CO) -#define SPITZ_IRQ_GPIO_CF_IRQ IRQ_GPIO(SPITZ_GPIO_CF_IRQ) -#define SPITZ_IRQ_GPIO_CF_CD IRQ_GPIO(SPITZ_GPIO_CF_CD) -#define SPITZ_IRQ_GPIO_CF2_IRQ IRQ_GPIO(SPITZ_GPIO_CF2_IRQ) -#define SPITZ_IRQ_GPIO_nSD_INT IRQ_GPIO(SPITZ_GPIO_nSD_INT) -#define SPITZ_IRQ_GPIO_nSD_DETECT IRQ_GPIO(SPITZ_GPIO_nSD_DETECT) +#define SPITZ_IRQ_GPIO_KEY_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_KEY_INT) +#define SPITZ_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_AC_IN) +#define SPITZ_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_AK_INT) +#define SPITZ_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_HP_IN) +#define SPITZ_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT) +#define SPITZ_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(SPITZ_GPIO_SYNC) +#define SPITZ_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(SPITZ_GPIO_ON_KEY) +#define SPITZ_IRQ_GPIO_SWA PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWA) +#define SPITZ_IRQ_GPIO_SWB PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWB) +#define SPITZ_IRQ_GPIO_BAT_COVER PXA_GPIO_TO_IRQ(SPITZ_GPIO_BAT_COVER) +#define SPITZ_IRQ_GPIO_FATAL_BAT PXA_GPIO_TO_IRQ(SPITZ_GPIO_FATAL_BAT) +#define SPITZ_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(SPITZ_GPIO_CO) +#define SPITZ_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_IRQ) +#define SPITZ_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_CD) +#define SPITZ_IRQ_GPIO_CF2_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF2_IRQ) +#define SPITZ_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_INT) +#define SPITZ_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_DETECT) /* * Shared data structures */ -extern struct platform_device spitzscoop_device; -extern struct platform_device spitzscoop2_device; extern struct platform_device spitzssp_device; extern struct sharpsl_charger_machinfo spitz_pm_machinfo; diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h deleted file mode 100644 index a012882c9ee..00000000000 --- a/arch/arm/mach-pxa/include/mach/ssp.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ssp.h - * - * Copyright (C) 2003 Russell King, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This driver supports the following PXA CPU/SSP ports:- - * - * PXA250 SSP - * PXA255 SSP, NSSP - * PXA26x SSP, NSSP, ASSP - * PXA27x SSP1, SSP2, SSP3 - * PXA3xx SSP1, SSP2, SSP3, SSP4 - */ - -#ifndef __ASM_ARCH_SSP_H -#define __ASM_ARCH_SSP_H - -#include <linux/list.h> - -enum pxa_ssp_type { - SSP_UNDEFINED = 0, - PXA25x_SSP, /* pxa 210, 250, 255, 26x */ - PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ - PXA27x_SSP, -}; - -struct ssp_device { - struct platform_device *pdev; - struct list_head node; - - struct clk *clk; - void __iomem *mmio_base; - unsigned long phys_base; - - const char *label; - int port_id; - int type; - int use_count; - int irq; - int drcmr_rx; - int drcmr_tx; -}; - -/* - * SSP initialisation flags - */ -#define SSP_NO_IRQ 0x1 /* don't register an irq handler in SSP driver */ - -struct ssp_state { - u32 cr0; - u32 cr1; - u32 to; - u32 psp; -}; - -struct ssp_dev { - struct ssp_device *ssp; - u32 port; - u32 mode; - u32 flags; - u32 psp_flags; - u32 speed; - int irq; -}; - -int ssp_write_word(struct ssp_dev *dev, u32 data); -int ssp_read_word(struct ssp_dev *dev, u32 *data); -int ssp_flush(struct ssp_dev *dev); -void ssp_enable(struct ssp_dev *dev); -void ssp_disable(struct ssp_dev *dev); -void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp); -void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp); -int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags); -int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed); -void ssp_exit(struct ssp_dev *dev); - -struct ssp_device *ssp_request(int port, const char *label); -void ssp_free(struct ssp_device *); -#endif /* __ASM_ARCH_SSP_H */ diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h deleted file mode 100644 index 0f381e69299..00000000000 --- a/arch/arm/mach-pxa/include/mach/system.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/system.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. - */ - -#include <asm/proc-fns.h> -#include "hardware.h" -#include "pxa2xx-regs.h" -#include "pxa-regs.h" - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - - -void arch_reset(char mode); diff --git a/arch/arm/mach-pxa/include/mach/timex.h b/arch/arm/mach-pxa/include/mach/timex.h deleted file mode 100644 index b05fc6683c4..00000000000 --- a/arch/arm/mach-pxa/include/mach/timex.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/timex.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. - */ - - -#if defined(CONFIG_PXA25x) -/* PXA250/210 timer base */ -#define CLOCK_TICK_RATE 3686400 -#elif defined(CONFIG_PXA27x) -/* PXA27x timer base */ -#ifdef CONFIG_MACH_MAINSTONE -#define CLOCK_TICK_RATE 3249600 -#else -#define CLOCK_TICK_RATE 3250000 -#endif -#else -#define CLOCK_TICK_RATE 3250000 -#endif diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index a72803f0461..0497d95cef2 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -13,6 +13,8 @@ #ifndef _ASM_ARCH_TOSA_H_ #define _ASM_ARCH_TOSA_H_ 1 +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ + /* TOSA Chip selects */ #define TOSA_LCDC_PHYS PXA_CS4_PHYS /* Internel Scoop */ @@ -20,10 +22,11 @@ /* Jacket Scoop */ #define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000) +#define TOSA_NR_IRQS (IRQ_BOARD_START + TC6393XB_NR_IRQS) /* * SCOOP2 internal GPIOs */ -#define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO +#define TOSA_SCOOP_GPIO_BASE PXA_NR_BUILTIN_GPIO #define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11 #define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1) #define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) @@ -41,7 +44,7 @@ /* * SCOOP2 jacket GPIOs */ -#define TOSA_SCOOP_JC_GPIO_BASE (NR_BUILTIN_GPIO + 12) +#define TOSA_SCOOP_JC_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12) #define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0) #define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1) #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) @@ -58,9 +61,7 @@ /* * TC6393XB GPIOs */ -#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12) -#define TOSA_TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i)) -#define TOSA_TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE)) +#define TOSA_TC6393XB_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 2 * 12) #define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0) #define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1) @@ -142,34 +143,34 @@ /* * Interrupts */ -#define TOSA_IRQ_GPIO_WAKEUP IRQ_GPIO(TOSA_GPIO_WAKEUP) -#define TOSA_IRQ_GPIO_AC_IN IRQ_GPIO(TOSA_GPIO_AC_IN) -#define TOSA_IRQ_GPIO_RECORD_BTN IRQ_GPIO(TOSA_GPIO_RECORD_BTN) -#define TOSA_IRQ_GPIO_SYNC IRQ_GPIO(TOSA_GPIO_SYNC) -#define TOSA_IRQ_GPIO_USB_IN IRQ_GPIO(TOSA_GPIO_USB_IN) -#define TOSA_IRQ_GPIO_JACKET_DETECT IRQ_GPIO(TOSA_GPIO_JACKET_DETECT) -#define TOSA_IRQ_GPIO_nSD_INT IRQ_GPIO(TOSA_GPIO_nSD_INT) -#define TOSA_IRQ_GPIO_nSD_DETECT IRQ_GPIO(TOSA_GPIO_nSD_DETECT) -#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG) -#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD) -#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG) -#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT) -#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW) -#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN) -#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ) -#define TOSA_IRQ_GPIO_ON_KEY IRQ_GPIO(TOSA_GPIO_ON_KEY) -#define TOSA_IRQ_GPIO_VGA_LINE IRQ_GPIO(TOSA_GPIO_VGA_LINE) -#define TOSA_IRQ_GPIO_TP_INT IRQ_GPIO(TOSA_GPIO_TP_INT) -#define TOSA_IRQ_GPIO_JC_CF_IRQ IRQ_GPIO(TOSA_GPIO_JC_CF_IRQ) -#define TOSA_IRQ_GPIO_BAT_LOCKED IRQ_GPIO(TOSA_GPIO_BAT_LOCKED) -#define TOSA_IRQ_GPIO_BAT1_LOW IRQ_GPIO(TOSA_GPIO_BAT1_LOW) -#define TOSA_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(69+(a)) - -#define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW) +#define TOSA_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(TOSA_GPIO_WAKEUP) +#define TOSA_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN) +#define TOSA_IRQ_GPIO_RECORD_BTN PXA_GPIO_TO_IRQ(TOSA_GPIO_RECORD_BTN) +#define TOSA_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(TOSA_GPIO_SYNC) +#define TOSA_IRQ_GPIO_USB_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_USB_IN) +#define TOSA_IRQ_GPIO_JACKET_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_JACKET_DETECT) +#define TOSA_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_INT) +#define TOSA_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_DETECT) +#define TOSA_IRQ_GPIO_BAT1_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_CRG) +#define TOSA_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_CD) +#define TOSA_IRQ_GPIO_BAT0_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_CRG) +#define TOSA_IRQ_GPIO_TC6393XB_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TC6393XB_INT) +#define TOSA_IRQ_GPIO_BAT0_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_LOW) +#define TOSA_IRQ_GPIO_EAR_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_EAR_IN) +#define TOSA_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_IRQ) +#define TOSA_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(TOSA_GPIO_ON_KEY) +#define TOSA_IRQ_GPIO_VGA_LINE PXA_GPIO_TO_IRQ(TOSA_GPIO_VGA_LINE) +#define TOSA_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TP_INT) +#define TOSA_IRQ_GPIO_JC_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_JC_CF_IRQ) +#define TOSA_IRQ_GPIO_BAT_LOCKED PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT_LOCKED) +#define TOSA_IRQ_GPIO_BAT1_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_LOW) +#define TOSA_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(69+(a)) + +#define TOSA_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_MAIN_BAT_LOW) #define TOSA_KEY_SYNC KEY_102ND /* ??? */ -#ifndef CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES +#ifndef CONFIG_TOSA_USE_EXT_KEYCODES #define TOSA_KEY_RECORD KEY_YEN #define TOSA_KEY_ADDRESSBOOK KEY_KATAKANA #define TOSA_KEY_CANCEL KEY_ESC @@ -195,4 +196,7 @@ #define TOSA_KEY_MAIL KEY_MAIL #endif +struct spi_device; +extern int tosa_bl_enable(struct spi_device *spi, int enable); + #endif /* _ASM_ARCH_TOSA_H_ */ diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h index 641d0ec110b..ae3ca013afa 100644 --- a/arch/arm/mach-pxa/include/mach/trizeps4.h +++ b/arch/arm/mach-pxa/include/mach/trizeps4.h @@ -10,6 +10,8 @@ #ifndef _TRIPEPS4_H_ #define _TRIPEPS4_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /* physical memory regions */ #define TRIZEPS4_FLASH_PHYS (PXA_CS0_PHYS) /* Flash region */ #define TRIZEPS4_DISK_PHYS (PXA_CS1_PHYS) /* Disk On Chip region */ @@ -17,11 +19,16 @@ #define TRIZEPS4_PIC_PHYS (PXA_CS3_PHYS) /* Logic chip on ConXS-Board */ #define TRIZEPS4_SDRAM_BASE 0xa0000000 /* SDRAM region */ -#define TRIZEPS4_CFSR_PHYS (PXA_CS3_PHYS) /* Logic chip on ConXS-Board CSFR register */ -#define TRIZEPS4_BOCR_PHYS (PXA_CS3_PHYS+0x02000000) /* Logic chip on ConXS-Board BOCR register */ -#define TRIZEPS4_IRCR_PHYS (PXA_CS3_PHYS+0x02400000) /* Logic chip on ConXS-Board IRCR register*/ -#define TRIZEPS4_UPSR_PHYS (PXA_CS3_PHYS+0x02800000) /* Logic chip on ConXS-Board UPSR register*/ -#define TRIZEPS4_DICR_PHYS (PXA_CS3_PHYS+0x03800000) /* Logic chip on ConXS-Board DICR register*/ + /* Logic on ConXS-board CSFR register*/ +#define TRIZEPS4_CFSR_PHYS (PXA_CS3_PHYS) + /* Logic on ConXS-board BOCR register*/ +#define TRIZEPS4_BOCR_PHYS (PXA_CS3_PHYS+0x02000000) + /* Logic on ConXS-board IRCR register*/ +#define TRIZEPS4_IRCR_PHYS (PXA_CS3_PHYS+0x02400000) + /* Logic on ConXS-board UPSR register*/ +#define TRIZEPS4_UPSR_PHYS (PXA_CS3_PHYS+0x02800000) + /* Logic on ConXS-board DICR register*/ +#define TRIZEPS4_DICR_PHYS (PXA_CS3_PHYS+0x03800000) /* virtual memory regions */ #define TRIZEPS4_DISK_VIRT 0xF0000000 /* Disk On Chip region */ @@ -38,21 +45,30 @@ /* Ethernet Controller Davicom DM9000 */ #define GPIO_DM9000 101 -#define TRIZEPS4_ETH_IRQ IRQ_GPIO(GPIO_DM9000) +#define TRIZEPS4_ETH_IRQ PXA_GPIO_TO_IRQ(GPIO_DM9000) /* UCB1400 audio / TS-controller */ #define GPIO_UCB1400 1 -#define TRIZEPS4_UCB1400_IRQ IRQ_GPIO(GPIO_UCB1400) +#define TRIZEPS4_UCB1400_IRQ PXA_GPIO_TO_IRQ(GPIO_UCB1400) /* PCMCIA socket Compact Flash */ #define GPIO_PCD 11 /* PCMCIA Card Detect */ -#define TRIZEPS4_CD_IRQ IRQ_GPIO(GPIO_PCD) +#define TRIZEPS4_CD_IRQ PXA_GPIO_TO_IRQ(GPIO_PCD) #define GPIO_PRDY 13 /* READY / nINT */ -#define TRIZEPS4_READY_NINT IRQ_GPIO(GPIO_PRDY) +#define TRIZEPS4_READY_NINT PXA_GPIO_TO_IRQ(GPIO_PRDY) /* MMC socket */ #define GPIO_MMC_DET 12 -#define TRIZEPS4_MMC_IRQ IRQ_GPIO(GPIO_MMC_DET) +#define TRIZEPS4_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO_MMC_DET) + +/* DOC NAND chip */ +#define GPIO_DOC_LOCK 94 +#define GPIO_DOC_IRQ 93 +#define TRIZEPS4_DOC_IRQ PXA_GPIO_TO_IRQ(GPIO_DOC_IRQ) + +/* SPI interface */ +#define GPIO_SPI 53 +#define TRIZEPS4_SPI_IRQ PXA_GPIO_TO_IRQ(GPIO_SPI) /* LEDS using tx2 / rx2 */ #define GPIO_SYS_BUSY_LED 46 @@ -60,26 +76,68 @@ /* Off-module PIC on ConXS board */ #define GPIO_PIC 0 -#define TRIZEPS4_PIC_IRQ IRQ_GPIO(GPIO_PIC) +#define TRIZEPS4_PIC_IRQ PXA_GPIO_TO_IRQ(GPIO_PIC) -#define CFSR_P2V(x) ((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT) -#define CFSR_V2P(x) ((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS) +#ifdef CONFIG_MACH_TRIZEPS_CONXS +/* for CONXS base board define these registers */ +#define CFSR_P2V(x) ((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT) +#define CFSR_V2P(x) ((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS) -#define BCR_P2V(x) ((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT) -#define BCR_V2P(x) ((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS) +#define BCR_P2V(x) ((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT) +#define BCR_V2P(x) ((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS) -#define DCR_P2V(x) ((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT) -#define DCR_V2P(x) ((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS) +#define DCR_P2V(x) ((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT) +#define DCR_V2P(x) ((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS) + +#define IRCR_P2V(x) ((x) - TRIZEPS4_IRCR_PHYS + TRIZEPS4_IRCR_VIRT) +#define IRCR_V2P(x) ((x) - TRIZEPS4_IRCR_VIRT + TRIZEPS4_IRCR_PHYS) #ifndef __ASSEMBLY__ -#define ConXS_CFSR (*((volatile unsigned short *)CFSR_P2V(0x0C000000))) -#define ConXS_BCR (*((volatile unsigned short *)BCR_P2V(0x0E000000))) -#define ConXS_DCR (*((volatile unsigned short *)DCR_P2V(0x0F800000))) +static inline unsigned short CFSR_readw(void) +{ + /* [Compact Flash Status Register] is read only */ + return *((unsigned short *)CFSR_P2V(0x0C000000)); +} +static inline void BCR_writew(unsigned short value) +{ + /* [Board Control Regsiter] is write only */ + *((unsigned short *)BCR_P2V(0x0E000000)) = value; +} +static inline void DCR_writew(unsigned short value) +{ + /* [Display Control Register] is write only */ + *((unsigned short *)DCR_P2V(0x0E000000)) = value; +} +static inline void IRCR_writew(unsigned short value) +{ + /* [InfraRed data Control Register] is write only */ + *((unsigned short *)IRCR_P2V(0x0E000000)) = value; +} #else #define ConXS_CFSR CFSR_P2V(0x0C000000) #define ConXS_BCR BCR_P2V(0x0E000000) #define ConXS_DCR DCR_P2V(0x0F800000) +#define ConXS_IRCR IRCR_P2V(0x0F800000) #endif +#else +/* for whatever baseboard define function registers */ +static inline unsigned short CFSR_readw(void) +{ + return 0; +} +static inline void BCR_writew(unsigned short value) +{ + ; +} +static inline void DCR_writew(unsigned short value) +{ + ; +} +static inline void IRCR_writew(unsigned short value) +{ + ; +} +#endif /* CONFIG_MACH_TRIZEPS_CONXS */ #define ConXS_CFSR_BVD_MASK 0x0003 #define ConXS_CFSR_BVD1 (1 << 0) diff --git a/arch/arm/mach-pxa/include/mach/udc.h b/arch/arm/mach-pxa/include/mach/udc.h index 2f82332e81a..9a827e32db9 100644 --- a/arch/arm/mach-pxa/include/mach/udc.h +++ b/arch/arm/mach-pxa/include/mach/udc.h @@ -2,7 +2,7 @@ * arch/arm/mach-pxa/include/mach/udc.h * */ -#include <asm/mach/udc_pxa2xx.h> +#include <linux/platform_data/pxa2xx_udc.h> extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info); diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h index 21e3e890af9..8c27757e68f 100644 --- a/arch/arm/mach-pxa/include/mach/uncompress.h +++ b/arch/arm/mach-pxa/include/mach/uncompress.h @@ -10,20 +10,41 @@ */ #include <linux/serial_reg.h> -#include <mach/pxa-regs.h> #include <asm/mach-types.h> -#define __REG(x) ((volatile unsigned long *)x) +#define FFUART_BASE (0x40100000) +#define BTUART_BASE (0x40200000) +#define STUART_BASE (0x40700000) -static volatile unsigned long *UART = FFUART; +unsigned long uart_base; +unsigned int uart_shift; +unsigned int uart_is_pxa; + +static inline unsigned char uart_read(int offset) +{ + return *(volatile unsigned char *)(uart_base + (offset << uart_shift)); +} + +static inline void uart_write(unsigned char val, int offset) +{ + *(volatile unsigned char *)(uart_base + (offset << uart_shift)) = val; +} + +static inline int uart_is_enabled(void) +{ + /* assume enabled by default for non-PXA uarts */ + return uart_is_pxa ? uart_read(UART_IER) & UART_IER_UUE : 1; +} static inline void putc(char c) { - if (!(UART[UART_IER] & IER_UUE)) + if (!uart_is_enabled()) return; - while (!(UART[UART_LSR] & LSR_TDRQ)) + + while (!(uart_read(UART_LSR) & UART_LSR_THRE)) barrier(); - UART[UART_TX] = c; + + uart_write(c, UART_TX); } /* @@ -35,11 +56,19 @@ static inline void flush(void) static inline void arch_decomp_setup(void) { - if (machine_is_littleton()) - UART = STUART; -} + /* initialize to default */ + uart_base = FFUART_BASE; + uart_shift = 2; + uart_is_pxa = 1; -/* - * nothing to do - */ -#define arch_decomp_wdog() + if (machine_is_littleton() || machine_is_intelmote2() + || machine_is_csb726() || machine_is_stargate2() + || machine_is_cm_x300() || machine_is_balloon3()) + uart_base = STUART_BASE; + + if (machine_is_arcom_zeus()) { + uart_base = 0x10000000; /* nCS4 */ + uart_shift = 1; + uart_is_pxa = 0; + } +} diff --git a/arch/arm/mach-pxa/include/mach/viper.h b/arch/arm/mach-pxa/include/mach/viper.h new file mode 100644 index 00000000000..5f5fbf1f648 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/viper.h @@ -0,0 +1,94 @@ +/* + * arch/arm/mach-pxa/include/mach/viper.h + * + * Author: Ian Campbell + * Created: Feb 03, 2003 + * Copyright: Arcom Control Systems. + * + * Maintained by Marc Zyngier <maz@misterjones.org> + * <marc.zyngier@altran.com> + * + * Created based on 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. + */ + +#ifndef ARCH_VIPER_H +#define ARCH_VIPER_H + +#define VIPER_BOOT_PHYS PXA_CS0_PHYS +#define VIPER_FLASH_PHYS PXA_CS1_PHYS +#define VIPER_ETH_PHYS PXA_CS2_PHYS +#define VIPER_USB_PHYS PXA_CS3_PHYS +#define VIPER_ETH_DATA_PHYS PXA_CS4_PHYS +#define VIPER_CPLD_PHYS PXA_CS5_PHYS + +#define VIPER_CPLD_BASE (0xf0000000) +#define VIPER_PC104IO_BASE (0xf1000000) +#define VIPER_USB_BASE (0xf1800000) + +#define VIPER_ETH_GPIO (0) +#define VIPER_CPLD_GPIO (1) +#define VIPER_USB_GPIO (2) +#define VIPER_UARTA_GPIO (4) +#define VIPER_UARTB_GPIO (3) +#define VIPER_CF_CD_GPIO (32) +#define VIPER_CF_RDY_GPIO (8) +#define VIPER_BCKLIGHT_EN_GPIO (9) +#define VIPER_LCD_EN_GPIO (10) +#define VIPER_PSU_DATA_GPIO (6) +#define VIPER_PSU_CLK_GPIO (11) +#define VIPER_UART_SHDN_GPIO (12) +#define VIPER_BRIGHTNESS_GPIO (16) +#define VIPER_PSU_nCS_LD_GPIO (19) +#define VIPER_UPS_GPIO (20) +#define VIPER_CF_POWER_GPIO (82) +#define VIPER_TPM_I2C_SDA_GPIO (26) +#define VIPER_TPM_I2C_SCL_GPIO (27) +#define VIPER_RTC_I2C_SDA_GPIO (83) +#define VIPER_RTC_I2C_SCL_GPIO (84) + +#define VIPER_CPLD_P2V(x) ((x) - VIPER_CPLD_PHYS + VIPER_CPLD_BASE) +#define VIPER_CPLD_V2P(x) ((x) - VIPER_CPLD_BASE + VIPER_CPLD_PHYS) + +#ifndef __ASSEMBLY__ +# define __VIPER_CPLD_REG(x) (*((volatile u16 *)VIPER_CPLD_P2V(x))) +#endif + +/* board level registers in the CPLD: (offsets from CPLD_BASE) ... */ + +/* ... Physical addresses */ +#define _VIPER_LO_IRQ_STATUS (VIPER_CPLD_PHYS + 0x100000) +#define _VIPER_ICR_PHYS (VIPER_CPLD_PHYS + 0x100002) +#define _VIPER_HI_IRQ_STATUS (VIPER_CPLD_PHYS + 0x100004) +#define _VIPER_VERSION_PHYS (VIPER_CPLD_PHYS + 0x100006) +#define VIPER_UARTA_PHYS (VIPER_CPLD_PHYS + 0x300010) +#define VIPER_UARTB_PHYS (VIPER_CPLD_PHYS + 0x300000) +#define _VIPER_SRAM_BASE (VIPER_CPLD_PHYS + 0x800000) + +/* ... Virtual addresses */ +#define VIPER_LO_IRQ_STATUS __VIPER_CPLD_REG(_VIPER_LO_IRQ_STATUS) +#define VIPER_HI_IRQ_STATUS __VIPER_CPLD_REG(_VIPER_HI_IRQ_STATUS) +#define VIPER_VERSION __VIPER_CPLD_REG(_VIPER_VERSION_PHYS) +#define VIPER_ICR __VIPER_CPLD_REG(_VIPER_ICR_PHYS) + +/* Decode VIPER_VERSION register */ +#define VIPER_CPLD_REVISION(x) (((x) >> 5) & 0x7) +#define VIPER_BOARD_VERSION(x) (((x) >> 3) & 0x3) +#define VIPER_BOARD_ISSUE(x) (((x) >> 0) & 0x7) + +/* Interrupt and Configuration Register (VIPER_ICR) */ +/* This is a write only register. Only CF_RST is used under Linux */ + +#define VIPER_ICR_RETRIG (1 << 0) +#define VIPER_ICR_AUTO_CLR (1 << 1) +#define VIPER_ICR_R_DIS (1 << 2) +#define VIPER_ICR_CF_RST (1 << 3) + +#endif + diff --git a/arch/arm/mach-pxa/include/mach/vmalloc.h b/arch/arm/mach-pxa/include/mach/vmalloc.h deleted file mode 100644 index e90c5eeb81d..00000000000 --- a/arch/arm/mach-pxa/include/mach/vmalloc.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/vmalloc.h - * - * Author: Nicolas Pitre - * Copyright: (C) 2001 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 VMALLOC_END (0xe8000000) diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h new file mode 100644 index 00000000000..7bfa3dd0fd5 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -0,0 +1,42 @@ +/* + * GPIOs and interrupts for Voipac PXA270 + * + * Copyright (C) 2010 + * 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. + * + */ + +#ifndef _INCLUDE_VPAC270_H_ +#define _INCLUDE_VPAC270_H_ + +#define GPIO1_VPAC270_USER_BTN 1 + +#define GPIO15_VPAC270_LED_ORANGE 15 + +#define GPIO81_VPAC270_BKL_ON 81 +#define GPIO83_VPAC270_NL_ON 83 + +#define GPIO52_VPAC270_SD_READONLY 52 +#define GPIO53_VPAC270_SD_DETECT_N 53 + +#define GPIO84_VPAC270_PCMCIA_CD 84 +#define GPIO35_VPAC270_PCMCIA_RDY 35 +#define GPIO107_VPAC270_PCMCIA_PPEN 107 +#define GPIO11_VPAC270_PCMCIA_RESET 11 +#define GPIO17_VPAC270_CF_CD 17 +#define GPIO12_VPAC270_CF_RDY 12 +#define GPIO16_VPAC270_CF_RESET 16 + +#define GPIO41_VPAC270_UDC_DETECT 41 + +#define GPIO114_VPAC270_ETH_IRQ 114 + +#define GPIO36_VPAC270_IDE_IRQ 36 + +#define GPIO113_VPAC270_TS_IRQ 113 + +#endif diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h new file mode 100644 index 00000000000..7b0f71ef316 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/z2.h @@ -0,0 +1,40 @@ +/* + * arch/arm/mach-pxa/include/mach/z2.h + * + * Author: Ken McGuire + * Created: Feb 6, 2009 + * + * 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_ZIPIT2_H +#define ASM_ARCH_ZIPIT2_H + +/* LEDs */ +#define GPIO10_ZIPITZ2_LED_WIFI 10 +#define GPIO85_ZIPITZ2_LED_CHARGED 85 +#define GPIO83_ZIPITZ2_LED_CHARGING 83 + +/* SD/MMC */ +#define GPIO96_ZIPITZ2_SD_DETECT 96 + +/* GPIO Buttons */ +#define GPIO1_ZIPITZ2_POWER_BUTTON 1 +#define GPIO98_ZIPITZ2_LID_BUTTON 98 + +/* Libertas GSPI8686 WiFi */ +#define GPIO14_ZIPITZ2_WIFI_POWER 14 +#define GPIO24_ZIPITZ2_WIFI_CS 24 +#define GPIO36_ZIPITZ2_WIFI_IRQ 36 + +/* LCD */ +#define GPIO19_ZIPITZ2_LCD_RESET 19 +#define GPIO88_ZIPITZ2_LCD_CS 88 + +/* MISC GPIOs */ +#define GPIO0_ZIPITZ2_AC_DETECT 0 +#define GPIO37_ZIPITZ2_HEADSET_DETECT 37 + +#endif diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h new file mode 100644 index 00000000000..56024f81d57 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/zeus.h @@ -0,0 +1,85 @@ +/* + * arch/arm/mach-pxa/include/mach/zeus.h + * + * Author: David Vrabel + * Created: Sept 28, 2005 + * Copyright: Arcom Control Systems Ltd. + * + * Maintained by: Marc Zyngier <maz@misterjones.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. + */ + +#ifndef _MACH_ZEUS_H +#define _MACH_ZEUS_H + +#define ZEUS_NR_IRQS (IRQ_BOARD_START + 48) + +/* Physical addresses */ +#define ZEUS_FLASH_PHYS PXA_CS0_PHYS +#define ZEUS_ETH0_PHYS PXA_CS1_PHYS +#define ZEUS_ETH1_PHYS PXA_CS2_PHYS +#define ZEUS_CPLD_PHYS (PXA_CS4_PHYS+0x2000000) +#define ZEUS_SRAM_PHYS PXA_CS5_PHYS +#define ZEUS_PC104IO_PHYS (0x30000000) + +#define ZEUS_CPLD_VERSION_PHYS (ZEUS_CPLD_PHYS + 0x00000000) +#define ZEUS_CPLD_ISA_IRQ_PHYS (ZEUS_CPLD_PHYS + 0x00800000) +#define ZEUS_CPLD_CONTROL_PHYS (ZEUS_CPLD_PHYS + 0x01000000) +#define ZEUS_CPLD_EXTWDOG_PHYS (ZEUS_CPLD_PHYS + 0x01800000) + +/* GPIOs */ +#define ZEUS_AC97_GPIO 0 +#define ZEUS_WAKEUP_GPIO 1 +#define ZEUS_UARTA_GPIO 9 +#define ZEUS_UARTB_GPIO 10 +#define ZEUS_UARTC_GPIO 12 +#define ZEUS_UARTD_GPIO 11 +#define ZEUS_ETH0_GPIO 14 +#define ZEUS_ISA_GPIO 17 +#define ZEUS_BKLEN_GPIO 19 +#define ZEUS_USB2_PWREN_GPIO 22 +#define ZEUS_PTT_GPIO 27 +#define ZEUS_CF_CD_GPIO 35 +#define ZEUS_MMC_WP_GPIO 52 +#define ZEUS_MMC_CD_GPIO 53 +#define ZEUS_EXTGPIO_GPIO 91 +#define ZEUS_CF_PWEN_GPIO 97 +#define ZEUS_CF_RDY_GPIO 99 +#define ZEUS_LCD_EN_GPIO 101 +#define ZEUS_ETH1_GPIO 113 +#define ZEUS_CAN_GPIO 116 + +#define ZEUS_EXT0_GPIO_BASE 128 +#define ZEUS_EXT1_GPIO_BASE 160 +#define ZEUS_USER_GPIO_BASE 192 + +#define ZEUS_EXT0_GPIO(x) (ZEUS_EXT0_GPIO_BASE + (x)) +#define ZEUS_EXT1_GPIO(x) (ZEUS_EXT1_GPIO_BASE + (x)) +#define ZEUS_USER_GPIO(x) (ZEUS_USER_GPIO_BASE + (x)) + +#define ZEUS_CAN_SHDN_GPIO ZEUS_EXT1_GPIO(2) + +/* + * CPLD registers: + * Only 4 registers, but spread over a 32MB address space. + * Be gentle, and remap that over 32kB... + */ + +#define ZEUS_CPLD IOMEM(0xf0000000) +#define ZEUS_CPLD_VERSION (ZEUS_CPLD + 0x0000) +#define ZEUS_CPLD_ISA_IRQ (ZEUS_CPLD + 0x1000) +#define ZEUS_CPLD_CONTROL (ZEUS_CPLD + 0x2000) + +/* CPLD register bits */ +#define ZEUS_CPLD_CONTROL_CF_RST 0x01 + +#define ZEUS_PC104IO IOMEM(0xf1000000) + +#define ZEUS_SRAM_SIZE (256 * 1024) + +#endif + + diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h index 0d35ca04731..ecca976f03d 100644 --- a/arch/arm/mach-pxa/include/mach/zylonite.h +++ b/arch/arm/mach-pxa/include/mach/zylonite.h @@ -5,16 +5,11 @@ #define EXT_GPIO(x) (128 + (x)) +#define ZYLONITE_NR_IRQS (IRQ_BOARD_START + 32) + /* the following variables are processor specific and initialized * by the corresponding zylonite_pxa3xx_init() */ -struct platform_mmc_slot { - int gpio_cd; - int gpio_wp; -}; - -extern struct platform_mmc_slot zylonite_mmc_slot[]; - extern int gpio_eth_irq; extern int gpio_debug_led1; extern int gpio_debug_led2; @@ -24,23 +19,23 @@ extern int wm9713_irq; extern int lcd_id; extern int lcd_orientation; -#ifdef CONFIG_CPU_PXA300 +#ifdef CONFIG_MACH_ZYLONITE300 extern void zylonite_pxa300_init(void); #else static inline void zylonite_pxa300_init(void) { if (cpu_is_pxa300() || cpu_is_pxa310()) - panic("%s: PXA300/PXA310 not supported\n", __FUNCTION__); + panic("%s: PXA300/PXA310 not supported\n", __func__); } #endif -#ifdef CONFIG_CPU_PXA320 +#ifdef CONFIG_MACH_ZYLONITE320 extern void zylonite_pxa320_init(void); #else static inline void zylonite_pxa320_init(void) { if (cpu_is_pxa320()) - panic("%s: PXA320 not supported\n", __FUNCTION__); + panic("%s: PXA320 not supported\n", __func__); } #endif diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 5e95c5372fe..0eecd83c624 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -11,110 +11,279 @@ * 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/module.h> #include <linux/interrupt.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> + +#include <asm/exception.h> #include <mach/hardware.h> -#include <asm/irq.h> -#include <asm/mach/irq.h> -#include <mach/pxa-regs.h> +#include <mach/irqs.h> #include "generic.h" -#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) -#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR)) -#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR)) +#define ICIP (0x000) +#define ICMR (0x004) +#define ICLR (0x008) +#define ICFR (0x00c) +#define ICPR (0x010) +#define ICCR (0x014) +#define ICHP (0x018) +#define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \ + ((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \ + (0x144 + (((i) - 64) << 2))) +#define ICHP_VAL_IRQ (1 << 31) +#define ICHP_IRQ(i) (((i) >> 16) & 0x7fff) +#define IPR_VALID (1 << 31) +#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) + +#define MAX_INTERNAL_IRQS 128 /* * This is for peripheral IRQs internal to the PXA chip. */ +static void __iomem *pxa_irq_base; static int pxa_internal_irq_nr; +static bool cpu_has_ipr; -static void pxa_mask_irq(unsigned int irq) +static inline void __iomem *irq_base(int i) { - _ICMR(irq) &= ~(1 << IRQ_BIT(irq)); + static unsigned long phys_base_offset[] = { + 0x0, + 0x9c, + 0x130, + }; + + return pxa_irq_base + phys_base_offset[i]; } -static void pxa_unmask_irq(unsigned int irq) +void pxa_mask_irq(struct irq_data *d) { - _ICMR(irq) |= 1 << IRQ_BIT(irq); + void __iomem *base = irq_data_get_irq_chip_data(d); + uint32_t icmr = __raw_readl(base + ICMR); + + icmr &= ~(1 << IRQ_BIT(d->irq)); + __raw_writel(icmr, base + ICMR); +} + +void pxa_unmask_irq(struct irq_data *d) +{ + void __iomem *base = irq_data_get_irq_chip_data(d); + uint32_t icmr = __raw_readl(base + ICMR); + + icmr |= 1 << IRQ_BIT(d->irq); + __raw_writel(icmr, base + ICMR); } static struct irq_chip pxa_internal_irq_chip = { .name = "SC", - .ack = pxa_mask_irq, - .mask = pxa_mask_irq, - .unmask = pxa_unmask_irq, + .irq_ack = pxa_mask_irq, + .irq_mask = pxa_mask_irq, + .irq_unmask = pxa_unmask_irq, }; -void __init pxa_init_irq(int irq_nr, set_wake_t fn) +asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs) +{ + uint32_t icip, icmr, mask; + + do { + icip = __raw_readl(pxa_irq_base + ICIP); + icmr = __raw_readl(pxa_irq_base + ICMR); + mask = icip & icmr; + + if (mask == 0) + break; + + handle_IRQ(PXA_IRQ(fls(mask) - 1), regs); + } while (1); +} + +asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs) { - int irq; + uint32_t ichp; + + do { + __asm__ __volatile__("mrc p6, 0, %0, c5, c0, 0\n": "=r"(ichp)); + + if ((ichp & ICHP_VAL_IRQ) == 0) + break; + + handle_IRQ(PXA_IRQ(ICHP_IRQ(ichp)), regs); + } while (1); +} + +void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int)) +{ + int irq, i, n; + + BUG_ON(irq_nr > MAX_INTERNAL_IRQS); pxa_internal_irq_nr = irq_nr; + cpu_has_ipr = !cpu_is_pxa25x(); + pxa_irq_base = io_p2v(0x40d00000); - for (irq = 0; irq < irq_nr; irq += 32) { - _ICMR(irq) = 0; /* disable all IRQs */ - _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */ - } + for (n = 0; n < irq_nr; n += 32) { + void __iomem *base = irq_base(n >> 5); - /* only unmasked interrupts kick us out of idle */ - ICCR = 1; + __raw_writel(0, base + ICMR); /* disable all IRQs */ + __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ + for (i = n; (i < (n + 32)) && (i < irq_nr); i++) { + /* initialize interrupt priority */ + if (cpu_has_ipr) + __raw_writel(i | IPR_VALID, pxa_irq_base + IPR(i)); - for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) { - set_irq_chip(irq, &pxa_internal_irq_chip); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); + irq = PXA_IRQ(i); + irq_set_chip_and_handler(irq, &pxa_internal_irq_chip, + handle_level_irq); + irq_set_chip_data(irq, base); + set_irq_flags(irq, IRQF_VALID); + } } - pxa_internal_irq_chip.set_wake = fn; + /* only unmasked interrupts kick us out of idle */ + __raw_writel(1, irq_base(0) + ICCR); + + pxa_internal_irq_chip.irq_set_wake = fn; } #ifdef CONFIG_PM -static unsigned long saved_icmr[2]; +static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32]; +static unsigned long saved_ipr[MAX_INTERNAL_IRQS]; -static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) +static int pxa_irq_suspend(void) { - int i, irq = PXA_IRQ(0); + int i; + + for (i = 0; i < pxa_internal_irq_nr / 32; i++) { + void __iomem *base = irq_base(i); - for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { - saved_icmr[i] = _ICMR(irq); - _ICMR(irq) = 0; + saved_icmr[i] = __raw_readl(base + ICMR); + __raw_writel(0, base + ICMR); + } + + if (cpu_has_ipr) { + for (i = 0; i < pxa_internal_irq_nr; i++) + saved_ipr[i] = __raw_readl(pxa_irq_base + IPR(i)); } return 0; } -static int pxa_irq_resume(struct sys_device *dev) +static void pxa_irq_resume(void) { - int i, irq = PXA_IRQ(0); + int i; + + for (i = 0; i < pxa_internal_irq_nr / 32; i++) { + void __iomem *base = irq_base(i); - for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { - _ICMR(irq) = saved_icmr[i]; - _ICLR(irq) = 0; + __raw_writel(saved_icmr[i], base + ICMR); + __raw_writel(0, base + ICLR); } - ICCR = 1; - return 0; + if (cpu_has_ipr) + for (i = 0; i < pxa_internal_irq_nr; i++) + __raw_writel(saved_ipr[i], pxa_irq_base + IPR(i)); + + __raw_writel(1, pxa_irq_base + ICCR); } #else #define pxa_irq_suspend NULL #define pxa_irq_resume NULL #endif -struct sysdev_class pxa_irq_sysclass = { - .name = "irq", +struct syscore_ops pxa_irq_syscore_ops = { .suspend = pxa_irq_suspend, .resume = pxa_irq_resume, }; -static int __init pxa_irq_init(void) +#ifdef CONFIG_OF +static struct irq_domain *pxa_irq_domain; + +static int pxa_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) { - return sysdev_class_register(&pxa_irq_sysclass); + void __iomem *base = irq_base(hw / 32); + + /* initialize interrupt priority */ + if (cpu_has_ipr) + __raw_writel(hw | IPR_VALID, pxa_irq_base + IPR(hw)); + + irq_set_chip_and_handler(hw, &pxa_internal_irq_chip, + handle_level_irq); + irq_set_chip_data(hw, base); + set_irq_flags(hw, IRQF_VALID); + + return 0; } -core_initcall(pxa_irq_init); +static struct irq_domain_ops pxa_irq_ops = { + .map = pxa_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static const struct of_device_id intc_ids[] __initconst = { + { .compatible = "marvell,pxa-intc", }, + {} +}; + +void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)) +{ + struct device_node *node; + struct resource res; + int n, ret; + + node = of_find_matching_node(NULL, intc_ids); + if (!node) { + pr_err("Failed to find interrupt controller in arch-pxa\n"); + return; + } + + ret = of_property_read_u32(node, "marvell,intc-nr-irqs", + &pxa_internal_irq_nr); + if (ret) { + pr_err("Not found marvell,intc-nr-irqs property\n"); + return; + } + + ret = of_address_to_resource(node, 0, &res); + if (ret < 0) { + pr_err("No registers defined for node\n"); + return; + } + pxa_irq_base = io_p2v(res.start); + + if (of_find_property(node, "marvell,intc-priority", NULL)) + cpu_has_ipr = 1; + + ret = irq_alloc_descs(-1, 0, pxa_internal_irq_nr, 0); + if (ret < 0) { + pr_err("Failed to allocate IRQ numbers\n"); + return; + } + + pxa_irq_domain = irq_domain_add_legacy(node, pxa_internal_irq_nr, 0, 0, + &pxa_irq_ops, NULL); + if (!pxa_irq_domain) + panic("Unable to add PXA IRQ domain\n"); + + irq_set_default_host(pxa_irq_domain); + + for (n = 0; n < pxa_internal_irq_nr; n += 32) { + void __iomem *base = irq_base(n >> 5); + + __raw_writel(0, base + ICMR); /* disable all IRQs */ + __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ + } + + /* only unmasked interrupts kick us out of idle */ + __raw_writel(1, irq_base(0) + ICCR); + + pxa_internal_irq_chip.irq_set_wake = fn; +} +#endif /* CONFIG_OF */ diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c deleted file mode 100644 index 18b20d46941..00000000000 --- a/arch/arm/mach-pxa/leds-idp.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/leds-idp.c - * - * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu> - * - * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com> - * - * Original (leds-footbridge.c) by Russell King - * - * Macros for actual LED manipulation should be in machine specific - * files in this 'mach' directory. - */ - - -#include <linux/init.h> - -#include <mach/hardware.h> -#include <asm/leds.h> -#include <asm/system.h> - -#include <mach/pxa-regs.h> -#include <mach/idp.h> - -#include "leds.h" - -#define LED_STATE_ENABLED 1 -#define LED_STATE_CLAIMED 2 - -static unsigned int led_state; -static unsigned int hw_led_state; - -void idp_leds_event(led_event_t evt) -{ - unsigned long flags; - - local_irq_save(flags); - - switch (evt) { - case led_start: - hw_led_state = IDP_HB_LED | IDP_BUSY_LED; - led_state = LED_STATE_ENABLED; - break; - - case led_stop: - led_state &= ~LED_STATE_ENABLED; - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = IDP_HB_LED | IDP_BUSY_LED; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = IDP_HB_LED | IDP_BUSY_LED; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state ^= IDP_HB_LED; - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state &= ~IDP_BUSY_LED; - break; - - case led_idle_end: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state |= IDP_BUSY_LED; - break; -#endif - - case led_halted: - break; - - case led_green_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= IDP_HB_LED; - break; - - case led_green_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~IDP_HB_LED; - break; - - case led_amber_on: - break; - - case led_amber_off: - break; - - case led_red_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= IDP_BUSY_LED; - break; - - case led_red_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~IDP_BUSY_LED; - break; - - default: - break; - } - - if (led_state & LED_STATE_ENABLED) - IDP_CPLD_LED_CONTROL = ( (IDP_CPLD_LED_CONTROL | IDP_LEDS_MASK) & ~hw_led_state); - else - IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK; - - local_irq_restore(flags); -} diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c deleted file mode 100644 index 1a258029c33..00000000000 --- a/arch/arm/mach-pxa/leds-lubbock.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/leds-lubbock.c - * - * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu> - * - * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com> - * - * Original (leds-footbridge.c) by Russell King - * - * Major surgery on April 2004 by Nicolas Pitre for less global - * namespace collision. Mostly adapted the Mainstone version. - */ - -#include <linux/init.h> - -#include <mach/hardware.h> -#include <asm/leds.h> -#include <asm/system.h> -#include <mach/pxa-regs.h> -#include <mach/lubbock.h> - -#include "leds.h" - -/* - * 8 discrete leds available for general use: - * - * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays - * so be sure to not monkey with them here. - */ - -#define D28 (1 << 0) -#define D27 (1 << 1) -#define D26 (1 << 2) -#define D25 (1 << 3) -#define D24 (1 << 4) -#define D23 (1 << 5) -#define D22 (1 << 6) -#define D21 (1 << 7) - -#define LED_STATE_ENABLED 1 -#define LED_STATE_CLAIMED 2 - -static unsigned int led_state; -static unsigned int hw_led_state; - -void lubbock_leds_event(led_event_t evt) -{ - unsigned long flags; - - local_irq_save(flags); - - switch (evt) { - case led_start: - hw_led_state = 0; - led_state = LED_STATE_ENABLED; - break; - - case led_stop: - led_state &= ~LED_STATE_ENABLED; - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = 0; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - hw_led_state ^= D26; - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - hw_led_state &= ~D27; - break; - - case led_idle_end: - hw_led_state |= D27; - break; -#endif - - case led_halted: - break; - - case led_green_on: - hw_led_state |= D21; - break; - - case led_green_off: - hw_led_state &= ~D21; - break; - - case led_amber_on: - hw_led_state |= D22; - break; - - case led_amber_off: - hw_led_state &= ~D22; - break; - - case led_red_on: - hw_led_state |= D23; - break; - - case led_red_off: - hw_led_state &= ~D23; - break; - - default: - break; - } - - if (led_state & LED_STATE_ENABLED) - LUB_DISC_BLNK_LED = (LUB_DISC_BLNK_LED | 0xff) & ~hw_led_state; - else - LUB_DISC_BLNK_LED |= 0xff; - - local_irq_restore(flags); -} diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c deleted file mode 100644 index 95e06b84963..00000000000 --- a/arch/arm/mach-pxa/leds-mainstone.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/leds-mainstone.c - * - * Author: Nicolas Pitre - * Created: Nov 05, 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. - */ - -#include <linux/init.h> - -#include <mach/hardware.h> -#include <asm/leds.h> -#include <asm/system.h> - -#include <mach/pxa-regs.h> -#include <mach/mainstone.h> - -#include "leds.h" - - -/* 8 discrete leds available for general use: */ -#define D28 (1 << 0) -#define D27 (1 << 1) -#define D26 (1 << 2) -#define D25 (1 << 3) -#define D24 (1 << 4) -#define D23 (1 << 5) -#define D22 (1 << 6) -#define D21 (1 << 7) - -#define LED_STATE_ENABLED 1 -#define LED_STATE_CLAIMED 2 - -static unsigned int led_state; -static unsigned int hw_led_state; - -void mainstone_leds_event(led_event_t evt) -{ - unsigned long flags; - - local_irq_save(flags); - - switch (evt) { - case led_start: - hw_led_state = 0; - led_state = LED_STATE_ENABLED; - break; - - case led_stop: - led_state &= ~LED_STATE_ENABLED; - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = 0; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - hw_led_state ^= D26; - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - hw_led_state &= ~D27; - break; - - case led_idle_end: - hw_led_state |= D27; - break; -#endif - - case led_halted: - break; - - case led_green_on: - hw_led_state |= D21; - break; - - case led_green_off: - hw_led_state &= ~D21; - break; - - case led_amber_on: - hw_led_state |= D22; - break; - - case led_amber_off: - hw_led_state &= ~D22; - break; - - case led_red_on: - hw_led_state |= D23; - break; - - case led_red_off: - hw_led_state &= ~D23; - break; - - default: - break; - } - - if (led_state & LED_STATE_ENABLED) - MST_LEDCTRL = (MST_LEDCTRL | 0xff) & ~hw_led_state; - else - MST_LEDCTRL |= 0xff; - - local_irq_restore(flags); -} diff --git a/arch/arm/mach-pxa/leds-trizeps4.c b/arch/arm/mach-pxa/leds-trizeps4.c deleted file mode 100644 index 3bc29007df3..00000000000 --- a/arch/arm/mach-pxa/leds-trizeps4.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/leds-trizeps4.c - * - * Author: Jürgen Schindele - * Created: 20 02, 2006 - * Copyright: Jürgen Schindele - * - * 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 <mach/hardware.h> -#include <asm/system.h> -#include <asm/types.h> -#include <asm/leds.h> - -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/trizeps4.h> - -#include "leds.h" - -#define LED_STATE_ENABLED 1 -#define LED_STATE_CLAIMED 2 - -#define SYS_BUSY 0x01 -#define HEARTBEAT 0x02 -#define BLINK 0x04 - -static unsigned int led_state; -static unsigned int hw_led_state; - -void trizeps4_leds_event(led_event_t evt) -{ - unsigned long flags; - - local_irq_save(flags); - - switch (evt) { - case led_start: - hw_led_state = 0; - pxa_gpio_mode( GPIO_SYS_BUSY_LED | GPIO_OUT); /* LED1 */ - pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT); /* LED2 */ - led_state = LED_STATE_ENABLED; - break; - - case led_stop: - led_state &= ~LED_STATE_ENABLED; - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = 0; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - hw_led_state ^= HEARTBEAT; - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - hw_led_state &= ~SYS_BUSY; - break; - - case led_idle_end: - hw_led_state |= SYS_BUSY; - break; -#endif - - case led_halted: - break; - - case led_green_on: - hw_led_state |= BLINK; - break; - - case led_green_off: - hw_led_state &= ~BLINK; - break; - - case led_amber_on: - break; - - case led_amber_off: - break; - - case led_red_on: - break; - - case led_red_off: - break; - - default: - break; - } - - if (led_state & LED_STATE_ENABLED) { - switch (hw_led_state) { - case 0: - GPSR(GPIO_SYS_BUSY_LED) |= GPIO_bit(GPIO_SYS_BUSY_LED); - GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED); - break; - case 1: - GPCR(GPIO_SYS_BUSY_LED) |= GPIO_bit(GPIO_SYS_BUSY_LED); - GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED); - break; - case 2: - GPSR(GPIO_SYS_BUSY_LED) |= GPIO_bit(GPIO_SYS_BUSY_LED); - GPCR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED); - break; - case 3: - GPCR(GPIO_SYS_BUSY_LED) |= GPIO_bit(GPIO_SYS_BUSY_LED); - GPCR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED); - break; - } - } - else { - /* turn all off */ - GPSR(GPIO_SYS_BUSY_LED) |= GPIO_bit(GPIO_SYS_BUSY_LED); - GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED); - } - - local_irq_restore(flags); -} diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c deleted file mode 100644 index e13eb841e48..00000000000 --- a/arch/arm/mach-pxa/leds.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/leds.c - * - * xscale LEDs dispatcher - * - * Copyright (C) 2001 Nicolas Pitre - * - * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc. - */ -#include <linux/compiler.h> -#include <linux/init.h> - -#include <asm/leds.h> -#include <asm/mach-types.h> - -#include "leds.h" - -static int __init -pxa_leds_init(void) -{ - if (machine_is_lubbock()) - leds_event = lubbock_leds_event; - if (machine_is_mainstone()) - leds_event = mainstone_leds_event; - if (machine_is_pxa_idp()) - leds_event = idp_leds_event; - if (machine_is_trizeps4()) - leds_event = trizeps4_leds_event; - - leds_event(led_start); - return 0; -} - -core_initcall(pxa_leds_init); diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h deleted file mode 100644 index 7f0dfe01345..00000000000 --- a/arch/arm/mach-pxa/leds.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-pxa/leds.h - * - * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc. - * - * blinky lights for various PXA-based systems: - * - */ - -extern void idp_leds_event(led_event_t evt); -extern void lubbock_leds_event(led_event_t evt); -extern void mainstone_leds_event(led_event_t evt); -extern void trizeps4_leds_event(led_event_t evt); diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 58f3402a037..5d665588c7e 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -20,7 +20,15 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> #include <linux/smc91x.h> +#include <linux/i2c.h> +#include <linux/leds.h> +#include <linux/mfd/da903x.h> +#include <linux/i2c/max732x.h> +#include <linux/i2c/pxa-i2c.h> #include <asm/types.h> #include <asm/setup.h> @@ -33,17 +41,17 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/pxa-regs.h> -#include <mach/mfp-pxa300.h> -#include <mach/gpio.h> -#include <mach/pxafb.h> -#include <mach/ssp.h> -#include <mach/pxa27x_keypad.h> -#include <mach/pxa3xx_nand.h> +#include <mach/pxa300.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/keypad-pxa27x.h> #include <mach/littleton.h> +#include <linux/platform_data/mtd-nand-pxa3xx.h> #include "generic.h" +#define GPIO_MMC1_CARD_DETECT mfp_to_gpio(MFP_PIN_GPIO15) + /* Littleton MFP configurations */ static mfp_cfg_t littleton_mfp_cfg[] __initdata = { /* LCD */ @@ -72,8 +80,8 @@ static mfp_cfg_t littleton_mfp_cfg[] __initdata = { /* SSP2 */ GPIO25_SSP2_SCLK, - GPIO17_SSP2_FRM, GPIO27_SSP2_TXD, + GPIO17_GPIO, /* SFRM as chip-select */ /* Debug Ethernet */ GPIO90_GPIO, @@ -92,6 +100,21 @@ static mfp_cfg_t littleton_mfp_cfg[] __initdata = { GPIO123_KP_MKOUT_2, GPIO124_KP_MKOUT_3, GPIO125_KP_MKOUT_4, + + /* MMC1 */ + GPIO3_MMC1_DAT0, + GPIO4_MMC1_DAT1, + GPIO5_MMC1_DAT2, + GPIO6_MMC1_DAT3, + GPIO7_MMC1_CLK, + GPIO8_MMC1_CMD, + GPIO15_GPIO, /* card detect */ + + /* UART3 */ + GPIO107_UART3_CTS, + GPIO108_UART3_RTS, + GPIO109_UART3_TXD, + GPIO110_UART3_RXD, }; static struct resource smc91x_resources[] = { @@ -101,8 +124,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), - .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, } }; @@ -123,160 +146,6 @@ static struct platform_device smc91x_device = { }; #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) -/* use bit 30, 31 as the indicator of command parameter number */ -#define CMD0(x) ((0x00000000) | ((x) << 9)) -#define CMD1(x, x1) ((0x40000000) | ((x) << 9) | 0x100 | (x1)) -#define CMD2(x, x1, x2) ((0x80000000) | ((x) << 18) | 0x20000 |\ - ((x1) << 9) | 0x100 | (x2)) - -static uint32_t lcd_panel_reset[] = { - CMD0(0x1), /* reset */ - CMD0(0x0), /* nop */ - CMD0(0x0), /* nop */ - CMD0(0x0), /* nop */ -}; - -static uint32_t lcd_panel_on[] = { - CMD0(0x29), /* Display ON */ - CMD2(0xB8, 0xFF, 0xF9), /* Output Control */ - CMD0(0x11), /* Sleep out */ - CMD1(0xB0, 0x16), /* Wake */ -}; - -static uint32_t lcd_panel_off[] = { - CMD0(0x28), /* Display OFF */ - CMD2(0xB8, 0x80, 0x02), /* Output Control */ - CMD0(0x10), /* Sleep in */ - CMD1(0xB0, 0x00), /* Deep stand by in */ -}; - -static uint32_t lcd_vga_pass_through[] = { - CMD1(0xB0, 0x16), - CMD1(0xBC, 0x80), - CMD1(0xE1, 0x00), - CMD1(0x36, 0x50), - CMD1(0x3B, 0x00), -}; - -static uint32_t lcd_qvga_pass_through[] = { - CMD1(0xB0, 0x16), - CMD1(0xBC, 0x81), - CMD1(0xE1, 0x00), - CMD1(0x36, 0x50), - CMD1(0x3B, 0x22), -}; - -static uint32_t lcd_vga_transfer[] = { - CMD1(0xcf, 0x02), /* Blanking period control (1) */ - CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */ - CMD1(0xd1, 0x01), /* CKV timing control on/off */ - CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */ - CMD2(0xd3, 0x1a, 0x0f), /* OEV timing control */ - CMD2(0xd4, 0x1f, 0xaf), /* ASW timing control (1) */ - CMD1(0xd5, 0x14), /* ASW timing control (2) */ - CMD0(0x21), /* Invert for normally black display */ - CMD0(0x29), /* Display on */ -}; - -static uint32_t lcd_qvga_transfer[] = { - CMD1(0xd6, 0x02), /* Blanking period control (1) */ - CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */ - CMD1(0xd8, 0x01), /* CKV timing control on/off */ - CMD2(0xd9, 0x00, 0x08), /* CKV 1,2 timing control */ - CMD2(0xde, 0x05, 0x0a), /* OEV timing control */ - CMD2(0xdf, 0x0a, 0x19), /* ASW timing control (1) */ - CMD1(0xe0, 0x0a), /* ASW timing control (2) */ - CMD0(0x21), /* Invert for normally black display */ - CMD0(0x29), /* Display on */ -}; - -static uint32_t lcd_panel_config[] = { - CMD2(0xb8, 0xff, 0xf9), /* Output control */ - CMD0(0x11), /* sleep out */ - CMD1(0xba, 0x01), /* Display mode (1) */ - CMD1(0xbb, 0x00), /* Display mode (2) */ - CMD1(0x3a, 0x60), /* Display mode 18-bit RGB */ - CMD1(0xbf, 0x10), /* Drive system change control */ - CMD1(0xb1, 0x56), /* Booster operation setup */ - CMD1(0xb2, 0x33), /* Booster mode setup */ - CMD1(0xb3, 0x11), /* Booster frequency setup */ - CMD1(0xb4, 0x02), /* Op amp/system clock */ - CMD1(0xb5, 0x35), /* VCS voltage */ - CMD1(0xb6, 0x40), /* VCOM voltage */ - CMD1(0xb7, 0x03), /* External display signal */ - CMD1(0xbd, 0x00), /* ASW slew rate */ - CMD1(0xbe, 0x00), /* Dummy data for QuadData operation */ - CMD1(0xc0, 0x11), /* Sleep out FR count (A) */ - CMD1(0xc1, 0x11), /* Sleep out FR count (B) */ - CMD1(0xc2, 0x11), /* Sleep out FR count (C) */ - CMD2(0xc3, 0x20, 0x40), /* Sleep out FR count (D) */ - CMD2(0xc4, 0x60, 0xc0), /* Sleep out FR count (E) */ - CMD2(0xc5, 0x10, 0x20), /* Sleep out FR count (F) */ - CMD1(0xc6, 0xc0), /* Sleep out FR count (G) */ - CMD2(0xc7, 0x33, 0x43), /* Gamma 1 fine tuning (1) */ - CMD1(0xc8, 0x44), /* Gamma 1 fine tuning (2) */ - CMD1(0xc9, 0x33), /* Gamma 1 inclination adjustment */ - CMD1(0xca, 0x00), /* Gamma 1 blue offset adjustment */ - CMD2(0xec, 0x01, 0xf0), /* Horizontal clock cycles */ -}; - -static void ssp_reconfig(struct ssp_dev *dev, int nparam) -{ - static int last_nparam = -1; - - /* check if it is necessary to re-config SSP */ - if (nparam == last_nparam) - return; - - ssp_disable(dev); - ssp_config(dev, (nparam == 2) ? 0x0010058a : 0x00100581, 0x18, 0, 0); - - last_nparam = nparam; -} - -static void ssp_send_cmd(uint32_t *cmd, int num) -{ - static int ssp_initialized; - static struct ssp_dev ssp2; - - int i; - - if (!ssp_initialized) { - ssp_init(&ssp2, 2, SSP_NO_IRQ); - ssp_initialized = 1; - } - - clk_enable(ssp2.ssp->clk); - for (i = 0; i < num; i++, cmd++) { - ssp_reconfig(&ssp2, (*cmd >> 30) & 0x3); - ssp_write_word(&ssp2, *cmd & 0x3fffffff); - - /* FIXME: ssp_flush() is mandatory here to work */ - ssp_flush(&ssp2); - } - clk_disable(ssp2.ssp->clk); -} - -static void littleton_lcd_power(int on, struct fb_var_screeninfo *var) -{ - if (on) { - ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_on)); - ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_reset)); - if (var->xres > 240) { - /* VGA */ - ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_pass_through)); - ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config)); - ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_transfer)); - } else { - /* QVGA */ - ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_pass_through)); - ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config)); - ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_transfer)); - } - } else - ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_off)); -} - static struct pxafb_mode_info tpo_tdo24mtea1_modes[] = { [0] = { /* VGA */ @@ -312,19 +181,48 @@ static struct pxafb_mach_info littleton_lcd_info = { .modes = tpo_tdo24mtea1_modes, .num_modes = 2, .lcd_conn = LCD_COLOR_TFT_16BPP, - .pxafb_lcd_power = littleton_lcd_power, }; static void littleton_init_lcd(void) { - set_pxa_fb_info(&littleton_lcd_info); + pxa_set_fb_info(NULL, &littleton_lcd_info); } #else static inline void littleton_init_lcd(void) {}; #endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */ +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +static struct pxa2xx_spi_master littleton_spi_info = { + .num_chipselect = 1, +}; + +static struct pxa2xx_spi_chip littleton_tdo24m_chip = { + .rx_threshold = 1, + .tx_threshold = 1, + .gpio_cs = LITTLETON_GPIO_LCD_CS, +}; + +static struct spi_board_info littleton_spi_devices[] __initdata = { + { + .modalias = "tdo24m", + .max_speed_hz = 1000000, + .bus_num = 2, + .chip_select = 0, + .controller_data= &littleton_tdo24m_chip, + }, +}; + +static void __init littleton_init_spi(void) +{ + pxa2xx_set_spi_info(2, &littleton_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices)); +} +#else +static inline void littleton_init_spi(void) {} +#endif + #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) -static unsigned int littleton_matrix_key_map[] = { +static const unsigned int littleton_matrix_key_map[] = { /* KEY(row, col, key_code) */ KEY(1, 3, KEY_0), KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), KEY(2, 0, KEY_3), KEY(0, 1, KEY_4), KEY(1, 1, KEY_5), KEY(2, 1, KEY_6), KEY(0, 2, KEY_7), @@ -351,11 +249,15 @@ static unsigned int littleton_matrix_key_map[] = { KEY(3, 1, KEY_F23), /* soft2 */ }; +static struct matrix_keymap_data littleton_matrix_keymap_data = { + .keymap = littleton_matrix_key_map, + .keymap_size = ARRAY_SIZE(littleton_matrix_key_map), +}; + static struct pxa27x_keypad_platform_data littleton_keypad_info = { .matrix_key_rows = 6, .matrix_key_cols = 5, - .matrix_key_map = littleton_matrix_key_map, - .matrix_key_map_size = ARRAY_SIZE(littleton_matrix_key_map), + .matrix_keymap_data = &littleton_matrix_keymap_data, .enable_rotary0 = 1, .rotary0_up_key = KEY_UP, @@ -371,6 +273,23 @@ static void __init littleton_init_keypad(void) static inline void littleton_init_keypad(void) {} #endif +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data littleton_mci_platform_data = { + .detect_delay_ms = 200, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = GPIO_MMC1_CARD_DETECT, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +static void __init littleton_init_mmc(void) +{ + pxa_set_mci_info(&littleton_mci_platform_data); +} +#else +static inline void littleton_init_mmc(void) {} +#endif + #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) static struct mtd_partition littleton_nand_partitions[] = { [0] = { @@ -410,8 +329,9 @@ static struct mtd_partition littleton_nand_partitions[] = { static struct pxa3xx_nand_platform_data littleton_nand_info = { .enable_arbiter = 1, - .parts = littleton_nand_partitions, - .nr_parts = ARRAY_SIZE(littleton_nand_partitions), + .num_cs = 1, + .parts[0] = littleton_nand_partitions, + .nr_parts[0] = ARRAY_SIZE(littleton_nand_partitions), }; static void __init littleton_init_nand(void) @@ -422,28 +342,112 @@ static void __init littleton_init_nand(void) static inline void littleton_init_nand(void) {} #endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ +#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) +static struct led_info littleton_da9034_leds[] = { + [0] = { + .name = "littleton:keypad1", + .flags = DA9034_LED_RAMP, + }, + [1] = { + .name = "littleton:keypad2", + .flags = DA9034_LED_RAMP, + }, + [2] = { + .name = "littleton:vibra", + .flags = 0, + }, +}; + +static struct da9034_touch_pdata littleton_da9034_touch = { + .x_inverted = 1, + .interval_ms = 20, +}; + +static struct da903x_subdev_info littleton_da9034_subdevs[] = { + { + .name = "da903x-led", + .id = DA9034_ID_LED_1, + .platform_data = &littleton_da9034_leds[0], + }, { + .name = "da903x-led", + .id = DA9034_ID_LED_2, + .platform_data = &littleton_da9034_leds[1], + }, { + .name = "da903x-led", + .id = DA9034_ID_VIBRA, + .platform_data = &littleton_da9034_leds[2], + }, { + .name = "da903x-backlight", + .id = DA9034_ID_WLED, + }, { + .name = "da9034-touch", + .id = DA9034_ID_TOUCH, + .platform_data = &littleton_da9034_touch, + }, +}; + +static struct da903x_platform_data littleton_da9034_info = { + .num_subdevs = ARRAY_SIZE(littleton_da9034_subdevs), + .subdevs = littleton_da9034_subdevs, +}; + +static struct max732x_platform_data littleton_max7320_info = { + .gpio_base = EXT0_GPIO_BASE, +}; + +static struct i2c_board_info littleton_i2c_info[] = { + [0] = { + .type = "da9034", + .addr = 0x34, + .platform_data = &littleton_da9034_info, + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO18)), + }, + [1] = { + .type = "max7320", + .addr = 0x50, + .platform_data = &littleton_max7320_info, + }, +}; + +static void __init littleton_init_i2c(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(littleton_i2c_info)); +} +#else +static inline void littleton_init_i2c(void) {} +#endif /* CONFIG_I2C_PXA || CONFIG_I2C_PXA_MODULE */ + static void __init littleton_init(void) { /* initialize MFP configurations */ pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mfp_cfg)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + /* * Note: we depend bootloader set the correct * value to MSC register for SMC91x. */ platform_device_register(&smc91x_device); + littleton_init_spi(); + littleton_init_i2c(); + littleton_init_mmc(); littleton_init_lcd(); littleton_init_keypad(); littleton_init_nand(); } MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)") - .phys_io = 0x40000000, - .boot_params = 0xa0000100, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .nr_irqs = LITTLETON_NR_IRQS, .init_irq = pxa3xx_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, .init_machine = littleton_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index b7038948d1d..9f6ec167902 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -12,10 +12,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#include <linux/gpio.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/bitops.h> @@ -38,25 +38,65 @@ #include <asm/mach/irq.h> #include <asm/mach/flash.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> +#include <mach/pxa27x.h> #include <mach/lpd270.h> #include <mach/audio.h> -#include <mach/pxafb.h> -#include <mach/mmc.h> -#include <mach/irda.h> -#include <mach/ohci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/smemc.h> #include "generic.h" #include "devices.h" +static unsigned long lpd270_pin_config[] __initdata = { + /* Chip Selects */ + GPIO15_nCS_1, /* Mainboard Flash */ + GPIO78_nCS_2, /* CPLD + Ethernet */ + + /* LCD - 16bpp Active TFT */ + 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, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, + GPIO77_LCD_BIAS, + GPIO16_PWM0_OUT, /* Backlight */ + + /* USB Host */ + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO45_AC97_SYSCLK, + + GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, +}; static unsigned int lpd270_irq_enabled; -static void lpd270_mask_irq(unsigned int irq) +static void lpd270_mask_irq(struct irq_data *d) { - int lpd270_irq = irq - LPD270_IRQ(0); + int lpd270_irq = d->irq - LPD270_IRQ(0); __raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS); @@ -64,9 +104,9 @@ static void lpd270_mask_irq(unsigned int irq) __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK); } -static void lpd270_unmask_irq(unsigned int irq) +static void lpd270_unmask_irq(struct irq_data *d) { - int lpd270_irq = irq - LPD270_IRQ(0); + int lpd270_irq = d->irq - LPD270_IRQ(0); lpd270_irq_enabled |= 1 << lpd270_irq; __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK); @@ -74,9 +114,9 @@ static void lpd270_unmask_irq(unsigned int irq) static struct irq_chip lpd270_irq_chip = { .name = "CPLD", - .ack = lpd270_mask_irq, - .mask = lpd270_mask_irq, - .unmask = lpd270_unmask_irq, + .irq_ack = lpd270_mask_irq, + .irq_mask = lpd270_mask_irq, + .irq_unmask = lpd270_unmask_irq, }; static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc) @@ -85,11 +125,11 @@ static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc) pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled; do { - GEDR(0) = GPIO_bit(0); /* clear useless edge notification */ + /* clear useless edge notification */ + desc->irq_data.chip->irq_ack(&desc->irq_data); if (likely(pending)) { irq = LPD270_IRQ(0) + __ffs(pending); - desc = irq_desc + irq; - desc_handle_irq(irq, desc); + generic_handle_irq(irq); pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled; @@ -108,40 +148,32 @@ static void __init lpd270_init_irq(void) /* setup extra LogicPD PXA270 irqs */ for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) { - set_irq_chip(irq, &lpd270_irq_chip); - set_irq_handler(irq, handle_level_irq); + irq_set_chip_and_handler(irq, &lpd270_irq_chip, + handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lpd270_irq_handler); + irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM -static int lpd270_irq_resume(struct sys_device *dev) +static void lpd270_irq_resume(void) { __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK); - return 0; } -static struct sysdev_class lpd270_irq_sysclass = { - .name = "cpld_irq", +static struct syscore_ops lpd270_irq_syscore_ops = { .resume = lpd270_irq_resume, }; -static struct sys_device lpd270_irq_device = { - .cls = &lpd270_irq_sysclass, -}; - static int __init lpd270_irq_device_init(void) { - int ret = -ENODEV; if (machine_is_logicpd_pxa270()) { - ret = sysdev_class_register(&lpd270_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&lpd270_irq_device); + register_syscore_ops(&lpd270_irq_syscore_ops); + return 0; } - return ret; + return -ENODEV; } device_initcall(lpd270_irq_device_init); @@ -237,6 +269,7 @@ static struct platform_pwm_backlight_data lpd270_backlight_data = { .max_brightness = 1, .dft_brightness = 1, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device lpd270_backlight_device = { @@ -265,8 +298,8 @@ static struct pxafb_mode_info sharp_lq057q3dc02_mode = { static struct pxafb_mach_info sharp_lq057q3dc02 = { .modes = &sharp_lq057q3dc02_mode, .num_modes = 1, - .lccr0 = 0x07800080, - .lccr3 = 0x00400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL | + LCD_ALTERNATE_MAPPING, }; /* 12.1" TFT SVGA (LoLo display number 2) */ @@ -287,8 +320,8 @@ static struct pxafb_mode_info sharp_lq121s1dg31_mode = { static struct pxafb_mach_info sharp_lq121s1dg31 = { .modes = &sharp_lq121s1dg31_mode, .num_modes = 1, - .lccr0 = 0x07800080, - .lccr3 = 0x00400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL | + LCD_ALTERNATE_MAPPING, }; /* 3.6" TFT QVGA (LoLo display number 3) */ @@ -309,8 +342,8 @@ static struct pxafb_mode_info sharp_lq036q1da01_mode = { static struct pxafb_mach_info sharp_lq036q1da01 = { .modes = &sharp_lq036q1da01_mode, .num_modes = 1, - .lccr0 = 0x07800080, - .lccr3 = 0x00400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL | + LCD_ALTERNATE_MAPPING, }; /* 6.4" TFT VGA (LoLo display number 5) */ @@ -331,8 +364,8 @@ static struct pxafb_mode_info sharp_lq64d343_mode = { static struct pxafb_mach_info sharp_lq64d343 = { .modes = &sharp_lq64d343_mode, .num_modes = 1, - .lccr0 = 0x07800080, - .lccr3 = 0x00400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL | + LCD_ALTERNATE_MAPPING, }; /* 10.4" TFT VGA (LoLo display number 7) */ @@ -353,8 +386,8 @@ static struct pxafb_mode_info sharp_lq10d368_mode = { static struct pxafb_mach_info sharp_lq10d368 = { .modes = &sharp_lq10d368_mode, .num_modes = 1, - .lccr0 = 0x07800080, - .lccr3 = 0x00400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL | + LCD_ALTERNATE_MAPPING, }; /* 3.5" TFT QVGA (LoLo display number 8) */ @@ -375,8 +408,8 @@ static struct pxafb_mode_info sharp_lq035q7db02_20_mode = { static struct pxafb_mach_info sharp_lq035q7db02_20 = { .modes = &sharp_lq035q7db02_20_mode, .num_modes = 1, - .lccr0 = 0x07800080, - .lccr3 = 0x00400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL | + LCD_ALTERNATE_MAPPING, }; static struct pxafb_mach_info *lpd270_lcd_to_use; @@ -411,28 +444,20 @@ static struct platform_device *platform_devices[] __initdata = { &lpd270_flash_device[1], }; -static int lpd270_ohci_init(struct device *dev) -{ - /* setup Port1 GPIO pin. */ - pxa_gpio_mode(88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ - pxa_gpio_mode(89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ - - /* Set the Power Control Polarity Low and Power Sense - Polarity Low to active low. */ - UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); - - return 0; -} - static struct pxaohci_platform_data lpd270_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, - .init = lpd270_ohci_init, + .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, }; static void __init lpd270_init(void) { - lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4; + pxa2xx_mfp_config(ARRAY_AND_SIZE(lpd270_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + lpd270_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4; lpd270_flash_data[1].width = 4; /* @@ -442,18 +467,12 @@ static void __init lpd270_init(void) */ ARB_CNTRL = ARB_CORE_PARK | 0x234; - /* - * On LogicPD PXA270, we route AC97_SYSCLK via GPIO45. - */ - pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); - pxa_gpio_mode(GPIO16_PWM0_MD); - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); pxa_set_ac97_info(NULL); if (lpd270_lcd_to_use != NULL) - set_pxa_fb_info(lpd270_lcd_to_use); + pxa_set_fb_info(NULL, lpd270_lcd_to_use); pxa_set_ohci_info(&lpd270_ohci_platform_data); } @@ -461,7 +480,7 @@ static void __init lpd270_init(void) static struct map_desc lpd270_io_desc[] __initdata = { { - .virtual = LPD270_CPLD_VIRT, + .virtual = (unsigned long)LPD270_CPLD_VIRT, .pfn = __phys_to_pfn(LPD270_CPLD_PHYS), .length = LPD270_CPLD_SIZE, .type = MT_DEVICE, @@ -470,18 +489,9 @@ static struct map_desc lpd270_io_desc[] __initdata = { static void __init lpd270_map_io(void) { - pxa_map_io(); + pxa27x_map_io(); iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc)); - /* initialize sleep mode regs (wake-up sources, etc) */ - PGSR0 = 0x00008800; - PGSR1 = 0x00000002; - PGSR2 = 0x0001FC00; - PGSR3 = 0x00001F81; - PWER = 0xC0000002; - PRER = 0x00000002; - PFER = 0x00000002; - /* for use I SRAM as framebuffer. */ PSLR |= 0x00000F04; PCFR = 0x00000066; @@ -489,11 +499,12 @@ static void __init lpd270_map_io(void) MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine") /* Maintainer: Peter Barada */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, + .atag_offset = 0x100, .map_io = lpd270_map_io, + .nr_irqs = LPD270_NR_IRQS, .init_irq = lpd270_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, .init_machine = lpd270_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 4ffdff2d9ff..d8a1be619f2 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -11,21 +11,25 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/gpio.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/platform_device.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/major.h> #include <linux/fb.h> #include <linux/interrupt.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/smc91x.h> +#include <linux/slab.h> +#include <linux/leds.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> -#include <mach/pxa2xx_spi.h> +#include <linux/spi/pxa2xx_spi.h> #include <asm/setup.h> #include <asm/memory.h> @@ -41,15 +45,15 @@ #include <asm/hardware/sa1111.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa25x.h> +#include <mach/pxa25x.h> #include <mach/audio.h> #include <mach/lubbock.h> #include <mach/udc.h> -#include <mach/irda.h> -#include <mach/pxafb.h> -#include <mach/mmc.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <mach/pm.h> +#include <mach/smemc.h> #include "generic.h" #include "clock.h" @@ -57,13 +61,24 @@ static unsigned long lubbock_pin_config[] __initdata = { GPIO15_nCS_1, /* CS1 - Flash */ + GPIO78_nCS_2, /* CS2 - Baseboard FGPA */ GPIO79_nCS_3, /* CS3 - SMC ethernet */ + GPIO80_nCS_4, /* CS4 - SA1111 */ /* SSP data pins */ GPIO23_SSP1_SCLK, GPIO25_SSP1_TXD, GPIO26_SSP1_RXD, + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* LCD - 16bpp DSTN */ + GPIOxx_LCD_DSTN_16BPP, + /* BTUART */ GPIO42_BTUART_RXD, GPIO43_BTUART_TXD, @@ -90,8 +105,14 @@ static unsigned long lubbock_pin_config[] __initdata = { GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, }; +#define LUB_HEXLED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x010) #define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080) +void lubbock_set_hexled(uint32_t value) +{ + LUB_HEXLED = value; +} + void lubbock_set_misc_wr(unsigned int mask, unsigned int set) { unsigned long flags; @@ -104,15 +125,15 @@ EXPORT_SYMBOL(lubbock_set_misc_wr); static unsigned long lubbock_irq_enabled; -static void lubbock_mask_irq(unsigned int irq) +static void lubbock_mask_irq(struct irq_data *d) { - int lubbock_irq = (irq - LUBBOCK_IRQ(0)); + int lubbock_irq = (d->irq - LUBBOCK_IRQ(0)); LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq)); } -static void lubbock_unmask_irq(unsigned int irq) +static void lubbock_unmask_irq(struct irq_data *d) { - int lubbock_irq = (irq - LUBBOCK_IRQ(0)); + int lubbock_irq = (d->irq - LUBBOCK_IRQ(0)); /* the irq can be acknowledged only if deasserted, so it's done here */ LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq); LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq)); @@ -120,20 +141,20 @@ static void lubbock_unmask_irq(unsigned int irq) static struct irq_chip lubbock_irq_chip = { .name = "FPGA", - .ack = lubbock_mask_irq, - .mask = lubbock_mask_irq, - .unmask = lubbock_unmask_irq, + .irq_ack = lubbock_mask_irq, + .irq_mask = lubbock_mask_irq, + .irq_unmask = lubbock_unmask_irq, }; static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; do { - GEDR(0) = GPIO_bit(0); /* clear our parent irq */ + /* clear our parent irq */ + desc->irq_data.chip->irq_ack(&desc->irq_data); if (likely(pending)) { irq = LUBBOCK_IRQ(0) + __ffs(pending); - desc = irq_desc + irq; - desc_handle_irq(irq, desc); + generic_handle_irq(irq); } pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); @@ -147,42 +168,33 @@ static void __init lubbock_init_irq(void) /* setup extra lubbock irqs */ for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { - set_irq_chip(irq, &lubbock_irq_chip); - set_irq_handler(irq, handle_level_irq); + irq_set_chip_and_handler(irq, &lubbock_irq_chip, + handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lubbock_irq_handler); + irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM -static int lubbock_irq_resume(struct sys_device *dev) +static void lubbock_irq_resume(void) { LUB_IRQ_MASK_EN = lubbock_irq_enabled; - return 0; } -static struct sysdev_class lubbock_irq_sysclass = { - .name = "cpld_irq", +static struct syscore_ops lubbock_irq_syscore_ops = { .resume = lubbock_irq_resume, }; -static struct sys_device lubbock_irq_device = { - .cls = &lubbock_irq_sysclass, -}; - static int __init lubbock_irq_device_init(void) { - int ret = -ENODEV; - if (machine_is_lubbock()) { - ret = sysdev_class_register(&lubbock_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&lubbock_irq_device); + register_syscore_ops(&lubbock_irq_syscore_ops); + return 0; } - return ret; + return -ENODEV; } device_initcall(lubbock_irq_device_init); @@ -212,11 +224,19 @@ static struct resource sa1111_resources[] = { }, }; +static struct sa1111_platform_data sa1111_info = { + .irq_base = LUBBOCK_SA1111_IRQ_BASE, + .disable_devs = SA1111_DEVID_SAC, +}; + static struct platform_device sa1111_device = { .name = "sa1111", .id = -1, .num_resources = ARRAY_SIZE(sa1111_resources), .resource = sa1111_resources, + .dev = { + .platform_data = &sa1111_info, + }, }; /* ADS7846 is connected through SSP ... and if your board has J5 populated, @@ -439,7 +459,7 @@ static int lubbock_mci_init(struct device *dev, init_timer(&mmc_timer); mmc_timer.data = (unsigned long) data; return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, - IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data); + 0, "lubbock-sd-detect", data); } static int lubbock_mci_get_ro(struct device *dev) @@ -454,11 +474,14 @@ static void lubbock_mci_exit(struct device *dev, void *data) } static struct pxamci_platform_data lubbock_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .detect_delay = 1, - .init = lubbock_mci_init, - .get_ro = lubbock_mci_get_ro, - .exit = lubbock_mci_exit, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .detect_delay_ms = 10, + .init = lubbock_mci_init, + .get_ro = lubbock_mci_get_ro, + .exit = lubbock_mci_exit, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, }; static void lubbock_irda_transceiver_mode(struct device *dev, int mode) @@ -476,8 +499,9 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode) } static struct pxaficp_platform_data lubbock_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_FIRMODE, - .transceiver_mode = lubbock_irda_transceiver_mode, + .gpio_pwdown = -1, + .transceiver_cap = IR_SIRMODE | IR_FIRMODE, + .transceiver_mode = lubbock_irda_transceiver_mode, }; static void __init lubbock_init(void) @@ -486,15 +510,19 @@ static void __init lubbock_init(void) pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL); pxa_set_udc_info(&udc_info); - set_pxa_fb_info(&sharp_lm8v31); + pxa_set_fb_info(NULL, &sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data); pxa_set_ac97_info(NULL); lubbock_flash_data[0].width = lubbock_flash_data[1].width = - (BOOT_DEF & 1) ? 2 : 4; + (__raw_readl(BOOT_DEF) & 1) ? 2 : 4; /* Compensate for the nROMBT switch which swaps the flash banks */ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", flashboot?"Flash":"ROM", flashboot); @@ -518,18 +546,111 @@ static struct map_desc lubbock_io_desc[] __initdata = { static void __init lubbock_map_io(void) { - pxa_map_io(); + pxa25x_map_io(); iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc)); PCFR |= PCFR_OPDE; } +/* + * Driver for the 8 discrete LEDs available for general use: + * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays + * so be sure to not monkey with them here. + */ + +#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) +struct lubbock_led { + struct led_classdev cdev; + u8 mask; +}; + +/* + * The triggers lines up below will only be used if the + * LED triggers are compiled in. + */ +static const struct { + const char *name; + const char *trigger; +} lubbock_leds[] = { + { "lubbock:D28", "default-on", }, + { "lubbock:D27", "cpu0", }, + { "lubbock:D26", "heartbeat" }, + { "lubbock:D25", }, + { "lubbock:D24", }, + { "lubbock:D23", }, + { "lubbock:D22", }, + { "lubbock:D21", }, +}; + +static void lubbock_led_set(struct led_classdev *cdev, + enum led_brightness b) +{ + struct lubbock_led *led = container_of(cdev, + struct lubbock_led, cdev); + u32 reg = LUB_DISC_BLNK_LED; + + if (b != LED_OFF) + reg |= led->mask; + else + reg &= ~led->mask; + + LUB_DISC_BLNK_LED = reg; +} + +static enum led_brightness lubbock_led_get(struct led_classdev *cdev) +{ + struct lubbock_led *led = container_of(cdev, + struct lubbock_led, cdev); + u32 reg = LUB_DISC_BLNK_LED; + + return (reg & led->mask) ? LED_FULL : LED_OFF; +} + +static int __init lubbock_leds_init(void) +{ + int i; + + if (!machine_is_lubbock()) + return -ENODEV; + + /* All ON */ + LUB_DISC_BLNK_LED |= 0xff; + for (i = 0; i < ARRAY_SIZE(lubbock_leds); i++) { + struct lubbock_led *led; + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (!led) + break; + + led->cdev.name = lubbock_leds[i].name; + led->cdev.brightness_set = lubbock_led_set; + led->cdev.brightness_get = lubbock_led_get; + led->cdev.default_trigger = lubbock_leds[i].trigger; + led->mask = BIT(i); + + if (led_classdev_register(NULL, &led->cdev) < 0) { + kfree(led); + break; + } + } + + return 0; +} + +/* + * Since we may have triggers on any subsystem, defer registration + * until after subsystem_init. + */ +fs_initcall(lubbock_leds_init); +#endif + MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") /* Maintainer: MontaVista Software Inc. */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = lubbock_map_io, + .nr_irqs = LUBBOCK_NR_IRQS, .init_irq = lubbock_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, .init_machine = lubbock_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 143f28adaf9..a9761c29302 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -25,19 +25,23 @@ #include <linux/mtd/physmap.h> #include <linux/pda_power.h> #include <linux/pwm_backlight.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/gpio-regulator.h> +#include <linux/regulator/machine.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 <asm/system_info.h> + +#include <mach/pxa27x.h> #include <mach/magician.h> -#include <mach/mfp-pxa27x.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxafb.h> -#include <mach/i2c.h> -#include <mach/mmc.h> -#include <mach/irda.h> -#include <mach/ohci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> #include "devices.h" #include "generic.h" @@ -66,6 +70,11 @@ static unsigned long magician_pin_config[] __initdata = { GPIO31_I2S_SYNC, GPIO113_I2S_SYSCLK, + /* SSP 1 */ + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + /* SSP 2 */ GPIO19_SSP2_SCLK, GPIO14_SSP2_SFRM, @@ -81,26 +90,7 @@ static unsigned long magician_pin_config[] __initdata = { GPIO112_MMC_CMD, /* LCD */ - 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, - GPIO74_LCD_FCLK, - GPIO75_LCD_LCLK, - GPIO76_LCD_PCLK, - GPIO77_LCD_BIAS, + GPIOxx_LCD_TFT_16BPP, /* QCI */ GPIO12_CIF_DD_7, @@ -123,43 +113,50 @@ static unsigned long magician_pin_config[] __initdata = { GPIO107_GPIO, /* DS1WM_IRQ */ GPIO108_GPIO, /* GSM_READY */ GPIO115_GPIO, /* nPEN_IRQ */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, }; /* * IRDA */ -static void magician_irda_transceiver_mode(struct device *dev, int mode) -{ - gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF); - pxa2xx_transceiver_mode(dev, mode); -} - static struct pxaficp_platform_data magician_ficp_info = { - .transceiver_cap = IR_SIRMODE | IR_OFF, - .transceiver_mode = magician_irda_transceiver_mode, + .gpio_pwdown = GPIO83_MAGICIAN_nIR_EN, + .transceiver_cap = IR_SIRMODE | IR_OFF, }; /* * GPIO Keys */ +#define INIT_KEY(_code, _gpio, _desc) \ + { \ + .code = KEY_##_code, \ + .gpio = _gpio, \ + .desc = _desc, \ + .type = EV_KEY, \ + .wakeup = 1, \ + } + static struct gpio_keys_button magician_button_table[] = { - {KEY_POWER, GPIO0_MAGICIAN_KEY_POWER, 0, "Power button"}, - {KEY_ESC, GPIO37_MAGICIAN_KEY_HANGUP, 0, "Hangup button"}, - {KEY_F10, GPIO38_MAGICIAN_KEY_CONTACTS, 0, "Contacts button"}, - {KEY_CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, 0, "Calendar button"}, - {KEY_CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, 0, "Camera button"}, - {KEY_UP, GPIO93_MAGICIAN_KEY_UP, 0, "Up button"}, - {KEY_DOWN, GPIO94_MAGICIAN_KEY_DOWN, 0, "Down button"}, - {KEY_LEFT, GPIO95_MAGICIAN_KEY_LEFT, 0, "Left button"}, - {KEY_RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, 0, "Right button"}, - {KEY_KPENTER, GPIO97_MAGICIAN_KEY_ENTER, 0, "Action button"}, - {KEY_RECORD, GPIO98_MAGICIAN_KEY_RECORD, 0, "Record button"}, - {KEY_VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, 0, "Volume up"}, - {KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"}, - {KEY_PHONE, GPIO102_MAGICIAN_KEY_PHONE, 0, "Phone button"}, - {KEY_PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, 0, "Headset button"}, + INIT_KEY(POWER, GPIO0_MAGICIAN_KEY_POWER, "Power button"), + INIT_KEY(ESC, GPIO37_MAGICIAN_KEY_HANGUP, "Hangup button"), + INIT_KEY(F10, GPIO38_MAGICIAN_KEY_CONTACTS, "Contacts button"), + INIT_KEY(CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, "Calendar button"), + INIT_KEY(CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, "Camera button"), + INIT_KEY(UP, GPIO93_MAGICIAN_KEY_UP, "Up button"), + INIT_KEY(DOWN, GPIO94_MAGICIAN_KEY_DOWN, "Down button"), + INIT_KEY(LEFT, GPIO95_MAGICIAN_KEY_LEFT, "Left button"), + INIT_KEY(RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, "Right button"), + INIT_KEY(KPENTER, GPIO97_MAGICIAN_KEY_ENTER, "Action button"), + INIT_KEY(RECORD, GPIO98_MAGICIAN_KEY_RECORD, "Record button"), + INIT_KEY(VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, "Volume up"), + INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"), + INIT_KEY(PHONE, GPIO102_MAGICIAN_KEY_PHONE, "Phone button"), + INIT_KEY(PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, "Headset button"), }; static struct gpio_keys_platform_data gpio_keys_data = { @@ -185,12 +182,12 @@ static struct platform_device gpio_keys = { static struct resource egpio_resources[] = { [0] = { .start = PXA_CS3_PHYS, - .end = PXA_CS3_PHYS + 0x20, + .end = PXA_CS3_PHYS + 0x20 - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ), - .end = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ), .flags = IORESOURCE_IRQ, }, }; @@ -332,8 +329,7 @@ static struct pxafb_mach_info toppoly_info = { .modes = toppoly_modes, .num_modes = 1, .fixed_modes = 1, - .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, - .lccr3 = LCCR3_PixRsEdg, + .lcd_conn = LCD_COLOR_TFT_16BPP, .pxafb_lcd_power = toppoly_lcd_power, }; @@ -341,8 +337,8 @@ static struct pxafb_mach_info samsung_info = { .modes = samsung_modes, .num_modes = 1, .fixed_modes = 1, - .lccr0 = LCCR0_LDDALT | LCCR0_Color | LCCR0_Sngl | LCCR0_Act, - .lccr3 = LCCR3_PixFlEdg, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\ + LCD_ALTERNATE_MAPPING, .pxafb_lcd_power = samsung_lcd_power, }; @@ -350,25 +346,17 @@ static struct pxafb_mach_info samsung_info = { * Backlight */ +static struct gpio magician_bl_gpios[] = { + { EGPIO_MAGICIAN_BL_POWER, GPIOF_DIR_OUT, "Backlight power" }, + { EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" }, +}; + static int magician_backlight_init(struct device *dev) { - int ret; - - ret = gpio_request(EGPIO_MAGICIAN_BL_POWER, "BL_POWER"); - if (ret) - goto err; - ret = gpio_request(EGPIO_MAGICIAN_BL_POWER2, "BL_POWER2"); - if (ret) - goto err2; - return 0; - -err2: - gpio_free(EGPIO_MAGICIAN_BL_POWER); -err: - return ret; + return gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios)); } -static int magician_backlight_notify(int brightness) +static int magician_backlight_notify(struct device *dev, int brightness) { gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness); if (brightness >= 200) { @@ -382,8 +370,7 @@ static int magician_backlight_notify(int brightness) static void magician_backlight_exit(struct device *dev) { - gpio_free(EGPIO_MAGICIAN_BL_POWER); - gpio_free(EGPIO_MAGICIAN_BL_POWER2); + gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios)); } static struct platform_pwm_backlight_data backlight_data = { @@ -391,6 +378,7 @@ static struct platform_pwm_backlight_data backlight_data = { .max_brightness = 272, .dft_brightness = 100, .pwm_period_ns = 30923, + .enable_gpio = -1, .init = magician_backlight_init, .notify = magician_backlight_notify, .exit = magician_backlight_exit, @@ -409,7 +397,7 @@ static struct platform_device backlight = { * LEDs */ -struct gpio_led gpio_leds[] = { +static struct gpio_led gpio_leds[] = { { .name = "magician::vibra", .default_trigger = "none", @@ -417,7 +405,7 @@ struct gpio_led gpio_leds[] = { }, { .name = "magician::phone_bl", - .default_trigger = "none", + .default_trigger = "backlight", .gpio = GPIO103_MAGICIAN_LED_KP, }, }; @@ -465,8 +453,6 @@ static struct pasic3_led pasic3_leds[] = { }, }; -static struct platform_device pasic3; - static struct pasic3_leds_machinfo pasic3_leds_info = { .num_leds = ARRAY_SIZE(pasic3_leds), .power_gpio = EGPIO_MAGICIAN_LED_POWER, @@ -485,14 +471,13 @@ static struct resource pasic3_resources[] = { }, /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */ [1] = { - .start = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ), - .end = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ), + .start = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; static struct pasic3_platform_data pasic3_platform_data = { - .bus_shift = 2, .led_pdata = &pasic3_leds_info, .clock_rate = 4000000, }; @@ -508,38 +493,37 @@ static struct platform_device pasic3 = { }; /* + * USB "Transceiver" + */ + +static struct resource gpio_vbus_resource = { + .flags = IORESOURCE_IRQ, + .start = IRQ_MAGICIAN_VBUS, + .end = IRQ_MAGICIAN_VBUS, +}; + +static struct gpio_vbus_mach_info gpio_vbus_info = { + .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN, + .gpio_vbus = EGPIO_MAGICIAN_CABLE_STATE_USB, +}; + +static struct platform_device gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .num_resources = 1, + .resource = &gpio_vbus_resource, + .dev = { + .platform_data = &gpio_vbus_info, + }, +}; + +/* * External power */ static int power_supply_init(struct device *dev) { - int ret; - - ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC"); - if (ret) - goto err_cs_ac; - ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_USB, "CABLE_STATE_USB"); - if (ret) - goto err_cs_usb; - ret = gpio_request(EGPIO_MAGICIAN_CHARGE_EN, "CHARGE_EN"); - if (ret) - goto err_chg_en; - ret = gpio_request(GPIO30_MAGICIAN_nCHARGE_EN, "nCHARGE_EN"); - if (!ret) - ret = gpio_direction_output(GPIO30_MAGICIAN_nCHARGE_EN, 0); - if (ret) - goto err_nchg_en; - - return 0; - -err_nchg_en: - gpio_free(EGPIO_MAGICIAN_CHARGE_EN); -err_chg_en: - gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB); -err_cs_usb: - gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC); -err_cs_ac: - return ret; + return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC"); } static int magician_is_ac_online(void) @@ -547,22 +531,8 @@ static int magician_is_ac_online(void) return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC); } -static int magician_is_usb_online(void) -{ - return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_USB); -} - -static void magician_set_charge(int flags) -{ - gpio_set_value(GPIO30_MAGICIAN_nCHARGE_EN, !flags); - gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags); -} - static void power_supply_exit(struct device *dev) { - gpio_free(GPIO30_MAGICIAN_nCHARGE_EN); - gpio_free(EGPIO_MAGICIAN_CHARGE_EN); - gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB); gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC); } @@ -573,8 +543,6 @@ static char *magician_supplicants[] = { static struct pda_power_pdata power_supply_info = { .init = power_supply_init, .is_ac_online = magician_is_ac_online, - .is_usb_online = magician_is_usb_online, - .set_charge = magician_set_charge, .exit = power_supply_exit, .supplied_to = magician_supplicants, .num_supplicants = ARRAY_SIZE(magician_supplicants), @@ -583,15 +551,17 @@ static struct pda_power_pdata power_supply_info = { static struct resource power_supply_resources[] = { [0] = { .name = "ac", - .flags = IORESOURCE_IRQ, - .start = IRQ_MAGICIAN_AC, - .end = IRQ_MAGICIAN_AC, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + .start = IRQ_MAGICIAN_VBUS, + .end = IRQ_MAGICIAN_VBUS, }, [1] = { .name = "usb", - .flags = IORESOURCE_IRQ, - .start = IRQ_MAGICIAN_AC, - .end = IRQ_MAGICIAN_AC, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + .start = IRQ_MAGICIAN_VBUS, + .end = IRQ_MAGICIAN_VBUS, }, }; @@ -605,63 +575,82 @@ static struct platform_device power_supply = { .num_resources = ARRAY_SIZE(power_supply_resources), }; - /* - * MMC/SD + * Battery charger */ -static int magician_mci_init(struct device *dev, - irq_handler_t detect_irq, void *data) -{ - int err; +static struct regulator_consumer_supply bq24022_consumers[] = { + REGULATOR_SUPPLY("vbus_draw", NULL), + REGULATOR_SUPPLY("ac_draw", NULL), +}; - err = request_irq(IRQ_MAGICIAN_SD, detect_irq, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - "MMC card detect", data); - if (err) - goto err_request_irq; - err = gpio_request(EGPIO_MAGICIAN_SD_POWER, "SD_POWER"); - if (err) - goto err_request_power; - err = gpio_request(EGPIO_MAGICIAN_nSD_READONLY, "nSD_READONLY"); - if (err) - goto err_request_readonly; +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, +}; - return 0; +static struct gpio bq24022_gpios[] = { + { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" }, +}; -err_request_readonly: - gpio_free(EGPIO_MAGICIAN_SD_POWER); -err_request_power: - free_irq(IRQ_MAGICIAN_SD, data); -err_request_irq: - return err; -} +static struct gpio_regulator_state bq24022_states[] = { + { .value = 100000, .gpios = (0 << 0) }, + { .value = 500000, .gpios = (1 << 0) }, +}; -static void magician_mci_setpower(struct device *dev, unsigned int vdd) -{ - struct pxamci_platform_data *pdata = dev->platform_data; +static struct gpio_regulator_config bq24022_info = { + .supply_name = "bq24022", - gpio_set_value(EGPIO_MAGICIAN_SD_POWER, (1 << vdd) & pdata->ocr_mask); -} + .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN, + .enable_high = 0, + .enabled_at_boot = 0, + + .gpios = bq24022_gpios, + .nr_gpios = ARRAY_SIZE(bq24022_gpios), + + .states = bq24022_states, + .nr_states = ARRAY_SIZE(bq24022_states), -static int magician_mci_get_ro(struct device *dev) + .type = REGULATOR_CURRENT, + .init_data = &bq24022_init_data, +}; + +static struct platform_device bq24022 = { + .name = "gpio-regulator", + .id = -1, + .dev = { + .platform_data = &bq24022_info, + }, +}; + +/* + * MMC/SD + */ + +static int magician_mci_init(struct device *dev, + irq_handler_t detect_irq, void *data) { - return (!gpio_get_value(EGPIO_MAGICIAN_nSD_READONLY)); + return request_irq(IRQ_MAGICIAN_SD, detect_irq, 0, + "mmc card detect", data); } static void magician_mci_exit(struct device *dev, void *data) { - gpio_free(EGPIO_MAGICIAN_nSD_READONLY); - gpio_free(EGPIO_MAGICIAN_SD_POWER); free_irq(IRQ_MAGICIAN_SD, data); } static struct pxamci_platform_data magician_mci_info = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = magician_mci_init, - .get_ro = magician_mci_get_ro, - .setpower = magician_mci_setpower, - .exit = magician_mci_exit, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = magician_mci_init, + .exit = magician_mci_exit, + .gpio_card_detect = -1, + .gpio_card_ro = EGPIO_MAGICIAN_nSD_READONLY, + .gpio_card_ro_invert = 1, + .gpio_power = EGPIO_MAGICIAN_SD_POWER, }; @@ -669,18 +658,10 @@ static struct pxamci_platform_data magician_mci_info = { * USB OHCI */ -static int magician_ohci_init(struct device *dev) -{ - UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) & - ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE); - - return 0; -} - static struct pxaohci_platform_data magician_ohci_info = { - .port_mode = PMM_PERPORT_MODE, - .init = magician_ohci_init, - .power_budget = 0, + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW, + .power_budget = 0, }; @@ -688,16 +669,14 @@ static struct pxaohci_platform_data magician_ohci_info = { * StrataFlash */ -static void magician_set_vpp(struct map_info *map, int vpp) +static void magician_set_vpp(struct platform_device *pdev, int vpp) { gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp); } -#define PXA_CS_SIZE 0x04000000 - static struct resource strataflash_resource = { .start = PXA_CS0_PHYS, - .end = PXA_CS0_PHYS + PXA_CS_SIZE - 1, + .end = PXA_CS0_PHYS + SZ_64M - 1, .flags = IORESOURCE_MEM, }; @@ -717,6 +696,14 @@ static struct platform_device strataflash = { }; /* + * I2C + */ + +static struct i2c_pxa_platform_data i2c_info = { + .fast_mode = 1, +}; + +/* * Platform devices */ @@ -725,30 +712,42 @@ static struct platform_device *devices[] __initdata = { &egpio, &backlight, &pasic3, + &bq24022, + &gpio_vbus, &power_supply, &strataflash, &leds_gpio, }; +static struct gpio magician_global_gpios[] = { + { GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" }, + { GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" }, + { GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" }, + { GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" }, + { GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" }, + { GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" }, +}; + static void __init magician_init(void) { void __iomem *cpld; int lcd_select; int err; - gpio_request(GPIO13_MAGICIAN_CPLD_IRQ, "CPLD_IRQ"); - gpio_request(GPIO107_MAGICIAN_DS1WM_IRQ, "DS1WM_IRQ"); - pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config)); + err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios)); + if (err) + pr_err("magician: Failed to request GPIOs: %d\n", err); - platform_add_devices(devices, ARRAY_SIZE(devices)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); - err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN"); - if (!err) { - gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1); - pxa_set_ficp_info(&magician_ficp_info); - } - pxa_set_i2c_info(NULL); + platform_add_devices(ARRAY_AND_SIZE(devices)); + + pxa_set_ficp_info(&magician_ficp_info); + pxa27x_set_i2c_power_info(NULL); + pxa_set_i2c_info(&i2c_info); pxa_set_mci_info(&magician_mci_info); pxa_set_ohci_info(&magician_ohci_info); @@ -760,28 +759,22 @@ static void __init magician_init(void) system_rev = board_id & 0x7; lcd_select = board_id & 0x8; pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly"); - if (lcd_select && (system_rev < 3)) { - gpio_request(GPIO75_MAGICIAN_SAMSUNG_POWER, "SAMSUNG_POWER"); - gpio_direction_output(GPIO75_MAGICIAN_SAMSUNG_POWER, 0); - } - gpio_request(GPIO104_MAGICIAN_LCD_POWER_1, "LCD_POWER_1"); - gpio_request(GPIO105_MAGICIAN_LCD_POWER_2, "LCD_POWER_2"); - gpio_request(GPIO106_MAGICIAN_LCD_POWER_3, "LCD_POWER_3"); - gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0); - gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0); - gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0); - set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info); + if (lcd_select && (system_rev < 3)) + gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER, + GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER"); + pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info); } else pr_err("LCD detection: CPLD mapping failed\n"); } MACHINE_START(MAGICIAN, "HTC Magician") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = MAGICIAN_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = magician_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index d44af761564..78b84c0dfc7 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -12,10 +12,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#include <linux/gpio.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/bitops.h> @@ -27,6 +27,9 @@ #include <linux/gpio_keys.h> #include <linux/pwm_backlight.h> #include <linux/smc91x.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/slab.h> +#include <linux/leds.h> #include <asm/types.h> #include <asm/setup.h> @@ -41,17 +44,15 @@ #include <asm/mach/irq.h> #include <asm/mach/flash.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa27x.h> +#include <mach/pxa27x.h> #include <mach/mainstone.h> #include <mach/audio.h> -#include <mach/pxafb.h> -#include <mach/i2c.h> -#include <mach/mmc.h> -#include <mach/irda.h> -#include <mach/ohci.h> -#include <mach/pxa27x_keypad.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <mach/smemc.h> #include "generic.h" #include "devices.h" @@ -61,26 +62,7 @@ static unsigned long mainstone_pin_config[] = { GPIO15_nCS_1, /* LCD - 16bpp Active TFT */ - 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, - GPIO74_LCD_FCLK, - GPIO75_LCD_LCLK, - GPIO76_LCD_PCLK, - GPIO77_LCD_BIAS, + GPIOxx_LCD_TFT_16BPP, GPIO16_PWM0_OUT, /* Backlight */ /* MMC */ @@ -108,6 +90,10 @@ static unsigned long mainstone_pin_config[] = { GPIO57_nIOIS16, /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, GPIO45_AC97_SYSCLK, /* Keypad */ @@ -128,21 +114,25 @@ static unsigned long mainstone_pin_config[] = { GPIO108_KP_MKOUT_5, GPIO96_KP_MKOUT_6, + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + /* GPIO */ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, }; static unsigned long mainstone_irq_enabled; -static void mainstone_mask_irq(unsigned int irq) +static void mainstone_mask_irq(struct irq_data *d) { - int mainstone_irq = (irq - MAINSTONE_IRQ(0)); + int mainstone_irq = (d->irq - MAINSTONE_IRQ(0)); MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq)); } -static void mainstone_unmask_irq(unsigned int irq) +static void mainstone_unmask_irq(struct irq_data *d) { - int mainstone_irq = (irq - MAINSTONE_IRQ(0)); + int mainstone_irq = (d->irq - MAINSTONE_IRQ(0)); /* the irq can be acknowledged only if deasserted, so it's done here */ MST_INTSETCLR &= ~(1 << mainstone_irq); MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq)); @@ -150,20 +140,20 @@ static void mainstone_unmask_irq(unsigned int irq) static struct irq_chip mainstone_irq_chip = { .name = "FPGA", - .ack = mainstone_mask_irq, - .mask = mainstone_mask_irq, - .unmask = mainstone_unmask_irq, + .irq_ack = mainstone_mask_irq, + .irq_mask = mainstone_mask_irq, + .irq_unmask = mainstone_unmask_irq, }; static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; do { - GEDR(0) = GPIO_bit(0); /* clear useless edge notification */ + /* clear useless edge notification */ + desc->irq_data.chip->irq_ack(&desc->irq_data); if (likely(pending)) { irq = MAINSTONE_IRQ(0) + __ffs(pending); - desc = irq_desc + irq; - desc_handle_irq(irq, desc); + generic_handle_irq(irq); } pending = MST_INTSETCLR & mainstone_irq_enabled; } while (pending); @@ -177,8 +167,8 @@ static void __init mainstone_init_irq(void) /* setup extra Mainstone irqs */ for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { - set_irq_chip(irq, &mainstone_irq_chip); - set_irq_handler(irq, handle_level_irq); + irq_set_chip_and_handler(irq, &mainstone_irq_chip, + handle_level_irq); if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); else @@ -190,37 +180,27 @@ static void __init mainstone_init_irq(void) MST_INTMSKENA = 0; MST_INTSETCLR = 0; - set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); + irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), mainstone_irq_handler); + irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM -static int mainstone_irq_resume(struct sys_device *dev) +static void mainstone_irq_resume(void) { MST_INTMSKENA = mainstone_irq_enabled; - return 0; } -static struct sysdev_class mainstone_irq_sysclass = { - .name = "cpld_irq", +static struct syscore_ops mainstone_irq_syscore_ops = { .resume = mainstone_irq_resume, }; -static struct sys_device mainstone_irq_device = { - .cls = &mainstone_irq_sysclass, -}; - static int __init mainstone_irq_device_init(void) { - int ret = -ENODEV; + if (machine_is_mainstone()) + register_syscore_ops(&mainstone_irq_syscore_ops); - if (machine_is_mainstone()) { - ret = sysdev_class_register(&mainstone_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&mainstone_irq_device); - } - return ret; + return 0; } device_initcall(mainstone_irq_device_init); @@ -358,6 +338,7 @@ static struct platform_pwm_backlight_data mainstone_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device mainstone_backlight_device = { @@ -420,7 +401,7 @@ static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_in */ MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; - err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED, + err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, 0, "MMC card detect", data); if (err) printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); @@ -428,7 +409,7 @@ static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_in return err; } -static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) +static int mainstone_mci_setpower(struct device *dev, unsigned int vdd) { struct pxamci_platform_data* p_d = dev->platform_data; @@ -440,6 +421,7 @@ static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) printk(KERN_DEBUG "%s: off\n", __func__); MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON; } + return 0; } static void mainstone_mci_exit(struct device *dev, void *data) @@ -448,10 +430,13 @@ static void mainstone_mci_exit(struct device *dev, void *data) } static struct pxamci_platform_data mainstone_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = mainstone_mci_init, - .setpower = mainstone_mci_setpower, - .exit = mainstone_mci_exit, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = mainstone_mci_init, + .setpower = mainstone_mci_setpower, + .exit = mainstone_mci_exit, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, }; static void mainstone_irda_transceiver_mode(struct device *dev, int mode) @@ -474,8 +459,9 @@ static void mainstone_irda_transceiver_mode(struct device *dev, int mode) } static struct pxaficp_platform_data mainstone_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, - .transceiver_mode = mainstone_irda_transceiver_mode, + .gpio_pwdown = -1, + .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, + .transceiver_mode = mainstone_irda_transceiver_mode, }; static struct gpio_keys_button gpio_keys_button[] = { @@ -508,23 +494,13 @@ static struct platform_device *platform_devices[] __initdata = { &mst_gpio_keys_device, }; -static int mainstone_ohci_init(struct device *dev) -{ - /* Set the Power Control Polarity Low and Power Sense - Polarity Low to active low. */ - UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); - - return 0; -} - static struct pxaohci_platform_data mainstone_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, - .init = mainstone_ohci_init, + .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, }; #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) -static unsigned int mainstone_matrix_keys[] = { +static const unsigned int mainstone_matrix_keys[] = { KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C), KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F), KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I), @@ -553,11 +529,15 @@ static unsigned int mainstone_matrix_keys[] = { KEY(4, 6, KEY_SELECT), }; +static struct matrix_keymap_data mainstone_matrix_keymap_data = { + .keymap = mainstone_matrix_keys, + .keymap_size = ARRAY_SIZE(mainstone_matrix_keys), +}; + struct pxa27x_keypad_platform_data mainstone_keypad_info = { .matrix_key_rows = 6, .matrix_key_cols = 7, - .matrix_key_map = mainstone_matrix_keys, - .matrix_key_map_size = ARRAY_SIZE(mainstone_matrix_keys), + .matrix_keymap_data = &mainstone_matrix_keymap_data, .enable_rotary0 = 1, .rotary0_up_key = KEY_UP, @@ -580,7 +560,11 @@ static void __init mainstone_init(void) pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config)); - mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4; + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4; mst_flash_data[1].width = 4; /* Compensate for SW7 which swaps the flash banks */ @@ -605,7 +589,7 @@ static void __init mainstone_init(void) else mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; - set_pxa_fb_info(&mainstone_pxafb_info); + pxa_set_fb_info(NULL, &mainstone_pxafb_info); mainstone_backlight_register(); pxa_set_mci_info(&mainstone_mci_platform_data); @@ -629,7 +613,7 @@ static struct map_desc mainstone_io_desc[] __initdata = { static void __init mainstone_map_io(void) { - pxa_map_io(); + pxa27x_map_io(); iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); /* for use I SRAM as framebuffer. */ @@ -637,13 +621,106 @@ static void __init mainstone_map_io(void) PCFR = 0x66; } +/* + * Driver for the 8 discrete LEDs available for general use: + * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays + * so be sure to not monkey with them here. + */ + +#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) +struct mainstone_led { + struct led_classdev cdev; + u8 mask; +}; + +/* + * The triggers lines up below will only be used if the + * LED triggers are compiled in. + */ +static const struct { + const char *name; + const char *trigger; +} mainstone_leds[] = { + { "mainstone:D28", "default-on", }, + { "mainstone:D27", "cpu0", }, + { "mainstone:D26", "heartbeat" }, + { "mainstone:D25", }, + { "mainstone:D24", }, + { "mainstone:D23", }, + { "mainstone:D22", }, + { "mainstone:D21", }, +}; + +static void mainstone_led_set(struct led_classdev *cdev, + enum led_brightness b) +{ + struct mainstone_led *led = container_of(cdev, + struct mainstone_led, cdev); + u32 reg = MST_LEDCTRL; + + if (b != LED_OFF) + reg |= led->mask; + else + reg &= ~led->mask; + + MST_LEDCTRL = reg; +} + +static enum led_brightness mainstone_led_get(struct led_classdev *cdev) +{ + struct mainstone_led *led = container_of(cdev, + struct mainstone_led, cdev); + u32 reg = MST_LEDCTRL; + + return (reg & led->mask) ? LED_FULL : LED_OFF; +} + +static int __init mainstone_leds_init(void) +{ + int i; + + if (!machine_is_mainstone()) + return -ENODEV; + + /* All ON */ + MST_LEDCTRL |= 0xff; + for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) { + struct mainstone_led *led; + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (!led) + break; + + led->cdev.name = mainstone_leds[i].name; + led->cdev.brightness_set = mainstone_led_set; + led->cdev.brightness_get = mainstone_led_get; + led->cdev.default_trigger = mainstone_leds[i].trigger; + led->mask = BIT(i); + + if (led_classdev_register(NULL, &led->cdev) < 0) { + kfree(led); + break; + } + } + + return 0; +} + +/* + * Since we may have triggers on any subsystem, defer registration + * until after subsystem_init. + */ +fs_initcall(mainstone_leds_init); +#endif + MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") /* Maintainer: MontaVista Software Inc. */ - .phys_io = 0x40000000, - .boot_params = 0xa0000100, /* BLOB boot parameter setting */ - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .atag_offset = 0x100, /* BLOB boot parameter setting */ .map_io = mainstone_map_io, + .nr_irqs = MAINSTONE_NR_IRQS, .init_irq = mainstone_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, .init_machine = mainstone_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 925575f10ac..ef0426a159d 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -12,20 +12,29 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#include <linux/gpio.h> +#include <linux/gpio-pxa.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/sysdev.h> +#include <linux/io.h> +#include <linux/syscore_ops.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-regs.h> #include <mach/mfp-pxa2xx.h> #include "generic.h" -#define PGSR(x) __REG2(0x40F00020, ((x) & 0x60) >> 3) +#define PGSR(x) __REG2(0x40F00020, (x) << 2) +#define __GAFR(u, x) __REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3) +#define GAFR_L(x) __GAFR(0, x) +#define GAFR_U(x) __GAFR(1, x) + +#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) +#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5)) +#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c) +#define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18) +#define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24) #define PWER_WE35 (1 << 24) @@ -33,54 +42,66 @@ struct gpio_desc { unsigned valid : 1; unsigned can_wakeup : 1; unsigned keypad_gpio : 1; + unsigned dir_inverted : 1; unsigned int mask; /* bit mask in PWER or PKWR */ + unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */ unsigned long config; }; static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1]; -static int __mfp_config_lpm(unsigned gpio, unsigned long lpm) -{ - unsigned mask = GPIO_bit(gpio); - - /* low power state */ - switch (lpm) { - case MFP_LPM_DRIVE_HIGH: - PGSR(gpio) |= mask; - break; - case MFP_LPM_DRIVE_LOW: - PGSR(gpio) &= ~mask; - break; - case MFP_LPM_INPUT: - break; - default: - pr_warning("%s: invalid low power state for GPIO%d\n", - __func__, gpio); - return -EINVAL; - } - return 0; -} +static unsigned long gpdr_lpm[4]; static int __mfp_config_gpio(unsigned gpio, unsigned long c) { unsigned long gafr, mask = GPIO_bit(gpio); - int fn; + int bank = gpio_to_bank(gpio); + int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */ + int shft = (gpio & 0xf) << 1; + int fn = MFP_AF(c); + int is_out = (c & MFP_DIR_OUT) ? 1 : 0; - fn = MFP_AF(c); if (fn > 3) return -EINVAL; - /* alternate function and direction */ - gafr = GAFR(gpio) & ~(0x3 << ((gpio & 0xf) * 2)); - GAFR(gpio) = gafr | (fn << ((gpio & 0xf) * 2)); + /* alternate function and direction at run-time */ + gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank); + gafr = (gafr & ~(0x3 << shft)) | (fn << shft); + + if (uorl == 0) + GAFR_L(bank) = gafr; + else + GAFR_U(bank) = gafr; - if (c & MFP_DIR_OUT) + if (is_out ^ gpio_desc[gpio].dir_inverted) GPDR(gpio) |= mask; else GPDR(gpio) &= ~mask; - if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK)) - return -EINVAL; + /* alternate function and direction at low power mode */ + switch (c & MFP_LPM_STATE_MASK) { + case MFP_LPM_DRIVE_HIGH: + PGSR(bank) |= mask; + is_out = 1; + break; + case MFP_LPM_DRIVE_LOW: + PGSR(bank) &= ~mask; + is_out = 1; + break; + case MFP_LPM_INPUT: + case MFP_LPM_DEFAULT: + break; + default: + /* warning and fall through, treat as MFP_LPM_DEFAULT */ + pr_warning("%s: GPIO%d: unsupported low power mode\n", + __func__, gpio); + break; + } + + if (is_out ^ gpio_desc[gpio].dir_inverted) + gpdr_lpm[bank] |= mask; + else + gpdr_lpm[bank] &= ~mask; /* give early warning if MFP_LPM_CAN_WAKEUP is set on the * configurations of those pins not able to wakeup @@ -91,7 +112,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) return -EINVAL; } - if ((c & MFP_LPM_CAN_WAKEUP) && (c & MFP_DIR_OUT)) { + if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { pr_warning("%s: output GPIO%d unable to wakeup\n", __func__, gpio); return -EINVAL; @@ -135,7 +156,7 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm) { - unsigned long flags; + unsigned long flags, c; int gpio; gpio = __mfp_validate(mfp); @@ -143,14 +164,18 @@ void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm) return; local_irq_save(flags); - __mfp_config_lpm(gpio, lpm); + + c = gpio_desc[gpio].config; + c = (c & ~MFP_LPM_STATE_MASK) | lpm; + __mfp_config_gpio(gpio, c); + local_irq_restore(flags); } int gpio_set_wake(unsigned int gpio, unsigned int on) { struct gpio_desc *d; - unsigned long c; + unsigned long c, mux_taken; if (gpio > mfp_to_gpio(MFP_PIN_GPIO127)) return -EINVAL; @@ -161,12 +186,25 @@ int gpio_set_wake(unsigned int gpio, unsigned int on) if (!d->valid) return -EINVAL; - if (d->keypad_gpio) - return -EINVAL; + /* Allow keypad GPIOs to wakeup system when + * configured as generic GPIOs. + */ + if (d->keypad_gpio && (MFP_AF(d->config) == 0) && + (d->config & MFP_LPM_CAN_WAKEUP)) { + if (on) + PKWR |= d->mask; + else + PKWR &= ~d->mask; + return 0; + } + + mux_taken = (PWER & d->mux_mask) & (~d->mask); + if (on && mux_taken) + return -EBUSY; if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) { if (on) { - PWER |= d->mask; + PWER = (PWER & ~d->mux_mask) | d->mask; if (c & MFP_LPM_EDGE_RISE) PRER |= d->mask; @@ -187,23 +225,32 @@ int gpio_set_wake(unsigned int gpio, unsigned int on) } #ifdef CONFIG_PXA25x -static int __init pxa25x_mfp_init(void) +static void __init pxa25x_mfp_init(void) { int i; - if (cpu_is_pxa25x()) { - for (i = 0; i <= 84; i++) - gpio_desc[i].valid = 1; - - for (i = 0; i <= 15; i++) { - gpio_desc[i].can_wakeup = 1; - gpio_desc[i].mask = GPIO_bit(i); - } + /* running before pxa_gpio_probe() */ +#ifdef CONFIG_CPU_PXA26x + pxa_last_gpio = 89; +#else + pxa_last_gpio = 84; +#endif + for (i = 0; i <= pxa_last_gpio; i++) + gpio_desc[i].valid = 1; + + for (i = 0; i <= 15; i++) { + gpio_desc[i].can_wakeup = 1; + gpio_desc[i].mask = GPIO_bit(i); } - return 0; + /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the + * direction bit inverted in GPDR2. See PXA26x DM 4.1.1. + */ + for (i = 86; i <= pxa_last_gpio; i++) + gpio_desc[i].dir_inverted = 1; } -postcore_initcall(pxa25x_mfp_init); +#else +static inline void pxa25x_mfp_init(void) {} #endif /* CONFIG_PXA25x */ #ifdef CONFIG_PXA27x @@ -215,63 +262,180 @@ static int pxa27x_pkwr_gpio[] = { int keypad_set_wake(unsigned int on) { unsigned int i, gpio, mask = 0; - - if (!on) { - PKWR = 0; - return 0; - } + struct gpio_desc *d; for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) { gpio = pxa27x_pkwr_gpio[i]; + d = &gpio_desc[gpio]; - if (gpio_desc[gpio].config & MFP_LPM_CAN_WAKEUP) + /* skip if configured as generic GPIO */ + if (MFP_AF(d->config) == 0) + continue; + + if (d->config & MFP_LPM_CAN_WAKEUP) mask |= gpio_desc[gpio].mask; } - PKWR = mask; + if (on) + PKWR |= mask; + else + PKWR &= ~mask; return 0; } -static int __init pxa27x_mfp_init(void) +#define PWER_WEMUX2_GPIO38 (1 << 16) +#define PWER_WEMUX2_GPIO53 (2 << 16) +#define PWER_WEMUX2_GPIO40 (3 << 16) +#define PWER_WEMUX2_GPIO36 (4 << 16) +#define PWER_WEMUX2_MASK (7 << 16) +#define PWER_WEMUX3_GPIO31 (1 << 19) +#define PWER_WEMUX3_GPIO113 (2 << 19) +#define PWER_WEMUX3_MASK (3 << 19) + +#define INIT_GPIO_DESC_MUXED(mux, gpio) \ +do { \ + gpio_desc[(gpio)].can_wakeup = 1; \ + gpio_desc[(gpio)].mask = PWER_ ## mux ## _GPIO ##gpio; \ + gpio_desc[(gpio)].mux_mask = PWER_ ## mux ## _MASK; \ +} while (0) + +static void __init pxa27x_mfp_init(void) { int i, gpio; - if (cpu_is_pxa27x()) { - for (i = 0; i <= 120; i++) { - /* skip GPIO2, 5, 6, 7, 8, they are not - * valid pins allow configuration - */ - if (i == 2 || i == 5 || i == 6 || - i == 7 || i == 8) - continue; + pxa_last_gpio = 120; /* running before pxa_gpio_probe() */ + for (i = 0; i <= pxa_last_gpio; i++) { + /* skip GPIO2, 5, 6, 7, 8, they are not + * valid pins allow configuration + */ + if (i == 2 || i == 5 || i == 6 || i == 7 || i == 8) + continue; - gpio_desc[i].valid = 1; - } + gpio_desc[i].valid = 1; + } - /* Keypad GPIOs */ - for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) { - gpio = pxa27x_pkwr_gpio[i]; - gpio_desc[gpio].can_wakeup = 1; - gpio_desc[gpio].keypad_gpio = 1; - gpio_desc[gpio].mask = 1 << i; - } + /* Keypad GPIOs */ + for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) { + gpio = pxa27x_pkwr_gpio[i]; + gpio_desc[gpio].can_wakeup = 1; + gpio_desc[gpio].keypad_gpio = 1; + gpio_desc[gpio].mask = 1 << i; + } - /* Overwrite GPIO13 as a PWER wakeup source */ - for (i = 0; i <= 15; i++) { - /* skip GPIO2, 5, 6, 7, 8 */ - if (GPIO_bit(i) & 0x1e4) - continue; + /* Overwrite GPIO13 as a PWER wakeup source */ + for (i = 0; i <= 15; i++) { + /* skip GPIO2, 5, 6, 7, 8 */ + if (GPIO_bit(i) & 0x1e4) + continue; - gpio_desc[i].can_wakeup = 1; - gpio_desc[i].mask = GPIO_bit(i); + gpio_desc[i].can_wakeup = 1; + gpio_desc[i].mask = GPIO_bit(i); + } + + gpio_desc[35].can_wakeup = 1; + gpio_desc[35].mask = PWER_WE35; + + INIT_GPIO_DESC_MUXED(WEMUX3, 31); + INIT_GPIO_DESC_MUXED(WEMUX3, 113); + INIT_GPIO_DESC_MUXED(WEMUX2, 38); + INIT_GPIO_DESC_MUXED(WEMUX2, 53); + INIT_GPIO_DESC_MUXED(WEMUX2, 40); + INIT_GPIO_DESC_MUXED(WEMUX2, 36); +} +#else +static inline void pxa27x_mfp_init(void) {} +#endif /* CONFIG_PXA27x */ + +#ifdef CONFIG_PM +static unsigned long saved_gafr[2][4]; +static unsigned long saved_gpdr[4]; +static unsigned long saved_gplr[4]; +static unsigned long saved_pgsr[4]; + +static int pxa2xx_mfp_suspend(void) +{ + int i; + + /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */ + for (i = 0; i < pxa_last_gpio; i++) { + if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && + (GPDR(i) & GPIO_bit(i))) { + if (GPLR(i) & GPIO_bit(i)) + PGSR(gpio_to_bank(i)) |= GPIO_bit(i); + else + PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i); } + } - gpio_desc[35].can_wakeup = 1; - gpio_desc[35].mask = PWER_WE35; + for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { + saved_gafr[0][i] = GAFR_L(i); + saved_gafr[1][i] = GAFR_U(i); + saved_gpdr[i] = GPDR(i * 32); + saved_gplr[i] = GPLR(i * 32); + saved_pgsr[i] = PGSR(i); + + GPSR(i * 32) = PGSR(i); + GPCR(i * 32) = ~PGSR(i); + } + + /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */ + for (i = 0; i < pxa_last_gpio; i++) { + if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) || + ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && + (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i)))) + GPDR(i) |= GPIO_bit(i); + else + GPDR(i) &= ~GPIO_bit(i); } return 0; } -postcore_initcall(pxa27x_mfp_init); -#endif /* CONFIG_PXA27x */ + +static void pxa2xx_mfp_resume(void) +{ + int i; + + for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { + GAFR_L(i) = saved_gafr[0][i]; + GAFR_U(i) = saved_gafr[1][i]; + GPSR(i * 32) = saved_gplr[i]; + GPCR(i * 32) = ~saved_gplr[i]; + GPDR(i * 32) = saved_gpdr[i]; + PGSR(i) = saved_pgsr[i]; + } + PSSR = PSSR_RDH | PSSR_PH; +} +#else +#define pxa2xx_mfp_suspend NULL +#define pxa2xx_mfp_resume NULL +#endif + +struct syscore_ops pxa2xx_mfp_syscore_ops = { + .suspend = pxa2xx_mfp_suspend, + .resume = pxa2xx_mfp_resume, +}; + +static int __init pxa2xx_mfp_init(void) +{ + int i; + + if (!cpu_is_pxa2xx()) + return 0; + + if (cpu_is_pxa25x()) + pxa25x_mfp_init(); + + if (cpu_is_pxa27x()) + pxa27x_mfp_init(); + + /* clear RDH bit to enable GPIO receivers after reset/sleep exit */ + PSSR = PSSR_RDH; + + /* initialize gafr_run[], pgsr_lpm[] from existing values */ + for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) + gpdr_lpm[i] = GPDR(i * 32); + + return 0; +} +postcore_initcall(pxa2xx_mfp_init); diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c index eb197a6e8e9..89863a01ecd 100644 --- a/arch/arm/mach-pxa/mfp-pxa3xx.c +++ b/arch/arm/mach-pxa/mfp-pxa3xx.c @@ -17,186 +17,12 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <mach/hardware.h> -#include <mach/mfp.h> #include <mach/mfp-pxa3xx.h> #include <mach/pxa3xx-regs.h> -/* mfp_spin_lock is used to ensure that MFP register configuration - * (most likely a read-modify-write operation) is atomic, and that - * mfp_table[] is consistent - */ -static DEFINE_SPINLOCK(mfp_spin_lock); - -static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE); - -struct pxa3xx_mfp_pin { - unsigned long config; /* -1 for not configured */ - unsigned long mfpr_off; /* MFPRxx Register offset */ - unsigned long mfpr_run; /* Run-Mode Register Value */ - unsigned long mfpr_lpm; /* Low Power Mode Register Value */ -}; - -static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX]; - -/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */ -static const unsigned long mfpr_lpm[] = { - MFPR_LPM_INPUT, - MFPR_LPM_DRIVE_LOW, - MFPR_LPM_DRIVE_HIGH, - MFPR_LPM_PULL_LOW, - MFPR_LPM_PULL_HIGH, - MFPR_LPM_FLOAT, -}; - -/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */ -static const unsigned long mfpr_pull[] = { - MFPR_PULL_NONE, - MFPR_PULL_LOW, - MFPR_PULL_HIGH, - MFPR_PULL_BOTH, -}; - -/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */ -static const unsigned long mfpr_edge[] = { - MFPR_EDGE_NONE, - MFPR_EDGE_RISE, - MFPR_EDGE_FALL, - MFPR_EDGE_BOTH, -}; - -#define mfpr_readl(off) \ - __raw_readl(mfpr_mmio_base + (off)) - -#define mfpr_writel(off, val) \ - __raw_writel(val, mfpr_mmio_base + (off)) - -#define mfp_configured(p) ((p)->config != -1) - -/* - * perform a read-back of any MFPR register to make sure the - * previous writings are finished - */ -#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) - -static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p) -{ - if (mfp_configured(p)) - mfpr_writel(p->mfpr_off, p->mfpr_run); -} - -static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p) -{ - if (mfp_configured(p)) { - unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR; - if (mfpr_clr != p->mfpr_run) - mfpr_writel(p->mfpr_off, mfpr_clr); - if (p->mfpr_lpm != mfpr_clr) - mfpr_writel(p->mfpr_off, p->mfpr_lpm); - } -} - -void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&mfp_spin_lock, flags); - - for (i = 0; i < num; i++, mfp_cfgs++) { - unsigned long tmp, c = *mfp_cfgs; - struct pxa3xx_mfp_pin *p; - int pin, af, drv, lpm, edge, pull; - - pin = MFP_PIN(c); - BUG_ON(pin >= MFP_PIN_MAX); - p = &mfp_table[pin]; - - af = MFP_AF(c); - drv = MFP_DS(c); - lpm = MFP_LPM_STATE(c); - edge = MFP_LPM_EDGE(c); - pull = MFP_PULL(c); - - /* run-mode pull settings will conflict with MFPR bits of - * low power mode state, calculate mfpr_run and mfpr_lpm - * individually if pull != MFP_PULL_NONE - */ - tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv); - - if (likely(pull == MFP_PULL_NONE)) { - p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge]; - p->mfpr_lpm = p->mfpr_run; - } else { - p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge]; - p->mfpr_run = tmp | mfpr_pull[pull]; - } - - p->config = c; __mfp_config_run(p); - } - - mfpr_sync(); - spin_unlock_irqrestore(&mfp_spin_lock, flags); -} - -unsigned long pxa3xx_mfp_read(int mfp) -{ - unsigned long val, flags; - - BUG_ON(mfp >= MFP_PIN_MAX); - - spin_lock_irqsave(&mfp_spin_lock, flags); - val = mfpr_readl(mfp_table[mfp].mfpr_off); - spin_unlock_irqrestore(&mfp_spin_lock, flags); - - return val; -} - -void pxa3xx_mfp_write(int mfp, unsigned long val) -{ - unsigned long flags; - - BUG_ON(mfp >= MFP_PIN_MAX); - - spin_lock_irqsave(&mfp_spin_lock, flags); - mfpr_writel(mfp_table[mfp].mfpr_off, val); - mfpr_sync(); - spin_unlock_irqrestore(&mfp_spin_lock, flags); -} - -void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map) -{ - struct pxa3xx_mfp_addr_map *p; - unsigned long offset, flags; - int i; - - spin_lock_irqsave(&mfp_spin_lock, flags); - - for (p = map; p->start != MFP_PIN_INVALID; p++) { - offset = p->offset; - i = p->start; - - do { - mfp_table[i].mfpr_off = offset; - mfp_table[i].mfpr_run = 0; - mfp_table[i].mfpr_lpm = 0; - offset += 4; i++; - } while ((i <= p->end) && (p->end != -1)); - } - - spin_unlock_irqrestore(&mfp_spin_lock, flags); -} - -void __init pxa3xx_init_mfp(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(mfp_table); i++) - mfp_table[i].config = -1; -} - #ifdef CONFIG_PM /* * Configure the MFPs appropriately for suspend/resume. @@ -205,25 +31,15 @@ void __init pxa3xx_init_mfp(void) * a pull-down mode if they're an active low chip select, and we're * just entering standby. */ -static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state) +static int pxa3xx_mfp_suspend(void) { - int pin; - - for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) { - struct pxa3xx_mfp_pin *p = &mfp_table[pin]; - __mfp_config_lpm(p); - } + mfp_config_lpm(); return 0; } -static int pxa3xx_mfp_resume(struct sys_device *d) +static void pxa3xx_mfp_resume(void) { - int pin; - - for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) { - struct pxa3xx_mfp_pin *p = &mfp_table[pin]; - __mfp_config_run(p); - } + mfp_config_run(); /* clear RDH bit when MFP settings are restored * @@ -231,25 +47,13 @@ static int pxa3xx_mfp_resume(struct sys_device *d) * preserve them here in case they will be referenced later */ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); - - return 0; } #else #define pxa3xx_mfp_suspend NULL #define pxa3xx_mfp_resume NULL #endif -struct sysdev_class pxa3xx_mfp_sysclass = { - .name = "mfp", +struct syscore_ops pxa3xx_mfp_syscore_ops = { .suspend = pxa3xx_mfp_suspend, - .resume = pxa3xx_mfp_resume, + .resume = pxa3xx_mfp_resume, }; - -static int __init mfp_init_devicefs(void) -{ - if (cpu_is_pxa3xx()) - return sysdev_class_register(&pxa3xx_mfp_sysclass); - - return 0; -} -postcore_initcall(mfp_init_devicefs); diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c new file mode 100644 index 00000000000..29997bde277 --- /dev/null +++ b/arch/arm/mach-pxa/mioa701.c @@ -0,0 +1,782 @@ +/* + * Handles the Mitac Mio A701 Board + * + * Copyright (C) 2008 Robert Jarzmik + * + * 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 + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/syscore_ops.h> +#include <linux/input.h> +#include <linux/delay.h> +#include <linux/gpio_keys.h> +#include <linux/pwm_backlight.h> +#include <linux/rtc.h> +#include <linux/leds.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/pda_power.h> +#include <linux/power_supply.h> +#include <linux/wm97xx.h> +#include <linux/mtd/physmap.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/reboot.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/max1586.h> +#include <linux/slab.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa27x.h> +#include <mach/regs-rtc.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <mach/udc.h> +#include <mach/pxa27x-udc.h> +#include <linux/platform_data/camera-pxa.h> +#include <mach/audio.h> +#include <mach/smemc.h> +#include <media/soc_camera.h> + +#include <mach/mioa701.h> + +#include "generic.h" +#include "devices.h" + +static unsigned long mioa701_pin_config[] = { + /* Mio global */ + MIO_CFG_OUT(GPIO9_CHARGE_EN, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO18_POWEROFF, AF0, DRIVE_LOW), + MFP_CFG_OUT(GPIO3, AF0, DRIVE_HIGH), + MFP_CFG_OUT(GPIO4, AF0, DRIVE_HIGH), + MIO_CFG_IN(GPIO80_MAYBE_CHARGE_VDROP, AF0), + + /* Backlight PWM 0 */ + GPIO16_PWM0_OUT, + + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + MIO_CFG_IN(GPIO78_SDIO_RO, AF0), + MIO_CFG_IN(GPIO15_SDIO_INSERT, AF0), + MIO_CFG_OUT(GPIO91_SDIO_EN, AF0, DRIVE_LOW), + + /* USB */ + MIO_CFG_IN(GPIO13_nUSB_DETECT, AF0), + MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW), + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* QCI */ + GPIO12_CIF_DD_7, + GPIO17_CIF_DD_6, + GPIO50_CIF_DD_3, + GPIO51_CIF_DD_2, + GPIO52_CIF_DD_4, + GPIO53_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO55_CIF_DD_1, + GPIO81_CIF_DD_0, + GPIO82_CIF_DD_5, + GPIO84_CIF_FV, + GPIO85_CIF_LV, + MIO_CFG_OUT(GPIO56_MT9M111_nOE, AF0, DRIVE_LOW), + + /* Bluetooth */ + MIO_CFG_IN(GPIO14_BT_nACTIVITY, AF0), + GPIO44_BTUART_CTS, + GPIO42_BTUART_RXD, + GPIO45_BTUART_RTS, + GPIO43_BTUART_TXD, + MIO_CFG_OUT(GPIO83_BT_ON, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO77_BT_UNKNOWN1, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO86_BT_MAYBE_nRESET, AF0, DRIVE_HIGH), + + /* GPS */ + MIO_CFG_OUT(GPIO23_GPS_UNKNOWN1, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO26_GPS_ON, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO27_GPS_RESET, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO106_GPS_UNKNOWN2, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO107_GPS_UNKNOWN3, AF0, DRIVE_LOW), + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* GSM */ + MIO_CFG_OUT(GPIO24_GSM_MOD_RESET_CMD, AF0, DRIVE_LOW), + MIO_CFG_OUT(GPIO88_GSM_nMOD_ON_CMD, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO90_GSM_nMOD_OFF_CMD, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO114_GSM_nMOD_DTE_UART_STATE, AF0, DRIVE_HIGH), + MIO_CFG_IN(GPIO25_GSM_MOD_ON_STATE, AF0), + MIO_CFG_IN(GPIO113_GSM_EVENT, AF0) | WAKEUP_ON_EDGE_BOTH, + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + GPIO36_FFUART_DCD, + GPIO37_FFUART_DSR, + GPIO39_FFUART_TXD, + GPIO40_FFUART_DTR, + GPIO41_FFUART_RTS, + + /* Sound */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO89_AC97_SYSCLK, + MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0), + + /* Leds */ + MIO_CFG_OUT(GPIO10_LED_nCharging, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO97_LED_nBlue, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO98_LED_nOrange, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO82_LED_nVibra, AF0, DRIVE_HIGH), + MIO_CFG_OUT(GPIO115_LED_nKeyboard, AF0, DRIVE_HIGH), + + /* Keyboard */ + MIO_CFG_IN(GPIO0_KEY_POWER, AF0) | WAKEUP_ON_EDGE_BOTH, + MIO_CFG_IN(GPIO93_KEY_VOLUME_UP, AF0), + MIO_CFG_IN(GPIO94_KEY_VOLUME_DOWN, AF0), + GPIO100_KP_MKIN_0, + GPIO101_KP_MKIN_1, + GPIO102_KP_MKIN_2, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* Unknown */ + MFP_CFG_IN(GPIO20, AF0), + MFP_CFG_IN(GPIO21, AF0), + MFP_CFG_IN(GPIO33, AF0), + MFP_CFG_OUT(GPIO49, AF0, DRIVE_HIGH), + MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH), + MFP_CFG_IN(GPIO96, AF0), + MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH), +}; + +/* LCD Screen and Backlight */ +static struct platform_pwm_backlight_data mioa701_backlight_data = { + .pwm_id = 0, + .max_brightness = 100, + .dft_brightness = 50, + .pwm_period_ns = 4000 * 1024, /* Fl = 250kHz */ + .enable_gpio = -1, +}; + +/* + * LTM0305A776C LCD panel timings + * + * see: + * - the LTM0305A776C datasheet, + * - and the PXA27x Programmers' manual + */ +static struct pxafb_mode_info mioa701_ltm0305a776c = { + .pixclock = 220000, /* CLK=4.545 MHz */ + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 4, + .vsync_len = 2, + .left_margin = 6, + .right_margin = 4, + .upper_margin = 5, + .lower_margin = 3, +}; + +static void mioa701_lcd_power(int on, struct fb_var_screeninfo *si) +{ + gpio_set_value(GPIO87_LCD_POWER, on); +} + +static struct pxafb_mach_info mioa701_pxafb_info = { + .modes = &mioa701_ltm0305a776c, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, + .pxafb_lcd_power = mioa701_lcd_power, +}; + +/* + * Keyboard configuration + */ +static const unsigned int mioa701_matrix_keys[] = { + KEY(0, 0, KEY_UP), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_MEDIA), + KEY(1, 0, KEY_DOWN), + KEY(1, 1, KEY_ENTER), + KEY(1, 2, KEY_CONNECT), /* GPS key */ + KEY(2, 0, KEY_LEFT), + KEY(2, 1, KEY_PHONE), /* Phone Green key */ + KEY(2, 2, KEY_CAMERA) /* Camera key */ +}; + +static struct matrix_keymap_data mioa701_matrix_keymap_data = { + .keymap = mioa701_matrix_keys, + .keymap_size = ARRAY_SIZE(mioa701_matrix_keys), +}; + +static struct pxa27x_keypad_platform_data mioa701_keypad_info = { + .matrix_key_rows = 3, + .matrix_key_cols = 3, + .matrix_keymap_data = &mioa701_matrix_keymap_data, +}; + +/* + * GPIO Key Configuration + */ +#define MIO_KEY(key, _gpio, _desc, _wakeup) \ + { .code = (key), .gpio = (_gpio), .active_low = 0, \ + .desc = (_desc), .type = EV_KEY, .wakeup = (_wakeup) } +static struct gpio_keys_button mioa701_button_table[] = { + MIO_KEY(KEY_EXIT, GPIO0_KEY_POWER, "Power button", 1), + MIO_KEY(KEY_VOLUMEUP, GPIO93_KEY_VOLUME_UP, "Volume up", 0), + MIO_KEY(KEY_VOLUMEDOWN, GPIO94_KEY_VOLUME_DOWN, "Volume down", 0), + MIO_KEY(KEY_HP, GPIO12_HPJACK_INSERT, "HP jack detect", 0) +}; + +static struct gpio_keys_platform_data mioa701_gpio_keys_data = { + .buttons = mioa701_button_table, + .nbuttons = ARRAY_SIZE(mioa701_button_table), +}; + +/* + * Leds and vibrator + */ +#define ONE_LED(_gpio, _name) \ +{ .gpio = (_gpio), .name = (_name), .active_low = true } +static struct gpio_led gpio_leds[] = { + ONE_LED(GPIO10_LED_nCharging, "mioa701:charging"), + ONE_LED(GPIO97_LED_nBlue, "mioa701:blue"), + ONE_LED(GPIO98_LED_nOrange, "mioa701:orange"), + ONE_LED(GPIO82_LED_nVibra, "mioa701:vibra"), + ONE_LED(GPIO115_LED_nKeyboard, "mioa701:keyboard") +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +/* + * GSM Sagem XS200 chip + * + * GSM handling was purged from kernel. For history, this is the way to go : + * - init : GPIO24_GSM_MOD_RESET_CMD = 0, GPIO114_GSM_nMOD_DTE_UART_STATE = 1 + * GPIO88_GSM_nMOD_ON_CMD = 1, GPIO90_GSM_nMOD_OFF_CMD = 1 + * - reset : GPIO24_GSM_MOD_RESET_CMD = 1, msleep(100), + * GPIO24_GSM_MOD_RESET_CMD = 0 + * - turn on : GPIO88_GSM_nMOD_ON_CMD = 0, msleep(1000), + * GPIO88_GSM_nMOD_ON_CMD = 1 + * - turn off : GPIO90_GSM_nMOD_OFF_CMD = 0, msleep(1000), + * GPIO90_GSM_nMOD_OFF_CMD = 1 + */ +static int is_gsm_on(void) +{ + int is_on; + + is_on = !!gpio_get_value(GPIO25_GSM_MOD_ON_STATE); + return is_on; +} + +irqreturn_t gsm_on_irq(int irq, void *p) +{ + printk(KERN_DEBUG "Mioa701: GSM status changed to %s\n", + is_gsm_on() ? "on" : "off"); + return IRQ_HANDLED; +} + +static struct gpio gsm_gpios[] = { + { GPIO25_GSM_MOD_ON_STATE, GPIOF_IN, "GSM state" }, + { GPIO113_GSM_EVENT, GPIOF_IN, "GSM event" }, +}; + +static int __init gsm_init(void) +{ + int rc; + + rc = gpio_request_array(ARRAY_AND_SIZE(gsm_gpios)); + if (rc) + goto err_gpio; + rc = request_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), gsm_on_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "GSM XS200 Power Irq", NULL); + if (rc) + goto err_irq; + + gpio_set_wake(GPIO113_GSM_EVENT, 1); + return 0; + +err_irq: + printk(KERN_ERR "Mioa701: Can't request GSM_ON irq\n"); + gpio_free_array(ARRAY_AND_SIZE(gsm_gpios)); +err_gpio: + printk(KERN_ERR "Mioa701: gsm not available\n"); + return rc; +} + +static void gsm_exit(void) +{ + free_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), NULL); + gpio_free_array(ARRAY_AND_SIZE(gsm_gpios)); +} + +/* + * Bluetooth BRF6150 chip + * + * BT handling was purged from kernel. For history, this is the way to go : + * - turn on : GPIO83_BT_ON = 1 + * - turn off : GPIO83_BT_ON = 0 + */ + +/* + * GPS Sirf Star III chip + * + * GPS handling was purged from kernel. For history, this is the way to go : + * - init : GPIO23_GPS_UNKNOWN1 = 1, GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0 + * GPIO106_GPS_UNKNOWN2 = 0, GPIO107_GPS_UNKNOWN3 = 0 + * - turn on : GPIO27_GPS_RESET = 1, GPIO26_GPS_ON = 1 + * - turn off : GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0 + */ + +/* + * USB UDC + */ +static int is_usb_connected(void) +{ + return !gpio_get_value(GPIO13_nUSB_DETECT); +} + +static struct pxa2xx_udc_mach_info mioa701_udc_info = { + .udc_is_connected = is_usb_connected, + .gpio_pullup = GPIO22_USB_ENABLE, +}; + +struct gpio_vbus_mach_info gpio_vbus_data = { + .gpio_vbus = GPIO13_nUSB_DETECT, + .gpio_vbus_inverted = 1, + .gpio_pullup = -1, +}; + +/* + * SDIO/MMC Card controller + */ +/** + * 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 mioa701_mci_info = { + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = GPIO15_SDIO_INSERT, + .gpio_card_ro = GPIO78_SDIO_RO, + .gpio_power = GPIO91_SDIO_EN, +}; + +/* FlashRAM */ +static struct resource docg3_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_8K - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device docg3 = { + .name = "docg3", + .id = -1, + .resource = &docg3_resource, + .num_resources = 1, + .dev = { + .platform_data = NULL, + }, +}; + +/* + * Suspend/Resume bootstrap management + * + * MIO A701 reboot sequence is highly ROM dependent. From the one dissassembled, + * this sequence is as follows : + * - disables interrupts + * - initialize SDRAM (self refresh RAM into active RAM) + * - initialize GPIOs (depends on value at 0xa020b020) + * - initialize coprossessors + * - if edge detect on PWR_SCL(GPIO3), then proceed to cold start + * - or if value at 0xa020b000 not equal to 0x0f0f0f0f, proceed to cold start + * - else do a resume, ie. jump to addr 0xa0100000 + */ +#define RESUME_ENABLE_ADDR 0xa020b000 +#define RESUME_ENABLE_VAL 0x0f0f0f0f +#define RESUME_BT_ADDR 0xa020b020 +#define RESUME_UNKNOWN_ADDR 0xa020b024 +#define RESUME_VECTOR_ADDR 0xa0100000 +#define BOOTSTRAP_WORDS mioa701_bootstrap_lg/4 + +static u32 *save_buffer; + +static void install_bootstrap(void) +{ + int i; + u32 *rom_bootstrap = phys_to_virt(RESUME_VECTOR_ADDR); + u32 *src = &mioa701_bootstrap; + + for (i = 0; i < BOOTSTRAP_WORDS; i++) + rom_bootstrap[i] = src[i]; +} + + +static int mioa701_sys_suspend(void) +{ + int i = 0, is_bt_on; + u32 *mem_resume_vector = phys_to_virt(RESUME_VECTOR_ADDR); + u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR); + u32 *mem_resume_bt = phys_to_virt(RESUME_BT_ADDR); + u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR); + + /* Devices prepare suspend */ + is_bt_on = !!gpio_get_value(GPIO83_BT_ON); + pxa2xx_mfp_set_lpm(GPIO83_BT_ON, + is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW); + + for (i = 0; i < BOOTSTRAP_WORDS; i++) + save_buffer[i] = mem_resume_vector[i]; + save_buffer[i++] = *mem_resume_enabler; + save_buffer[i++] = *mem_resume_bt; + save_buffer[i++] = *mem_resume_unknown; + + *mem_resume_enabler = RESUME_ENABLE_VAL; + *mem_resume_bt = is_bt_on; + + install_bootstrap(); + return 0; +} + +static void mioa701_sys_resume(void) +{ + int i = 0; + u32 *mem_resume_vector = phys_to_virt(RESUME_VECTOR_ADDR); + u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR); + u32 *mem_resume_bt = phys_to_virt(RESUME_BT_ADDR); + u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR); + + for (i = 0; i < BOOTSTRAP_WORDS; i++) + mem_resume_vector[i] = save_buffer[i]; + *mem_resume_enabler = save_buffer[i++]; + *mem_resume_bt = save_buffer[i++]; + *mem_resume_unknown = save_buffer[i++]; +} + +static struct syscore_ops mioa701_syscore_ops = { + .suspend = mioa701_sys_suspend, + .resume = mioa701_sys_resume, +}; + +static int __init bootstrap_init(void) +{ + int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3); + + register_syscore_ops(&mioa701_syscore_ops); + + save_buffer = kmalloc(save_size, GFP_KERNEL); + if (!save_buffer) + return -ENOMEM; + printk(KERN_INFO "MioA701: allocated %d bytes for bootstrap\n", + save_size); + return 0; +} + +static void bootstrap_exit(void) +{ + kfree(save_buffer); + unregister_syscore_ops(&mioa701_syscore_ops); + + printk(KERN_CRIT "Unregistering mioa701 suspend will hang next" + "resume !!!\n"); +} + +/* + * Power Supply + */ +static char *supplicants[] = { + "mioa701_battery" +}; + +static int is_ac_connected(void) +{ + return gpio_get_value(GPIO96_AC_DETECT); +} + +static void mioa701_set_charge(int flags) +{ + gpio_set_value(GPIO9_CHARGE_EN, (flags == PDA_POWER_CHARGE_USB)); +} + +static struct pda_power_pdata power_pdata = { + .is_ac_online = is_ac_connected, + .is_usb_online = is_usb_connected, + .set_charge = mioa701_set_charge, + .supplied_to = supplicants, + .num_supplicants = ARRAY_SIZE(supplicants), +}; + +static struct resource power_resources[] = { + [0] = { + .name = "ac", + .start = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT), + .end = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + }, + [1] = { + .name = "usb", + .start = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT), + .end = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct platform_device power_dev = { + .name = "pda-power", + .id = -1, + .resource = power_resources, + .num_resources = ARRAY_SIZE(power_resources), + .dev = { + .platform_data = &power_pdata, + }, +}; + +static struct wm97xx_batt_pdata mioa701_battery_data = { + .batt_aux = WM97XX_AUX_ID1, + .temp_aux = -1, + .charge_gpio = -1, + .min_voltage = 0xc00, + .max_voltage = 0xfc0, + .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION, + .batt_div = 1, + .batt_mult = 1, + .batt_name = "mioa701_battery", +}; + +static struct wm97xx_pdata mioa701_wm97xx_pdata = { + .batt_pdata = &mioa701_battery_data, +}; + +/* + * Voltage regulation + */ +static struct regulator_consumer_supply max1586_consumers[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +static struct regulator_init_data max1586_v3_info = { + .constraints = { + .name = "vcc_core range", + .min_uV = 1000000, + .max_uV = 1705000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(max1586_consumers), + .consumer_supplies = max1586_consumers, +}; + +static struct max1586_subdev_data max1586_subdevs[] = { + { .name = "vcc_core", .id = MAX1586_V3, + .platform_data = &max1586_v3_info }, +}; + +static struct max1586_platform_data max1586_info = { + .subdevs = max1586_subdevs, + .num_subdevs = ARRAY_SIZE(max1586_subdevs), + .v3_gain = MAX1586_GAIN_NO_R24, /* 700..1475 mV */ +}; + +/* + * Camera interface + */ +struct pxacamera_platform_data mioa701_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 __initdata mioa701_pi2c_devices[] = { + { + I2C_BOARD_INFO("max1586", 0x14), + .platform_data = &max1586_info, + }, +}; + +/* Board I2C devices. */ +static struct i2c_board_info mioa701_i2c_devices[] = { + { + I2C_BOARD_INFO("mt9m111", 0x5d), + }, +}; + +static struct soc_camera_link iclink = { + .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */ + .board_info = &mioa701_i2c_devices[0], + .i2c_adapter_id = 0, +}; + +struct i2c_pxa_platform_data i2c_pdata = { + .fast_mode = 1, +}; + +static pxa2xx_audio_ops_t mioa701_ac97_info = { + .reset_gpio = 95, + .codec_pdata = { &mioa701_wm97xx_pdata, }, +}; + +/* + * Mio global + */ + +/* Devices */ +#define MIO_PARENT_DEV(var, strname, tparent, pdata) \ +static struct platform_device var = { \ + .name = strname, \ + .id = -1, \ + .dev = { \ + .platform_data = pdata, \ + .parent = tparent, \ + }, \ +}; +#define MIO_SIMPLE_DEV(var, strname, pdata) \ + MIO_PARENT_DEV(var, strname, NULL, pdata) + +MIO_SIMPLE_DEV(mioa701_gpio_keys, "gpio-keys", &mioa701_gpio_keys_data) +MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight", &pxa27x_device_pwm0.dev, + &mioa701_backlight_data); +MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info) +MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL) +MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL) +MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL) +MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data); +MIO_SIMPLE_DEV(mioa701_camera, "soc-camera-pdrv",&iclink); + +static struct platform_device *devices[] __initdata = { + &mioa701_gpio_keys, + &mioa701_backlight, + &mioa701_led, + &pxa2xx_pcm, + &mioa701_sound, + &power_dev, + &docg3, + &gpio_vbus, + &mioa701_camera, + &mioa701_board, +}; + +static void mioa701_machine_exit(void); + +static void mioa701_poweroff(void) +{ + mioa701_machine_exit(); + pxa_restart(REBOOT_SOFT, NULL); +} + +static void mioa701_restart(enum reboot_mode c, const char *cmd) +{ + mioa701_machine_exit(); + pxa_restart(REBOOT_SOFT, cmd); +} + +static struct gpio global_gpios[] = { + { GPIO9_CHARGE_EN, GPIOF_OUT_INIT_HIGH, "Charger enable" }, + { GPIO18_POWEROFF, GPIOF_OUT_INIT_LOW, "Power Off" }, + { GPIO87_LCD_POWER, GPIOF_OUT_INIT_LOW, "LCD Power" }, + { GPIO56_MT9M111_nOE, GPIOF_OUT_INIT_LOW, "Camera nOE" }, +}; + +static struct regulator_consumer_supply fixed_5v0_consumers[] = { + REGULATOR_SUPPLY("power", "pwm-backlight"), +}; + +static void __init mioa701_machine_init(void) +{ + int rc; + + PSLR = 0xff100000; /* SYSDEL=125ms, PWRDEL=125ms, PSLR_SL_ROD=1 */ + PCFR = PCFR_DC_EN | PCFR_GPR_EN | PCFR_OPDE; + RTTR = 32768 - 1; /* Reset crazy WinCE value */ + UP2OCR = UP2OCR_HXOE; + + /* + * Set up the flash memory : DiskOnChip G3 on first static memory bank + */ + __raw_writel(0x7ff02dd8, MSC0); + __raw_writel(0x0001c391, MCMEM0); + __raw_writel(0x0001c391, MCATT0); + __raw_writel(0x0001c391, MCIO0); + + + pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + rc = gpio_request_array(ARRAY_AND_SIZE(global_gpios)); + if (rc) + pr_err("MioA701: Failed to request GPIOs: %d", rc); + bootstrap_init(); + pxa_set_fb_info(NULL, &mioa701_pxafb_info); + pxa_set_mci_info(&mioa701_mci_info); + pxa_set_keypad_info(&mioa701_keypad_info); + pxa_set_udc_info(&mioa701_udc_info); + pxa_set_ac97_info(&mioa701_ac97_info); + pm_power_off = mioa701_poweroff; + platform_add_devices(devices, ARRAY_SIZE(devices)); + gsm_init(); + + i2c_register_board_info(1, ARRAY_AND_SIZE(mioa701_pi2c_devices)); + pxa_set_i2c_info(&i2c_pdata); + pxa27x_set_i2c_power_info(NULL); + pxa_set_camera_info(&mioa701_pxacamera_platform_data); + + regulator_register_always_on(0, "fixed-5.0V", fixed_5v0_consumers, + ARRAY_SIZE(fixed_5v0_consumers), + 5000000); +} + +static void mioa701_machine_exit(void) +{ + bootstrap_exit(); + gsm_exit(); +} + +MACHINE_START(MIOA701, "MIO A701") + .atag_offset = 0x100, + .map_io = &pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = &pxa27x_init_irq, + .handle_irq = &pxa27x_handle_irq, + .init_machine = mioa701_machine_init, + .init_time = pxa_timer_init, + .restart = mioa701_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/mioa701_bootresume.S b/arch/arm/mach-pxa/mioa701_bootresume.S new file mode 100644 index 00000000000..324d25a48c8 --- /dev/null +++ b/arch/arm/mach-pxa/mioa701_bootresume.S @@ -0,0 +1,37 @@ +/* Bootloader to resume MIO A701 + * + * 2007-1-12 Robert Jarzmik + * + * This code is licenced under the GPLv2. +*/ + +#include <linux/linkage.h> +#include <asm/assembler.h> + +/* + * Note: Yes, part of the following code is located into the .data section. + * This is to allow jumpaddr to be accessed with a relative load + * while we can't rely on any MMU translation. We could have put + * sleep_save_sp in the .text section as well, but some setups might + * insist on it to be truly read-only. + */ + .data +ENTRY(mioa701_bootstrap) +0: + b 1f +ENTRY(mioa701_jumpaddr) + .word 0x40f00008 @ PSPR in no-MMU mode +1: + mov r0, #0xa0000000 @ Don't suppose memory access works + orr r0, r0, #0x00200000 @ even if it's supposed to + orr r0, r0, #0x0000b000 + mov r1, #0 + str r1, [r0] @ Early disable resume for next boot + ldr r0, mioa701_jumpaddr @ (Murphy's Law) + ldr r0, [r0] + mov pc, r0 +2: + +ENTRY(mioa701_bootstrap_lg) + .data + .word 2b-0b diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c new file mode 100644 index 00000000000..854f1f562d6 --- /dev/null +++ b/arch/arm/mach-pxa/mp900.c @@ -0,0 +1,104 @@ +/* + * linux/arch/arm/mach-pxa/mp900.c + * + * Support for the NEC MobilePro900/C platform + * + * Based on mach-pxa/gumstix.c + * + * 2007, 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com> + * 2007, 2008 Michael Petchkovsky <mkpetch@internode.on.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/device.h> +#include <linux/platform_device.h> +#include <linux/types.h> +#include <linux/usb/isp116x.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa25x.h> +#include "generic.h" + +static void isp116x_pfm_delay(struct device *dev, int delay) +{ + + /* 400Mhz PXA2 = 2.5ns / instruction */ + + int cyc = delay / 10; + + /* 4 Instructions = 4 x 2.5ns = 10ns */ + __asm__ volatile ("0:\n" + "subs %0, %1, #1\n" + "bge 0b\n" + :"=r" (cyc) + :"0"(cyc) + ); +} + +static struct isp116x_platform_data isp116x_pfm_data = { + .remote_wakeup_enable = 1, + .delay = isp116x_pfm_delay, +}; + +static struct resource isp116x_pfm_resources[] = { + [0] = { + .start = 0x0d000000, + .end = 0x0d000000 + 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x0d000000 + 4, + .end = 0x0d000000 + 5, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 61, + .end = 61, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mp900c_dummy_device = { + .name = "mp900c_dummy", + .id = -1, +}; + +static struct platform_device mp900c_usb = { + .name = "isp116x-hcd", + .num_resources = ARRAY_SIZE(isp116x_pfm_resources), + .resource = isp116x_pfm_resources, + .dev.platform_data = &isp116x_pfm_data, +}; + +static struct platform_device *devices[] __initdata = { + &mp900c_dummy_device, + &mp900c_usb, +}; + +static void __init mp900c_init(void) +{ + printk(KERN_INFO "MobilePro 900/C machine init\n"); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +/* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */ +MACHINE_START(NEC_MP900, "MobilePro900/C") + .atag_offset = 0x220100, + .init_time = pxa_timer_init, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_machine = mp900c_init, + .restart = pxa_restart, +MACHINE_END + diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c new file mode 100644 index 00000000000..d04ed4961e6 --- /dev/null +++ b/arch/arm/mach-pxa/mxm8x10.c @@ -0,0 +1,475 @@ +/* + * linux/arch/arm/mach-pxa/mxm8x10.c + * + * Support for the Embedian MXM-8x10 Computer on Module + * + * Copyright (C) 2006 Marvell International Ltd. + * 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/serial_8250.h> +#include <linux/dm9000.h> +#include <linux/gpio.h> +#include <linux/i2c/pxa-i2c.h> + +#include <linux/platform_data/mtd-nand-pxa3xx.h> + +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/pxa320.h> + +#include <mach/mxm8x10.h> + +#include "devices.h" +#include "generic.h" + +/* GPIO pin definition + +External device stuff - Leave unconfigured for now... +--------------------- +GPIO0 - DREQ (External DMA Request) +GPIO3 - nGCS2 (External Chip Select) Where is nGCS0; nGCS1; nGCS4; nGCS5 ? +GPIO4 - nGCS3 +GPIO15 - EXT_GPIO1 +GPIO16 - EXT_GPIO2 +GPIO17 - EXT_GPIO3 +GPIO24 - EXT_GPIO4 +GPIO25 - EXT_GPIO5 +GPIO26 - EXT_GPIO6 +GPIO27 - EXT_GPIO7 +GPIO28 - EXT_GPIO8 +GPIO29 - EXT_GPIO9 +GPIO30 - EXT_GPIO10 +GPIO31 - EXT_GPIO11 +GPIO57 - EXT_GPIO12 +GPIO74 - EXT_IRQ1 +GPIO75 - EXT_IRQ2 +GPIO76 - EXT_IRQ3 +GPIO77 - EXT_IRQ4 +GPIO78 - EXT_IRQ5 +GPIO79 - EXT_IRQ6 +GPIO80 - EXT_IRQ7 +GPIO81 - EXT_IRQ8 +GPIO87 - VCCIO_PWREN (External Device PWREN) + +Dallas 1-Wire - Leave unconfigured for now... +------------- +GPIO0_2 - DS - 1Wire + +Ethernet +-------- +GPIO1 - DM9000 PWR +GPIO9 - DM9K_nIRQ +GPIO36 - DM9K_RESET + +Keypad - Leave unconfigured by for now... +------ +GPIO1_2 - KP_DKIN0 +GPIO5_2 - KP_MKOUT7 +GPIO82 - KP_DKIN1 +GPIO85 - KP_DKIN2 +GPIO86 - KP_DKIN3 +GPIO113 - KP_MKIN0 +GPIO114 - KP_MKIN1 +GPIO115 - KP_MKIN2 +GPIO116 - KP_MKIN3 +GPIO117 - KP_MKIN4 +GPIO118 - KP_MKIN5 +GPIO119 - KP_MKIN6 +GPIO120 - KP_MKIN7 +GPIO121 - KP_MKOUT0 +GPIO122 - KP_MKOUT1 +GPIO122 - KP_MKOUT2 +GPIO123 - KP_MKOUT3 +GPIO124 - KP_MKOUT4 +GPIO125 - KP_MKOUT5 +GPIO127 - KP_MKOUT6 + +Data Bus - Leave unconfigured for now... +-------- +GPIO2 - nWait (Data Bus) + +USB Device +---------- +GPIO4_2 - USBD_PULLUP +GPIO10 - UTM_CLK (USB Device UTM Clk) +GPIO49 - USB 2.0 Device UTM_DATA0 +GPIO50 - USB 2.0 Device UTM_DATA1 +GPIO51 - USB 2.0 Device UTM_DATA2 +GPIO52 - USB 2.0 Device UTM_DATA3 +GPIO53 - USB 2.0 Device UTM_DATA4 +GPIO54 - USB 2.0 Device UTM_DATA5 +GPIO55 - USB 2.0 Device UTM_DATA6 +GPIO56 - USB 2.0 Device UTM_DATA7 +GPIO58 - UTM_RXVALID (USB 2.0 Device) +GPIO59 - UTM_RXACTIVE (USB 2.0 Device) +GPIO60 - UTM_RXERROR +GPIO61 - UTM_OPMODE0 +GPIO62 - UTM_OPMODE1 +GPIO71 - USBD_INT (USB Device?) +GPIO73 - UTM_TXREADY (USB 2.0 Device) +GPIO83 - UTM_TXVALID (USB 2.0 Device) +GPIO98 - UTM_RESET (USB 2.0 device) +GPIO99 - UTM_XCVR_SELECT +GPIO100 - UTM_TERM_SELECT +GPIO101 - UTM_SUSPENDM_X +GPIO102 - UTM_LINESTATE0 +GPIO103 - UTM_LINESTATE1 + +Card-Bus Interface - Leave unconfigured for now... +------------------ +GPIO5 - nPIOR (I/O space output enable) +GPIO6 - nPIOW (I/O space write enable) +GPIO7 - nIOS16 (Input from I/O space telling size of data bus) +GPIO8 - nPWAIT (Input for inserting wait states) + +LCD +--- +GPIO6_2 - LDD0 +GPIO7_2 - LDD1 +GPIO8_2 - LDD2 +GPIO9_2 - LDD3 +GPIO11_2 - LDD5 +GPIO12_2 - LDD6 +GPIO13_2 - LDD7 +GPIO14_2 - VSYNC +GPIO15_2 - HSYNC +GPIO16_2 - VCLK +GPIO17_2 - HCLK +GPIO18_2 - VDEN +GPIO63 - LDD8 (CPU LCD) +GPIO64 - LDD9 (CPU LCD) +GPIO65 - LDD10 (CPU LCD) +GPIO66 - LDD11 (CPU LCD) +GPIO67 - LDD12 (CPU LCD) +GPIO68 - LDD13 (CPU LCD) +GPIO69 - LDD14 (CPU LCD) +GPIO70 - LDD15 (CPU LCD) +GPIO88 - VCCLCD_PWREN (LCD Panel PWREN) +GPIO97 - BACKLIGHT_EN +GPIO104 - LCD_PWREN + +PWM - Leave unconfigured for now... +--- +GPIO11 - PWM0 +GPIO12 - PWM1 +GPIO13 - PWM2 +GPIO14 - PWM3 + +SD-CARD +------- +GPIO18 - SDDATA0 +GPIO19 - SDDATA1 +GPIO20 - SDDATA2 +GPIO21 - SDDATA3 +GPIO22 - SDCLK +GPIO23 - SDCMD +GPIO72 - SD_WP +GPIO84 - SD_nIRQ_CD (SD-Card) + +I2C +--- +GPIO32 - I2CSCL +GPIO33 - I2CSDA + +AC97 +---- +GPIO35 - AC97_SDATA_IN +GPIO37 - AC97_SDATA_OUT +GPIO38 - AC97_SYNC +GPIO39 - AC97_BITCLK +GPIO40 - AC97_nRESET + +UART1 +----- +GPIO41 - UART_RXD1 +GPIO42 - UART_TXD1 +GPIO43 - UART_CTS1 +GPIO44 - UART_DCD1 +GPIO45 - UART_DSR1 +GPIO46 - UART_nRI1 +GPIO47 - UART_DTR1 +GPIO48 - UART_RTS1 + +UART2 +----- +GPIO109 - RTS2 +GPIO110 - RXD2 +GPIO111 - TXD2 +GPIO112 - nCTS2 + +UART3 +----- +GPIO105 - nCTS3 +GPIO106 - nRTS3 +GPIO107 - TXD3 +GPIO108 - RXD3 + +SSP3 - Leave unconfigured for now... +---- +GPIO89 - SSP3_CLK +GPIO90 - SSP3_SFRM +GPIO91 - SSP3_TXD +GPIO92 - SSP3_RXD + +SSP4 +GPIO93 - SSP4_CLK +GPIO94 - SSP4_SFRM +GPIO95 - SSP4_TXD +GPIO96 - SSP4_RXD +*/ + +static mfp_cfg_t mfp_cfg[] __initdata = { + /* USB */ + GPIO10_UTM_CLK, + GPIO49_U2D_PHYDATA_0, + GPIO50_U2D_PHYDATA_1, + GPIO51_U2D_PHYDATA_2, + GPIO52_U2D_PHYDATA_3, + GPIO53_U2D_PHYDATA_4, + GPIO54_U2D_PHYDATA_5, + GPIO55_U2D_PHYDATA_6, + GPIO56_U2D_PHYDATA_7, + GPIO58_UTM_RXVALID, + GPIO59_UTM_RXACTIVE, + GPIO60_U2D_RXERROR, + GPIO61_U2D_OPMODE0, + GPIO62_U2D_OPMODE1, + GPIO71_GPIO, /* USBD_INT */ + GPIO73_UTM_TXREADY, + GPIO83_U2D_TXVALID, + GPIO98_U2D_RESET, + GPIO99_U2D_XCVR_SEL, + GPIO100_U2D_TERM_SEL, + GPIO101_U2D_SUSPEND, + GPIO102_UTM_LINESTATE_0, + GPIO103_UTM_LINESTATE_1, + GPIO4_2_GPIO | MFP_PULL_HIGH, /* UTM_PULLUP */ + + /* DM9000 */ + GPIO1_GPIO, + GPIO9_GPIO, + GPIO36_GPIO, + + /* AC97 */ + GPIO35_AC97_SDATA_IN_0, + GPIO37_AC97_SDATA_OUT, + GPIO38_AC97_SYNC, + GPIO39_AC97_BITCLK, + GPIO40_AC97_nACRESET, + + /* UARTS */ + GPIO41_UART1_RXD, + GPIO42_UART1_TXD, + GPIO43_UART1_CTS, + GPIO44_UART1_DCD, + GPIO45_UART1_DSR, + GPIO46_UART1_RI, + GPIO47_UART1_DTR, + GPIO48_UART1_RTS, + + GPIO109_UART2_RTS, + GPIO110_UART2_RXD, + GPIO111_UART2_TXD, + GPIO112_UART2_CTS, + + GPIO105_UART3_CTS, + GPIO106_UART3_RTS, + GPIO107_UART3_TXD, + GPIO108_UART3_RXD, + + GPIO78_GPIO, + GPIO79_GPIO, + GPIO80_GPIO, + GPIO81_GPIO, + + /* I2C */ + GPIO32_I2C_SCL, + GPIO33_I2C_SDA, + + /* MMC */ + GPIO18_MMC1_DAT0, + GPIO19_MMC1_DAT1, + GPIO20_MMC1_DAT2, + GPIO21_MMC1_DAT3, + GPIO22_MMC1_CLK, + GPIO23_MMC1_CMD, + GPIO72_GPIO | MFP_PULL_HIGH, /* Card Detect */ + GPIO84_GPIO | MFP_PULL_LOW, /* Write Protect */ + + /* IRQ */ + GPIO74_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ1 */ + GPIO75_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ2 */ + GPIO76_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ3 */ + GPIO77_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ4 */ + GPIO78_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ5 */ + GPIO79_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ6 */ + GPIO80_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ7 */ + GPIO81_GPIO | MFP_LPM_EDGE_RISE /* EXT_IRQ8 */ +}; + +/* MMC/MCI Support */ +#if defined(CONFIG_MMC) +static struct pxamci_platform_data mxm_8x10_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .detect_delay_ms = 10, + .gpio_card_detect = MXM_8X10_SD_nCD, + .gpio_card_ro = MXM_8X10_SD_WP, + .gpio_power = -1 +}; + +void __init mxm_8x10_mmc_init(void) +{ + pxa_set_mci_info(&mxm_8x10_mci_platform_data); +} +#endif + +/* USB Open Host Controller Interface */ +static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = { + .port_mode = PMM_NPS_MODE, + .flags = ENABLE_PORT_ALL +}; + +void __init mxm_8x10_usb_host_init(void) +{ + pxa_set_ohci_info(&mxm_8x10_ohci_platform_data); +} + +/* AC97 Sound Support */ +static struct platform_device mxm_8x10_ac97_device = { + .name = "pxa2xx-ac97" +}; + +void __init mxm_8x10_ac97_init(void) +{ + platform_device_register(&mxm_8x10_ac97_device); +} + +/* NAND flash Support */ +#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#define NAND_BLOCK_SIZE SZ_128K +#define NB(x) (NAND_BLOCK_SIZE * (x)) +static struct mtd_partition mxm_8x10_nand_partitions[] = { + [0] = { + .name = "boot", + .size = NB(0x002), + .offset = NB(0x000), + .mask_flags = MTD_WRITEABLE + }, + [1] = { + .name = "kernel", + .size = NB(0x010), + .offset = NB(0x002), + .mask_flags = MTD_WRITEABLE + }, + [2] = { + .name = "root", + .size = NB(0x36c), + .offset = NB(0x012) + }, + [3] = { + .name = "bbt", + .size = NB(0x082), + .offset = NB(0x37e), + .mask_flags = MTD_WRITEABLE + } +}; + +static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = { + .enable_arbiter = 1, + .keep_config = 1, + .num_cs = 1, + .parts[0] = mxm_8x10_nand_partitions, + .nr_parts[0] = ARRAY_SIZE(mxm_8x10_nand_partitions) +}; + +static void __init mxm_8x10_nand_init(void) +{ + pxa3xx_set_nand_info(&mxm_8x10_nand_info); +} +#else +static inline void mxm_8x10_nand_init(void) {} +#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ + +/* Ethernet support: Davicom DM9000 */ +static struct resource dm9k_resources[] = { + [0] = { + .start = MXM_8X10_ETH_PHYS + 0x300, + .end = MXM_8X10_ETH_PHYS + 0x300, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = MXM_8X10_ETH_PHYS + 0x308, + .end = MXM_8X10_ETH_PHYS + 0x308, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE + } +}; + +static struct dm9000_plat_data dm9k_plat_data = { + .flags = DM9000_PLATF_16BITONLY +}; + +static struct platform_device dm9k_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(dm9k_resources), + .resource = dm9k_resources, + .dev = { + .platform_data = &dm9k_plat_data + } +}; + +static void __init mxm_8x10_ethernet_init(void) +{ + platform_device_register(&dm9k_device); +} + +/* PXA UARTs */ +static void __init mxm_8x10_uarts_init(void) +{ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); +} + +/* I2C and Real Time Clock */ +static struct i2c_board_info __initdata mxm_8x10_i2c_devices[] = { + { + I2C_BOARD_INFO("ds1337", 0x68) + } +}; + +static void __init mxm_8x10_i2c_init(void) +{ + i2c_register_board_info(0, mxm_8x10_i2c_devices, + ARRAY_SIZE(mxm_8x10_i2c_devices)); + pxa_set_i2c_info(NULL); +} + +void __init mxm_8x10_barebones_init(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg)); + + mxm_8x10_uarts_init(); + mxm_8x10_nand_init(); + mxm_8x10_i2c_init(); + mxm_8x10_ethernet_init(); +} diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c new file mode 100644 index 00000000000..e54a296fb81 --- /dev/null +++ b/arch/arm/mach-pxa/palm27x.c @@ -0,0 +1,478 @@ +/* + * Common code for Palm LD, T5, TX, Z72 + * + * Copyright (C) 2010-2011 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/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/wm97xx.h> +#include <linux/power_supply.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/regulator/max1586.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa27x.h> +#include <mach/audio.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <mach/udc.h> +#include <linux/platform_data/asoc-palm27x.h> +#include <mach/palm27x.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 palm27x_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .detect_delay_ms = 200, +}; + +void __init palm27x_mmc_init(int detect, int ro, int power, + int power_inverted) +{ + palm27x_mci_platform_data.gpio_card_detect = detect; + palm27x_mci_platform_data.gpio_card_ro = ro; + palm27x_mci_platform_data.gpio_power = power; + palm27x_mci_platform_data.gpio_power_invert = power_inverted; + + pxa_set_mci_info(&palm27x_mci_platform_data); +} +#endif + +/****************************************************************************** + * Power management - standby + ******************************************************************************/ +#if defined(CONFIG_SUSPEND) +void __init palm27x_pm_init(unsigned long str_base) +{ + static const unsigned long resume[] = { + 0xe3a00101, /* mov r0, #0x40000000 */ + 0xe380060f, /* orr r0, r0, #0x00f00000 */ + 0xe590f008, /* ldr pc, [r0, #0x08] */ + }; + + /* + * Copy the bootloader. + * NOTE: PalmZ72 uses a different wakeup method! + */ + memcpy(phys_to_virt(str_base), resume, sizeof(resume)); +} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +struct pxafb_mode_info palm_320x480_lcd_mode = { + .pixclock = 57692, + .xres = 320, + .yres = 480, + .bpp = 16, + + .left_margin = 32, + .right_margin = 1, + .upper_margin = 7, + .lower_margin = 1, + + .hsync_len = 4, + .vsync_len = 1, +}; + +struct pxafb_mode_info palm_320x320_lcd_mode = { + .pixclock = 115384, + .xres = 320, + .yres = 320, + .bpp = 16, + + .left_margin = 27, + .right_margin = 7, + .upper_margin = 7, + .lower_margin = 8, + + .hsync_len = 6, + .vsync_len = 1, +}; + +struct pxafb_mode_info palm_320x320_new_lcd_mode = { + .pixclock = 86538, + .xres = 320, + .yres = 320, + .bpp = 16, + + .left_margin = 20, + .right_margin = 8, + .upper_margin = 8, + .lower_margin = 5, + + .hsync_len = 4, + .vsync_len = 1, +}; + +static struct pxafb_mach_info palm27x_lcd_screen = { + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +static int palm27x_lcd_power; +static void palm27x_lcd_ctl(int on, struct fb_var_screeninfo *info) +{ + gpio_set_value(palm27x_lcd_power, on); +} + +void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode) +{ + palm27x_lcd_screen.modes = mode; + + if (gpio_is_valid(power)) { + if (!gpio_request(power, "LCD power")) { + pr_err("Palm27x: failed to claim lcd power gpio!\n"); + return; + } + if (!gpio_direction_output(power, 1)) { + pr_err("Palm27x: lcd power configuration failed!\n"); + return; + } + palm27x_lcd_power = power; + palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl; + } + + pxa_set_fb_info(NULL, &palm27x_lcd_screen); +} +#endif + +/****************************************************************************** + * USB Gadget + ******************************************************************************/ +#if defined(CONFIG_USB_PXA27X) || \ + defined(CONFIG_USB_PXA27X_MODULE) +static struct gpio_vbus_mach_info palm27x_udc_info = { + .gpio_vbus_inverted = 1, +}; + +static struct platform_device palm27x_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &palm27x_udc_info, + }, +}; + +void __init palm27x_udc_init(int vbus, int pullup, int vbus_inverted) +{ + palm27x_udc_info.gpio_vbus = vbus; + palm27x_udc_info.gpio_pullup = pullup; + + palm27x_udc_info.gpio_vbus_inverted = vbus_inverted; + + if (!gpio_request(pullup, "USB Pullup")) { + gpio_direction_output(pullup, + palm27x_udc_info.gpio_vbus_inverted); + gpio_free(pullup); + } else + return; + + platform_device_register(&palm27x_gpio_vbus); +} +#endif + +/****************************************************************************** + * IrDA + ******************************************************************************/ +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) +static struct pxaficp_platform_data palm27x_ficp_platform_data = { + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; + +void __init palm27x_irda_init(int pwdn) +{ + palm27x_ficp_platform_data.gpio_pwdown = pwdn; + pxa_set_ficp_info(&palm27x_ficp_platform_data); +} +#endif + +/****************************************************************************** + * WM97xx audio, battery + ******************************************************************************/ +#if defined(CONFIG_TOUCHSCREEN_WM97XX) || \ + defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE) +static struct wm97xx_batt_pdata palm27x_batt_pdata = { + .batt_aux = WM97XX_AUX_ID3, + .temp_aux = WM97XX_AUX_ID2, + .charge_gpio = -1, + .batt_mult = 1000, + .batt_div = 414, + .temp_mult = 1, + .temp_div = 1, + .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO, + .batt_name = "main-batt", +}; + +static struct wm97xx_pdata palm27x_wm97xx_pdata = { + .batt_pdata = &palm27x_batt_pdata, +}; + +static pxa2xx_audio_ops_t palm27x_ac97_pdata = { + .codec_pdata = { &palm27x_wm97xx_pdata, }, +}; + +static struct palm27x_asoc_info palm27x_asoc_pdata = { + .jack_gpio = -1, +}; + +static struct platform_device palm27x_asoc = { + .name = "palm27x-asoc", + .id = -1, + .dev = { + .platform_data = &palm27x_asoc_pdata, + }, +}; + +void __init palm27x_ac97_init(int minv, int maxv, int jack, int reset) +{ + palm27x_ac97_pdata.reset_gpio = reset; + palm27x_asoc_pdata.jack_gpio = jack; + + if (minv < 0 || maxv < 0) { + palm27x_ac97_pdata.codec_pdata[0] = NULL; + pxa_set_ac97_info(&palm27x_ac97_pdata); + } else { + palm27x_batt_pdata.min_voltage = minv, + palm27x_batt_pdata.max_voltage = maxv, + + pxa_set_ac97_info(&palm27x_ac97_pdata); + platform_device_register(&palm27x_asoc); + } +} +#endif + +/****************************************************************************** + * Backlight + ******************************************************************************/ +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static int palm_bl_power; +static int palm_lcd_power; + +static int palm27x_backlight_init(struct device *dev) +{ + int ret; + + ret = gpio_request(palm_bl_power, "BL POWER"); + if (ret) + goto err; + ret = gpio_direction_output(palm_bl_power, 0); + if (ret) + goto err2; + + if (gpio_is_valid(palm_lcd_power)) { + ret = gpio_request(palm_lcd_power, "LCD POWER"); + if (ret) + goto err2; + ret = gpio_direction_output(palm_lcd_power, 0); + if (ret) + goto err3; + } + + return 0; +err3: + gpio_free(palm_lcd_power); +err2: + gpio_free(palm_bl_power); +err: + return ret; +} + +static int palm27x_backlight_notify(struct device *dev, int brightness) +{ + gpio_set_value(palm_bl_power, brightness); + if (gpio_is_valid(palm_lcd_power)) + gpio_set_value(palm_lcd_power, brightness); + return brightness; +} + +static void palm27x_backlight_exit(struct device *dev) +{ + gpio_free(palm_bl_power); + if (gpio_is_valid(palm_lcd_power)) + gpio_free(palm_lcd_power); +} + +static struct platform_pwm_backlight_data palm27x_backlight_data = { + .pwm_id = 0, + .max_brightness = 0xfe, + .dft_brightness = 0x7e, + .pwm_period_ns = 3500 * 1024, + .enable_gpio = -1, + .init = palm27x_backlight_init, + .notify = palm27x_backlight_notify, + .exit = palm27x_backlight_exit, +}; + +static struct platform_device palm27x_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &palm27x_backlight_data, + }, +}; + +void __init palm27x_pwm_init(int bl, int lcd) +{ + palm_bl_power = bl; + palm_lcd_power = lcd; + platform_device_register(&palm27x_backlight); +} +#endif + +/****************************************************************************** + * Power supply + ******************************************************************************/ +#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE) +static int palm_ac_state; +static int palm_usb_state; + +static int palm27x_power_supply_init(struct device *dev) +{ + int ret; + + ret = gpio_request(palm_ac_state, "AC state"); + if (ret) + goto err1; + ret = gpio_direction_input(palm_ac_state); + if (ret) + goto err2; + + if (gpio_is_valid(palm_usb_state)) { + ret = gpio_request(palm_usb_state, "USB state"); + if (ret) + goto err2; + ret = gpio_direction_input(palm_usb_state); + if (ret) + goto err3; + } + + return 0; +err3: + gpio_free(palm_usb_state); +err2: + gpio_free(palm_ac_state); +err1: + return ret; +} + +static void palm27x_power_supply_exit(struct device *dev) +{ + gpio_free(palm_usb_state); + gpio_free(palm_ac_state); +} + +static int palm27x_is_ac_online(void) +{ + return gpio_get_value(palm_ac_state); +} + +static int palm27x_is_usb_online(void) +{ + return !gpio_get_value(palm_usb_state); +} +static char *palm27x_supplicants[] = { + "main-battery", +}; + +static struct pda_power_pdata palm27x_ps_info = { + .init = palm27x_power_supply_init, + .exit = palm27x_power_supply_exit, + .is_ac_online = palm27x_is_ac_online, + .is_usb_online = palm27x_is_usb_online, + .supplied_to = palm27x_supplicants, + .num_supplicants = ARRAY_SIZE(palm27x_supplicants), +}; + +static struct platform_device palm27x_power_supply = { + .name = "pda-power", + .id = -1, + .dev = { + .platform_data = &palm27x_ps_info, + }, +}; + +void __init palm27x_power_init(int ac, int usb) +{ + palm_ac_state = ac; + palm_usb_state = usb; + platform_device_register(&palm27x_power_supply); +} +#endif + +/****************************************************************************** + * Core power regulator + ******************************************************************************/ +#if defined(CONFIG_REGULATOR_MAX1586) || \ + defined(CONFIG_REGULATOR_MAX1586_MODULE) +static struct regulator_consumer_supply palm27x_max1587a_consumers[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +static struct regulator_init_data palm27x_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 = palm27x_max1587a_consumers, + .num_consumer_supplies = ARRAY_SIZE(palm27x_max1587a_consumers), +}; + +static struct max1586_subdev_data palm27x_max1587a_subdevs[] = { + { + .name = "vcc_core", + .id = MAX1586_V3, + .platform_data = &palm27x_max1587a_v3_info, + } +}; + +static struct max1586_platform_data palm27x_max1587a_info = { + .subdevs = palm27x_max1587a_subdevs, + .num_subdevs = ARRAY_SIZE(palm27x_max1587a_subdevs), + .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */ +}; + +static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = { + { + I2C_BOARD_INFO("max1586", 0x14), + .platform_data = &palm27x_max1587a_info, + }, +}; + +static struct i2c_pxa_platform_data palm27x_i2c_power_info = { + .use_pio = 1, +}; + +void __init palm27x_pmic_init(void) +{ + i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); + pxa27x_set_i2c_power_info(&palm27x_i2c_power_info); +} +#endif diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c new file mode 100644 index 00000000000..cf210b11ffc --- /dev/null +++ b/arch/arm/mach-pxa/palmld.c @@ -0,0 +1,357 @@ +/* + * Hardware definitions for Palm LifeDrive + * + * Author: Marek Vasut <marek.vasut@gmail.com> + * + * Based on work of: + * Alex Osborne <ato@meshy.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. + * + * (find more info at www.hackndev.com) + * + */ + +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/wm97xx.h> +#include <linux/power_supply.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 <mach/pxa27x.h> +#include <mach/audio.h> +#include <mach/palmld.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <linux/platform_data/asoc-palm27x.h> +#include <mach/palm27x.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmld_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, + GPIO14_GPIO, /* SD detect */ + GPIO114_GPIO, /* SD power */ + GPIO116_GPIO, /* SD r/o switch */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO89_AC97_SYSCLK, + GPIO95_AC97_nRESET, + + /* IrDA */ + GPIO108_GPIO, /* ir disable */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* MATRIX 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, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* GPIO KEYS */ + GPIO10_GPIO, /* hotsync button */ + GPIO12_GPIO, /* power switch */ + GPIO15_GPIO, /* lock switch */ + + /* LEDs */ + GPIO52_GPIO, /* green led */ + GPIO94_GPIO, /* orange led */ + + /* PCMCIA */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO79_PSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO36_GPIO, /* wifi power */ + GPIO38_GPIO, /* wifi ready */ + GPIO81_GPIO, /* wifi reset */ + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO39_FFUART_TXD, + + /* HDD */ + GPIO98_GPIO, /* HDD reset */ + GPIO115_GPIO, /* HDD power */ + + /* MISC */ + GPIO13_GPIO, /* earphone detect */ +}; + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition palmld_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct physmap_flash_data palmld_flash_data[] = { + { + .width = 2, /* bankwidth in bytes */ + .parts = palmld_partitions, + .nr_parts = ARRAY_SIZE(palmld_partitions) + } +}; + +static struct resource palmld_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_4M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device palmld_flash = { + .name = "physmap-flash", + .id = 0, + .resource = &palmld_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = palmld_flash_data, + }, +}; + +static void __init palmld_nor_init(void) +{ + platform_device_register(&palmld_flash); +} +#else +static inline void palmld_nor_init(void) {} +#endif + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static const unsigned int palmld_matrix_keys[] = { + KEY(0, 1, KEY_F2), + KEY(0, 2, KEY_UP), + + KEY(1, 0, KEY_F3), + KEY(1, 1, KEY_F4), + KEY(1, 2, KEY_RIGHT), + + KEY(2, 0, KEY_F1), + KEY(2, 1, KEY_F5), + KEY(2, 2, KEY_DOWN), + + KEY(3, 0, KEY_F6), + KEY(3, 1, KEY_ENTER), + KEY(3, 2, KEY_LEFT), +}; + +static struct matrix_keymap_data palmld_matrix_keymap_data = { + .keymap = palmld_matrix_keys, + .keymap_size = ARRAY_SIZE(palmld_matrix_keys), +}; + +static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = { + .matrix_key_rows = 4, + .matrix_key_cols = 3, + .matrix_keymap_data = &palmld_matrix_keymap_data, + + .debounce_interval = 30, +}; + +static void __init palmld_kpc_init(void) +{ + pxa_set_keypad_info(&palmld_keypad_platform_data); +} +#else +static inline void palmld_kpc_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button palmld_pxa_buttons[] = { + {KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" }, + {KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" }, + {KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" }, +}; + +static struct gpio_keys_platform_data palmld_pxa_keys_data = { + .buttons = palmld_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmld_pxa_buttons), +}; + +static struct platform_device palmld_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmld_pxa_keys_data, + }, +}; + +static void __init palmld_keys_init(void) +{ + platform_device_register(&palmld_pxa_keys); +} +#else +static inline void palmld_keys_init(void) {} +#endif + +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led gpio_leds[] = { +{ + .name = "palmld:green:led", + .default_trigger = "none", + .gpio = GPIO_NR_PALMLD_LED_GREEN, +}, { + .name = "palmld:amber:led", + .default_trigger = "none", + .gpio = GPIO_NR_PALMLD_LED_AMBER, +}, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device palmld_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + } +}; + +static void __init palmld_leds_init(void) +{ + platform_device_register(&palmld_leds); +} +#else +static inline void palmld_leds_init(void) {} +#endif + +/****************************************************************************** + * HDD + ******************************************************************************/ +#if defined(CONFIG_PATA_PALMLD) || defined(CONFIG_PATA_PALMLD_MODULE) +static struct platform_device palmld_ide_device = { + .name = "pata_palmld", + .id = -1, +}; + +static void __init palmld_ide_init(void) +{ + platform_device_register(&palmld_ide_device); +} +#else +static inline void palmld_ide_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static struct map_desc palmld_io_desc[] __initdata = { +{ + .virtual = PALMLD_IDE_VIRT, + .pfn = __phys_to_pfn(PALMLD_IDE_PHYS), + .length = PALMLD_IDE_SIZE, + .type = MT_DEVICE +}, +{ + .virtual = PALMLD_USB_VIRT, + .pfn = __phys_to_pfn(PALMLD_USB_PHYS), + .length = PALMLD_USB_SIZE, + .type = MT_DEVICE +}, +}; + +static void __init palmld_map_io(void) +{ + pxa27x_map_io(); + iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc)); +} + +static void __init palmld_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + palm27x_mmc_init(GPIO_NR_PALMLD_SD_DETECT_N, GPIO_NR_PALMLD_SD_READONLY, + GPIO_NR_PALMLD_SD_POWER, 0); + palm27x_pm_init(PALMLD_STR_BASE); + palm27x_lcd_init(-1, &palm_320x480_lcd_mode); + palm27x_irda_init(GPIO_NR_PALMLD_IR_DISABLE); + palm27x_ac97_init(PALMLD_BAT_MIN_VOLTAGE, PALMLD_BAT_MAX_VOLTAGE, + GPIO_NR_PALMLD_EARPHONE_DETECT, 95); + palm27x_pwm_init(GPIO_NR_PALMLD_BL_POWER, GPIO_NR_PALMLD_LCD_POWER); + palm27x_power_init(GPIO_NR_PALMLD_POWER_DETECT, + GPIO_NR_PALMLD_USB_DETECT_N); + palm27x_pmic_init(); + palmld_kpc_init(); + palmld_keys_init(); + palmld_nor_init(); + palmld_leds_init(); + palmld_ide_init(); +} + +MACHINE_START(PALMLD, "Palm LifeDrive") + .atag_offset = 0x100, + .map_io = palmld_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = palmld_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c new file mode 100644 index 00000000000..3ed9b029428 --- /dev/null +++ b/arch/arm/mach-pxa/palmt5.c @@ -0,0 +1,218 @@ +/* + * Hardware definitions for Palm Tungsten|T5 + * + * Author: Marek Vasut <marek.vasut@gmail.com> + * + * Based on work of: + * Ales Snuparek <snuparek@atlas.cz> + * Justin Kendrick <twilightsentry@gmail.com> + * RichardT5 <richard_t5@users.sourceforge.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. + * + * (find more info at www.hackndev.com) + * + */ + +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/memblock.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/wm97xx.h> +#include <linux/power_supply.h> +#include <linux/usb/gpio_vbus.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa27x.h> +#include <mach/audio.h> +#include <mach/palmt5.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <mach/udc.h> +#include <linux/platform_data/asoc-palm27x.h> +#include <mach/palm27x.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmt5_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, + GPIO14_GPIO, /* SD detect */ + GPIO114_GPIO, /* SD power */ + GPIO115_GPIO, /* SD r/o switch */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO89_AC97_SYSCLK, + GPIO95_AC97_nRESET, + + /* IrDA */ + GPIO40_GPIO, /* ir disable */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* USB */ + GPIO15_GPIO, /* usb detect */ + GPIO93_GPIO, /* usb power */ + + /* MATRIX 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, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO39_FFUART_TXD, + + /* MISC */ + GPIO10_GPIO, /* hotsync button */ + GPIO90_GPIO, /* power detect */ + GPIO107_GPIO, /* earphone detect */ +}; + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static const unsigned int palmt5_matrix_keys[] = { + KEY(0, 0, KEY_POWER), + KEY(0, 1, KEY_F1), + KEY(0, 2, KEY_ENTER), + + KEY(1, 0, KEY_F2), + KEY(1, 1, KEY_F3), + KEY(1, 2, KEY_F4), + + KEY(2, 0, KEY_UP), + KEY(2, 2, KEY_DOWN), + + KEY(3, 0, KEY_RIGHT), + KEY(3, 2, KEY_LEFT), +}; + +static struct matrix_keymap_data palmt5_matrix_keymap_data = { + .keymap = palmt5_matrix_keys, + .keymap_size = ARRAY_SIZE(palmt5_matrix_keys), +}; + +static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = { + .matrix_key_rows = 4, + .matrix_key_cols = 3, + .matrix_keymap_data = &palmt5_matrix_keymap_data, + + .debounce_interval = 30, +}; + +static void __init palmt5_kpc_init(void) +{ + pxa_set_keypad_info(&palmt5_keypad_platform_data); +} +#else +static inline void palmt5_kpc_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button palmt5_pxa_buttons[] = { + {KEY_F8, GPIO_NR_PALMT5_HOTSYNC_BUTTON_N, 1, "HotSync Button" }, +}; + +static struct gpio_keys_platform_data palmt5_pxa_keys_data = { + .buttons = palmt5_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmt5_pxa_buttons), +}; + +static struct platform_device palmt5_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmt5_pxa_keys_data, + }, +}; + +static void __init palmt5_keys_init(void) +{ + platform_device_register(&palmt5_pxa_keys); +} +#else +static inline void palmt5_keys_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init palmt5_reserve(void) +{ + memblock_reserve(0xa0200000, 0x1000); +} + +static void __init palmt5_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + palm27x_mmc_init(GPIO_NR_PALMT5_SD_DETECT_N, GPIO_NR_PALMT5_SD_READONLY, + GPIO_NR_PALMT5_SD_POWER, 0); + palm27x_pm_init(PALMT5_STR_BASE); + palm27x_lcd_init(-1, &palm_320x480_lcd_mode); + palm27x_udc_init(GPIO_NR_PALMT5_USB_DETECT_N, + GPIO_NR_PALMT5_USB_PULLUP, 1); + palm27x_irda_init(GPIO_NR_PALMT5_IR_DISABLE); + palm27x_ac97_init(PALMT5_BAT_MIN_VOLTAGE, PALMT5_BAT_MAX_VOLTAGE, + GPIO_NR_PALMT5_EARPHONE_DETECT, 95); + palm27x_pwm_init(GPIO_NR_PALMT5_BL_POWER, GPIO_NR_PALMT5_LCD_POWER); + palm27x_power_init(GPIO_NR_PALMT5_POWER_DETECT, -1); + palm27x_pmic_init(); + palmt5_kpc_init(); + palmt5_keys_init(); +} + +MACHINE_START(PALMT5, "Palm Tungsten|T5") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .reserve = palmt5_reserve, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = palmt5_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c new file mode 100644 index 00000000000..7691c974ca4 --- /dev/null +++ b/arch/arm/mach-pxa/palmtc.c @@ -0,0 +1,515 @@ +/* + * linux/arch/arm/mach-pxa/palmtc.c + * + * Support for the Palm Tungsten|C + * + * Author: Marek Vasut <marek.vasut@gmail.com> + * + * Based on work of: + * Petr Blaha <p3t3@centrum.cz> + * Chetan S. Kumar <shivakumar.chetan@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/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/input.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/input/matrix_keypad.h> +#include <linux/ucb1400.h> +#include <linux/power_supply.h> +#include <linux/gpio_keys.h> +#include <linux/mtd/physmap.h> +#include <linux/usb/gpio_vbus.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa25x.h> +#include <mach/audio.h> +#include <mach/palmtc.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <mach/udc.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmtc_pin_config[] __initdata = { + /* MMC */ + GPIO6_MMC_CLK, + GPIO8_MMC_CS0, + GPIO12_GPIO, /* detect */ + GPIO32_GPIO, /* power */ + GPIO54_GPIO, /* r/o switch */ + + /* PCMCIA */ + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO49_nPWE, + GPIO48_nPOE, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO57_nIOIS16, + GPIO56_nPWAIT, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* IrDA */ + GPIO45_GPIO, /* ir disable */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* PWM */ + GPIO17_PWM1_OUT, + + /* USB */ + GPIO4_GPIO, /* detect */ + GPIO36_GPIO, /* pullup */ + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* MATRIX KEYPAD */ + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 0 */ + GPIO9_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 1 */ + GPIO10_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 2 */ + GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 3 */ + GPIO18_GPIO | MFP_LPM_DRIVE_LOW, /* out 0 */ + GPIO19_GPIO | MFP_LPM_DRIVE_LOW, /* out 1 */ + GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* out 2 */ + GPIO21_GPIO | MFP_LPM_DRIVE_LOW, /* out 3 */ + GPIO22_GPIO | MFP_LPM_DRIVE_LOW, /* out 4 */ + GPIO23_GPIO | MFP_LPM_DRIVE_LOW, /* out 5 */ + GPIO24_GPIO | MFP_LPM_DRIVE_LOW, /* out 6 */ + GPIO25_GPIO | MFP_LPM_DRIVE_LOW, /* out 7 */ + GPIO26_GPIO | MFP_LPM_DRIVE_LOW, /* out 8 */ + GPIO27_GPIO | MFP_LPM_DRIVE_LOW, /* out 9 */ + GPIO79_GPIO | MFP_LPM_DRIVE_LOW, /* out 10 */ + GPIO80_GPIO | MFP_LPM_DRIVE_LOW, /* out 11 */ + + /* PXA GPIO KEYS */ + GPIO7_GPIO | WAKEUP_ON_EDGE_BOTH, /* hotsync button on cradle */ + + /* MISC */ + GPIO1_RST, /* reset */ + GPIO2_GPIO, /* earphone detect */ + GPIO16_GPIO, /* backlight switch */ +}; + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data palmtc_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_power = GPIO_NR_PALMTC_SD_POWER, + .gpio_card_ro = GPIO_NR_PALMTC_SD_READONLY, + .gpio_card_detect = GPIO_NR_PALMTC_SD_DETECT_N, + .detect_delay_ms = 200, +}; + +static void __init palmtc_mmc_init(void) +{ + pxa_set_mci_info(&palmtc_mci_platform_data); +} +#else +static inline void palmtc_mmc_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button palmtc_pxa_buttons[] = { + {KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1}, +}; + +static struct gpio_keys_platform_data palmtc_pxa_keys_data = { + .buttons = palmtc_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmtc_pxa_buttons), +}; + +static struct platform_device palmtc_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmtc_pxa_keys_data, + }, +}; + +static void __init palmtc_keys_init(void) +{ + platform_device_register(&palmtc_pxa_keys); +} +#else +static inline void palmtc_keys_init(void) {} +#endif + +/****************************************************************************** + * Backlight + ******************************************************************************/ +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static struct platform_pwm_backlight_data palmtc_backlight_data = { + .pwm_id = 1, + .max_brightness = PALMTC_MAX_INTENSITY, + .dft_brightness = PALMTC_MAX_INTENSITY, + .pwm_period_ns = PALMTC_PERIOD_NS, + .enable_gpio = GPIO_NR_PALMTC_BL_POWER, +}; + +static struct platform_device palmtc_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa25x_device_pwm1.dev, + .platform_data = &palmtc_backlight_data, + }, +}; + +static void __init palmtc_pwm_init(void) +{ + platform_device_register(&palmtc_backlight); +} +#else +static inline void palmtc_pwm_init(void) {} +#endif + +/****************************************************************************** + * IrDA + ******************************************************************************/ +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) +static struct pxaficp_platform_data palmtc_ficp_platform_data = { + .gpio_pwdown = GPIO_NR_PALMTC_IR_DISABLE, + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; + +static void __init palmtc_irda_init(void) +{ + pxa_set_ficp_info(&palmtc_ficp_platform_data); +} +#else +static inline void palmtc_irda_init(void) {} +#endif + +/****************************************************************************** + * Keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE) +static const uint32_t palmtc_matrix_keys[] = { + KEY(0, 0, KEY_F1), + KEY(0, 1, KEY_X), + KEY(0, 2, KEY_POWER), + KEY(0, 3, KEY_TAB), + KEY(0, 4, KEY_A), + KEY(0, 5, KEY_Q), + KEY(0, 6, KEY_LEFTSHIFT), + KEY(0, 7, KEY_Z), + KEY(0, 8, KEY_S), + KEY(0, 9, KEY_W), + KEY(0, 10, KEY_E), + KEY(0, 11, KEY_UP), + + KEY(1, 0, KEY_F2), + KEY(1, 1, KEY_DOWN), + KEY(1, 3, KEY_D), + KEY(1, 4, KEY_C), + KEY(1, 5, KEY_F), + KEY(1, 6, KEY_R), + KEY(1, 7, KEY_SPACE), + KEY(1, 8, KEY_V), + KEY(1, 9, KEY_G), + KEY(1, 10, KEY_T), + KEY(1, 11, KEY_LEFT), + + KEY(2, 0, KEY_F3), + KEY(2, 1, KEY_LEFTCTRL), + KEY(2, 3, KEY_H), + KEY(2, 4, KEY_Y), + KEY(2, 5, KEY_N), + KEY(2, 6, KEY_J), + KEY(2, 7, KEY_U), + KEY(2, 8, KEY_M), + KEY(2, 9, KEY_K), + KEY(2, 10, KEY_I), + KEY(2, 11, KEY_RIGHT), + + KEY(3, 0, KEY_F4), + KEY(3, 1, KEY_ENTER), + KEY(3, 3, KEY_DOT), + KEY(3, 4, KEY_L), + KEY(3, 5, KEY_O), + KEY(3, 6, KEY_LEFTALT), + KEY(3, 7, KEY_ENTER), + KEY(3, 8, KEY_BACKSPACE), + KEY(3, 9, KEY_P), + KEY(3, 10, KEY_B), + KEY(3, 11, KEY_FN), +}; + +const struct matrix_keymap_data palmtc_keymap_data = { + .keymap = palmtc_matrix_keys, + .keymap_size = ARRAY_SIZE(palmtc_matrix_keys), +}; + +static const unsigned int palmtc_keypad_row_gpios[] = { + 0, 9, 10, 11 +}; + +static const unsigned int palmtc_keypad_col_gpios[] = { + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80 +}; + +static struct matrix_keypad_platform_data palmtc_keypad_platform_data = { + .keymap_data = &palmtc_keymap_data, + .row_gpios = palmtc_keypad_row_gpios, + .num_row_gpios = ARRAY_SIZE(palmtc_keypad_row_gpios), + .col_gpios = palmtc_keypad_col_gpios, + .num_col_gpios = ARRAY_SIZE(palmtc_keypad_col_gpios), + .active_low = 1, + + .debounce_ms = 20, + .col_scan_delay_us = 5, +}; + +static struct platform_device palmtc_keyboard = { + .name = "matrix-keypad", + .id = -1, + .dev = { + .platform_data = &palmtc_keypad_platform_data, + }, +}; +static void __init palmtc_mkp_init(void) +{ + platform_device_register(&palmtc_keyboard); +} +#else +static inline void palmtc_mkp_init(void) {} +#endif + +/****************************************************************************** + * UDC + ******************************************************************************/ +#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE) +static struct gpio_vbus_mach_info palmtc_udc_info = { + .gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N, + .gpio_vbus_inverted = 1, + .gpio_pullup = GPIO_NR_PALMTC_USB_POWER, +}; + +static struct platform_device palmtc_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &palmtc_udc_info, + }, +}; + +static void __init palmtc_udc_init(void) +{ + platform_device_register(&palmtc_gpio_vbus); +}; +#else +static inline void palmtc_udc_init(void) {} +#endif + +/****************************************************************************** + * Touchscreen / Battery / GPIO-extender + ******************************************************************************/ +#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ + defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static struct platform_device palmtc_ucb1400_device = { + .name = "ucb1400_core", + .id = -1, +}; + +static void __init palmtc_ts_init(void) +{ + pxa_set_ac97_info(NULL); + platform_device_register(&palmtc_ucb1400_device); +} +#else +static inline void palmtc_ts_init(void) {} +#endif + +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led palmtc_gpio_leds[] = { +{ + .name = "palmtc:green:user", + .default_trigger = "none", + .gpio = GPIO_NR_PALMTC_LED_POWER, + .active_low = 1, +}, { + .name = "palmtc:vibra:vibra", + .default_trigger = "none", + .gpio = GPIO_NR_PALMTC_VIBRA_POWER, + .active_low = 1, +} + +}; + +static struct gpio_led_platform_data palmtc_gpio_led_info = { + .leds = palmtc_gpio_leds, + .num_leds = ARRAY_SIZE(palmtc_gpio_leds), +}; + +static struct platform_device palmtc_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &palmtc_gpio_led_info, + } +}; + +static void __init palmtc_leds_init(void) +{ + platform_device_register(&palmtc_leds); +} +#else +static inline void palmtc_leds_init(void) {} +#endif + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct resource palmtc_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_16M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct mtd_partition palmtc_flash_parts[] = { + { + .name = "U-Boot Bootloader", + .offset = 0x0, + .size = 0x40000, + }, + { + .name = "Linux Kernel", + .offset = 0x40000, + .size = 0x2c0000, + }, + { + .name = "Filesystem", + .offset = 0x300000, + .size = 0xcc0000, + }, + { + .name = "U-Boot Environment", + .offset = 0xfc0000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data palmtc_flash_data = { + .width = 4, + .parts = palmtc_flash_parts, + .nr_parts = ARRAY_SIZE(palmtc_flash_parts), +}; + +static struct platform_device palmtc_flash = { + .name = "physmap-flash", + .id = -1, + .resource = &palmtc_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &palmtc_flash_data, + }, +}; + +static void __init palmtc_nor_init(void) +{ + platform_device_register(&palmtc_flash); +} +#else +static inline void palmtc_nor_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info palmtc_lcd_modes[] = { + { + .pixclock = 115384, + .xres = 320, + .yres = 320, + .bpp = 16, + + .left_margin = 27, + .right_margin = 7, + .upper_margin = 7, + .lower_margin = 8, + + .hsync_len = 6, + .vsync_len = 1, + }, +}; + +static struct pxafb_mach_info palmtc_lcd_screen = { + .modes = palmtc_lcd_modes, + .num_modes = ARRAY_SIZE(palmtc_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +static void __init palmtc_lcd_init(void) +{ + pxa_set_fb_info(NULL, &palmtc_lcd_screen); +} +#else +static inline void palmtc_lcd_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init palmtc_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + pxa_set_hwuart_info(NULL); + + palmtc_mmc_init(); + palmtc_keys_init(); + palmtc_pwm_init(); + palmtc_irda_init(); + palmtc_mkp_init(); + palmtc_udc_init(); + palmtc_ts_init(); + palmtc_nor_init(); + palmtc_lcd_init(); + palmtc_leds_init(); +}; + +MACHINE_START(PALMTC, "Palm Tungsten|C") + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = palmtc_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c new file mode 100644 index 00000000000..956fd24ee6f --- /dev/null +++ b/arch/arm/mach-pxa/palmte2.c @@ -0,0 +1,370 @@ +/* + * Hardware definitions for Palm Tungsten|E2 + * + * Author: + * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com> + * + * Rewrite for mainline: + * 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. + * + * (find more info at www.hackndev.com) + * + */ + +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/wm97xx.h> +#include <linux/power_supply.h> +#include <linux/usb/gpio_vbus.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa25x.h> +#include <mach/audio.h> +#include <mach/palmte2.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <mach/udc.h> +#include <linux/platform_data/asoc-palm27x.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmte2_pin_config[] __initdata = { + /* MMC */ + GPIO6_MMC_CLK, + GPIO8_MMC_CS0, + GPIO10_GPIO, /* SD detect */ + GPIO55_GPIO, /* SD power */ + GPIO51_GPIO, /* SD r/o switch */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* USB */ + GPIO15_GPIO, /* usb detect */ + GPIO53_GPIO, /* usb power */ + + /* IrDA */ + GPIO48_GPIO, /* ir disable */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* GPIO KEYS */ + GPIO5_GPIO, /* notes */ + GPIO7_GPIO, /* tasks */ + GPIO11_GPIO, /* calendar */ + GPIO13_GPIO, /* contacts */ + GPIO14_GPIO, /* center */ + GPIO19_GPIO, /* left */ + GPIO20_GPIO, /* right */ + GPIO21_GPIO, /* down */ + GPIO22_GPIO, /* up */ + + /* MISC */ + GPIO1_RST, /* reset */ + GPIO4_GPIO, /* Hotsync button */ + GPIO9_GPIO, /* power detect */ + GPIO15_GPIO, /* earphone detect */ + GPIO37_GPIO, /* LCD power */ + GPIO56_GPIO, /* Backlight power */ +}; + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +static struct pxamci_platform_data palmte2_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = GPIO_NR_PALMTE2_SD_DETECT_N, + .gpio_card_ro = GPIO_NR_PALMTE2_SD_READONLY, + .gpio_power = GPIO_NR_PALMTE2_SD_POWER, +}; + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +static struct gpio_keys_button palmte2_pxa_buttons[] = { + {KEY_F1, GPIO_NR_PALMTE2_KEY_CONTACTS, 1, "Contacts" }, + {KEY_F2, GPIO_NR_PALMTE2_KEY_CALENDAR, 1, "Calendar" }, + {KEY_F3, GPIO_NR_PALMTE2_KEY_TASKS, 1, "Tasks" }, + {KEY_F4, GPIO_NR_PALMTE2_KEY_NOTES, 1, "Notes" }, + {KEY_ENTER, GPIO_NR_PALMTE2_KEY_CENTER, 1, "Center" }, + {KEY_LEFT, GPIO_NR_PALMTE2_KEY_LEFT, 1, "Left" }, + {KEY_RIGHT, GPIO_NR_PALMTE2_KEY_RIGHT, 1, "Right" }, + {KEY_DOWN, GPIO_NR_PALMTE2_KEY_DOWN, 1, "Down" }, + {KEY_UP, GPIO_NR_PALMTE2_KEY_UP, 1, "Up" }, +}; + +static struct gpio_keys_platform_data palmte2_pxa_keys_data = { + .buttons = palmte2_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmte2_pxa_buttons), +}; + +static struct platform_device palmte2_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmte2_pxa_keys_data, + }, +}; +#endif + +/****************************************************************************** + * Backlight + ******************************************************************************/ +static struct gpio palmte_bl_gpios[] = { + { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" }, + { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" }, +}; + +static int palmte2_backlight_init(struct device *dev) +{ + return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios)); +} + +static int palmte2_backlight_notify(struct device *dev, int brightness) +{ + gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness); + gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness); + return brightness; +} + +static void palmte2_backlight_exit(struct device *dev) +{ + gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios)); +} + +static struct platform_pwm_backlight_data palmte2_backlight_data = { + .pwm_id = 0, + .max_brightness = PALMTE2_MAX_INTENSITY, + .dft_brightness = PALMTE2_MAX_INTENSITY, + .pwm_period_ns = PALMTE2_PERIOD_NS, + .enable_gpio = -1, + .init = palmte2_backlight_init, + .notify = palmte2_backlight_notify, + .exit = palmte2_backlight_exit, +}; + +static struct platform_device palmte2_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa25x_device_pwm0.dev, + .platform_data = &palmte2_backlight_data, + }, +}; + +/****************************************************************************** + * IrDA + ******************************************************************************/ +static struct pxaficp_platform_data palmte2_ficp_platform_data = { + .gpio_pwdown = GPIO_NR_PALMTE2_IR_DISABLE, + .transceiver_cap = IR_SIRMODE | IR_OFF, +}; + +/****************************************************************************** + * UDC + ******************************************************************************/ +static struct gpio_vbus_mach_info palmte2_udc_info = { + .gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N, + .gpio_vbus_inverted = 1, + .gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP, +}; + +static struct platform_device palmte2_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &palmte2_udc_info, + }, +}; + +/****************************************************************************** + * Power supply + ******************************************************************************/ +static int power_supply_init(struct device *dev) +{ + int ret; + + ret = gpio_request(GPIO_NR_PALMTE2_POWER_DETECT, "CABLE_STATE_AC"); + if (ret) + goto err1; + ret = gpio_direction_input(GPIO_NR_PALMTE2_POWER_DETECT); + if (ret) + goto err2; + + return 0; + +err2: + gpio_free(GPIO_NR_PALMTE2_POWER_DETECT); +err1: + return ret; +} + +static int palmte2_is_ac_online(void) +{ + return gpio_get_value(GPIO_NR_PALMTE2_POWER_DETECT); +} + +static void power_supply_exit(struct device *dev) +{ + gpio_free(GPIO_NR_PALMTE2_POWER_DETECT); +} + +static char *palmte2_supplicants[] = { + "main-battery", +}; + +static struct pda_power_pdata power_supply_info = { + .init = power_supply_init, + .is_ac_online = palmte2_is_ac_online, + .exit = power_supply_exit, + .supplied_to = palmte2_supplicants, + .num_supplicants = ARRAY_SIZE(palmte2_supplicants), +}; + +static struct platform_device power_supply = { + .name = "pda-power", + .id = -1, + .dev = { + .platform_data = &power_supply_info, + }, +}; + +/****************************************************************************** + * WM97xx audio, battery + ******************************************************************************/ +static struct wm97xx_batt_pdata palmte2_batt_pdata = { + .batt_aux = WM97XX_AUX_ID3, + .temp_aux = WM97XX_AUX_ID2, + .charge_gpio = -1, + .max_voltage = PALMTE2_BAT_MAX_VOLTAGE, + .min_voltage = PALMTE2_BAT_MIN_VOLTAGE, + .batt_mult = 1000, + .batt_div = 414, + .temp_mult = 1, + .temp_div = 1, + .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO, + .batt_name = "main-batt", +}; + +static struct wm97xx_pdata palmte2_wm97xx_pdata = { + .batt_pdata = &palmte2_batt_pdata, +}; + +static pxa2xx_audio_ops_t palmte2_ac97_pdata = { + .codec_pdata = { &palmte2_wm97xx_pdata, }, +}; + +static struct palm27x_asoc_info palmte2_asoc_pdata = { + .jack_gpio = GPIO_NR_PALMTE2_EARPHONE_DETECT, +}; + +static struct platform_device palmte2_asoc = { + .name = "palm27x-asoc", + .id = -1, + .dev = { + .platform_data = &palmte2_asoc_pdata, + }, +}; + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +static struct pxafb_mode_info palmte2_lcd_modes[] = { +{ + .pixclock = 77757, + .xres = 320, + .yres = 320, + .bpp = 16, + + .left_margin = 28, + .right_margin = 7, + .upper_margin = 7, + .lower_margin = 5, + + .hsync_len = 4, + .vsync_len = 1, +}, +}; + +static struct pxafb_mach_info palmte2_lcd_screen = { + .modes = palmte2_lcd_modes, + .num_modes = ARRAY_SIZE(palmte2_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static struct platform_device *devices[] __initdata = { +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + &palmte2_pxa_keys, +#endif + &palmte2_backlight, + &power_supply, + &palmte2_asoc, + &palmte2_gpio_vbus, +}; + +/* setup udc GPIOs initial state */ +static void __init palmte2_udc_init(void) +{ + if (!gpio_request(GPIO_NR_PALMTE2_USB_PULLUP, "UDC Vbus")) { + gpio_direction_output(GPIO_NR_PALMTE2_USB_PULLUP, 1); + gpio_free(GPIO_NR_PALMTE2_USB_PULLUP); + } +} + +static void __init palmte2_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa_set_fb_info(NULL, &palmte2_lcd_screen); + pxa_set_mci_info(&palmte2_mci_platform_data); + palmte2_udc_init(); + pxa_set_ac97_info(&palmte2_ac97_pdata); + pxa_set_ficp_info(&palmte2_ficp_platform_data); + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +MACHINE_START(PALMTE2, "Palm Tungsten|E2") + .atag_offset = 0x100, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = palmte2_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c new file mode 100644 index 00000000000..d8b937c870d --- /dev/null +++ b/arch/arm/mach-pxa/palmtreo.c @@ -0,0 +1,560 @@ +/* + * Hardware definitions for Palm Treo smartphones + * + * currently supported: + * Palm Treo 680 (GSM) + * Palm Centro 685 (GSM) + * + * Author: Tomas Cech <sleep_walker@suse.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. + * + * (find more info at www.hackndev.com) + * + */ + +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/memblock.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/power_supply.h> +#include <linux/w1-gpio.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa27x.h> +#include <mach/pxa27x-udc.h> +#include <mach/audio.h> +#include <mach/palmtreo.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <mach/udc.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/pxa2xx-regs.h> +#include <linux/platform_data/asoc-palm27x.h> +#include <linux/platform_data/camera-pxa.h> +#include <mach/palm27x.h> + +#include <sound/pxa2xx-lib.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long treo_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, + GPIO113_GPIO, /* SD detect */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO89_AC97_SYSCLK, + GPIO95_AC97_nRESET, + + /* IrDA */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* USB */ + GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* usb detect */ + + /* MATRIX KEYPAD */ + GPIO101_KP_MKIN_1, + GPIO102_KP_MKIN_2, + GPIO97_KP_MKIN_3, + GPIO98_KP_MKIN_4, + GPIO91_KP_MKIN_6, + GPIO13_KP_MKIN_7, + GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, + GPIO96_KP_MKOUT_6, + GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, /* Hotsync button */ + + /* Quick Capture Interface */ + GPIO84_CIF_FV, + GPIO85_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, + + /* GSM */ + GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH, /* GSM host wake up */ + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + GPIO39_FFUART_TXD, + GPIO41_FFUART_RTS, + + /* MISC. */ + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* external power detect */ + GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH, /* silent switch */ + GPIO116_GPIO, /* headphone detect */ + GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* bluetooth host wake up */ +}; + +#ifdef CONFIG_MACH_TREO680 +static unsigned long treo680_pin_config[] __initdata = { + GPIO33_GPIO, /* SD read only */ + + /* MATRIX KEYPAD - different wake up source */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO99_KP_MKIN_5, + + /* LCD... L_BIAS alt fn not configured on Treo680; is GPIO instead */ + GPIOxx_LCD_16BPP, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, +}; +#endif /* CONFIG_MACH_TREO680 */ + +#ifdef CONFIG_MACH_CENTRO +static unsigned long centro685_pin_config[] __initdata = { + /* Bluetooth attached to BT UART*/ + MFP_CFG_OUT(GPIO80, AF0, DRIVE_LOW), /* power: LOW = off */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* MATRIX KEYPAD - different wake up source */ + GPIO100_KP_MKIN_0, + GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, +}; +#endif /* CONFIG_MACH_CENTRO */ + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if IS_ENABLED(CONFIG_KEYBOARD_PXA27x) +static const unsigned int treo680_matrix_keys[] = { + KEY(0, 0, KEY_F8), /* Red/Off/Power */ + KEY(0, 1, KEY_LEFT), + KEY(0, 2, KEY_LEFTCTRL), /* Alternate */ + KEY(0, 3, KEY_L), + KEY(0, 4, KEY_A), + KEY(0, 5, KEY_Q), + KEY(0, 6, KEY_P), + + KEY(1, 0, KEY_RIGHTCTRL), /* Menu */ + KEY(1, 1, KEY_RIGHT), + KEY(1, 2, KEY_LEFTSHIFT), /* Left shift */ + KEY(1, 3, KEY_Z), + KEY(1, 4, KEY_S), + KEY(1, 5, KEY_W), + + KEY(2, 0, KEY_F1), /* Phone */ + KEY(2, 1, KEY_UP), + KEY(2, 2, KEY_0), + KEY(2, 3, KEY_X), + KEY(2, 4, KEY_D), + KEY(2, 5, KEY_E), + + KEY(3, 0, KEY_F10), /* Calendar */ + KEY(3, 1, KEY_DOWN), + KEY(3, 2, KEY_SPACE), + KEY(3, 3, KEY_C), + KEY(3, 4, KEY_F), + KEY(3, 5, KEY_R), + + KEY(4, 0, KEY_F12), /* Mail */ + KEY(4, 1, KEY_KPENTER), + KEY(4, 2, KEY_RIGHTALT), /* Alt */ + KEY(4, 3, KEY_V), + KEY(4, 4, KEY_G), + KEY(4, 5, KEY_T), + + KEY(5, 0, KEY_F9), /* Home */ + KEY(5, 1, KEY_PAGEUP), /* Side up */ + KEY(5, 2, KEY_DOT), + KEY(5, 3, KEY_B), + KEY(5, 4, KEY_H), + KEY(5, 5, KEY_Y), + + KEY(6, 0, KEY_TAB), /* Side Activate */ + KEY(6, 1, KEY_PAGEDOWN), /* Side down */ + KEY(6, 2, KEY_ENTER), + KEY(6, 3, KEY_N), + KEY(6, 4, KEY_J), + KEY(6, 5, KEY_U), + + KEY(7, 0, KEY_F6), /* Green/Call */ + KEY(7, 1, KEY_O), + KEY(7, 2, KEY_BACKSPACE), + KEY(7, 3, KEY_M), + KEY(7, 4, KEY_K), + KEY(7, 5, KEY_I), +}; + +static const unsigned int centro_matrix_keys[] = { + KEY(0, 0, KEY_F9), /* Home */ + KEY(0, 1, KEY_LEFT), + KEY(0, 2, KEY_LEFTCTRL), /* Alternate */ + KEY(0, 3, KEY_L), + KEY(0, 4, KEY_A), + KEY(0, 5, KEY_Q), + KEY(0, 6, KEY_P), + + KEY(1, 0, KEY_RIGHTCTRL), /* Menu */ + KEY(1, 1, KEY_RIGHT), + KEY(1, 2, KEY_LEFTSHIFT), /* Left shift */ + KEY(1, 3, KEY_Z), + KEY(1, 4, KEY_S), + KEY(1, 5, KEY_W), + + KEY(2, 0, KEY_F1), /* Phone */ + KEY(2, 1, KEY_UP), + KEY(2, 2, KEY_0), + KEY(2, 3, KEY_X), + KEY(2, 4, KEY_D), + KEY(2, 5, KEY_E), + + KEY(3, 0, KEY_F10), /* Calendar */ + KEY(3, 1, KEY_DOWN), + KEY(3, 2, KEY_SPACE), + KEY(3, 3, KEY_C), + KEY(3, 4, KEY_F), + KEY(3, 5, KEY_R), + + KEY(4, 0, KEY_F12), /* Mail */ + KEY(4, 1, KEY_KPENTER), + KEY(4, 2, KEY_RIGHTALT), /* Alt */ + KEY(4, 3, KEY_V), + KEY(4, 4, KEY_G), + KEY(4, 5, KEY_T), + + KEY(5, 0, KEY_F8), /* Red/Off/Power */ + KEY(5, 1, KEY_PAGEUP), /* Side up */ + KEY(5, 2, KEY_DOT), + KEY(5, 3, KEY_B), + KEY(5, 4, KEY_H), + KEY(5, 5, KEY_Y), + + KEY(6, 0, KEY_TAB), /* Side Activate */ + KEY(6, 1, KEY_PAGEDOWN), /* Side down */ + KEY(6, 2, KEY_ENTER), + KEY(6, 3, KEY_N), + KEY(6, 4, KEY_J), + KEY(6, 5, KEY_U), + + KEY(7, 0, KEY_F6), /* Green/Call */ + KEY(7, 1, KEY_O), + KEY(7, 2, KEY_BACKSPACE), + KEY(7, 3, KEY_M), + KEY(7, 4, KEY_K), + KEY(7, 5, KEY_I), +}; + +static struct matrix_keymap_data treo680_matrix_keymap_data = { + .keymap = treo680_matrix_keys, + .keymap_size = ARRAY_SIZE(treo680_matrix_keys), +}; + +static struct matrix_keymap_data centro_matrix_keymap_data = { + .keymap = centro_matrix_keys, + .keymap_size = ARRAY_SIZE(centro_matrix_keys), +}; + +static struct pxa27x_keypad_platform_data treo680_keypad_pdata = { + .matrix_key_rows = 8, + .matrix_key_cols = 7, + .matrix_keymap_data = &treo680_matrix_keymap_data, + .direct_key_map = { KEY_CONNECT }, + .direct_key_num = 1, + + .debounce_interval = 30, +}; + +static void __init palmtreo_kpc_init(void) +{ + static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata; + + if (machine_is_centro()) + data->matrix_keymap_data = ¢ro_matrix_keymap_data; + + pxa_set_keypad_info(&treo680_keypad_pdata); +} +#else +static inline void palmtreo_kpc_init(void) {} +#endif + +/****************************************************************************** + * USB host + ******************************************************************************/ +#if IS_ENABLED(CONFIG_USB_OHCI_HCD) +static struct pxaohci_platform_data treo680_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT3, + .power_budget = 0, +}; + +static void __init palmtreo_uhc_init(void) +{ + if (machine_is_treo680()) + pxa_set_ohci_info(&treo680_ohci_info); +} +#else +static inline void palmtreo_uhc_init(void) {} +#endif + +/****************************************************************************** + * Vibra and LEDs + ******************************************************************************/ +static struct gpio_led treo680_gpio_leds[] = { + { + .name = "treo680:vibra:vibra", + .default_trigger = "none", + .gpio = GPIO_NR_TREO680_VIBRATE_EN, + }, + { + .name = "treo680:green:led", + .default_trigger = "mmc0", + .gpio = GPIO_NR_TREO_GREEN_LED, + }, + { + .name = "treo680:white:keybbl", + .default_trigger = "none", + .gpio = GPIO_NR_TREO680_KEYB_BL, + }, +}; + +static struct gpio_led_platform_data treo680_gpio_led_info = { + .leds = treo680_gpio_leds, + .num_leds = ARRAY_SIZE(treo680_gpio_leds), +}; + +static struct gpio_led centro_gpio_leds[] = { + { + .name = "centro:vibra:vibra", + .default_trigger = "none", + .gpio = GPIO_NR_CENTRO_VIBRATE_EN, + }, + { + .name = "centro:green:led", + .default_trigger = "mmc0", + .gpio = GPIO_NR_TREO_GREEN_LED, + }, + { + .name = "centro:white:keybbl", + .default_trigger = "none", + .active_low = 1, + .gpio = GPIO_NR_CENTRO_KEYB_BL, + }, +}; + +static struct gpio_led_platform_data centro_gpio_led_info = { + .leds = centro_gpio_leds, + .num_leds = ARRAY_SIZE(centro_gpio_leds), +}; + +static struct platform_device palmtreo_leds = { + .name = "leds-gpio", + .id = -1, +}; + +static void __init palmtreo_leds_init(void) +{ + if (machine_is_centro()) + palmtreo_leds.dev.platform_data = ¢ro_gpio_led_info; + else if (machine_is_treo680()) + palmtreo_leds.dev.platform_data = &treo680_gpio_led_info; + + platform_device_register(&palmtreo_leds); +} + +/****************************************************************************** + * diskonchip docg4 flash + ******************************************************************************/ +#if defined(CONFIG_MACH_TREO680) +/* REVISIT: does the centro have this device also? */ +#if IS_ENABLED(CONFIG_MTD_NAND_DOCG4) +static struct resource docg4_resources[] = { + { + .start = 0x00000000, + .end = 0x00001FFF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device treo680_docg4_flash = { + .name = "docg4", + .id = -1, + .resource = docg4_resources, + .num_resources = ARRAY_SIZE(docg4_resources), +}; + +static void __init treo680_docg4_flash_init(void) +{ + platform_device_register(&treo680_docg4_flash); +} +#else +static inline void treo680_docg4_flash_init(void) {} +#endif +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init treo_reserve(void) +{ + memblock_reserve(0xa0000000, 0x1000); + memblock_reserve(0xa2000000, 0x1000); +} + +static void __init palmphone_common_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(treo_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + palm27x_pm_init(TREO_STR_BASE); + palm27x_lcd_init(GPIO_NR_TREO_BL_POWER, &palm_320x320_new_lcd_mode); + palm27x_udc_init(GPIO_NR_TREO_USB_DETECT, GPIO_NR_TREO_USB_PULLUP, 1); + palm27x_irda_init(GPIO_NR_TREO_IR_EN); + palm27x_ac97_init(-1, -1, -1, 95); + palm27x_pwm_init(GPIO_NR_TREO_BL_POWER, -1); + palm27x_power_init(GPIO_NR_TREO_POWER_DETECT, -1); + palm27x_pmic_init(); + palmtreo_kpc_init(); + palmtreo_uhc_init(); + palmtreo_leds_init(); +} + +#ifdef CONFIG_MACH_TREO680 +void __init treo680_gpio_init(void) +{ + unsigned int gpio; + + /* drive all three lcd gpios high initially */ + const unsigned long lcd_flags = GPIOF_INIT_HIGH | GPIOF_DIR_OUT; + + /* + * LCD GPIO initialization... + */ + + /* + * This is likely the power to the lcd. Toggling it low/high appears to + * turn the lcd off/on. Can be toggled after lcd is initialized without + * any apparent adverse effects to the lcd operation. Note that this + * gpio line is used by the lcd controller as the L_BIAS signal, but + * treo680 configures it as gpio. + */ + gpio = GPIO_NR_TREO680_LCD_POWER; + if (gpio_request_one(gpio, lcd_flags, "LCD power") < 0) + goto fail; + + /* + * These two are called "enables", for lack of a better understanding. + * If either of these are toggled after the lcd is initialized, the + * image becomes degraded. N.B. The IPL shipped with the treo + * configures GPIO_NR_TREO680_LCD_EN_N as output and drives it high. If + * the IPL is ever reprogrammed, this initialization may be need to be + * revisited. + */ + gpio = GPIO_NR_TREO680_LCD_EN; + if (gpio_request_one(gpio, lcd_flags, "LCD enable") < 0) + goto fail; + gpio = GPIO_NR_TREO680_LCD_EN_N; + if (gpio_request_one(gpio, lcd_flags, "LCD enable_n") < 0) + goto fail; + + /* driving this low turns LCD on */ + gpio_set_value(GPIO_NR_TREO680_LCD_EN_N, 0); + + return; + fail: + pr_err("gpio %d initialization failed\n", gpio); + gpio_free(GPIO_NR_TREO680_LCD_POWER); + gpio_free(GPIO_NR_TREO680_LCD_EN); + gpio_free(GPIO_NR_TREO680_LCD_EN_N); +} + +static void __init treo680_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config)); + palmphone_common_init(); + treo680_gpio_init(); + palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY, + GPIO_NR_TREO680_SD_POWER, 0); + treo680_docg4_flash_init(); +} +#endif + +#ifdef CONFIG_MACH_CENTRO +static void __init centro_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config)); + palmphone_common_init(); + palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, -1, + GPIO_NR_CENTRO_SD_POWER, 1); +} +#endif + +#ifdef CONFIG_MACH_TREO680 +MACHINE_START(TREO680, "Palm Treo 680") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .reserve = treo_reserve, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = treo680_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_CENTRO +MACHINE_START(CENTRO, "Palm Centro 685") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .reserve = treo_reserve, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = centro_init, + .restart = pxa_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index fe924a23deb..83f830dd8ad 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -25,20 +25,28 @@ #include <linux/pda_power.h> #include <linux/pwm_backlight.h> #include <linux/gpio.h> +#include <linux/wm97xx.h> +#include <linux/power_supply.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/physmap.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <mach/pxa27x.h> #include <mach/audio.h> #include <mach/palmtx.h> -#include <mach/mmc.h> -#include <mach/pxafb.h> -#include <mach/pxa-regs.h> -#include <mach/mfp-pxa27x.h> -#include <mach/irda.h> -#include <mach/pxa27x_keypad.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/keypad-pxa27x.h> #include <mach/udc.h> +#include <linux/platform_data/asoc-palm27x.h> +#include <mach/palm27x.h> #include "generic.h" #include "devices.h" @@ -54,14 +62,20 @@ static unsigned long palmtx_pin_config[] __initdata = { GPIO110_MMC_DAT_2, GPIO111_MMC_DAT_3, GPIO112_MMC_CMD, + GPIO14_GPIO, /* SD detect */ + GPIO114_GPIO, /* SD power */ + GPIO115_GPIO, /* SD r/o switch */ /* AC97 */ GPIO28_AC97_BITCLK, GPIO29_AC97_SDATA_IN_0, GPIO30_AC97_SDATA_OUT, GPIO31_AC97_SYNC, + GPIO89_AC97_SYSCLK, + GPIO95_AC97_nRESET, /* IrDA */ + GPIO40_GPIO, /* ir disable */ GPIO46_FICP_RXD, GPIO47_FICP_TXD, @@ -69,7 +83,8 @@ static unsigned long palmtx_pin_config[] __initdata = { GPIO16_PWM0_OUT, /* USB */ - GPIO13_GPIO, + GPIO13_GPIO, /* usb detect */ + GPIO93_GPIO, /* usb power */ /* PCMCIA */ GPIO48_nPOE, @@ -82,76 +97,86 @@ static unsigned long palmtx_pin_config[] __initdata = { GPIO55_nPREG, GPIO56_nPWAIT, GPIO57_nIOIS16, + GPIO94_GPIO, /* wifi power 1 */ + GPIO108_GPIO, /* wifi power 2 */ + GPIO116_GPIO, /* wifi ready */ + + /* MATRIX 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, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO39_FFUART_TXD, + + /* NAND */ + GPIO15_nCS_1, + GPIO18_RDY, + + /* MISC. */ + GPIO10_GPIO, /* hotsync button */ + GPIO12_GPIO, /* power detect */ + GPIO107_GPIO, /* earphone detect */ }; /****************************************************************************** - * SD/MMC card controller + * NOR Flash ******************************************************************************/ -static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int, - void *data) -{ - int err = 0; - - /* Setup an interrupt for detecting card insert/remove events */ - err = request_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, palmtx_detect_int, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM | - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "SD/MMC card detect", data); - if (err) { - printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n", - __func__); - return err; +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition palmtx_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 } +}; - err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER"); - if (err) - goto pwr_err; - - err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY"); - if (err) - goto ro_err; - - printk(KERN_DEBUG "%s: irq registered\n", __func__); - - return 0; - -ro_err: - gpio_free(GPIO_NR_PALMTX_SD_POWER); -pwr_err: - free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data); - return err; -} +static struct physmap_flash_data palmtx_flash_data[] = { + { + .width = 2, /* bankwidth in bytes */ + .parts = palmtx_partitions, + .nr_parts = ARRAY_SIZE(palmtx_partitions) + } +}; -static void palmtx_mci_exit(struct device *dev, void *data) -{ - gpio_free(GPIO_NR_PALMTX_SD_READONLY); - gpio_free(GPIO_NR_PALMTX_SD_POWER); - free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data); -} +static struct resource palmtx_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; -static void palmtx_mci_power(struct device *dev, unsigned int vdd) -{ - struct pxamci_platform_data *p_d = dev->platform_data; - gpio_set_value(GPIO_NR_PALMTX_SD_POWER, p_d->ocr_mask & (1 << vdd)); -} +static struct platform_device palmtx_flash = { + .name = "physmap-flash", + .id = 0, + .resource = &palmtx_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = palmtx_flash_data, + }, +}; -static int palmtx_mci_get_ro(struct device *dev) +static void __init palmtx_nor_init(void) { - return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY); + platform_device_register(&palmtx_flash); } - -static struct pxamci_platform_data palmtx_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .setpower = palmtx_mci_power, - .get_ro = palmtx_mci_get_ro, - .init = palmtx_mci_init, - .exit = palmtx_mci_exit, -}; +#else +static inline void palmtx_nor_init(void) {} +#endif /****************************************************************************** * GPIO keyboard ******************************************************************************/ -static unsigned int palmtx_matrix_keys[] = { +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static const unsigned int palmtx_matrix_keys[] = { KEY(0, 0, KEY_POWER), KEY(0, 1, KEY_F1), KEY(0, 2, KEY_ENTER), @@ -165,21 +190,33 @@ static unsigned int palmtx_matrix_keys[] = { KEY(3, 0, KEY_RIGHT), KEY(3, 2, KEY_LEFT), +}; +static struct matrix_keymap_data palmtx_matrix_keymap_data = { + .keymap = palmtx_matrix_keys, + .keymap_size = ARRAY_SIZE(palmtx_matrix_keys), }; static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = { .matrix_key_rows = 4, .matrix_key_cols = 3, - .matrix_key_map = palmtx_matrix_keys, - .matrix_key_map_size = ARRAY_SIZE(palmtx_matrix_keys), + .matrix_keymap_data = &palmtx_matrix_keymap_data, .debounce_interval = 30, }; +static void __init palmtx_kpc_init(void) +{ + pxa_set_keypad_info(&palmtx_keypad_platform_data); +} +#else +static inline void palmtx_kpc_init(void) {} +#endif + /****************************************************************************** * GPIO keys ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) static struct gpio_keys_button palmtx_pxa_buttons[] = { {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" }, }; @@ -197,220 +234,143 @@ static struct platform_device palmtx_pxa_keys = { }, }; -/****************************************************************************** - * Backlight - ******************************************************************************/ -static int palmtx_backlight_init(struct device *dev) -{ - int ret; - - ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER"); - if (ret) - goto err; - ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER"); - if (ret) - goto err2; - - return 0; -err2: - gpio_free(GPIO_NR_PALMTX_BL_POWER); -err: - return ret; -} - -static int palmtx_backlight_notify(int brightness) -{ - gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness); - gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness); - return brightness; -} - -static void palmtx_backlight_exit(struct device *dev) +static void __init palmtx_keys_init(void) { - gpio_free(GPIO_NR_PALMTX_BL_POWER); - gpio_free(GPIO_NR_PALMTX_LCD_POWER); + platform_device_register(&palmtx_pxa_keys); } - -static struct platform_pwm_backlight_data palmtx_backlight_data = { - .pwm_id = 0, - .max_brightness = PALMTX_MAX_INTENSITY, - .dft_brightness = PALMTX_MAX_INTENSITY, - .pwm_period_ns = PALMTX_PERIOD_NS, - .init = palmtx_backlight_init, - .notify = palmtx_backlight_notify, - .exit = palmtx_backlight_exit, -}; - -static struct platform_device palmtx_backlight = { - .name = "pwm-backlight", - .dev = { - .parent = &pxa27x_device_pwm0.dev, - .platform_data = &palmtx_backlight_data, - }, -}; - -/****************************************************************************** - * IrDA - ******************************************************************************/ -static void palmtx_irda_transceiver_mode(struct device *dev, int mode) -{ - gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF); - pxa2xx_transceiver_mode(dev, mode); -} - -static struct pxaficp_platform_data palmtx_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, - .transceiver_mode = palmtx_irda_transceiver_mode, -}; - -/****************************************************************************** - * UDC - ******************************************************************************/ -static void palmtx_udc_command(int cmd) -{ - gpio_set_value(GPIO_NR_PALMTX_USB_POWER, !cmd); - udelay(50); - gpio_set_value(GPIO_NR_PALMTX_USB_PULLUP, !cmd); -} - -static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = { - .gpio_vbus = GPIO_NR_PALMTX_USB_DETECT_N, - .gpio_vbus_inverted = 1, - .udc_command = palmtx_udc_command, -}; +#else +static inline void palmtx_keys_init(void) {} +#endif /****************************************************************************** - * Power supply + * NAND Flash ******************************************************************************/ -static int power_supply_init(struct device *dev) +#if defined(CONFIG_MTD_NAND_PLATFORM) || \ + defined(CONFIG_MTD_NAND_PLATFORM_MODULE) +static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) { - int ret; - - ret = gpio_request(GPIO_NR_PALMTX_POWER_DETECT, "CABLE_STATE_AC"); - if (ret) - goto err_cs_ac; - - ret = gpio_request(GPIO_NR_PALMTX_USB_DETECT_N, "CABLE_STATE_USB"); - if (ret) - goto err_cs_usb; - - return 0; - -err_cs_usb: - gpio_free(GPIO_NR_PALMTX_POWER_DETECT); -err_cs_ac: - return ret; + struct nand_chip *this = mtd->priv; + char __iomem *nandaddr = this->IO_ADDR_W; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, PALMTX_NAND_CLE_VIRT); + else if (ctrl & NAND_ALE) + writeb(cmd, PALMTX_NAND_ALE_VIRT); + else + writeb(cmd, nandaddr); } -static int palmtx_is_ac_online(void) -{ - return gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT); -} - -static int palmtx_is_usb_online(void) -{ - return !gpio_get_value(GPIO_NR_PALMTX_USB_DETECT_N); -} - -static void power_supply_exit(struct device *dev) -{ - gpio_free(GPIO_NR_PALMTX_USB_DETECT_N); - gpio_free(GPIO_NR_PALMTX_POWER_DETECT); -} - -static char *palmtx_supplicants[] = { - "main-battery", +static struct mtd_partition palmtx_partition_info[] = { + [0] = { + .name = "palmtx-0", + .offset = 0, + .size = MTDPART_SIZ_FULL + }, }; -static struct pda_power_pdata power_supply_info = { - .init = power_supply_init, - .is_ac_online = palmtx_is_ac_online, - .is_usb_online = palmtx_is_usb_online, - .exit = power_supply_exit, - .supplied_to = palmtx_supplicants, - .num_supplicants = ARRAY_SIZE(palmtx_supplicants), +struct platform_nand_data palmtx_nand_platdata = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .nr_partitions = ARRAY_SIZE(palmtx_partition_info), + .partitions = palmtx_partition_info, + .chip_delay = 20, + }, + .ctrl = { + .cmd_ctrl = palmtx_nand_cmd_ctl, + }, }; -static struct platform_device power_supply = { - .name = "pda-power", - .id = -1, - .dev = { - .platform_data = &power_supply_info, +static struct resource palmtx_nand_resource[] = { + [0] = { + .start = PXA_CS1_PHYS, + .end = PXA_CS1_PHYS + SZ_1M - 1, + .flags = IORESOURCE_MEM, }, }; -/****************************************************************************** - * Framebuffer - ******************************************************************************/ -static struct pxafb_mode_info palmtx_lcd_modes[] = { -{ - .pixclock = 57692, - .xres = 320, - .yres = 480, - .bpp = 16, - - .left_margin = 32, - .right_margin = 1, - .upper_margin = 7, - .lower_margin = 1, - - .hsync_len = 4, - .vsync_len = 1, -}, +static struct platform_device palmtx_nand = { + .name = "gen_nand", + .num_resources = ARRAY_SIZE(palmtx_nand_resource), + .resource = palmtx_nand_resource, + .id = -1, + .dev = { + .platform_data = &palmtx_nand_platdata, + } }; -static struct pxafb_mach_info palmtx_lcd_screen = { - .modes = palmtx_lcd_modes, - .num_modes = ARRAY_SIZE(palmtx_lcd_modes), - .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, -}; +static void __init palmtx_nand_init(void) +{ + platform_device_register(&palmtx_nand); +} +#else +static inline void palmtx_nand_init(void) {} +#endif /****************************************************************************** * Machine init ******************************************************************************/ -static struct platform_device *devices[] __initdata = { -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) - &palmtx_pxa_keys, -#endif - &palmtx_backlight, - &power_supply, -}; - static struct map_desc palmtx_io_desc[] __initdata = { { - .virtual = PALMTX_PCMCIA_VIRT, + .virtual = (unsigned long)PALMTX_PCMCIA_VIRT, .pfn = __phys_to_pfn(PALMTX_PCMCIA_PHYS), .length = PALMTX_PCMCIA_SIZE, - .type = MT_DEVICE -}, + .type = MT_DEVICE, +}, { + .virtual = (unsigned long)PALMTX_NAND_ALE_VIRT, + .pfn = __phys_to_pfn(PALMTX_NAND_ALE_PHYS), + .length = SZ_1M, + .type = MT_DEVICE, +}, { + .virtual = (unsigned long)PALMTX_NAND_CLE_VIRT, + .pfn = __phys_to_pfn(PALMTX_NAND_CLE_PHYS), + .length = SZ_1M, + .type = MT_DEVICE, +} }; static void __init palmtx_map_io(void) { - pxa_map_io(); + pxa27x_map_io(); iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc)); } static void __init palmtx_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config)); - - set_pxa_fb_info(&palmtx_lcd_screen); - pxa_set_mci_info(&palmtx_mci_platform_data); - pxa_set_udc_info(&palmtx_udc_info); - pxa_set_ac97_info(NULL); - pxa_set_ficp_info(&palmtx_ficp_platform_data); - pxa_set_keypad_info(&palmtx_keypad_platform_data); - - platform_add_devices(devices, ARRAY_SIZE(devices)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + palm27x_mmc_init(GPIO_NR_PALMTX_SD_DETECT_N, GPIO_NR_PALMTX_SD_READONLY, + GPIO_NR_PALMTX_SD_POWER, 0); + palm27x_pm_init(PALMTX_STR_BASE); + palm27x_lcd_init(-1, &palm_320x480_lcd_mode); + palm27x_udc_init(GPIO_NR_PALMTX_USB_DETECT_N, + GPIO_NR_PALMTX_USB_PULLUP, 1); + palm27x_irda_init(GPIO_NR_PALMTX_IR_DISABLE); + palm27x_ac97_init(PALMTX_BAT_MIN_VOLTAGE, PALMTX_BAT_MAX_VOLTAGE, + GPIO_NR_PALMTX_EARPHONE_DETECT, 95); + palm27x_pwm_init(GPIO_NR_PALMTX_BL_POWER, GPIO_NR_PALMTX_LCD_POWER); + palm27x_power_init(GPIO_NR_PALMTX_POWER_DETECT, -1); + palm27x_pmic_init(); + palmtx_kpc_init(); + palmtx_keys_init(); + palmtx_nor_init(); + palmtx_nand_init(); } MACHINE_START(PALMTX, "Palm T|X") - .phys_io = PALMTX_PHYS_IO_START, - .io_pg_offst = io_p2v(0x40000000), - .boot_params = 0xa0000100, + .atag_offset = 0x100, .map_io = palmtx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, - .init_machine = palmtx_init + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = palmtx_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c new file mode 100644 index 00000000000..1a35ddf218d --- /dev/null +++ b/arch/arm/mach-pxa/palmz72.c @@ -0,0 +1,414 @@ +/* + * Hardware definitions for Palm Zire72 + * + * Authors: + * Vladimir "Farcaller" Pouzanov <farcaller@gmail.com> + * Sergey Lapin <slapin@ossfans.org> + * Alex Osborne <bobofdoom@gmail.com> + * Jan Herman <2hp@seznam.cz> + * + * Rewrite for mainline: + * 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. + * + * (find more info at www.hackndev.com) + * + */ + +#include <linux/platform_device.h> +#include <linux/syscore_ops.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/wm97xx.h> +#include <linux/power_supply.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/i2c-gpio.h> + +#include <asm/mach-types.h> +#include <asm/suspend.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa27x.h> +#include <mach/audio.h> +#include <mach/palmz72.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <mach/udc.h> +#include <linux/platform_data/asoc-palm27x.h> +#include <mach/palm27x.h> + +#include <mach/pm.h> +#include <linux/platform_data/camera-pxa.h> + +#include <media/soc_camera.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmz72_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, + GPIO14_GPIO, /* SD detect */ + GPIO115_GPIO, /* SD RO */ + GPIO98_GPIO, /* SD power */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO89_AC97_SYSCLK, + GPIO113_AC97_nRESET, + + /* IrDA */ + GPIO49_GPIO, /* ir disable */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* USB */ + GPIO15_GPIO, /* usb detect */ + GPIO95_GPIO, /* usb pullup */ + + /* Matrix 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, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + GPIO20_GPIO, /* bl power */ + GPIO21_GPIO, /* LCD border switch */ + GPIO22_GPIO, /* LCD border color */ + GPIO96_GPIO, /* lcd power */ + + /* PXA Camera */ + GPIO81_CIF_DD_0, + GPIO48_CIF_DD_5, + GPIO50_CIF_DD_3, + GPIO51_CIF_DD_2, + GPIO52_CIF_DD_4, + GPIO53_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO55_CIF_DD_1, + GPIO84_CIF_FV, + GPIO85_CIF_LV, + GPIO93_CIF_DD_6, + GPIO108_CIF_DD_7, + + GPIO56_GPIO, /* OV9640 Powerdown */ + GPIO57_GPIO, /* OV9640 Reset */ + GPIO91_GPIO, /* OV9640 Power */ + + /* I2C */ + GPIO117_GPIO, /* I2C_SCL */ + GPIO118_GPIO, /* I2C_SDA */ + + /* Misc. */ + GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */ + GPIO88_GPIO, /* green led */ + GPIO27_GPIO, /* WM9712 IRQ */ +}; + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static const unsigned int palmz72_matrix_keys[] = { + KEY(0, 0, KEY_POWER), + KEY(0, 1, KEY_F1), + KEY(0, 2, KEY_ENTER), + + KEY(1, 0, KEY_F2), + KEY(1, 1, KEY_F3), + KEY(1, 2, KEY_F4), + + KEY(2, 0, KEY_UP), + KEY(2, 2, KEY_DOWN), + + KEY(3, 0, KEY_RIGHT), + KEY(3, 2, KEY_LEFT), +}; + +static struct matrix_keymap_data almz72_matrix_keymap_data = { + .keymap = palmz72_matrix_keys, + .keymap_size = ARRAY_SIZE(palmz72_matrix_keys), +}; + +static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = { + .matrix_key_rows = 4, + .matrix_key_cols = 3, + .matrix_keymap_data = &almz72_matrix_keymap_data, + + .debounce_interval = 30, +}; + +static void __init palmz72_kpc_init(void) +{ + pxa_set_keypad_info(&palmz72_keypad_platform_data); +} +#else +static inline void palmz72_kpc_init(void) {} +#endif + +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led gpio_leds[] = { + { + .name = "palmz72:green:led", + .default_trigger = "none", + .gpio = GPIO_NR_PALMZ72_LED_GREEN, + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device palmz72_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + } +}; + +static void __init palmz72_leds_init(void) +{ + platform_device_register(&palmz72_leds); +} +#else +static inline void palmz72_leds_init(void) {} +#endif + +#ifdef CONFIG_PM + +/* We have some black magic here + * PalmOS ROM on recover expects special struct physical address + * to be transferred via PSPR. Using this struct PalmOS restores + * its state after sleep. As for Linux, we need to setup it the + * same way. More than that, PalmOS ROM changes some values in memory. + * For now only one location is found, which needs special treatment. + * Thanks to Alex Osborne, Andrzej Zaborowski, and lots of other people + * for reading backtraces for me :) + */ + +#define PALMZ72_SAVE_DWORD ((unsigned long *)0xc0000050) + +static struct palmz72_resume_info palmz72_resume_info = { + .magic0 = 0xb4e6, + .magic1 = 1, + + /* reset state, MMU off etc */ + .arm_control = 0, + .aux_control = 0, + .ttb = 0, + .domain_access = 0, + .process_id = 0, +}; + +static unsigned long store_ptr; + +/* syscore_ops for Palm Zire 72 PM */ + +static int palmz72_pm_suspend(void) +{ + /* setup the resume_info struct for the original bootloader */ + palmz72_resume_info.resume_addr = (u32) cpu_resume; + + /* Storing memory touched by ROM */ + store_ptr = *PALMZ72_SAVE_DWORD; + + /* Setting PSPR to a proper value */ + PSPR = virt_to_phys(&palmz72_resume_info); + + return 0; +} + +static void palmz72_pm_resume(void) +{ + *PALMZ72_SAVE_DWORD = store_ptr; +} + +static struct syscore_ops palmz72_pm_syscore_ops = { + .suspend = palmz72_pm_suspend, + .resume = palmz72_pm_resume, +}; + +static int __init palmz72_pm_init(void) +{ + if (machine_is_palmz72()) { + register_syscore_ops(&palmz72_pm_syscore_ops); + return 0; + } + return -ENODEV; +} + +device_initcall(palmz72_pm_init); +#endif + +/****************************************************************************** + * SoC Camera + ******************************************************************************/ +#if defined(CONFIG_SOC_CAMERA_OV9640) || \ + defined(CONFIG_SOC_CAMERA_OV9640_MODULE) +static struct pxacamera_platform_data palmz72_pxacamera_platform_data = { + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, + .mclk_10khz = 2600, +}; + +/* Board I2C devices. */ +static struct i2c_board_info palmz72_i2c_device[] = { + { + I2C_BOARD_INFO("ov9640", 0x30), + } +}; + +static int palmz72_camera_power(struct device *dev, int power) +{ + gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power); + mdelay(50); + return 0; +} + +static int palmz72_camera_reset(struct device *dev) +{ + gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1); + mdelay(50); + gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0); + mdelay(50); + return 0; +} + +static struct soc_camera_link palmz72_iclink = { + .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */ + .board_info = &palmz72_i2c_device[0], + .i2c_adapter_id = 0, + .module_name = "ov96xx", + .power = &palmz72_camera_power, + .reset = &palmz72_camera_reset, + .flags = SOCAM_DATAWIDTH_8, +}; + +static struct i2c_gpio_platform_data palmz72_i2c_bus_data = { + .sda_pin = 118, + .scl_pin = 117, + .udelay = 10, + .timeout = 100, +}; + +static struct platform_device palmz72_i2c_bus_device = { + .name = "i2c-gpio", + .id = 0, /* we use this as a replacement for i2c-pxa */ + .dev = { + .platform_data = &palmz72_i2c_bus_data, + } +}; + +static struct platform_device palmz72_camera = { + .name = "soc-camera-pdrv", + .id = -1, + .dev = { + .platform_data = &palmz72_iclink, + }, +}; + +/* Here we request the camera GPIOs and configure them. We power up the camera + * module, deassert the reset pin, but put it into powerdown (low to no power + * consumption) mode. This allows us to later bring the module up fast. */ +static struct gpio palmz72_camera_gpios[] = { + { GPIO_NR_PALMZ72_CAM_POWER, GPIOF_INIT_HIGH,"Camera DVDD" }, + { GPIO_NR_PALMZ72_CAM_RESET, GPIOF_INIT_LOW, "Camera RESET" }, + { GPIO_NR_PALMZ72_CAM_PWDN, GPIOF_INIT_LOW, "Camera PWDN" }, +}; + +static inline void __init palmz72_cam_gpio_init(void) +{ + int ret; + + ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios)); + if (!ret) + gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios)); + else + printk(KERN_ERR "Camera GPIO init failed!\n"); + + return; +} + +static void __init palmz72_camera_init(void) +{ + palmz72_cam_gpio_init(); + pxa_set_camera_info(&palmz72_pxacamera_platform_data); + platform_device_register(&palmz72_i2c_bus_device); + platform_device_register(&palmz72_camera); +} +#else +static inline void palmz72_camera_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init palmz72_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + palm27x_mmc_init(GPIO_NR_PALMZ72_SD_DETECT_N, GPIO_NR_PALMZ72_SD_RO, + GPIO_NR_PALMZ72_SD_POWER_N, 1); + palm27x_lcd_init(-1, &palm_320x320_lcd_mode); + palm27x_udc_init(GPIO_NR_PALMZ72_USB_DETECT_N, + GPIO_NR_PALMZ72_USB_PULLUP, 0); + palm27x_irda_init(GPIO_NR_PALMZ72_IR_DISABLE); + palm27x_ac97_init(PALMZ72_BAT_MIN_VOLTAGE, PALMZ72_BAT_MAX_VOLTAGE, + -1, 113); + palm27x_pwm_init(-1, -1); + palm27x_power_init(-1, -1); + palm27x_pmic_init(); + palmz72_kpc_init(); + palmz72_leds_init(); + palmz72_camera_init(); +} + +MACHINE_START(PALMZ72, "Palm Zire72") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = palmz72_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index 730b9f6ede1..69918c7e3f1 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -25,15 +25,12 @@ #include <linux/mtd/physmap.h> #include <linux/spi/spi.h> #include <linux/spi/max7301.h> +#include <linux/spi/pxa2xx_spi.h> #include <linux/leds.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx_spi.h> +#include <mach/pxa27x.h> #include <mach/pcm027.h> #include "generic.h" @@ -86,6 +83,28 @@ * *) CPU internal use only */ +static unsigned long pcm027_pin_config[] __initdata = { + /* Chip Selects */ + GPIO20_nSDCS_2, + GPIO21_nSDCS_3, + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO80_nCS_4, + GPIO33_nCS_5, /* Ethernet */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* GPIO */ + GPIO52_GPIO, /* IRQ from network controller */ +#ifdef CONFIG_LEDS_GPIO + GPIO90_GPIO, /* PCM027_LED_CPU */ + GPIO91_GPIO, /* PCM027_LED_HEART_BEAT */ +#endif + GPIO114_GPIO, /* IRQ from CAN controller */ +}; + /* * SMC91x network controller specific stuff */ @@ -206,13 +225,13 @@ static void __init pcm027_init(void) */ ARB_CNTRL = ARB_CORE_PARK | 0x234; - platform_add_devices(devices, ARRAY_SIZE(devices)); + pxa2xx_mfp_config(pcm027_pin_config, ARRAY_SIZE(pcm027_pin_config)); - /* LEDs (on demand only) */ -#ifdef CONFIG_LEDS_GPIO - pxa_gpio_mode(PCM027_LED_CPU | GPIO_OUT); - pxa_gpio_mode(PCM027_LED_HEARD_BEAT | GPIO_OUT); -#endif /* CONFIG_LEDS_GPIO */ + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + platform_add_devices(devices, ARRAY_SIZE(devices)); /* at last call the baseboard to initialize itself */ #ifdef CONFIG_MACH_PCM990_BASEBOARD @@ -225,7 +244,7 @@ static void __init pcm027_init(void) static void __init pcm027_map_io(void) { - pxa_map_io(); + pxa27x_map_io(); /* initialize sleep mode regs (wake-up sources, etc) */ PGSR0 = 0x01308000; @@ -239,11 +258,12 @@ static void __init pcm027_map_io(void) MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270") /* Maintainer: Pengutronix */ - .boot_params = 0xa0000100, - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .atag_offset = 0x100, .map_io = pcm027_map_io, + .nr_irqs = PCM027_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, .init_machine = pcm027_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 420c9b3813f..2897da2a5df 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -19,25 +19,24 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#include <linux/gpio.h> #include <linux/irq.h> #include <linux/platform_device.h> #include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> #include <linux/pwm_backlight.h> +#include <media/mt9v022.h> #include <media/soc_camera.h> -#include <asm/gpio.h> -#include <mach/i2c.h> -#include <mach/camera.h> +#include <linux/platform_data/camera-pxa.h> #include <asm/mach/map.h> -#include <mach/pxa-regs.h> +#include <mach/pxa27x.h> #include <mach/audio.h> -#include <mach/mmc.h> -#include <mach/ohci.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> #include <mach/pcm990_baseboard.h> -#include <mach/pxafb.h> -#include <mach/mfp-pxa27x.h> +#include <linux/platform_data/video-pxafb.h> #include "devices.h" #include "generic.h" @@ -55,8 +54,30 @@ static unsigned long pcm990_pin_config[] __initdata = { GPIO89_USBH1_PEN, /* PWM0 */ GPIO16_PWM0_OUT, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, }; +static void __iomem *pcm990_cpld_base; + +static u8 pcm990_cpld_readb(unsigned int reg) +{ + return readb(pcm990_cpld_base + reg); +} + +static void pcm990_cpld_writeb(u8 value, unsigned int reg) +{ + writeb(value, pcm990_cpld_base + reg); +} + /* * pcm990_lcd_power - control power supply to the LCD * @on: 0 = switch off, 1 = switch on @@ -70,13 +91,13 @@ static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var) /* enable LCD-Latches * power on LCD */ - __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = - PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON; + pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON, + PCM990_CTRL_REG3); } else { /* disable LCD-Latches * power off LCD */ - __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = 0x00; + pcm990_cpld_writeb(0, PCM990_CTRL_REG3); } } #endif @@ -100,8 +121,7 @@ static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = { static struct pxafb_mach_info pcm990_fbinfo __initdata = { .modes = &fb_info_sharp_lq084v1dg21, .num_modes = 1, - .lccr0 = LCCR0_PAS, - .lccr3 = LCCR3_PCP, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, .pxafb_lcd_power = pcm990_lcd_power, }; #elif defined(CONFIG_PCM990_DISPLAY_NEC) @@ -123,8 +143,7 @@ struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = { static struct pxafb_mach_info pcm990_fbinfo __initdata = { .modes = &fb_info_nec_nl6448bc20_18d, .num_modes = 1, - .lccr0 = LCCR0_Act, - .lccr3 = LCCR3_PixFlEdg, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, .pxafb_lcd_power = pcm990_lcd_power, }; #endif @@ -134,6 +153,7 @@ static struct platform_pwm_backlight_data pcm990_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device pcm990_backlight_device = { @@ -234,38 +254,52 @@ static struct platform_device pcm990_backlight_device = { static unsigned long pcm990_irq_enabled; -static void pcm990_mask_ack_irq(unsigned int irq) +static void pcm990_mask_ack_irq(struct irq_data *d) { - int pcm990_irq = (irq - PCM027_IRQ(0)); - PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq)); + int pcm990_irq = (d->irq - PCM027_IRQ(0)); + + pcm990_irq_enabled &= ~(1 << pcm990_irq); + + pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA); } -static void pcm990_unmask_irq(unsigned int irq) +static void pcm990_unmask_irq(struct irq_data *d) { - int pcm990_irq = (irq - PCM027_IRQ(0)); + int pcm990_irq = (d->irq - PCM027_IRQ(0)); + u8 val; + /* the irq can be acknowledged only if deasserted, so it's done here */ - PCM990_INTSETCLR |= 1 << pcm990_irq; - PCM990_INTMSKENA = (pcm990_irq_enabled |= (1 << pcm990_irq)); + + pcm990_irq_enabled |= (1 << pcm990_irq); + + val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR); + val |= 1 << pcm990_irq; + pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR); + + pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA); } static struct irq_chip pcm990_irq_chip = { - .mask_ack = pcm990_mask_ack_irq, - .unmask = pcm990_unmask_irq, + .irq_mask_ack = pcm990_mask_ack_irq, + .irq_unmask = pcm990_unmask_irq, }; static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc) { - unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled; + unsigned long pending; + + pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR); + pending &= pcm990_irq_enabled; do { - GEDR(PCM990_CTRL_INT_IRQ_GPIO) = - GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO); + /* clear our parent IRQ */ + desc->irq_data.chip->irq_ack(&desc->irq_data); if (likely(pending)) { irq = PCM027_IRQ(0) + __ffs(pending); - desc = irq_desc + irq; - desc_handle_irq(irq, desc); + generic_handle_irq(irq); } - pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled; + pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR); + pending &= pcm990_irq_enabled; } while (pending); } @@ -275,16 +309,17 @@ static void __init pcm990_init_irq(void) /* setup extra PCM990 irqs */ for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) { - set_irq_chip(irq, &pcm990_irq_chip); - set_irq_handler(irq, handle_level_irq); + irq_set_chip_and_handler(irq, &pcm990_irq_chip, + handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - PCM990_INTMSKENA = 0x00; /* disable all Interrupts */ - PCM990_INTSETCLR = 0xFF; + /* disable all Interrupts */ + pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA); + pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR); - set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler); - set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE); + irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler); + irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE); } static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, @@ -292,7 +327,7 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, { int err; - err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED, + err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, 0, "MMC card detect", data); if (err) printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC " @@ -301,16 +336,20 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, return err; } -static void pcm990_mci_setpower(struct device *dev, unsigned int vdd) +static int pcm990_mci_setpower(struct device *dev, unsigned int vdd) { struct pxamci_platform_data *p_d = dev->platform_data; + u8 val; + + val = pcm990_cpld_readb(PCM990_CTRL_REG5); if ((1 << vdd) & p_d->ocr_mask) - __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) = - PCM990_CTRL_MMC2PWR; + val |= PCM990_CTRL_MMC2PWR; else - __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) = - ~PCM990_CTRL_MMC2PWR; + val &= ~PCM990_CTRL_MMC2PWR; + + pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5); + return 0; } static void pcm990_mci_exit(struct device *dev, void *data) @@ -321,43 +360,20 @@ static void pcm990_mci_exit(struct device *dev, void *data) #define MSECS_PER_JIFFY (1000/HZ) static struct pxamci_platform_data pcm990_mci_platform_data = { - .detect_delay = 250 / MSECS_PER_JIFFY, - .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .init = pcm990_mci_init, - .setpower = pcm990_mci_setpower, - .exit = pcm990_mci_exit, + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .init = pcm990_mci_init, + .setpower = pcm990_mci_setpower, + .exit = pcm990_mci_exit, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, }; -/* - * init OHCI hardware to work with - * - * Note: Only USB port 1 (host only) is connected - * - * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low - * GPIO89 (USBHPEN#1): power-on out, on when low - */ -static int pcm990_ohci_init(struct device *dev) -{ - /* - * disable USB port 2 and 3 - * power sense is active low - */ - UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 | - UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE); - /* - * wait 10ms after Power on - * overcurrent per port - * power switch per port - */ - UHCRHDA = (5<<24) | (1<<11) | (1<<8); /* FIXME: Required? */ - - return 0; -} - static struct pxaohci_platform_data pcm990_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, - .init = pcm990_ohci_init, - .exit = NULL, + .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW, + .power_on_delay = 10, }; /* @@ -382,38 +398,69 @@ static unsigned long pcm990_camera_pin_config[] = { GPIO44_CIF_LV, }; -static int pcm990_pxacamera_init(struct device *dev) -{ - pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config)); - return 0; -} - /* * CICR4: PCLK_EN: Pixel clock is supplied by the sensor * MCLK_EN: Master clock is generated by PXA * PCP: Data sampled on the falling edge of pixel clock */ struct pxacamera_platform_data pcm990_pxacamera_platform_data = { - .init = pcm990_pxacamera_init, .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_10 | PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN/* | PXA_CAMERA_PCP*/, .mclk_10khz = 1000, }; -#include <linux/i2c/pca953x.h> +#include <linux/platform_data/pca953x.h> static struct pca953x_platform_data pca9536_data = { - .gpio_base = NR_BUILTIN_GPIO + 1, + .gpio_base = PXA_NR_BUILTIN_GPIO, }; -static struct soc_camera_link iclink[] = { - { - .bus_id = 0, /* Must match with the camera ID above */ - .gpio = NR_BUILTIN_GPIO + 1, - }, { - .bus_id = 0, /* Must match with the camera ID above */ +static int gpio_bus_switch = -EINVAL; + +static int pcm990_camera_set_bus_param(struct soc_camera_link *link, + unsigned long flags) +{ + if (gpio_bus_switch < 0) { + if (flags == SOCAM_DATAWIDTH_10) + return 0; + else + return -EINVAL; } -}; + + if (flags & SOCAM_DATAWIDTH_8) + gpio_set_value_cansleep(gpio_bus_switch, 1); + else + gpio_set_value_cansleep(gpio_bus_switch, 0); + + return 0; +} + +static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link) +{ + int ret; + + if (gpio_bus_switch < 0) { + ret = gpio_request(PXA_NR_BUILTIN_GPIO, "camera"); + if (!ret) { + gpio_bus_switch = PXA_NR_BUILTIN_GPIO; + gpio_direction_output(gpio_bus_switch, 0); + } + } + + if (gpio_bus_switch >= 0) + return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10; + else + return SOCAM_DATAWIDTH_10; +} + +static void pcm990_camera_free_bus(struct soc_camera_link *link) +{ + if (gpio_bus_switch < 0) + return; + + gpio_free(gpio_bus_switch); + gpio_bus_switch = -EINVAL; +} /* Board I2C devices. */ static struct i2c_board_info __initdata pcm990_i2c_devices[] = { @@ -421,33 +468,57 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = { /* Must initialize before the camera(s) */ I2C_BOARD_INFO("pca9536", 0x41), .platform_data = &pca9536_data, - }, { + }, +}; + +static struct mt9v022_platform_data mt9v022_pdata = { + .y_skip_top = 1, +}; + +static struct i2c_board_info pcm990_camera_i2c[] = { + { I2C_BOARD_INFO("mt9v022", 0x48), - .platform_data = &iclink[0], /* With extender */ }, { I2C_BOARD_INFO("mt9m001", 0x5d), - .platform_data = &iclink[0], /* With extender */ }, }; -#endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ -/* - * enable generic access to the base board control CPLDs U6 and U7 - */ -static struct map_desc pcm990_io_desc[] __initdata = { +static struct soc_camera_link iclink[] = { { - .virtual = PCM990_CTRL_BASE, - .pfn = __phys_to_pfn(PCM990_CTRL_PHYS), - .length = PCM990_CTRL_SIZE, - .type = MT_DEVICE /* CPLD */ + .bus_id = 0, /* Must match with the camera ID */ + .board_info = &pcm990_camera_i2c[0], + .priv = &mt9v022_pdata, + .i2c_adapter_id = 0, + .query_bus_param = pcm990_camera_query_bus_param, + .set_bus_param = pcm990_camera_set_bus_param, + .free_bus = pcm990_camera_free_bus, }, { - .virtual = PCM990_CF_PLD_BASE, - .pfn = __phys_to_pfn(PCM990_CF_PLD_PHYS), - .length = PCM990_CF_PLD_SIZE, - .type = MT_DEVICE /* CPLD */ - } + .bus_id = 0, /* Must match with the camera ID */ + .board_info = &pcm990_camera_i2c[1], + .i2c_adapter_id = 0, + .query_bus_param = pcm990_camera_query_bus_param, + .set_bus_param = pcm990_camera_set_bus_param, + .free_bus = pcm990_camera_free_bus, + }, }; +static struct platform_device pcm990_camera[] = { + { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &iclink[0], + }, + }, { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &iclink[1], + }, + }, +}; +#endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ + /* * system init for baseboard usage. Will be called by pcm027 init. * @@ -458,14 +529,17 @@ void __init pcm990_baseboard_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config)); - /* register CPLD access */ - iotable_init(ARRAY_AND_SIZE(pcm990_io_desc)); + pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE); + if (!pcm990_cpld_base) { + pr_err("pcm990: failed to ioremap cpld\n"); + return; + } /* register CPLD's IRQ controller */ pcm990_init_irq(); #ifndef CONFIG_PCM990_DISPLAY_NONE - set_pxa_fb_info(&pcm990_fbinfo); + pxa_set_fb_info(NULL, &pcm990_fbinfo); #endif platform_device_register(&pcm990_backlight_device); @@ -479,9 +553,13 @@ void __init pcm990_baseboard_init(void) pxa_set_ac97_info(NULL); #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) + pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config)); pxa_set_camera_info(&pcm990_pxacamera_platform_data); i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices)); + + platform_device_register(&pcm990_camera[0]); + platform_device_register(&pcm990_camera[1]); #endif printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n"); diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 1b539e67557..37178a8559b 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -14,15 +14,9 @@ #include <linux/module.h> #include <linux/suspend.h> #include <linux/errno.h> -#include <linux/time.h> +#include <linux/slab.h> -#include <mach/hardware.h> -#include <asm/memory.h> -#include <asm/system.h> #include <mach/pm.h> -#include <mach/pxa-regs.h> -#include <mach/lubbock.h> -#include <asm/mach/time.h> struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; static unsigned long *sleep_save; @@ -39,7 +33,7 @@ int pxa_pm_enter(suspend_state_t state) #endif /* skip registers saving for standby */ - if (state != PM_SUSPEND_STANDBY) { + if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) { pxa_cpu_pm_fns->save(sleep_save); /* before sleeping, calculate and save a checksum */ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) @@ -48,18 +42,17 @@ int pxa_pm_enter(suspend_state_t state) /* *** go zzz *** */ pxa_cpu_pm_fns->enter(state); - cpu_init(); - if (state != PM_SUSPEND_STANDBY) { + if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) { /* after sleeping, validate the checksum */ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) checksum += sleep_save[i]; /* if invalid, display message and wait for a hardware reset */ if (checksum != sleep_save_checksum) { -#ifdef CONFIG_ARCH_LUBBOCK - LUB_HEXLED = 0xbadbadc5; -#endif + + lubbock_set_hexled(0xbadbadc5); + while (1) pxa_cpu_pm_fns->enter(state); } @@ -73,11 +66,6 @@ int pxa_pm_enter(suspend_state_t state) EXPORT_SYMBOL_GPL(pxa_pm_enter); -unsigned long sleep_phys_sp(void *sp) -{ - return virt_to_phys(sp); -} - static int pxa_pm_valid(suspend_state_t state) { if (pxa_cpu_pm_fns) @@ -86,9 +74,27 @@ static int pxa_pm_valid(suspend_state_t state) return -EINVAL; } -static struct platform_suspend_ops pxa_pm_ops = { +int pxa_pm_prepare(void) +{ + int ret = 0; + + if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->prepare) + ret = pxa_cpu_pm_fns->prepare(); + + return ret; +} + +void pxa_pm_finish(void) +{ + if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish) + pxa_cpu_pm_fns->finish(); +} + +static const struct platform_suspend_ops pxa_pm_ops = { .valid = pxa_pm_valid, .enter = pxa_pm_enter, + .prepare = pxa_pm_prepare, + .finish = pxa_pm_finish, }; static int __init pxa_pm_init(void) diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 3f5f484549b..13199162911 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -16,32 +16,36 @@ */ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/export.h> #include <linux/platform_device.h> #include <linux/fb.h> #include <linux/pm.h> #include <linux/delay.h> +#include <linux/mtd/physmap.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/mtd/sharpsl.h> +#include <linux/memblock.h> #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/irq.h> #include <asm/setup.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/mmc.h> +#include <mach/pxa25x.h> +#include <linux/platform_data/mmc-pxamci.h> #include <mach/udc.h> -#include <mach/i2c.h> -#include <mach/irda.h> +#include <linux/platform_data/irda-pxaficp.h> #include <mach/poodle.h> -#include <mach/pxafb.h> -#include <mach/sharpsl.h> -#include <mach/ssp.h> +#include <linux/platform_data/video-pxafb.h> #include <asm/hardware/scoop.h> #include <asm/hardware/locomo.h> @@ -49,7 +53,69 @@ #include "generic.h" #include "devices.h" -#include "sharpsl.h" + +static unsigned long poodle_pin_config[] __initdata = { + /* I/O */ + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO18_RDY, + + /* Clock */ + GPIO12_32KHz, + + /* SSP1 */ + GPIO23_SSP1_SCLK, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + GPIO24_GPIO, /* POODLE_GPIO_TP_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, + + /* LCD */ + GPIOxx_LCD_TFT_16BPP, + + /* 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 */ + GPIO9_GPIO, /* POODLE_GPIO_nSD_DETECT */ + GPIO7_GPIO, /* POODLE_GPIO_nSD_WP */ + GPIO3_GPIO, /* POODLE_GPIO_SD_PWR */ + GPIO33_GPIO, /* POODLE_GPIO_SD_PWR1 */ + + GPIO20_GPIO, /* POODLE_GPIO_USB_PULLUP */ + GPIO22_GPIO, /* POODLE_GPIO_IR_ON */ +}; static struct resource poodle_scoop_resources[] = { [0] = { @@ -62,6 +128,7 @@ static struct resource poodle_scoop_resources[] = { static struct scoop_config poodle_scoop_setup = { .io_dir = POODLE_SCOOP_IO_DIR, .io_out = POODLE_SCOOP_IO_OUT, + .gpio_base = POODLE_SCOOP_GPIO_BASE, }; struct platform_device poodle_scoop_device = { @@ -74,27 +141,6 @@ struct platform_device poodle_scoop_device = { .resource = poodle_scoop_resources, }; -static void poodle_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); -} - static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { { .dev = &poodle_scoop_device.dev, @@ -107,12 +153,16 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { static struct scoop_pcmcia_config poodle_pcmcia_config = { .devs = &poodle_pcmcia_scoop[0], .num_devs = 1, - .pcmcia_init = poodle_pcmcia_init, }; EXPORT_SYMBOL(poodle_scoop_device); +static struct platform_device poodle_audio_device = { + .name = "poodle-audio", + .id = -1, +}; + /* LoCoMo device */ static struct resource locomo_resources[] = { [0] = { @@ -121,77 +171,64 @@ static struct resource locomo_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_GPIO(10), - .end = IRQ_GPIO(10), + .start = PXA_GPIO_TO_IRQ(10), + .end = PXA_GPIO_TO_IRQ(10), .flags = IORESOURCE_IRQ, }, }; +static struct locomo_platform_data locomo_info = { + .irq_base = IRQ_BOARD_START, +}; + struct platform_device poodle_locomo_device = { .name = "locomo", .id = 0, .num_resources = ARRAY_SIZE(locomo_resources), .resource = locomo_resources, + .dev = { + .platform_data = &locomo_info, + }, }; EXPORT_SYMBOL(poodle_locomo_device); -/* - * Poodle SSP Device - */ - -struct platform_device poodle_ssp_device = { - .name = "corgi-ssp", - .id = -1, +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +static struct pxa2xx_spi_master poodle_spi_info = { + .num_chipselect = 1, }; -struct corgissp_machinfo poodle_ssp_machinfo = { - .port = 1, - .cs_lcdcon = -1, - .cs_ads7846 = -1, - .cs_max1111 = -1, - .clk_lcdcon = 2, - .clk_ads7846 = 36, - .clk_max1111 = 2, +static struct ads7846_platform_data poodle_ads7846_info = { + .model = 7846, + .vref_delay_usecs = 100, + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .gpio_pendown = POODLE_GPIO_TP_INT, }; +static struct pxa2xx_spi_chip poodle_ads7846_chip = { + .gpio_cs = POODLE_GPIO_TP_CS, +}; -/* - * Poodle Touch Screen Device - */ -static struct resource poodlets_resources[] = { - [0] = { - .start = POODLE_IRQ_GPIO_TP_INT, - .end = POODLE_IRQ_GPIO_TP_INT, - .flags = IORESOURCE_IRQ, +static struct spi_board_info poodle_spi_devices[] = { + { + .modalias = "ads7846", + .max_speed_hz = 10000, + .bus_num = 1, + .platform_data = &poodle_ads7846_info, + .controller_data= &poodle_ads7846_chip, + .irq = PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT), }, }; -static unsigned long poodle_get_hsync_invperiod(void) -{ - return 0; -} - -static void poodle_null_hsync(void) +static void __init poodle_init_spi(void) { + pxa2xx_set_spi_info(1, &poodle_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices)); } - -static struct corgits_machinfo poodle_ts_machinfo = { - .get_hsync_invperiod = poodle_get_hsync_invperiod, - .put_hsync = poodle_null_hsync, - .wait_hsync = poodle_null_hsync, -}; - -static struct platform_device poodle_ts_device = { - .name = "corgi-ts", - .dev = { - .platform_data = &poodle_ts_machinfo, - }, - .id = -1, - .num_resources = ARRAY_SIZE(poodlets_resources), - .resource = poodlets_resources, -}; - +#else +static inline void poodle_init_spi(void) {} +#endif /* * MMC/SD Device @@ -199,102 +236,78 @@ static struct platform_device poodle_ts_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 poodle_mci_platform_data; - static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data) { int err; - /* setup GPIO for PXA25x MMC controller */ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - pxa_gpio_mode(POODLE_GPIO_nSD_DETECT | GPIO_IN); - pxa_gpio_mode(POODLE_GPIO_nSD_WP | GPIO_IN); - pxa_gpio_mode(POODLE_GPIO_SD_PWR | GPIO_OUT); - pxa_gpio_mode(POODLE_GPIO_SD_PWR1 | GPIO_OUT); - - poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250); + err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR"); + if (err) + goto err_free_2; - err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC card detect", data); + err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1"); if (err) - printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + goto err_free_3; + + gpio_direction_output(POODLE_GPIO_SD_PWR, 0); + gpio_direction_output(POODLE_GPIO_SD_PWR1, 0); + return 0; + +err_free_3: + gpio_free(POODLE_GPIO_SD_PWR); +err_free_2: return err; } -static void poodle_mci_setpower(struct device *dev, unsigned int vdd) +static int poodle_mci_setpower(struct device *dev, unsigned int vdd) { struct pxamci_platform_data* p_d = dev->platform_data; - if (( 1 << vdd) & p_d->ocr_mask) { - GPSR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR); + if ((1 << vdd) & p_d->ocr_mask) { + gpio_set_value(POODLE_GPIO_SD_PWR, 1); mdelay(2); - GPSR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1); + gpio_set_value(POODLE_GPIO_SD_PWR1, 1); } else { - GPCR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1); - GPCR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR); + gpio_set_value(POODLE_GPIO_SD_PWR1, 0); + gpio_set_value(POODLE_GPIO_SD_PWR, 0); } -} -static int poodle_mci_get_ro(struct device *dev) -{ - return GPLR(POODLE_GPIO_nSD_WP) & GPIO_bit(POODLE_GPIO_nSD_WP); + return 0; } - static void poodle_mci_exit(struct device *dev, void *data) { - free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data); + gpio_free(POODLE_GPIO_SD_PWR1); + gpio_free(POODLE_GPIO_SD_PWR); } static struct pxamci_platform_data poodle_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = poodle_mci_init, - .get_ro = poodle_mci_get_ro, - .setpower = poodle_mci_setpower, - .exit = poodle_mci_exit, + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = poodle_mci_init, + .setpower = poodle_mci_setpower, + .exit = poodle_mci_exit, + .gpio_card_detect = POODLE_GPIO_nSD_DETECT, + .gpio_card_ro = POODLE_GPIO_nSD_WP, + .gpio_power = -1, }; /* * Irda */ -static void poodle_irda_transceiver_mode(struct device *dev, int mode) -{ - if (mode & IR_OFF) { - GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON); - } else { - GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON); - } - pxa2xx_transceiver_mode(dev, mode); -} - static struct pxaficp_platform_data poodle_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_OFF, - .transceiver_mode = poodle_irda_transceiver_mode, + .gpio_pwdown = POODLE_GPIO_IR_ON, + .transceiver_cap = IR_SIRMODE | IR_OFF, }; /* * USB Device Controller */ -static void poodle_udc_command(int cmd) -{ - switch(cmd) { - case PXA2XX_UDC_CMD_CONNECT: - GPSR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP); - break; - case PXA2XX_UDC_CMD_DISCONNECT: - GPCR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP); - break; - } -} - static struct pxa2xx_udc_mach_info udc_info __initdata = { /* no connect GPIO; poodle can't tell connection status */ - .udc_command = poodle_udc_command, + .gpio_pullup = POODLE_GPIO_USB_PULLUP, }; @@ -316,25 +329,103 @@ static struct pxafb_mode_info poodle_fb_mode = { static struct pxafb_mach_info poodle_fb_info = { .modes = &poodle_fb_mode, .num_modes = 1, - .lccr0 = LCCR0_Act | LCCR0_Sngl | LCCR0_Color, - .lccr3 = 0, + .lcd_conn = LCD_COLOR_TFT_16BPP, +}; + +static struct mtd_partition sharpsl_nand_partitions[] = { + { + .name = "System Area", + .offset = 0, + .size = 7 * 1024 * 1024, + }, + { + .name = "Root Filesystem", + .offset = 7 * 1024 * 1024, + .size = 22 * 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 = { &poodle_locomo_device, &poodle_scoop_device, - &poodle_ssp_device, - &poodle_ts_device, + &poodle_audio_device, + &sharpsl_nand_device, + &sharpsl_rom_device, }; -static void poodle_poweroff(void) -{ - arm_machine_restart('h'); -} +static struct i2c_board_info __initdata poodle_i2c_devices[] = { + { I2C_BOARD_INFO("wm8731", 0x1b) }, +}; -static void poodle_restart(char mode) +static void poodle_poweroff(void) { - arm_machine_restart('h'); + pxa_restart(REBOOT_HARD, NULL); } static void __init poodle_init(void) @@ -342,79 +433,43 @@ static void __init poodle_init(void) int ret = 0; pm_power_off = poodle_poweroff; - arm_pm_restart = poodle_restart; - - /* setup sleep mode values */ - PWER = 0x00000002; - PFER = 0x00000000; - PRER = 0x00000002; - PGSR0 = 0x00008000; - PGSR1 = 0x003F0202; - PGSR2 = 0x0001C000; + PCFR |= PCFR_OPDE; - /* cpu initialize */ - /* Pgsr Register */ - PGSR0 = 0x0146dd80; - PGSR1 = 0x03bf0890; - PGSR2 = 0x0001c000; - - /* Alternate Register */ - GAFR0_L = 0x01001000; - GAFR0_U = 0x591a8010; - GAFR1_L = 0x900a8451; - GAFR1_U = 0xaaa5aaaa; - GAFR2_L = 0x8aaaaaaa; - GAFR2_U = 0x00000002; - - /* Direction Register */ - GPDR0 = 0xd3f0904c; - GPDR1 = 0xfcffb7d3; - GPDR2 = 0x0001ffff; - - /* Output Register */ - GPCR0 = 0x00000000; - GPCR1 = 0x00000000; - GPCR2 = 0x00000000; - - GPSR0 = 0x00400000; - GPSR1 = 0x00000000; - GPSR2 = 0x00000000; - - set_pxa_fb_parent(&poodle_locomo_device.dev); - set_pxa_fb_info(&poodle_fb_info); - pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT); - pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT); - pxa_set_udc_info(&udc_info); - pxa_set_mci_info(&poodle_mci_platform_data); - pxa_set_ficp_info(&poodle_ficp_platform_data); - pxa_set_i2c_info(NULL); + pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); platform_scoop_config = &poodle_pcmcia_config; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); - if (ret) { - printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n"); - } - corgi_ssp_set_machinfo(&poodle_ssp_machinfo); + if (ret) + pr_warning("poodle: Unable to register LoCoMo device\n"); + + pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); + pxa_set_udc_info(&udc_info); + pxa_set_mci_info(&poodle_mci_platform_data); + pxa_set_ficp_info(&poodle_ficp_platform_data); + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices)); + poodle_init_spi(); } -static void __init fixup_poodle(struct machine_desc *desc, - struct tag *tags, char **cmdline, struct meminfo *mi) +static void __init fixup_poodle(struct tag *tags, char **cmdline) { sharpsl_save_param(); - mi->nr_banks=1; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (32*1024*1024); + memblock_add(0xa0000000, SZ_32M); } MACHINE_START(POODLE, "SHARP Poodle") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_poodle, - .map_io = pxa_map_io, + .map_io = pxa25x_map_io, + .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */ .init_irq = pxa25x_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, .init_machine = poodle_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c deleted file mode 100644 index 316cd986da5..00000000000 --- a/arch/arm/mach-pxa/pwm.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/pwm.c - * - * simple driver for PWM (Pulse Width Modulator) controller - * - * 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. - * - * 2008-02-13 initial version - * eric miao <eric.miao@marvell.com> - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/pwm.h> - -#include <asm/div64.h> -#include <mach/pxa-regs.h> - -/* PWM registers and bits definitions */ -#define PWMCR (0x00) -#define PWMDCR (0x04) -#define PWMPCR (0x08) - -#define PWMCR_SD (1 << 6) -#define PWMDCR_FD (1 << 10) - -struct pwm_device { - struct list_head node; - struct platform_device *pdev; - - const char *label; - struct clk *clk; - int clk_enabled; - void __iomem *mmio_base; - - unsigned int use_count; - unsigned int pwm_id; -}; - -/* - * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE - * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE - */ -int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) -{ - unsigned long long c; - unsigned long period_cycles, prescale, pv, dc; - - if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) - return -EINVAL; - - c = clk_get_rate(pwm->clk); - c = c * period_ns; - do_div(c, 1000000000); - period_cycles = c; - - if (period_cycles < 0) - period_cycles = 1; - prescale = (period_cycles - 1) / 1024; - pv = period_cycles / (prescale + 1) - 1; - - if (prescale > 63) - return -EINVAL; - - if (duty_ns == period_ns) - dc = PWMDCR_FD; - else - dc = (pv + 1) * duty_ns / period_ns; - - /* NOTE: the clock to PWM has to be enabled first - * before writing to the registers - */ - clk_enable(pwm->clk); - __raw_writel(prescale, pwm->mmio_base + PWMCR); - __raw_writel(dc, pwm->mmio_base + PWMDCR); - __raw_writel(pv, pwm->mmio_base + PWMPCR); - clk_disable(pwm->clk); - - return 0; -} -EXPORT_SYMBOL(pwm_config); - -int pwm_enable(struct pwm_device *pwm) -{ - int rc = 0; - - if (!pwm->clk_enabled) { - rc = clk_enable(pwm->clk); - if (!rc) - pwm->clk_enabled = 1; - } - return rc; -} -EXPORT_SYMBOL(pwm_enable); - -void pwm_disable(struct pwm_device *pwm) -{ - if (pwm->clk_enabled) { - clk_disable(pwm->clk); - pwm->clk_enabled = 0; - } -} -EXPORT_SYMBOL(pwm_disable); - -static DEFINE_MUTEX(pwm_lock); -static LIST_HEAD(pwm_list); - -struct pwm_device *pwm_request(int pwm_id, const char *label) -{ - struct pwm_device *pwm; - int found = 0; - - mutex_lock(&pwm_lock); - - list_for_each_entry(pwm, &pwm_list, node) { - if (pwm->pwm_id == pwm_id) { - found = 1; - break; - } - } - - if (found) { - if (pwm->use_count == 0) { - pwm->use_count++; - pwm->label = label; - } else - pwm = ERR_PTR(-EBUSY); - } else - pwm = ERR_PTR(-ENOENT); - - mutex_unlock(&pwm_lock); - return pwm; -} -EXPORT_SYMBOL(pwm_request); - -void pwm_free(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - - if (pwm->use_count) { - pwm->use_count--; - pwm->label = NULL; - } else - pr_warning("PWM device already freed\n"); - - mutex_unlock(&pwm_lock); -} -EXPORT_SYMBOL(pwm_free); - -static inline void __add_pwm(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - list_add_tail(&pwm->node, &pwm_list); - mutex_unlock(&pwm_lock); -} - -static struct pwm_device *pwm_probe(struct platform_device *pdev, - unsigned int pwm_id, struct pwm_device *parent_pwm) -{ - struct pwm_device *pwm; - struct resource *r; - int ret = 0; - - pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); - if (pwm == NULL) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return ERR_PTR(-ENOMEM); - } - - pwm->clk = clk_get(&pdev->dev, "PWMCLK"); - if (IS_ERR(pwm->clk)) { - ret = PTR_ERR(pwm->clk); - goto err_free; - } - pwm->clk_enabled = 0; - - pwm->use_count = 0; - pwm->pwm_id = pwm_id; - pwm->pdev = pdev; - - if (parent_pwm != NULL) { - /* registers for the second PWM has offset of 0x10 */ - pwm->mmio_base = parent_pwm->mmio_base + 0x10; - __add_pwm(pwm); - return pwm; - } - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) { - dev_err(&pdev->dev, "no memory resource defined\n"); - ret = -ENODEV; - goto err_free_clk; - } - - r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); - if (r == NULL) { - dev_err(&pdev->dev, "failed to request memory resource\n"); - ret = -EBUSY; - goto err_free_clk; - } - - pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); - if (pwm->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to ioremap() registers\n"); - ret = -ENODEV; - goto err_free_mem; - } - - __add_pwm(pwm); - platform_set_drvdata(pdev, pwm); - return pwm; - -err_free_mem: - release_mem_region(r->start, r->end - r->start + 1); -err_free_clk: - clk_put(pwm->clk); -err_free: - kfree(pwm); - return ERR_PTR(ret); -} - -static int __devinit pxa25x_pwm_probe(struct platform_device *pdev) -{ - struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL); - - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - return 0; -} - -static int __devinit pxa27x_pwm_probe(struct platform_device *pdev) -{ - struct pwm_device *pwm; - - pwm = pwm_probe(pdev, pdev->id, NULL); - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - pwm = pwm_probe(pdev, pdev->id + 2, pwm); - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - return 0; -} - -static int __devexit pwm_remove(struct platform_device *pdev) -{ - struct pwm_device *pwm; - struct resource *r; - - pwm = platform_get_drvdata(pdev); - if (pwm == NULL) - return -ENODEV; - - mutex_lock(&pwm_lock); - list_del(&pwm->node); - mutex_unlock(&pwm_lock); - - iounmap(pwm->mmio_base); - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, r->end - r->start + 1); - - clk_put(pwm->clk); - kfree(pwm); - return 0; -} - -static struct platform_driver pxa25x_pwm_driver = { - .driver = { - .name = "pxa25x-pwm", - }, - .probe = pxa25x_pwm_probe, - .remove = __devexit_p(pwm_remove), -}; - -static struct platform_driver pxa27x_pwm_driver = { - .driver = { - .name = "pxa27x-pwm", - }, - .probe = pxa27x_pwm_probe, - .remove = __devexit_p(pwm_remove), -}; - -static int __init pwm_init(void) -{ - int ret = 0; - - ret = platform_driver_register(&pxa25x_pwm_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa25x_pwm_driver\n"); - return ret; - } - - ret = platform_driver_register(&pxa27x_pwm_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa27x_pwm_driver\n"); - return ret; - } - - return ret; -} -arch_initcall(pwm_init); - -static void __exit pwm_exit(void) -{ - platform_driver_unregister(&pxa25x_pwm_driver); - platform_driver_unregister(&pxa27x_pwm_driver); -} -module_exit(pwm_exit); - -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c new file mode 100644 index 00000000000..f6a2c4b1c1d --- /dev/null +++ b/arch/arm/mach-pxa/pxa-dt.c @@ -0,0 +1,63 @@ +/* + * linux/arch/arm/mach-pxa/pxa-dt.c + * + * Copyright (C) 2012 Daniel Mack + * + * 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 + * publishhed by the Free Software Foundation. + */ + +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <mach/irqs.h> +#include <mach/pxa3xx.h> + +#include "generic.h" + +#ifdef CONFIG_PXA3xx +extern void __init pxa3xx_dt_init_irq(void); + +static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL), + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL), + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL), + OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL), + OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL), + OF_DEV_AUXDATA("intel,pxa3xx-gpio", 0x40e00000, "pxa3xx-gpio", NULL), + OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL), + OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL), + OF_DEV_AUXDATA("mrvl,pwri2c", 0x40f500c0, "pxa3xx-i2c.1", NULL), + OF_DEV_AUXDATA("marvell,pxa3xx-nand", 0x43100000, "pxa3xx-nand", NULL), + {} +}; + +static void __init pxa3xx_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, + pxa3xx_auxdata_lookup, NULL); +} + +static const char *pxa3xx_dt_board_compat[] __initdata = { + "marvell,pxa300", + "marvell,pxa310", + "marvell,pxa320", + NULL, +}; +#endif + +#ifdef CONFIG_PXA3xx +DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)") + .map_io = pxa3xx_map_io, + .init_irq = pxa3xx_dt_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, + .init_machine = pxa3xx_dt_init, + .dt_compat = pxa3xx_dt_board_compat, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 305452b56e9..f2c28972084 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -16,21 +16,25 @@ * initialization stuff for PXA machines which can be overridden later if * need be. */ +#include <linux/gpio.h> +#include <linux/gpio-pxa.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/suspend.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> +#include <linux/irq.h> +#include <asm/mach/map.h> +#include <asm/suspend.h> #include <mach/hardware.h> #include <mach/irqs.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa25x.h> +#include <mach/pxa25x.h> #include <mach/reset.h> #include <mach/pm.h> #include <mach/dma.h> +#include <mach/smemc.h> #include "generic.h" #include "devices.h" @@ -91,23 +95,21 @@ unsigned int pxa25x_get_clk_frequency_khz(int info) return (turbo & 1) ? (N/1000) : (M/1000); } -/* - * Return the current memory clock frequency in units of 10kHz - */ -unsigned int pxa25x_get_memclk_frequency_10khz(void) +static unsigned long clk_pxa25x_mem_getrate(struct clk *clk) { - return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000; + return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK; } -static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk) -{ - return pxa25x_get_memclk_frequency_10khz() * 10000; -} +static const struct clkops clk_pxa25x_mem_ops = { + .enable = clk_dummy_enable, + .disable = clk_dummy_disable, + .getrate = clk_pxa25x_mem_getrate, +}; static const struct clkops clk_pxa25x_lcd_ops = { - .enable = clk_cken_enable, - .disable = clk_cken_disable, - .getrate = clk_pxa25x_lcd_getrate, + .enable = clk_pxa2xx_cken_enable, + .disable = clk_pxa2xx_cken_disable, + .getrate = clk_pxa25x_mem_getrate, }; static unsigned long gpio12_config_32k[] = { @@ -161,38 +163,62 @@ static const struct clkops clk_pxa25x_gpio11_ops = { * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) */ -static struct clk pxa25x_hwuart_clk = - INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) -; /* * PXA 2xx clock declarations. */ -static struct clk pxa25x_clks[] = { - INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), - INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), - INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), - INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), - INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa25x_device_udc.dev), - INIT_CLK("GPIO11_CLK", &clk_pxa25x_gpio11_ops, 3686400, 0, NULL), - INIT_CLK("GPIO12_CLK", &clk_pxa25x_gpio12_ops, 32768, 0, NULL), - INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), - INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), - - INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), - INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), - INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, &pxa25x_device_pwm0.dev), - INIT_CKEN("PWMCLK", PWM1, 3686400, 0, &pxa25x_device_pwm1.dev), - - INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), - - /* - INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), - */ - INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), +static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1); +static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1); +static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1); +static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1); +static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5); +static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0); +static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0); +static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0); +static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0); +static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0); +static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0); +static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0); +static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0); +static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0); +static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0); + +static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops); +static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0); +static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0); +static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0); + +static struct clk_lookup pxa25x_clkregs[] = { + INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL), + INIT_CLKREG(&clk_pxa25x_ffuart, "pxa2xx-uart.0", NULL), + INIT_CLKREG(&clk_pxa25x_btuart, "pxa2xx-uart.1", NULL), + INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-uart.2", NULL), + INIT_CLKREG(&clk_pxa25x_usb, "pxa25x-udc", NULL), + INIT_CLKREG(&clk_pxa25x_mmc, "pxa2xx-mci.0", NULL), + INIT_CLKREG(&clk_pxa25x_i2c, "pxa2xx-i2c.0", NULL), + INIT_CLKREG(&clk_pxa25x_ssp, "pxa25x-ssp.0", NULL), + INIT_CLKREG(&clk_pxa25x_nssp, "pxa25x-nssp.1", NULL), + INIT_CLKREG(&clk_pxa25x_assp, "pxa25x-nssp.2", NULL), + INIT_CLKREG(&clk_pxa25x_pwm0, "pxa25x-pwm.0", NULL), + INIT_CLKREG(&clk_pxa25x_pwm1, "pxa25x-pwm.1", NULL), + INIT_CLKREG(&clk_pxa25x_i2s, "pxa2xx-i2s", NULL), + INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-ir", "UARTCLK"), + INIT_CLKREG(&clk_pxa25x_ficp, "pxa2xx-ir", "FICPCLK"), + INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"), + INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), + INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), + INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), +#ifdef CONFIG_CPU_PXA26x + INIT_CLKREG(&clk_dummy, "pxa26x-gpio", NULL), +#else + INIT_CLKREG(&clk_dummy, "pxa25x-gpio", NULL), +#endif + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; +static struct clk_lookup pxa25x_hwuart_clkreg = + INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL); + #ifdef CONFIG_PM #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x @@ -203,49 +229,19 @@ static struct clk pxa25x_clks[] = { * More ones like CP and general purpose register values are preserved * with the stack pointer in sleep.S. */ -enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, - - SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, - SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, - SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, - +enum { SLEEP_SAVE_PSTR, - - SLEEP_SAVE_CKEN, - SLEEP_SAVE_COUNT }; static void pxa25x_cpu_pm_save(unsigned long *sleep_save) { - SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); - - SAVE(GAFR0_L); SAVE(GAFR0_U); - SAVE(GAFR1_L); SAVE(GAFR1_U); - SAVE(GAFR2_L); SAVE(GAFR2_U); - - SAVE(CKEN); SAVE(PSTR); - - /* Clear GPIO transition detect bits */ - GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; } static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) { - /* ensure not to come back here if it wasn't intended */ - PSPR = 0; - - /* restore registers */ - RESTORE(GAFR0_L); RESTORE(GAFR0_U); - RESTORE(GAFR1_L); RESTORE(GAFR1_U); - RESTORE(GAFR2_L); RESTORE(GAFR2_U); - RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); - - PSSR = PSSR_RDH | PSSR_PH; - - RESTORE(CKEN); RESTORE(PSTR); } @@ -256,19 +252,32 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: - /* set resume return address */ - PSPR = virt_to_phys(pxa_cpu_resume); - pxa25x_cpu_suspend(PWRMODE_SLEEP); + cpu_suspend(PWRMODE_SLEEP, pxa25x_finish_suspend); break; } } +static int pxa25x_cpu_pm_prepare(void) +{ + /* set resume return address */ + PSPR = virt_to_phys(cpu_resume); + return 0; +} + +static void pxa25x_cpu_pm_finish(void) +{ + /* ensure not to come back here if it wasn't intended */ + PSPR = 0; +} + static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { .save_count = SLEEP_SAVE_COUNT, .valid = suspend_valid_only_mem, .save = pxa25x_cpu_pm_save, .restore = pxa25x_cpu_pm_restore, .enter = pxa25x_cpu_pm_enter, + .prepare = pxa25x_cpu_pm_prepare, + .finish = pxa25x_cpu_pm_finish, }; static void __init pxa25x_init_pm(void) @@ -282,15 +291,15 @@ static inline void pxa25x_init_pm(void) {} /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm */ -static int pxa25x_set_wake(unsigned int irq, unsigned int on) +static int pxa25x_set_wake(struct irq_data *d, unsigned int on) { - int gpio = IRQ_TO_GPIO(irq); + int gpio = pxa_irq_to_gpio(d->irq); uint32_t mask = 0; if (gpio >= 0 && gpio < 85) return gpio_set_wake(gpio, on); - if (irq == IRQ_RTCAlrm) { + if (d->irq == IRQ_RTCAlrm) { mask = PWER_RTC; goto set_pwer; } @@ -309,65 +318,78 @@ set_pwer: void __init pxa25x_init_irq(void) { pxa_init_irq(32, pxa25x_set_wake); - pxa_init_gpio(85, pxa25x_set_wake); } +#ifdef CONFIG_CPU_PXA26x +void __init pxa26x_init_irq(void) +{ + pxa_init_irq(32, pxa25x_set_wake); +} +#endif + +static struct map_desc pxa25x_io_desc[] __initdata = { + { /* Mem Ctl */ + .virtual = (unsigned long)SMEMC_VIRT, + .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), + .length = 0x00200000, + .type = MT_DEVICE + }, +}; + +void __init pxa25x_map_io(void) +{ + pxa_map_io(); + iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc)); + pxa25x_get_clk_frequency_khz(1); +} + +static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = { + .irq_base = PXA_GPIO_TO_IRQ(0), + .gpio_set_wake = gpio_set_wake, +}; + static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_udc, - &pxa_device_ffuart, - &pxa_device_btuart, - &pxa_device_stuart, + &pxa_device_pmu, &pxa_device_i2s, - &pxa_device_rtc, + &sa1100_device_rtc, &pxa25x_device_ssp, &pxa25x_device_nssp, &pxa25x_device_assp, &pxa25x_device_pwm0, &pxa25x_device_pwm1, -}; - -static struct sys_device pxa25x_sysdev[] = { - { - .cls = &pxa_irq_sysclass, - }, { - .cls = &pxa_gpio_sysclass, - }, + &pxa_device_asoc_platform, }; static int __init pxa25x_init(void) { - int i, ret = 0; - - /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ - if (cpu_is_pxa255()) - clks_register(&pxa25x_hwuart_clk, 1); + int ret = 0; - if (cpu_is_pxa21x() || cpu_is_pxa25x()) { + if (cpu_is_pxa25x()) { reset_status = RCSR; - clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); + clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs)); - if ((ret = pxa_init_dma(16))) + if ((ret = pxa_init_dma(IRQ_DMA, 16))) return ret; pxa25x_init_pm(); - for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) { - ret = sysdev_register(&pxa25x_sysdev[i]); - if (ret) - pr_err("failed to register sysdev[%d]\n", i); - } + register_syscore_ops(&pxa_irq_syscore_ops); + register_syscore_ops(&pxa2xx_mfp_syscore_ops); + register_syscore_ops(&pxa2xx_clock_syscore_ops); + pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info); ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); if (ret) return ret; } - /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ + /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */ if (cpu_is_pxa255()) - ret = platform_device_register(&pxa_device_hwuart); + clkdev_add(&pxa25x_hwuart_clkreg); return ret; } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index f9f6a9c31f4..301471a07a1 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -11,29 +11,68 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/gpio.h> +#include <linux/gpio-pxa.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/suspend.h> #include <linux/platform_device.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/i2c/pxa-i2c.h> +#include <asm/mach/map.h> #include <mach/hardware.h> #include <asm/irq.h> +#include <asm/suspend.h> #include <mach/irqs.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa27x.h> +#include <mach/pxa27x.h> #include <mach/reset.h> -#include <mach/ohci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> #include <mach/pm.h> #include <mach/dma.h> -#include <mach/i2c.h> +#include <mach/smemc.h> #include "generic.h" #include "devices.h" #include "clock.h" +void pxa27x_clear_otgph(void) +{ + if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH)) + PSSR |= PSSR_OTGPH; +} +EXPORT_SYMBOL(pxa27x_clear_otgph); + +static unsigned long ac97_reset_config[] = { + GPIO113_AC97_nRESET_GPIO_HIGH, + GPIO113_AC97_nRESET, + GPIO95_AC97_nRESET_GPIO_HIGH, + GPIO95_AC97_nRESET, +}; + +void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio) +{ + /* + * This helper function is used to work around a bug in the pxa27x's + * ac97 controller during a warm reset. The configuration of the + * reset_gpio is changed as follows: + * to_gpio == true: configured to generic output gpio and driven high + * to_gpio == false: configured to ac97 controller alt fn AC97_nRESET + */ + + if (reset_gpio == 113) + pxa2xx_mfp_config(to_gpio ? &ac97_reset_config[0] : + &ac97_reset_config[1], 1); + + if (reset_gpio == 95) + pxa2xx_mfp_config(to_gpio ? &ac97_reset_config[2] : + &ac97_reset_config[3], 1); +} +EXPORT_SYMBOL_GPL(pxa27x_configure_ac97reset); + /* Crystal clock: 13MHz */ #define BASE_CLK 13000000 @@ -82,10 +121,9 @@ unsigned int pxa27x_get_clk_frequency_khz(int info) } /* - * Return the current mem clock frequency in units of 10kHz as - * reflected by CCCR[A], B, and L + * Return the current mem clock frequency as reflected by CCCR[A], B, and L */ -unsigned int pxa27x_get_memclk_frequency_10khz(void) +static unsigned long clk_pxa27x_mem_getrate(struct clk *clk) { unsigned long ccsr, clkcfg; unsigned int l, L, m, M; @@ -104,9 +142,15 @@ unsigned int pxa27x_get_memclk_frequency_10khz(void) L = l * BASE_CLK; M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); - return (M / 10000); + return M; } +static const struct clkops clk_pxa27x_mem_ops = { + .enable = clk_dummy_enable, + .disable = clk_dummy_disable, + .getrate = clk_pxa27x_mem_getrate, +}; + /* * Return the current LCD clock frequency in units of 10kHz as */ @@ -132,45 +176,69 @@ static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) } static const struct clkops clk_pxa27x_lcd_ops = { - .enable = clk_cken_enable, - .disable = clk_cken_disable, + .enable = clk_pxa2xx_cken_enable, + .disable = clk_pxa2xx_cken_disable, .getrate = clk_pxa27x_lcd_getrate, }; -static struct clk pxa27x_clks[] = { - INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev), - INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL), - - INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), - INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), - INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), - - INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), - INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa27x_device_udc.dev), - INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), - INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), - - INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev), - INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), - INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev), - - INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), - INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), - INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), - INIT_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), - INIT_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), - - INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), - INIT_CKEN("AC97CONFCLK", AC97CONF, 24576000, 0, NULL), - - /* - INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), - INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), - INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), - INIT_CKEN("IMCLK", IM, 0, 0, NULL), - INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL), - */ +static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); +static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1); +static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1); +static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0); +static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0); +static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5); +static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); +static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); +static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); +static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0); +static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0); + +static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops); +static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); +static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0); + +static struct clk_lookup pxa27x_clkregs[] = { + INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), + INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL), + INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL), + INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL), + INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL), + INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL), + INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL), + INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL), + INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL), + INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"), + INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"), + INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL), + INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL), + INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL), + INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL), + INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL), + INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL), + INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL), + INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL), + INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"), + INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"), + INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"), + INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"), + INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"), + INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), + INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), + INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa27x-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; #ifdef CONFIG_PM @@ -179,71 +247,60 @@ static struct clk pxa27x_clks[] = { #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] /* + * allow platforms to override default PWRMODE setting used for PM_SUSPEND_MEM + */ +static unsigned int pwrmode = PWRMODE_SLEEP; + +int __init pxa27x_set_pwrmode(unsigned int mode) +{ + switch (mode) { + case PWRMODE_SLEEP: + case PWRMODE_DEEPSLEEP: + pwrmode = mode; + return 0; + } + + return -EINVAL; +} + +/* * List of global PXA peripheral registers to preserve. * More ones like CP and general purpose register values are preserved * with the stack pointer in sleep.S. */ -enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, - - SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, - SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, - SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, - SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, - +enum { SLEEP_SAVE_PSTR, - - SLEEP_SAVE_CKEN, - SLEEP_SAVE_MDREFR, - SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, - SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, - + SLEEP_SAVE_PCFR, SLEEP_SAVE_COUNT }; void pxa27x_cpu_pm_save(unsigned long *sleep_save) { - SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); - - SAVE(GAFR0_L); SAVE(GAFR0_U); - SAVE(GAFR1_L); SAVE(GAFR1_U); - SAVE(GAFR2_L); SAVE(GAFR2_U); - SAVE(GAFR3_L); SAVE(GAFR3_U); - - SAVE(MDREFR); - SAVE(PWER); SAVE(PCFR); SAVE(PRER); - SAVE(PFER); SAVE(PKWR); + sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR); + SAVE(PCFR); - SAVE(CKEN); SAVE(PSTR); } void pxa27x_cpu_pm_restore(unsigned long *sleep_save) { - /* ensure not to come back here if it wasn't intended */ - PSPR = 0; - - /* restore registers */ - RESTORE(GAFR0_L); RESTORE(GAFR0_U); - RESTORE(GAFR1_L); RESTORE(GAFR1_U); - RESTORE(GAFR2_L); RESTORE(GAFR2_U); - RESTORE(GAFR3_L); RESTORE(GAFR3_U); - RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); - - RESTORE(MDREFR); - RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); - RESTORE(PFER); RESTORE(PKWR); + __raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR); + RESTORE(PCFR); PSSR = PSSR_RDH | PSSR_PH; - RESTORE(CKEN); - RESTORE(PSTR); } void pxa27x_cpu_pm_enter(suspend_state_t state) { extern void pxa_cpu_standby(void); +#ifndef CONFIG_IWMMXT + u64 acc0; + + asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); +#endif /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; @@ -259,9 +316,10 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) pxa_cpu_standby(); break; case PM_SUSPEND_MEM: - /* set resume return address */ - PSPR = virt_to_phys(pxa_cpu_resume); - pxa27x_cpu_suspend(PWRMODE_SLEEP); + cpu_suspend(pwrmode, pxa27x_finish_suspend); +#ifndef CONFIG_IWMMXT + asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); +#endif break; } } @@ -271,12 +329,27 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state) return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; } +static int pxa27x_cpu_pm_prepare(void) +{ + /* set resume return address */ + PSPR = virt_to_phys(cpu_resume); + return 0; +} + +static void pxa27x_cpu_pm_finish(void) +{ + /* ensure not to come back here if it wasn't intended */ + PSPR = 0; +} + static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { .save_count = SLEEP_SAVE_COUNT, .save = pxa27x_cpu_pm_save, .restore = pxa27x_cpu_pm_restore, .valid = pxa27x_cpu_pm_valid, .enter = pxa27x_cpu_pm_enter, + .prepare = pxa27x_cpu_pm_prepare, + .finish = pxa27x_cpu_pm_finish, }; static void __init pxa27x_init_pm(void) @@ -290,18 +363,18 @@ static inline void pxa27x_init_pm(void) {} /* PXA27x: Various gpios can issue wakeup events. This logic only * handles the simple cases, not the WEMUX2 and WEMUX3 options */ -static int pxa27x_set_wake(unsigned int irq, unsigned int on) +static int pxa27x_set_wake(struct irq_data *d, unsigned int on) { - int gpio = IRQ_TO_GPIO(irq); + int gpio = pxa_irq_to_gpio(d->irq); uint32_t mask; if (gpio >= 0 && gpio < 128) return gpio_set_wake(gpio, on); - if (irq == IRQ_KEYPAD) + if (d->irq == IRQ_KEYPAD) return keypad_set_wake(on); - switch (irq) { + switch (d->irq) { case IRQ_RTCAlrm: mask = PWER_RTC; break; @@ -323,48 +396,55 @@ static int pxa27x_set_wake(unsigned int irq, unsigned int on) void __init pxa27x_init_irq(void) { pxa_init_irq(34, pxa27x_set_wake); - pxa_init_gpio(128, pxa27x_set_wake); } -/* - * device registration specific to PXA27x. - */ - -static struct resource i2c_power_resources[] = { - { - .start = 0x40f00180, - .end = 0x40f001a3, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_PWRI2C, - .end = IRQ_PWRI2C, - .flags = IORESOURCE_IRQ, +static struct map_desc pxa27x_io_desc[] __initdata = { + { /* Mem Ctl */ + .virtual = (unsigned long)SMEMC_VIRT, + .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), + .length = 0x00200000, + .type = MT_DEVICE + }, { /* IMem ctl */ + .virtual = 0xfe000000, + .pfn = __phys_to_pfn(0x58000000), + .length = 0x00100000, + .type = MT_DEVICE }, }; -struct platform_device pxa27x_device_i2c_power = { - .name = "pxa2xx-i2c", - .id = 1, - .resource = i2c_power_resources, - .num_resources = ARRAY_SIZE(i2c_power_resources), -}; +void __init pxa27x_map_io(void) +{ + pxa_map_io(); + iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc)); + pxa27x_get_clk_frequency_khz(1); +} -void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) +/* + * device registration specific to PXA27x. + */ +void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info) { local_irq_disable(); PCFR |= PCFR_PI2CEN; local_irq_enable(); - pxa27x_device_i2c_power.dev.platform_data = info; + pxa_register_device(&pxa27x_device_i2c_power, info); } +static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { + .irq_base = PXA_GPIO_TO_IRQ(0), + .gpio_set_wake = gpio_set_wake, +}; + static struct platform_device *devices[] __initdata = { &pxa27x_device_udc, - &pxa_device_ffuart, - &pxa_device_btuart, - &pxa_device_stuart, + &pxa_device_pmu, &pxa_device_i2s, + &pxa_device_asoc_ssp1, + &pxa_device_asoc_ssp2, + &pxa_device_asoc_ssp3, + &pxa_device_asoc_platform, + &sa1100_device_rtc, &pxa_device_rtc, - &pxa27x_device_i2c_power, &pxa27x_device_ssp1, &pxa27x_device_ssp2, &pxa27x_device_ssp3, @@ -372,35 +452,26 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_pwm1, }; -static struct sys_device pxa27x_sysdev[] = { - { - .cls = &pxa_irq_sysclass, - }, { - .cls = &pxa_gpio_sysclass, - }, -}; - static int __init pxa27x_init(void) { - int i, ret = 0; + int ret = 0; if (cpu_is_pxa27x()) { reset_status = RCSR; - clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); + clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs)); - if ((ret = pxa_init_dma(32))) + if ((ret = pxa_init_dma(IRQ_DMA, 32))) return ret; pxa27x_init_pm(); - for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) { - ret = sysdev_register(&pxa27x_sysdev[i]); - if (ret) - pr_err("failed to register sysdev[%d]\n", i); - } + register_syscore_ops(&pxa_irq_syscore_ops); + register_syscore_ops(&pxa2xx_mfp_syscore_ops); + register_syscore_ops(&pxa2xx_clock_syscore_ops); + pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c index 73d04d81c75..447dcbb22f6 100644 --- a/arch/arm/mach-pxa/pxa2xx.c +++ b/arch/arm/mach-pxa/pxa2xx.c @@ -13,13 +13,13 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/io.h> #include <mach/hardware.h> #include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa2xx.h> #include <mach/mfp-pxa25x.h> #include <mach/reset.h> -#include <mach/irda.h> +#include <linux/platform_data/irda-pxaficp.h> void pxa2xx_clear_reset_status(unsigned int mask) { @@ -53,3 +53,4 @@ void pxa2xx_transceiver_mode(struct device *dev, int mode) } else BUG(); } +EXPORT_SYMBOL_GPL(pxa2xx_transceiver_mode); diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index 9adc7fc4618..17cbc0c7bdb 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c @@ -16,16 +16,15 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/io.h> -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> -#include <mach/mfp-pxa300.h> +#include <mach/pxa300.h> #include "generic.h" #include "devices.h" #include "clock.h" -static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = { +static struct mfp_addr_map pxa300_mfp_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO2, 0x00b4), MFP_ADDR_X(GPIO3, GPIO26, 0x027c), @@ -74,7 +73,7 @@ static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = { }; /* override pxa300 MFP register addresses */ -static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = { +static struct mfp_addr_map pxa310_mfp_addr_map[] __initdata = { MFP_ADDR_X(GPIO30, GPIO98, 0x0418), MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C), @@ -85,27 +84,31 @@ static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = { MFP_ADDR_END, }; -static struct clk common_clks[] = { - PXA3xx_CKEN("NANDCLK", NAND, 156000000, 0, &pxa3xx_device_nand.dev), +static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0); +static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0); + +static struct clk_lookup common_clkregs[] = { + INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), }; -static struct clk pxa310_clks[] = { -#ifdef CONFIG_CPU_PXA310 - PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), -#endif +static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); + +static struct clk_lookup pxa310_clkregs[] = { + INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL), }; static int __init pxa300_init(void) { if (cpu_is_pxa300() || cpu_is_pxa310()) { - pxa3xx_init_mfp(); - pxa3xx_mfp_init_addr(pxa300_mfp_addr_map); - clks_register(ARRAY_AND_SIZE(common_clks)); + mfp_init_base(io_p2v(MFPR_BASE)); + mfp_init_addr(pxa300_mfp_addr_map); + clkdev_add_table(ARRAY_AND_SIZE(common_clkregs)); } if (cpu_is_pxa310()) { - pxa3xx_mfp_init_addr(pxa310_mfp_addr_map); - clks_register(ARRAY_AND_SIZE(pxa310_clks)); + mfp_init_addr(pxa310_mfp_addr_map); + clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs)); } return 0; diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c index 016eb18f01a..6dc99d4f2dc 100644 --- a/arch/arm/mach-pxa/pxa320.c +++ b/arch/arm/mach-pxa/pxa320.c @@ -16,17 +16,15 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/io.h> -#include <mach/hardware.h> -#include <mach/mfp.h> -#include <mach/pxa3xx-regs.h> -#include <mach/mfp-pxa320.h> +#include <mach/pxa320.h> #include "generic.h" #include "devices.h" #include "clock.h" -static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { +static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO4, 0x0124), MFP_ADDR_X(GPIO5, GPIO9, 0x028C), @@ -80,16 +78,20 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { MFP_ADDR_END, }; -static struct clk pxa320_clks[] = { - PXA3xx_CKEN("NANDCLK", NAND, 104000000, 0, &pxa3xx_device_nand.dev), +static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0); +static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0); + +static struct clk_lookup pxa320_clkregs[] = { + INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), }; static int __init pxa320_init(void) { if (cpu_is_pxa320()) { - pxa3xx_init_mfp(); - pxa3xx_mfp_init_addr(pxa320_mfp_addr_map); - clks_register(ARRAY_AND_SIZE(pxa320_clks)); + mfp_init_base(io_p2v(MFPR_BASE)); + mfp_init_addr(pxa320_mfp_addr_map); + clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs)); } return 0; diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c new file mode 100644 index 00000000000..e329ccefd36 --- /dev/null +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -0,0 +1,391 @@ +/* + * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c + * + * code specific to pxa3xx aka Monahans + * + * Copyright (C) 2010 CompuLab Ltd. + * + * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il> + * initial version: pxa310 USB Host mode support + * + * 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/slab.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/usb.h> +#include <linux/usb/otg.h> + +#include <mach/hardware.h> +#include <mach/regs-u2d.h> +#include <linux/platform_data/usb-pxa3xx-ulpi.h> + +struct pxa3xx_u2d_ulpi { + struct clk *clk; + void __iomem *mmio_base; + + struct usb_phy *otg; + unsigned int ulpi_mode; +}; + +static struct pxa3xx_u2d_ulpi *u2d; + +static inline u32 u2d_readl(u32 reg) +{ + return __raw_readl(u2d->mmio_base + reg); +} + +static inline void u2d_writel(u32 reg, u32 val) +{ + __raw_writel(val, u2d->mmio_base + reg); +} + +#if defined(CONFIG_PXA310_ULPI) +enum u2d_ulpi_phy_mode { + SYNCH = 0, + CARKIT = (1 << 0), + SER_3PIN = (1 << 1), + SER_6PIN = (1 << 2), + LOWPOWER = (1 << 3), +}; + +static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void) +{ + return (u2d_readl(U2DOTGUSR) >> 28) & 0xF; +} + +static int pxa310_ulpi_poll(void) +{ + int timeout = 50000; + + while (timeout--) { + if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN)) + return 0; + + cpu_relax(); + } + + pr_warning("%s: ULPI access timed out!\n", __func__); + + return -ETIMEDOUT; +} + +static int pxa310_ulpi_read(struct usb_phy *otg, u32 reg) +{ + int err; + + if (pxa310_ulpi_get_phymode() != SYNCH) { + pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); + return -EBUSY; + } + + u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16)); + msleep(5); + + err = pxa310_ulpi_poll(); + if (err) + return err; + + return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA; +} + +static int pxa310_ulpi_write(struct usb_phy *otg, u32 val, u32 reg) +{ + if (pxa310_ulpi_get_phymode() != SYNCH) { + pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); + return -EBUSY; + } + + u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8)); + msleep(5); + + return pxa310_ulpi_poll(); +} + +struct usb_phy_io_ops pxa310_ulpi_access_ops = { + .read = pxa310_ulpi_read, + .write = pxa310_ulpi_write, +}; + +static void pxa310_otg_transceiver_rtsm(void) +{ + u32 u2dotgcr; + + /* put PHY to sync mode */ + u2dotgcr = u2d_readl(U2DOTGCR); + u2dotgcr |= U2DOTGCR_RTSM | U2DOTGCR_UTMID; + u2d_writel(U2DOTGCR, u2dotgcr); + msleep(10); + + /* setup OTG sync mode */ + u2dotgcr = u2d_readl(U2DOTGCR); + u2dotgcr |= U2DOTGCR_ULAF; + u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF); + u2d_writel(U2DOTGCR, u2dotgcr); +} + +static int pxa310_start_otg_host_transcvr(struct usb_bus *host) +{ + int err; + + pxa310_otg_transceiver_rtsm(); + + err = usb_phy_init(u2d->otg); + if (err) { + pr_err("OTG transceiver init failed"); + return err; + } + + err = otg_set_vbus(u2d->otg->otg, 1); + if (err) { + pr_err("OTG transceiver VBUS set failed"); + return err; + } + + err = otg_set_host(u2d->otg->otg, host); + if (err) + pr_err("OTG transceiver Host mode set failed"); + + return err; +} + +static int pxa310_start_otg_hc(struct usb_bus *host) +{ + u32 u2dotgcr; + int err; + + /* disable USB device controller */ + u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE); + u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID); + u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F); + + err = pxa310_start_otg_host_transcvr(host); + if (err) + return err; + + /* set xceiver mode */ + if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL) + u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS); + else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL) + u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS); + + /* start OTG host controller */ + u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF; + u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF)); + + return 0; +} + +static void pxa310_stop_otg_hc(void) +{ + pxa310_otg_transceiver_rtsm(); + + otg_set_host(u2d->otg->otg, NULL); + otg_set_vbus(u2d->otg->otg, 0); + usb_phy_shutdown(u2d->otg); +} + +static void pxa310_u2d_setup_otg_hc(void) +{ + u32 u2dotgcr; + + u2dotgcr = u2d_readl(U2DOTGCR); + u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID; + u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF); + u2d_writel(U2DOTGCR, u2dotgcr); + msleep(5); + u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE); + msleep(5); + u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F); +} + +static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata) +{ + unsigned int ulpi_mode = ULPI_OTG_DRVVBUS; + + if (pdata) { + if (pdata->ulpi_mode & ULPI_SER_6PIN) + ulpi_mode |= ULPI_IC_6PIN_SERIAL; + else if (pdata->ulpi_mode & ULPI_SER_3PIN) + ulpi_mode |= ULPI_IC_3PIN_SERIAL; + } + + u2d->ulpi_mode = ulpi_mode; + + u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode); + if (!u2d->otg) + return -ENOMEM; + + u2d->otg->io_priv = u2d->mmio_base; + + return 0; +} + +static void pxa310_otg_exit(void) +{ + kfree(u2d->otg); +} +#else +static inline void pxa310_u2d_setup_otg_hc(void) {} +static inline int pxa310_start_otg_hc(struct usb_bus *host) +{ + return 0; +} +static inline void pxa310_stop_otg_hc(void) {} +static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata) +{ + return 0; +} +static inline void pxa310_otg_exit(void) {} +#endif /* CONFIG_PXA310_ULPI */ + +int pxa3xx_u2d_start_hc(struct usb_bus *host) +{ + int err = 0; + + /* In case the PXA3xx ULPI isn't used, do nothing. */ + if (!u2d) + return 0; + + clk_enable(u2d->clk); + + if (cpu_is_pxa310()) { + pxa310_u2d_setup_otg_hc(); + err = pxa310_start_otg_hc(host); + } + + return err; +} +EXPORT_SYMBOL_GPL(pxa3xx_u2d_start_hc); + +void pxa3xx_u2d_stop_hc(struct usb_bus *host) +{ + /* In case the PXA3xx ULPI isn't used, do nothing. */ + if (!u2d) + return; + + if (cpu_is_pxa310()) + pxa310_stop_otg_hc(); + + clk_disable(u2d->clk); +} +EXPORT_SYMBOL_GPL(pxa3xx_u2d_stop_hc); + +static int pxa3xx_u2d_probe(struct platform_device *pdev) +{ + struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data; + struct resource *r; + int err; + + u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); + if (!u2d) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + u2d->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(u2d->clk)) { + dev_err(&pdev->dev, "failed to get u2d clock\n"); + err = PTR_ERR(u2d->clk); + goto err_free_mem; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no IO memory resource defined\n"); + err = -ENODEV; + goto err_put_clk; + } + + r = request_mem_region(r->start, resource_size(r), pdev->name); + if (!r) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + err = -EBUSY; + goto err_put_clk; + } + + u2d->mmio_base = ioremap(r->start, resource_size(r)); + if (!u2d->mmio_base) { + dev_err(&pdev->dev, "ioremap() failed\n"); + err = -ENODEV; + goto err_free_res; + } + + if (pdata->init) { + err = pdata->init(&pdev->dev); + if (err) + goto err_free_io; + } + + /* Only PXA310 U2D has OTG functionality */ + if (cpu_is_pxa310()) { + err = pxa310_otg_init(pdata); + if (err) + goto err_free_plat; + } + + platform_set_drvdata(pdev, &u2d); + + return 0; + +err_free_plat: + if (pdata->exit) + pdata->exit(&pdev->dev); +err_free_io: + iounmap(u2d->mmio_base); +err_free_res: + release_mem_region(r->start, resource_size(r)); +err_put_clk: + clk_put(u2d->clk); +err_free_mem: + kfree(u2d); + return err; +} + +static int pxa3xx_u2d_remove(struct platform_device *pdev) +{ + struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data; + struct resource *r; + + if (cpu_is_pxa310()) { + pxa310_stop_otg_hc(); + pxa310_otg_exit(); + } + + if (pdata->exit) + pdata->exit(&pdev->dev); + + platform_set_drvdata(pdev, NULL); + iounmap(u2d->mmio_base); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, resource_size(r)); + + clk_put(u2d->clk); + + kfree(u2d); + + return 0; +} + +static struct platform_driver pxa3xx_u2d_ulpi_driver = { + .driver = { + .name = "pxa3xx-u2d", + .owner = THIS_MODULE, + }, + .probe = pxa3xx_u2d_probe, + .remove = pxa3xx_u2d_remove, +}; +module_platform_driver(pxa3xx_u2d_ulpi_driver); + +MODULE_DESCRIPTION("PXA3xx U2D ULPI driver"); +MODULE_AUTHOR("Igor Grinberg"); +MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 03cbc38103e..87011f3de69 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -12,227 +12,90 @@ * 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/gpio-pxa.h> #include <linux/pm.h> #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/io.h> -#include <linux/sysdev.h> +#include <linux/of.h> +#include <linux/syscore_ops.h> +#include <linux/i2c/pxa-i2c.h> +#include <asm/mach/map.h> +#include <asm/suspend.h> #include <mach/hardware.h> #include <mach/pxa3xx-regs.h> #include <mach/reset.h> -#include <mach/ohci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> #include <mach/pm.h> #include <mach/dma.h> -#include <mach/ssp.h> +#include <mach/smemc.h> +#include <mach/irqs.h> #include "generic.h" #include "devices.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 static memory controller multiplier (SMCFS) */ -static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; - -/* crystal frequency to HSIO bus frequency multiplier (HSS) */ -static unsigned char hss_mult[4] = { 8, 12, 16, 0 }; - -/* - * 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 static memory controller clock frequency - * in units of 10kHz - */ -unsigned int pxa3xx_get_memclk_frequency_10khz(void) -{ - unsigned long acsr; - unsigned int smcfs, clk = 0; - - acsr = ACSR; - - smcfs = (acsr >> 23) & 0x7; - clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK; - - return (clk / 10000); -} - -void pxa3xx_clear_reset_status(unsigned int mask) -{ - /* RESET_STATUS_* has a 1:1 mapping with ARSR */ - ARSR = mask; -} - -/* - * 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; -} - -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, -}; - -static const struct clkops clk_pxa3xx_hsio_ops = { - .enable = clk_pxa3xx_cken_enable, - .disable = clk_pxa3xx_cken_disable, - .getrate = clk_pxa3xx_hsio_getrate, -}; - -static const struct clkops clk_pxa3xx_ac97_ops = { - .enable = clk_pxa3xx_cken_enable, - .disable = clk_pxa3xx_cken_disable, - .getrate = clk_pxa3xx_ac97_getrate, -}; - -static void clk_pout_enable(struct clk *clk) -{ - OSCC |= OSCC_PEN; -} - -static void clk_pout_disable(struct clk *clk) -{ - OSCC &= ~OSCC_PEN; -} - -static const struct clkops clk_pout_ops = { - .enable = clk_pout_enable, - .disable = clk_pout_disable, -}; - -static struct clk pxa3xx_clks[] = { - { - .name = "CLK_POUT", - .ops = &clk_pout_ops, - .rate = 13000000, - .delay = 70, - }, - - PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev), - PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL), - PXA3xx_CK("AC97CLK", AC97, &clk_pxa3xx_ac97_ops, NULL), - - PXA3xx_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), - PXA3xx_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), - PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL), - - PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa27x_device_udc.dev), - PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev), - PXA3xx_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev), - - PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), - PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), - PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), - PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev), - PXA3xx_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), - PXA3xx_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), - - PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), - PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), +#define PECR_IE(n) ((1 << ((n) * 2)) << 28) +#define PECR_IS(n) ((1 << ((n) * 2)) << 29) + +extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)); + +static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); +static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); +static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); +static DEFINE_PXA3_CKEN(pxa3xx_i2c, I2C, 32842000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_udc, UDC, 48000000, 5); +static DEFINE_PXA3_CKEN(pxa3xx_usbh, USBH, 48000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_u2d, USB2, 48000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_keypad, KEYPAD, 32768, 0); +static DEFINE_PXA3_CKEN(pxa3xx_ssp1, SSP1, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_ssp2, SSP2, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_ssp3, SSP3, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_ssp4, SSP4, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); +static DEFINE_PXA3_CKEN(pxa3xx_gpio, GPIO, 13000000, 0); + +static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); +static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); +static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); +static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); +static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70); + +static struct clk_lookup pxa3xx_clkregs[] = { + INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), + /* Power I2C clock is always on */ + INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), + INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), + INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), + INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), + INIT_CLKREG(&clk_pxa3xx_ffuart, "pxa2xx-uart.0", NULL), + INIT_CLKREG(&clk_pxa3xx_btuart, "pxa2xx-uart.1", NULL), + INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-uart.2", NULL), + INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-ir", "UARTCLK"), + INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL), + INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL), + INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL), + INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL), + INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL), + INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL), + INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL), + INIT_CLKREG(&clk_pxa3xx_ssp3, "pxa27x-ssp.2", NULL), + INIT_CLKREG(&clk_pxa3xx_ssp4, "pxa27x-ssp.3", NULL), + INIT_CLKREG(&clk_pxa3xx_pwm0, "pxa27x-pwm.0", NULL), + INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), + INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), + INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), + INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_pxa3xx_gpio, "pxa3xx-gpio", NULL), + INIT_CLKREG(&clk_pxa3xx_gpio, "pxa93x-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; #ifdef CONFIG_PM @@ -243,30 +106,6 @@ static struct clk pxa3xx_clks[] = { static void __iomem *sram; static unsigned long wakeup_src; -#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x -#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] - -enum { SLEEP_SAVE_CKENA, - SLEEP_SAVE_CKENB, - SLEEP_SAVE_ACCR, - - SLEEP_SAVE_COUNT, -}; - -static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) -{ - SAVE(CKENA); - SAVE(CKENB); - SAVE(ACCR); -} - -static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) -{ - RESTORE(ACCR); - RESTORE(CKENA); - RESTORE(CKENB); -} - /* * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic * memory controller has to be reinitialised, so we place some code @@ -309,9 +148,13 @@ static void pxa3xx_cpu_pm_suspend(void) { volatile unsigned long *p = (volatile void *)0xc0000000; unsigned long saved_data = *p; +#ifndef CONFIG_IWMMXT + u64 acc0; - extern void pxa3xx_cpu_suspend(void); - extern void pxa3xx_cpu_resume(void); + asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); +#endif + + extern int pxa3xx_finish_suspend(unsigned long); /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); @@ -329,13 +172,17 @@ static void pxa3xx_cpu_pm_suspend(void) PSPR = 0x5c014000; /* overwrite with the resume address */ - *p = virt_to_phys(pxa3xx_cpu_resume); + *p = virt_to_phys(cpu_resume); - pxa3xx_cpu_suspend(); + cpu_suspend(0, pxa3xx_finish_suspend); *p = saved_data; AD3ER = 0; + +#ifndef CONFIG_IWMMXT + asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); +#endif } static void pxa3xx_cpu_pm_enter(suspend_state_t state) @@ -365,9 +212,6 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { - .save_count = SLEEP_SAVE_COUNT, - .save = pxa3xx_cpu_pm_save, - .restore = pxa3xx_cpu_pm_restore, .valid = pxa3xx_cpu_pm_valid, .enter = pxa3xx_cpu_pm_enter, }; @@ -400,11 +244,11 @@ static void __init pxa3xx_init_pm(void) pxa_cpu_pm_fns = &pxa3xx_cpu_pm_fns; } -static int pxa3xx_set_wake(unsigned int irq, unsigned int on) +static int pxa3xx_set_wake(struct irq_data *d, unsigned int on) { unsigned long flags, mask = 0; - switch (irq) { + switch (d->irq) { case IRQ_SSP3: mask = ADXER_MFP_WSSP3; break; @@ -493,7 +337,57 @@ static inline void pxa3xx_init_pm(void) {} #define pxa3xx_set_wake NULL #endif -void __init pxa3xx_init_irq(void) +static void pxa_ack_ext_wakeup(struct irq_data *d) +{ + PECR |= PECR_IS(d->irq - IRQ_WAKEUP0); +} + +static void pxa_mask_ext_wakeup(struct irq_data *d) +{ + pxa_mask_irq(d); + PECR &= ~PECR_IE(d->irq - IRQ_WAKEUP0); +} + +static void pxa_unmask_ext_wakeup(struct irq_data *d) +{ + pxa_unmask_irq(d); + PECR |= PECR_IE(d->irq - IRQ_WAKEUP0); +} + +static int pxa_set_ext_wakeup_type(struct irq_data *d, unsigned int flow_type) +{ + if (flow_type & IRQ_TYPE_EDGE_RISING) + PWER |= 1 << (d->irq - IRQ_WAKEUP0); + + if (flow_type & IRQ_TYPE_EDGE_FALLING) + PWER |= 1 << (d->irq - IRQ_WAKEUP0 + 2); + + return 0; +} + +static struct irq_chip pxa_ext_wakeup_chip = { + .name = "WAKEUP", + .irq_ack = pxa_ack_ext_wakeup, + .irq_mask = pxa_mask_ext_wakeup, + .irq_unmask = pxa_unmask_ext_wakeup, + .irq_set_type = pxa_set_ext_wakeup_type, +}; + +static void __init pxa_init_ext_wakeup_irq(int (*fn)(struct irq_data *, + unsigned int)) +{ + int irq; + + for (irq = IRQ_WAKEUP0; irq <= IRQ_WAKEUP1; irq++) { + irq_set_chip_and_handler(irq, &pxa_ext_wakeup_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID); + } + + pxa_ext_wakeup_chip.irq_set_wake = fn; +} + +static void __init __pxa3xx_init_irq(void) { /* enable CP6 access */ u32 value; @@ -501,20 +395,62 @@ void __init pxa3xx_init_irq(void) value |= (1 << 6); __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value)); + pxa_init_ext_wakeup_irq(pxa3xx_set_wake); +} + +void __init pxa3xx_init_irq(void) +{ + __pxa3xx_init_irq(); pxa_init_irq(56, pxa3xx_set_wake); - pxa_init_gpio(128, NULL); +} + +#ifdef CONFIG_OF +void __init pxa3xx_dt_init_irq(void) +{ + __pxa3xx_init_irq(); + pxa_dt_irq_init(pxa3xx_set_wake); +} +#endif /* CONFIG_OF */ + +static struct map_desc pxa3xx_io_desc[] __initdata = { + { /* Mem Ctl */ + .virtual = (unsigned long)SMEMC_VIRT, + .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE), + .length = 0x00200000, + .type = MT_DEVICE + } +}; + +void __init pxa3xx_map_io(void) +{ + pxa_map_io(); + iotable_init(ARRAY_AND_SIZE(pxa3xx_io_desc)); + pxa3xx_get_clk_frequency_khz(1); } /* * device registration specific to PXA3xx. */ +void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_i2c_power, info); +} + +static struct pxa_gpio_platform_data pxa3xx_gpio_pdata = { + .irq_base = PXA_GPIO_TO_IRQ(0), +}; + static struct platform_device *devices[] __initdata = { -/* &pxa_device_udc, The UDC driver is PXA25x only */ - &pxa_device_ffuart, - &pxa_device_btuart, - &pxa_device_stuart, + &pxa27x_device_udc, + &pxa_device_pmu, &pxa_device_i2s, + &pxa_device_asoc_ssp1, + &pxa_device_asoc_ssp2, + &pxa_device_asoc_ssp3, + &pxa_device_asoc_ssp4, + &pxa_device_asoc_platform, + &sa1100_device_rtc, &pxa_device_rtc, &pxa27x_device_ssp1, &pxa27x_device_ssp2, @@ -524,19 +460,9 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_pwm1, }; -static struct sys_device pxa3xx_sysdev[] = { - { - .cls = &pxa_irq_sysclass, - }, { - .cls = &pxa3xx_mfp_sysclass, - }, { - .cls = &pxa_gpio_sysclass, - }, -}; - static int __init pxa3xx_init(void) { - int i, ret = 0; + int ret = 0; if (cpu_is_pxa3xx()) { @@ -550,20 +476,29 @@ static int __init pxa3xx_init(void) */ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); - clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); + clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs)); - if ((ret = pxa_init_dma(32))) + if ((ret = pxa_init_dma(IRQ_DMA, 32))) return ret; pxa3xx_init_pm(); - for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) { - ret = sysdev_register(&pxa3xx_sysdev[i]); - if (ret) - pr_err("failed to register sysdev[%d]\n", i); - } + register_syscore_ops(&pxa_irq_syscore_ops); + register_syscore_ops(&pxa3xx_mfp_syscore_ops); + register_syscore_ops(&pxa3xx_clock_syscore_ops); + + if (of_have_populated_dt()) + return 0; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + if (ret) + return ret; + if (cpu_is_pxa300() || cpu_is_pxa310() || cpu_is_pxa320()) { + platform_device_add_data(&pxa3xx_device_gpio, + &pxa3xx_gpio_pdata, + sizeof(pxa3xx_gpio_pdata)); + ret = platform_device_register(&pxa3xx_device_gpio); + } } return ret; diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c index 13e6bfdfff6..ab624487cf3 100644 --- a/arch/arm/mach-pxa/pxa930.c +++ b/arch/arm/mach-pxa/pxa930.c @@ -12,14 +12,16 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/irq.h> #include <linux/dma-mapping.h> +#include <linux/irq.h> +#include <linux/gpio-pxa.h> +#include <linux/platform_device.h> -#include <mach/hardware.h> -#include <mach/mfp-pxa930.h> +#include <mach/pxa930.h> -static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = { +#include "devices.h" + +static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = { MFP_ADDR(GPIO0, 0x02e0), MFP_ADDR(GPIO1, 0x02dc), @@ -177,13 +179,40 @@ static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = { MFP_ADDR_END, }; +static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = { + MFP_ADDR(GPIO159, 0x0524), + MFP_ADDR(GPIO163, 0x0534), + MFP_ADDR(GPIO167, 0x0544), + MFP_ADDR(GPIO168, 0x0548), + MFP_ADDR(GPIO169, 0x054c), + MFP_ADDR(GPIO170, 0x0550), + MFP_ADDR(GPIO171, 0x0554), + MFP_ADDR(GPIO172, 0x0558), + MFP_ADDR(GPIO173, 0x055c), + + MFP_ADDR_END, +}; + +static struct pxa_gpio_platform_data pxa93x_gpio_pdata = { + .irq_base = PXA_GPIO_TO_IRQ(0), +}; + static int __init pxa930_init(void) { - if (cpu_is_pxa930()) { - pxa3xx_init_mfp(); - pxa3xx_mfp_init_addr(pxa930_mfp_addr_map); + int ret = 0; + + if (cpu_is_pxa93x()) { + mfp_init_base(io_p2v(MFPR_BASE)); + mfp_init_addr(pxa930_mfp_addr_map); + platform_device_add_data(&pxa93x_device_gpio, + &pxa93x_gpio_pdata, + sizeof(pxa93x_gpio_pdata)); + ret = platform_device_register(&pxa93x_device_gpio); } + if (cpu_is_pxa935()) + mfp_init_addr(pxa935_mfp_addr_map); + return 0; } diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c new file mode 100644 index 00000000000..8386dc30b3e --- /dev/null +++ b/arch/arm/mach-pxa/raumfeld.c @@ -0,0 +1,1129 @@ +/* + * arch/arm/mach-pxa/raumfeld.c + * + * Support for the following Raumfeld devices: + * + * * Controller + * * Connector + * * Speaker S/M + * + * See http://www.raumfeld.com for details. + * + * Copyright (c) 2009 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/interrupt.h> +#include <linux/gpio.h> +#include <linux/smsc911x.h> +#include <linux/input.h> +#include <linux/rotary_encoder.h> +#include <linux/gpio_keys.h> +#include <linux/input/eeti_ts.h> +#include <linux/leds.h> +#include <linux/w1-gpio.h> +#include <linux/sched.h> +#include <linux/pwm_backlight.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/spi/spi.h> +#include <linux/spi/spi_gpio.h> +#include <linux/lis3lv02d.h> +#include <linux/pda_power.h> +#include <linux/power_supply.h> +#include <linux/regulator/max8660.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/consumer.h> +#include <linux/delay.h> + +#include <asm/system_info.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa300.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/mtd-nand-pxa3xx.h> + +#include "generic.h" +#include "devices.h" +#include "clock.h" + +/* common GPIO definitions */ + +/* inputs */ +#define GPIO_ON_OFF (14) +#define GPIO_VOLENC_A (19) +#define GPIO_VOLENC_B (20) +#define GPIO_CHARGE_DONE (23) +#define GPIO_CHARGE_IND (27) +#define GPIO_TOUCH_IRQ (32) +#define GPIO_ETH_IRQ (40) +#define GPIO_SPI_MISO (98) +#define GPIO_ACCEL_IRQ (104) +#define GPIO_RESCUE_BOOT (115) +#define GPIO_DOCK_DETECT (116) +#define GPIO_KEY1 (117) +#define GPIO_KEY2 (118) +#define GPIO_KEY3 (119) +#define GPIO_CHARGE_USB_OK (112) +#define GPIO_CHARGE_DC_OK (101) +#define GPIO_CHARGE_USB_SUSP (102) + +/* outputs */ +#define GPIO_SHUTDOWN_SUPPLY (16) +#define GPIO_SHUTDOWN_BATT (18) +#define GPIO_CHRG_PEN2 (31) +#define GPIO_TFT_VA_EN (33) +#define GPIO_SPDIF_CS (34) +#define GPIO_LED2 (35) +#define GPIO_LED1 (36) +#define GPIO_SPDIF_RESET (38) +#define GPIO_SPI_CLK (95) +#define GPIO_MCLK_DAC_CS (96) +#define GPIO_SPI_MOSI (97) +#define GPIO_W1_PULLUP_ENABLE (105) +#define GPIO_DISPLAY_ENABLE (106) +#define GPIO_MCLK_RESET (111) +#define GPIO_W2W_RESET (113) +#define GPIO_W2W_PDN (114) +#define GPIO_CODEC_RESET (120) +#define GPIO_AUDIO_VA_ENABLE (124) +#define GPIO_ACCEL_CS (125) +#define GPIO_ONE_WIRE (126) + +/* + * GPIO configurations + */ +static mfp_cfg_t raumfeld_controller_pin_config[] __initdata = { + /* UART1 */ + GPIO77_UART1_RXD, + GPIO78_UART1_TXD, + GPIO79_UART1_CTS, + GPIO81_UART1_DSR, + GPIO83_UART1_DTR, + GPIO84_UART1_RTS, + + /* UART3 */ + GPIO110_UART3_RXD, + + /* USB Host */ + GPIO0_2_USBH_PEN, + GPIO1_2_USBH_PWR, + + /* I2C */ + GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + + /* SPI */ + GPIO34_GPIO, /* SPDIF_CS */ + GPIO96_GPIO, /* MCLK_CS */ + GPIO125_GPIO, /* ACCEL_CS */ + + /* MMC */ + GPIO3_MMC1_DAT0, + GPIO4_MMC1_DAT1, + GPIO5_MMC1_DAT2, + GPIO6_MMC1_DAT3, + GPIO7_MMC1_CLK, + GPIO8_MMC1_CMD, + + /* One-wire */ + GPIO126_GPIO | MFP_LPM_FLOAT, + GPIO105_GPIO | MFP_PULL_LOW | MFP_LPM_PULL_LOW, + + /* CHRG_USB_OK */ + GPIO101_GPIO | MFP_PULL_HIGH, + /* CHRG_USB_OK */ + GPIO112_GPIO | MFP_PULL_HIGH, + /* CHRG_USB_SUSP */ + GPIO102_GPIO, + /* DISPLAY_ENABLE */ + GPIO106_GPIO, + /* DOCK_DETECT */ + GPIO116_GPIO | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + + /* 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, + GPIO70_LCD_LDD_16, + GPIO71_LCD_LDD_17, + GPIO72_LCD_FCLK, + GPIO73_LCD_LCLK, + GPIO74_LCD_PCLK, + GPIO75_LCD_BIAS, +}; + +static mfp_cfg_t raumfeld_connector_pin_config[] __initdata = { + /* UART1 */ + GPIO77_UART1_RXD, + GPIO78_UART1_TXD, + GPIO79_UART1_CTS, + GPIO81_UART1_DSR, + GPIO83_UART1_DTR, + GPIO84_UART1_RTS, + + /* UART3 */ + GPIO110_UART3_RXD, + + /* USB Host */ + GPIO0_2_USBH_PEN, + GPIO1_2_USBH_PWR, + + /* I2C */ + GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + + /* SPI */ + GPIO34_GPIO, /* SPDIF_CS */ + GPIO96_GPIO, /* MCLK_CS */ + GPIO125_GPIO, /* ACCEL_CS */ + + /* MMC */ + GPIO3_MMC1_DAT0, + GPIO4_MMC1_DAT1, + GPIO5_MMC1_DAT2, + GPIO6_MMC1_DAT3, + GPIO7_MMC1_CLK, + GPIO8_MMC1_CMD, + + /* Ethernet */ + GPIO1_nCS2, /* CS */ + GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */ + + /* SSP for I2S */ + GPIO85_SSP1_SCLK, + GPIO89_SSP1_EXTCLK, + GPIO86_SSP1_FRM, + GPIO87_SSP1_TXD, + GPIO88_SSP1_RXD, + GPIO90_SSP1_SYSCLK, + + /* SSP2 for S/PDIF */ + GPIO25_SSP2_SCLK, + GPIO26_SSP2_FRM, + GPIO27_SSP2_TXD, + GPIO29_SSP2_EXTCLK, + + /* LEDs */ + GPIO35_GPIO | MFP_LPM_PULL_LOW, + GPIO36_GPIO | MFP_LPM_DRIVE_HIGH, +}; + +static mfp_cfg_t raumfeld_speaker_pin_config[] __initdata = { + /* UART1 */ + GPIO77_UART1_RXD, + GPIO78_UART1_TXD, + GPIO79_UART1_CTS, + GPIO81_UART1_DSR, + GPIO83_UART1_DTR, + GPIO84_UART1_RTS, + + /* UART3 */ + GPIO110_UART3_RXD, + + /* USB Host */ + GPIO0_2_USBH_PEN, + GPIO1_2_USBH_PWR, + + /* I2C */ + GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT, + + /* SPI */ + GPIO34_GPIO, /* SPDIF_CS */ + GPIO96_GPIO, /* MCLK_CS */ + GPIO125_GPIO, /* ACCEL_CS */ + + /* MMC */ + GPIO3_MMC1_DAT0, + GPIO4_MMC1_DAT1, + GPIO5_MMC1_DAT2, + GPIO6_MMC1_DAT3, + GPIO7_MMC1_CLK, + GPIO8_MMC1_CMD, + + /* Ethernet */ + GPIO1_nCS2, /* CS */ + GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */ + + /* SSP for I2S */ + GPIO85_SSP1_SCLK, + GPIO89_SSP1_EXTCLK, + GPIO86_SSP1_FRM, + GPIO87_SSP1_TXD, + GPIO88_SSP1_RXD, + GPIO90_SSP1_SYSCLK, + + /* LEDs */ + GPIO35_GPIO | MFP_LPM_PULL_LOW, + GPIO36_GPIO | MFP_LPM_DRIVE_HIGH, +}; + +/* + * SMSC LAN9220 Ethernet + */ + +static struct resource smc91x_resources[] = { + { + .start = PXA3xx_CS2_PHYS, + .end = PXA3xx_CS2_PHYS + 0xfffff, + .flags = IORESOURCE_MEM, + }, + { + .start = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ), + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, + } +}; + +static struct smsc911x_platform_config raumfeld_smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, +}; + +static struct platform_device smc91x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &raumfeld_smsc911x_config, + } +}; + +/** + * NAND + */ + +static struct mtd_partition raumfeld_nand_partitions[] = { + { + .name = "Bootloader", + .offset = 0, + .size = 0xa0000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "BootloaderEnvironment", + .offset = 0xa0000, + .size = 0x20000, + }, + { + .name = "BootloaderSplashScreen", + .offset = 0xc0000, + .size = 0x60000, + }, + { + .name = "UBI", + .offset = 0x120000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct pxa3xx_nand_platform_data raumfeld_nand_info = { + .enable_arbiter = 1, + .keep_config = 1, + .num_cs = 1, + .parts[0] = raumfeld_nand_partitions, + .nr_parts[0] = ARRAY_SIZE(raumfeld_nand_partitions), +}; + +/** + * USB (OHCI) support + */ + +static struct pxaohci_platform_data raumfeld_ohci_info = { + .port_mode = PMM_GLOBAL_MODE, + .flags = ENABLE_PORT1, +}; + +/** + * Rotary encoder input device + */ + +static struct rotary_encoder_platform_data raumfeld_rotary_encoder_info = { + .steps = 24, + .axis = REL_X, + .relative_axis = 1, + .gpio_a = GPIO_VOLENC_A, + .gpio_b = GPIO_VOLENC_B, + .inverted_a = 1, + .inverted_b = 0, +}; + +static struct platform_device rotary_encoder_device = { + .name = "rotary-encoder", + .id = 0, + .dev = { + .platform_data = &raumfeld_rotary_encoder_info, + } +}; + +/** + * GPIO buttons + */ + +static struct gpio_keys_button gpio_keys_button[] = { + { + .code = KEY_F1, + .type = EV_KEY, + .gpio = GPIO_KEY1, + .active_low = 1, + .wakeup = 0, + .debounce_interval = 5, /* ms */ + .desc = "Button 1", + }, + { + .code = KEY_F2, + .type = EV_KEY, + .gpio = GPIO_KEY2, + .active_low = 1, + .wakeup = 0, + .debounce_interval = 5, /* ms */ + .desc = "Button 2", + }, + { + .code = KEY_F3, + .type = EV_KEY, + .gpio = GPIO_KEY3, + .active_low = 1, + .wakeup = 0, + .debounce_interval = 5, /* ms */ + .desc = "Button 3", + }, + { + .code = KEY_F4, + .type = EV_KEY, + .gpio = GPIO_RESCUE_BOOT, + .active_low = 0, + .wakeup = 0, + .debounce_interval = 5, /* ms */ + .desc = "rescue boot button", + }, + { + .code = KEY_F5, + .type = EV_KEY, + .gpio = GPIO_DOCK_DETECT, + .active_low = 1, + .wakeup = 0, + .debounce_interval = 5, /* ms */ + .desc = "dock detect", + }, + { + .code = KEY_F6, + .type = EV_KEY, + .gpio = GPIO_ON_OFF, + .active_low = 0, + .wakeup = 0, + .debounce_interval = 5, /* ms */ + .desc = "on_off button", + }, +}; + +static struct gpio_keys_platform_data gpio_keys_platform_data = { + .buttons = gpio_keys_button, + .nbuttons = ARRAY_SIZE(gpio_keys_button), + .rep = 0, +}; + +static struct platform_device raumfeld_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_keys_platform_data, + } +}; + +/** + * GPIO LEDs + */ + +static struct gpio_led raumfeld_leds[] = { + { + .name = "raumfeld:1", + .gpio = GPIO_LED1, + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "raumfeld:2", + .gpio = GPIO_LED2, + .active_low = 0, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + } +}; + +static struct gpio_led_platform_data raumfeld_led_platform_data = { + .leds = raumfeld_leds, + .num_leds = ARRAY_SIZE(raumfeld_leds), +}; + +static struct platform_device raumfeld_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &raumfeld_led_platform_data, + }, +}; + +/** + * One-wire (W1 bus) support + */ + +static void w1_enable_external_pullup(int enable) +{ + gpio_set_value(GPIO_W1_PULLUP_ENABLE, enable); + msleep(100); +} + +static struct w1_gpio_platform_data w1_gpio_platform_data = { + .pin = GPIO_ONE_WIRE, + .is_open_drain = 0, + .enable_external_pullup = w1_enable_external_pullup, + .ext_pullup_enable_pin = -EINVAL, +}; + +struct platform_device raumfeld_w1_gpio_device = { + .name = "w1-gpio", + .dev = { + .platform_data = &w1_gpio_platform_data + } +}; + +static void __init raumfeld_w1_init(void) +{ + int ret = gpio_request(GPIO_W1_PULLUP_ENABLE, + "W1 external pullup enable"); + + if (ret < 0) + pr_warning("Unable to request GPIO_W1_PULLUP_ENABLE\n"); + else + gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0); + + platform_device_register(&raumfeld_w1_gpio_device); +} + +/** + * Framebuffer device + */ + +/* PWM controlled backlight */ +static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = { + .pwm_id = 0, + .max_brightness = 100, + .dft_brightness = 100, + /* 10000 ns = 10 ms ^= 100 kHz */ + .pwm_period_ns = 10000, + .enable_gpio = -1, +}; + +static struct platform_device raumfeld_pwm_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &raumfeld_pwm_backlight_data, + } +}; + +/* LT3593 controlled backlight */ +static struct gpio_led raumfeld_lt3593_led = { + .name = "backlight", + .gpio = mfp_to_gpio(MFP_PIN_GPIO17), + .default_state = LEDS_GPIO_DEFSTATE_ON, +}; + +static struct gpio_led_platform_data raumfeld_lt3593_platform_data = { + .leds = &raumfeld_lt3593_led, + .num_leds = 1, +}; + +static struct platform_device raumfeld_lt3593_device = { + .name = "leds-lt3593", + .id = -1, + .dev = { + .platform_data = &raumfeld_lt3593_platform_data, + }, +}; + +static struct pxafb_mode_info sharp_lq043t3dx02_mode = { + .pixclock = 111000, + .xres = 480, + .yres = 272, + .bpp = 16, + .hsync_len = 41, + .left_margin = 2, + .right_margin = 1, + .vsync_len = 10, + .upper_margin = 3, + .lower_margin = 1, + .sync = 0, +}; + +static struct pxafb_mach_info raumfeld_sharp_lcd_info = { + .modes = &sharp_lq043t3dx02_mode, + .num_modes = 1, + .video_mem_size = 0x400000, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +#ifdef CONFIG_PXA3XX_GCU + .acceleration_enabled = 1, +#endif +}; + +static void __init raumfeld_lcd_init(void) +{ + int ret; + + ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); + if (ret < 0) + pr_warning("Unable to request GPIO_TFT_VA_EN\n"); + else + gpio_direction_output(GPIO_TFT_VA_EN, 1); + + msleep(100); + + ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); + if (ret < 0) + pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); + else + gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); + + /* Hardware revision 2 has the backlight regulator controlled + * by an LT3593, earlier and later devices use PWM for that. */ + if ((system_rev & 0xff) == 2) { + platform_device_register(&raumfeld_lt3593_device); + } else { + mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT; + pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1); + platform_device_register(&raumfeld_pwm_backlight_device); + } + + pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info); + platform_device_register(&pxa3xx_device_gcu); +} + +/** + * SPI devices + */ + +struct spi_gpio_platform_data raumfeld_spi_platform_data = { + .sck = GPIO_SPI_CLK, + .mosi = GPIO_SPI_MOSI, + .miso = GPIO_SPI_MISO, + .num_chipselect = 3, +}; + +static struct platform_device raumfeld_spi_device = { + .name = "spi_gpio", + .id = 0, + .dev = { + .platform_data = &raumfeld_spi_platform_data, + } +}; + +static struct lis3lv02d_platform_data lis3_pdata = { + .click_flags = LIS3_CLICK_SINGLE_X | + LIS3_CLICK_SINGLE_Y | + LIS3_CLICK_SINGLE_Z, + .irq_cfg = LIS3_IRQ1_CLICK | LIS3_IRQ2_CLICK, + .wakeup_flags = LIS3_WAKEUP_X_LO | LIS3_WAKEUP_X_HI | + LIS3_WAKEUP_Y_LO | LIS3_WAKEUP_Y_HI | + LIS3_WAKEUP_Z_LO | LIS3_WAKEUP_Z_HI, + .wakeup_thresh = 10, + .click_thresh_x = 10, + .click_thresh_y = 10, + .click_thresh_z = 10, +}; + +#define SPI_AK4104 \ +{ \ + .modalias = "ak4104-codec", \ + .max_speed_hz = 10000, \ + .bus_num = 0, \ + .chip_select = 0, \ + .controller_data = (void *) GPIO_SPDIF_CS, \ +} + +#define SPI_LIS3 \ +{ \ + .modalias = "lis3lv02d_spi", \ + .max_speed_hz = 1000000, \ + .bus_num = 0, \ + .chip_select = 1, \ + .controller_data = (void *) GPIO_ACCEL_CS, \ + .platform_data = &lis3_pdata, \ + .irq = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ), \ +} + +#define SPI_DAC7512 \ +{ \ + .modalias = "dac7512", \ + .max_speed_hz = 1000000, \ + .bus_num = 0, \ + .chip_select = 2, \ + .controller_data = (void *) GPIO_MCLK_DAC_CS, \ +} + +static struct spi_board_info connector_spi_devices[] __initdata = { + SPI_AK4104, + SPI_DAC7512, +}; + +static struct spi_board_info speaker_spi_devices[] __initdata = { + SPI_DAC7512, +}; + +static struct spi_board_info controller_spi_devices[] __initdata = { + SPI_LIS3, +}; + +/** + * MMC for Marvell Libertas 8688 via SDIO + */ + +static int raumfeld_mci_init(struct device *dev, irq_handler_t isr, void *data) +{ + gpio_set_value(GPIO_W2W_RESET, 1); + gpio_set_value(GPIO_W2W_PDN, 1); + + return 0; +} + +static void raumfeld_mci_exit(struct device *dev, void *data) +{ + gpio_set_value(GPIO_W2W_RESET, 0); + gpio_set_value(GPIO_W2W_PDN, 0); +} + +static struct pxamci_platform_data raumfeld_mci_platform_data = { + .init = raumfeld_mci_init, + .exit = raumfeld_mci_exit, + .detect_delay_ms = 200, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +/* + * External power / charge logic + */ + +static int power_supply_init(struct device *dev) +{ + return 0; +} + +static void power_supply_exit(struct device *dev) +{ +} + +static int raumfeld_is_ac_online(void) +{ + return !gpio_get_value(GPIO_CHARGE_DC_OK); +} + +static int raumfeld_is_usb_online(void) +{ + return 0; +} + +static char *raumfeld_power_supplicants[] = { "ds2760-battery.0" }; + +static void raumfeld_power_signal_charged(void) +{ + struct power_supply *psy = + power_supply_get_by_name(raumfeld_power_supplicants[0]); + + if (psy) + power_supply_set_battery_charged(psy); +} + +static int raumfeld_power_resume(void) +{ + /* check if GPIO_CHARGE_DONE went low while we were sleeping */ + if (!gpio_get_value(GPIO_CHARGE_DONE)) + raumfeld_power_signal_charged(); + + return 0; +} + +static struct pda_power_pdata power_supply_info = { + .init = power_supply_init, + .is_ac_online = raumfeld_is_ac_online, + .is_usb_online = raumfeld_is_usb_online, + .exit = power_supply_exit, + .supplied_to = raumfeld_power_supplicants, + .num_supplicants = ARRAY_SIZE(raumfeld_power_supplicants), + .resume = raumfeld_power_resume, +}; + +static struct resource power_supply_resources[] = { + { + .name = "ac", + .flags = IORESOURCE_IRQ | + IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, + .start = GPIO_CHARGE_DC_OK, + .end = GPIO_CHARGE_DC_OK, + }, +}; + +static irqreturn_t charge_done_irq(int irq, void *dev_id) +{ + raumfeld_power_signal_charged(); + return IRQ_HANDLED; +} + +static struct platform_device raumfeld_power_supply = { + .name = "pda-power", + .id = -1, + .dev = { + .platform_data = &power_supply_info, + }, + .resource = power_supply_resources, + .num_resources = ARRAY_SIZE(power_supply_resources), +}; + +static void __init raumfeld_power_init(void) +{ + int ret; + + /* Set PEN2 high to enable maximum charge current */ + ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2"); + if (ret < 0) + pr_warning("Unable to request GPIO_CHRG_PEN2\n"); + else + gpio_direction_output(GPIO_CHRG_PEN2, 1); + + ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK"); + if (ret < 0) + pr_warning("Unable to request GPIO_CHARGE_DC_OK\n"); + + ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP"); + if (ret < 0) + pr_warning("Unable to request GPIO_CHARGE_USB_SUSP\n"); + else + gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0); + + power_supply_resources[0].start = gpio_to_irq(GPIO_CHARGE_DC_OK); + power_supply_resources[0].end = gpio_to_irq(GPIO_CHARGE_DC_OK); + + ret = request_irq(gpio_to_irq(GPIO_CHARGE_DONE), + &charge_done_irq, IORESOURCE_IRQ_LOWEDGE, + "charge_done", NULL); + + if (ret < 0) + printk(KERN_ERR "%s: unable to register irq %d\n", __func__, + GPIO_CHARGE_DONE); + else + platform_device_register(&raumfeld_power_supply); +} + +/* Fixed regulator for AUDIO_VA, 0-0048 maps to the cs4270 codec device */ + +static struct regulator_consumer_supply audio_va_consumer_supply = + REGULATOR_SUPPLY("va", "0-0048"); + +struct regulator_init_data audio_va_initdata = { + .consumer_supplies = &audio_va_consumer_supply, + .num_consumer_supplies = 1, + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static struct fixed_voltage_config audio_va_config = { + .supply_name = "audio_va", + .microvolts = 5000000, + .gpio = GPIO_AUDIO_VA_ENABLE, + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &audio_va_initdata, +}; + +static struct platform_device audio_va_device = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &audio_va_config, + }, +}; + +/* Dummy supplies for Codec's VD/VLC */ + +static struct regulator_consumer_supply audio_dummy_supplies[] = { + REGULATOR_SUPPLY("vd", "0-0048"), + REGULATOR_SUPPLY("vlc", "0-0048"), +}; + +struct regulator_init_data audio_dummy_initdata = { + .consumer_supplies = audio_dummy_supplies, + .num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies), + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static struct fixed_voltage_config audio_dummy_config = { + .supply_name = "audio_vd", + .microvolts = 3300000, + .gpio = -1, + .init_data = &audio_dummy_initdata, +}; + +static struct platform_device audio_supply_dummy_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &audio_dummy_config, + }, +}; + +static struct platform_device *audio_regulator_devices[] = { + &audio_va_device, + &audio_supply_dummy_device, +}; + +/** + * Regulator support via MAX8660 + */ + +static struct regulator_consumer_supply vcc_mmc_supply = + REGULATOR_SUPPLY("vmmc", "pxa2xx-mci.0"); + +static struct regulator_init_data vcc_mmc_init_data = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_MODE, + }, + .consumer_supplies = &vcc_mmc_supply, + .num_consumer_supplies = 1, +}; + +struct max8660_subdev_data max8660_v6_subdev_data = { + .id = MAX8660_V6, + .name = "vmmc", + .platform_data = &vcc_mmc_init_data, +}; + +static struct max8660_platform_data max8660_pdata = { + .subdevs = &max8660_v6_subdev_data, + .num_subdevs = 1, +}; + +/** + * I2C devices + */ + +static struct i2c_board_info raumfeld_pwri2c_board_info = { + .type = "max8660", + .addr = 0x34, + .platform_data = &max8660_pdata, +}; + +static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = { + .type = "cs4270", + .addr = 0x48, +}; + +static struct eeti_ts_platform_data eeti_ts_pdata = { + .irq_active_high = 1, + .irq_gpio = GPIO_TOUCH_IRQ, +}; + +static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { + .type = "eeti_ts", + .addr = 0x0a, + .platform_data = &eeti_ts_pdata, +}; + +static struct platform_device *raumfeld_common_devices[] = { + &raumfeld_gpio_keys_device, + &raumfeld_led_device, + &raumfeld_spi_device, +}; + +static void __init raumfeld_audio_init(void) +{ + int ret; + + ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset"); + if (ret < 0) + pr_warning("unable to request GPIO_CODEC_RESET\n"); + else + gpio_direction_output(GPIO_CODEC_RESET, 1); + + ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset"); + if (ret < 0) + pr_warning("unable to request GPIO_SPDIF_RESET\n"); + else + gpio_direction_output(GPIO_SPDIF_RESET, 1); + + ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset"); + if (ret < 0) + pr_warning("unable to request GPIO_MCLK_RESET\n"); + else + gpio_direction_output(GPIO_MCLK_RESET, 1); + + platform_add_devices(ARRAY_AND_SIZE(audio_regulator_devices)); +} + +static void __init raumfeld_common_init(void) +{ + int ret; + + /* The on/off button polarity has changed after revision 1 */ + if ((system_rev & 0xff) > 1) { + int i; + + for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++) + if (!strcmp(gpio_keys_button[i].desc, "on_off button")) + gpio_keys_button[i].active_low = 1; + } + + enable_irq_wake(IRQ_WAKEUP0); + + pxa3xx_set_nand_info(&raumfeld_nand_info); + pxa3xx_set_i2c_power_info(NULL); + pxa_set_ohci_info(&raumfeld_ohci_info); + pxa_set_mci_info(&raumfeld_mci_platform_data); + pxa_set_i2c_info(NULL); + pxa_set_ffuart_info(NULL); + + ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset"); + if (ret < 0) + pr_warning("Unable to request GPIO_W2W_RESET\n"); + else + gpio_direction_output(GPIO_W2W_RESET, 0); + + ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup"); + if (ret < 0) + pr_warning("Unable to request GPIO_W2W_PDN\n"); + else + gpio_direction_output(GPIO_W2W_PDN, 0); + + /* this can be used to switch off the device */ + ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown"); + if (ret < 0) + pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n"); + else + gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0); + + platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices)); + i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1); +} + +static void __init raumfeld_controller_init(void) +{ + int ret; + + pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config)); + platform_device_register(&rotary_encoder_device); + spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices)); + i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1); + + ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown"); + if (ret < 0) + pr_warning("Unable to request GPIO_SHUTDOWN_BATT\n"); + else + gpio_direction_output(GPIO_SHUTDOWN_BATT, 0); + + raumfeld_common_init(); + raumfeld_power_init(); + raumfeld_lcd_init(); + raumfeld_w1_init(); +} + +static void __init raumfeld_connector_init(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config)); + spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices)); + i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1); + + platform_device_register(&smc91x_device); + + raumfeld_audio_init(); + raumfeld_common_init(); +} + +static void __init raumfeld_speaker_init(void) +{ + pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_speaker_pin_config)); + spi_register_board_info(ARRAY_AND_SIZE(speaker_spi_devices)); + i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1); + + platform_device_register(&smc91x_device); + platform_device_register(&rotary_encoder_device); + + raumfeld_audio_init(); + raumfeld_common_init(); +} + +/* physical memory regions */ +#define RAUMFELD_SDRAM_BASE 0xa0000000 /* SDRAM region */ + +#ifdef CONFIG_MACH_RAUMFELD_RC +MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") + .atag_offset = 0x100, + .init_machine = raumfeld_controller_init, + .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR +MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") + .atag_offset = 0x100, + .init_machine = raumfeld_connector_init, + .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_RAUMFELD_SPEAKER +MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") + .atag_offset = 0x100, + .init_machine = raumfeld_speaker_init, + .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c index 9996c612c3d..263b15249b5 100644 --- a/arch/arm/mach-pxa/reset.c +++ b/arch/arm/mach-pxa/reset.c @@ -7,11 +7,13 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/gpio.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/proc-fns.h> +#include <asm/system_misc.h> -#include <mach/pxa-regs.h> +#include <mach/regs-ost.h> #include <mach/reset.h> +#include <mach/smemc.h> unsigned int reset_status; EXPORT_SYMBOL(reset_status); @@ -20,7 +22,7 @@ static void do_hw_reset(void); static int reset_gpio = -1; -int init_gpio_reset(int gpio) +int init_gpio_reset(int gpio, int output, int level) { int rc; @@ -30,9 +32,12 @@ int init_gpio_reset(int gpio) goto out; } - rc = gpio_direction_input(gpio); + if (output) + rc = gpio_direction_output(gpio, level); + else + rc = gpio_direction_input(gpio); if (rc) { - printk(KERN_ERR "Can't configure reset_gpio for input\n"); + printk(KERN_ERR "Can't configure reset_gpio\n"); gpio_free(gpio); goto out; } @@ -73,26 +78,36 @@ static void do_gpio_reset(void) static void do_hw_reset(void) { /* Initialize the watchdog and let it fire */ - OWER = OWER_WME; - OSSR = OSSR_M3; - OSMR3 = OSCR + 368640; /* ... in 100 ms */ + writel_relaxed(OWER_WME, OWER); + writel_relaxed(OSSR_M3, OSSR); + /* ... in 100 ms */ + writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3); + /* + * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) + * we put SDRAM into self-refresh to prevent that + */ + while (1) + writel_relaxed(MDREFR_SLFRSH, MDREFR); } -void arch_reset(char mode) +void pxa_restart(enum reboot_mode mode, const char *cmd) { + local_irq_disable(); + local_fiq_disable(); + clear_reset_status(RESET_STATUS_ALL); switch (mode) { - case 's': + case REBOOT_SOFT: /* Jump into ROM at address 0 */ - cpu_reset(0); - break; - case 'h': - do_hw_reset(); + soft_restart(0); break; - case 'g': + case REBOOT_GPIO: do_gpio_reset(); break; + case REBOOT_HARD: + default: + do_hw_reset(); + break; } } - diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index e7ea91ce7f0..710c493eac8 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -17,22 +17,74 @@ #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> #include <linux/smc91x.h> +#include <linux/mfd/da903x.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/onenand.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> -#include <mach/mfp-pxa930.h> +#include <asm/mach/flash.h> + +#include <mach/pxa930.h> +#include <linux/platform_data/video-pxafb.h> #include "devices.h" #include "generic.h" +#define GPIO_LCD_RESET (16) + /* SAAR MFP configurations */ static mfp_cfg_t saar_mfp_cfg[] __initdata = { + /* LCD */ + GPIO23_LCD_DD0, + GPIO24_LCD_DD1, + GPIO25_LCD_DD2, + GPIO26_LCD_DD3, + GPIO27_LCD_DD4, + GPIO28_LCD_DD5, + GPIO29_LCD_DD6, + GPIO44_LCD_DD7, + GPIO21_LCD_CS, + GPIO22_LCD_VSYNC, + GPIO17_LCD_FCLK_RD, + GPIO18_LCD_LCLK_A0, + GPIO19_LCD_PCLK_WR, + GPIO16_GPIO, /* LCD reset */ + /* Ethernet */ DF_nCS1_nCS3, GPIO97_GPIO, + + /* DFI */ + DF_INT_RnB_ND_INT_RnB, + DF_nRE_nOE_ND_nRE, + DF_nWE_ND_nWE, + DF_CLE_nOE_ND_CLE, + DF_nADV1_ALE_ND_ALE, + DF_nADV2_ALE_nCS3, + DF_nCS0_ND_nCS0, + DF_IO0_ND_IO0, + DF_IO1_ND_IO1, + DF_IO2_ND_IO2, + DF_IO3_ND_IO3, + DF_IO4_ND_IO4, + DF_IO5_ND_IO5, + DF_IO6_ND_IO6, + DF_IO7_ND_IO7, + DF_IO8_ND_IO8, + DF_IO9_ND_IO9, + DF_IO10_ND_IO10, + DF_IO11_ND_IO11, + DF_IO12_ND_IO12, + DF_IO13_ND_IO13, + DF_IO14_ND_IO14, + DF_IO15_ND_IO15, }; #define SAAR_ETH_PHYS (0x14000000) @@ -44,8 +96,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), - .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; @@ -64,21 +116,492 @@ static struct platform_device smc91x_device = { }, }; +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static uint16_t lcd_power_on[] = { + /* single frame */ + SMART_CMD_NOOP, + SMART_CMD(0x00), + SMART_DELAY(0), + + SMART_CMD_NOOP, + SMART_CMD(0x00), + SMART_DELAY(0), + + SMART_CMD_NOOP, + SMART_CMD(0x00), + SMART_DELAY(0), + + SMART_CMD_NOOP, + SMART_CMD(0x00), + SMART_DELAY(10), + + /* calibration control */ + SMART_CMD(0x00), + SMART_CMD(0xA4), + SMART_DAT(0x80), + SMART_DAT(0x01), + SMART_DELAY(150), + + /*Power-On Init sequence*/ + SMART_CMD(0x00), /* output ctrl */ + SMART_CMD(0x01), + SMART_DAT(0x01), + SMART_DAT(0x00), + SMART_CMD(0x00), /* wave ctrl */ + SMART_CMD(0x02), + SMART_DAT(0x07), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x03), /* entry mode */ + SMART_DAT(0xD0), + SMART_DAT(0x30), + SMART_CMD(0x00), + SMART_CMD(0x08), /* display ctrl 2 */ + SMART_DAT(0x08), + SMART_DAT(0x08), + SMART_CMD(0x00), + SMART_CMD(0x09), /* display ctrl 3 */ + SMART_DAT(0x04), + SMART_DAT(0x2F), + SMART_CMD(0x00), + SMART_CMD(0x0A), /* display ctrl 4 */ + SMART_DAT(0x00), + SMART_DAT(0x08), + SMART_CMD(0x00), + SMART_CMD(0x0D), /* Frame Marker position */ + SMART_DAT(0x00), + SMART_DAT(0x08), + SMART_CMD(0x00), + SMART_CMD(0x60), /* Driver output control */ + SMART_DAT(0x27), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x61), /* Base image display control */ + SMART_DAT(0x00), + SMART_DAT(0x01), + SMART_CMD(0x00), + SMART_CMD(0x30), /* Y settings 30h-3Dh */ + SMART_DAT(0x07), + SMART_DAT(0x07), + SMART_CMD(0x00), + SMART_CMD(0x31), + SMART_DAT(0x00), + SMART_DAT(0x07), + SMART_CMD(0x00), + SMART_CMD(0x32), /* Timing(3), ASW HOLD=0.5CLK */ + SMART_DAT(0x04), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x33), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */ + SMART_DAT(0x03), + SMART_DAT(0x03), + SMART_CMD(0x00), + SMART_CMD(0x34), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x35), + SMART_DAT(0x02), + SMART_DAT(0x05), + SMART_CMD(0x00), + SMART_CMD(0x36), + SMART_DAT(0x1F), + SMART_DAT(0x1F), + SMART_CMD(0x00), + SMART_CMD(0x37), + SMART_DAT(0x07), + SMART_DAT(0x07), + SMART_CMD(0x00), + SMART_CMD(0x38), + SMART_DAT(0x00), + SMART_DAT(0x07), + SMART_CMD(0x00), + SMART_CMD(0x39), + SMART_DAT(0x04), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x3A), + SMART_DAT(0x03), + SMART_DAT(0x03), + SMART_CMD(0x00), + SMART_CMD(0x3B), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x3C), + SMART_DAT(0x02), + SMART_DAT(0x05), + SMART_CMD(0x00), + SMART_CMD(0x3D), + SMART_DAT(0x1F), + SMART_DAT(0x1F), + SMART_CMD(0x00), /* Display control 1 */ + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0x01), + SMART_CMD(0x00), /* Power control 5 */ + SMART_CMD(0x17), + SMART_DAT(0x00), + SMART_DAT(0x01), + SMART_CMD(0x00), /* Power control 1 */ + SMART_CMD(0x10), + SMART_DAT(0x10), + SMART_DAT(0xB0), + SMART_CMD(0x00), /* Power control 2 */ + SMART_CMD(0x11), + SMART_DAT(0x01), + SMART_DAT(0x30), + SMART_CMD(0x00), /* Power control 3 */ + SMART_CMD(0x12), + SMART_DAT(0x01), + SMART_DAT(0x9E), + SMART_CMD(0x00), /* Power control 4 */ + SMART_CMD(0x13), + SMART_DAT(0x17), + SMART_DAT(0x00), + SMART_CMD(0x00), /* Power control 3 */ + SMART_CMD(0x12), + SMART_DAT(0x01), + SMART_DAT(0xBE), + SMART_DELAY(100), + + /* display mode : 240*320 */ + SMART_CMD(0x00), /* RAM address set(H) 0*/ + SMART_CMD(0x20), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* RAM address set(V) 4*/ + SMART_CMD(0x21), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* Start of Window RAM address set(H) 8*/ + SMART_CMD(0x50), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* End of Window RAM address set(H) 12*/ + SMART_CMD(0x51), + SMART_DAT(0x00), + SMART_DAT(0xEF), + SMART_CMD(0x00), /* Start of Window RAM address set(V) 16*/ + SMART_CMD(0x52), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* End of Window RAM address set(V) 20*/ + SMART_CMD(0x53), + SMART_DAT(0x01), + SMART_DAT(0x3F), + SMART_CMD(0x00), /* Panel interface control 1 */ + SMART_CMD(0x90), + SMART_DAT(0x00), + SMART_DAT(0x1A), + SMART_CMD(0x00), /* Panel interface control 2 */ + SMART_CMD(0x92), + SMART_DAT(0x04), + SMART_DAT(0x00), + SMART_CMD(0x00), /* Panel interface control 3 */ + SMART_CMD(0x93), + SMART_DAT(0x00), + SMART_DAT(0x05), + SMART_DELAY(20), +}; + +static uint16_t lcd_panel_on[] = { + SMART_CMD(0x00), + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0x21), + SMART_DELAY(1), + + SMART_CMD(0x00), + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0x61), + SMART_DELAY(100), + + SMART_CMD(0x00), + SMART_CMD(0x07), + SMART_DAT(0x01), + SMART_DAT(0x73), + SMART_DELAY(1), +}; + +static uint16_t lcd_panel_off[] = { + SMART_CMD(0x00), + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0x72), + SMART_DELAY(40), + + SMART_CMD(0x00), + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0x01), + SMART_DELAY(1), + + SMART_CMD(0x00), + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_DELAY(1), +}; + +static uint16_t lcd_power_off[] = { + SMART_CMD(0x00), + SMART_CMD(0x10), + SMART_DAT(0x00), + SMART_DAT(0x80), + + SMART_CMD(0x00), + SMART_CMD(0x11), + SMART_DAT(0x01), + SMART_DAT(0x60), + + SMART_CMD(0x00), + SMART_CMD(0x12), + SMART_DAT(0x01), + SMART_DAT(0xAE), + SMART_DELAY(40), + + SMART_CMD(0x00), + SMART_CMD(0x10), + SMART_DAT(0x00), + SMART_DAT(0x00), +}; + +static uint16_t update_framedata[] = { + /* set display ram: 240*320 */ + SMART_CMD(0x00), /* RAM address set(H) 0*/ + SMART_CMD(0x20), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* RAM address set(V) 4*/ + SMART_CMD(0x21), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* Start of Window RAM address set(H) 8 */ + SMART_CMD(0x50), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* End of Window RAM address set(H) 12 */ + SMART_CMD(0x51), + SMART_DAT(0x00), + SMART_DAT(0xEF), + SMART_CMD(0x00), /* Start of Window RAM address set(V) 16 */ + SMART_CMD(0x52), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), /* End of Window RAM address set(V) 20 */ + SMART_CMD(0x53), + SMART_DAT(0x01), + SMART_DAT(0x3F), + + /* wait for vsync cmd before transferring frame data */ + SMART_CMD_WAIT_FOR_VSYNC, + + /* write ram */ + SMART_CMD(0x00), + SMART_CMD(0x22), + + /* write frame data */ + SMART_CMD_WRITE_FRAME, +}; + +static void ltm022a97a_lcd_power(int on, struct fb_var_screeninfo *var) +{ + static int pin_requested = 0; + struct fb_info *info = container_of(var, struct fb_info, var); + int err; + + if (!pin_requested) { + err = gpio_request(GPIO_LCD_RESET, "lcd reset"); + if (err) { + pr_err("failed to request gpio for LCD reset\n"); + return; + } + + gpio_direction_output(GPIO_LCD_RESET, 0); + pin_requested = 1; + } + + if (on) { + gpio_set_value(GPIO_LCD_RESET, 0); msleep(100); + gpio_set_value(GPIO_LCD_RESET, 1); msleep(10); + + pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_on)); + pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_on)); + } else { + pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_off)); + pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_off)); + } + + err = pxafb_smart_flush(info); + if (err) + pr_err("%s: timed out\n", __func__); +} + +static void ltm022a97a_update(struct fb_info *info) +{ + pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata)); + pxafb_smart_flush(info); +} + +static struct pxafb_mode_info toshiba_ltm022a97a_modes[] = { + [0] = { + .xres = 240, + .yres = 320, + .bpp = 16, + .a0csrd_set_hld = 30, + .a0cswr_set_hld = 30, + .wr_pulse_width = 30, + .rd_pulse_width = 30, + .op_hold_time = 30, + .cmd_inh_time = 60, + + /* L_LCLK_A0 and L_LCLK_RD active low */ + .sync = FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT, + }, +}; + +static struct pxafb_mach_info saar_lcd_info = { + .modes = toshiba_ltm022a97a_modes, + .num_modes = 1, + .lcd_conn = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL, + .pxafb_lcd_power = ltm022a97a_lcd_power, + .smart_update = ltm022a97a_update, +}; + +static void __init saar_init_lcd(void) +{ + pxa_set_fb_info(NULL, &saar_lcd_info); +} +#else +static inline void saar_init_lcd(void) {} +#endif + +#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) +static struct da9034_backlight_pdata saar_da9034_backlight = { + .output_current = 4, /* 4mA */ +}; + +static struct da903x_subdev_info saar_da9034_subdevs[] = { + [0] = { + .name = "da903x-backlight", + .id = DA9034_ID_WLED, + .platform_data = &saar_da9034_backlight, + }, +}; + +static struct da903x_platform_data saar_da9034_info = { + .num_subdevs = ARRAY_SIZE(saar_da9034_subdevs), + .subdevs = saar_da9034_subdevs, +}; + +static struct i2c_board_info saar_i2c_info[] = { + [0] = { + .type = "da9034", + .addr = 0x34, + .platform_data = &saar_da9034_info, + .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)), + }, +}; + +static void __init saar_init_i2c(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(saar_i2c_info)); +} +#else +static inline void saar_init_i2c(void) {} +#endif + +#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE) +static struct mtd_partition saar_onenand_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = SZ_1M, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "reserved", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "reserved", + .offset = MTDPART_OFS_APPEND, + .size = SZ_8M, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = (SZ_2M + SZ_1M), + .mask_flags = 0, + }, { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = SZ_32M + SZ_16M, + .mask_flags = 0, + } +}; + +static struct onenand_platform_data saar_onenand_info = { + .parts = saar_onenand_partitions, + .nr_parts = ARRAY_SIZE(saar_onenand_partitions), +}; + +#define SMC_CS0_PHYS_BASE (0x10000000) + +static struct resource saar_resource_onenand[] = { + [0] = { + .start = SMC_CS0_PHYS_BASE, + .end = SMC_CS0_PHYS_BASE + SZ_1M, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device saar_device_onenand = { + .name = "onenand-flash", + .id = -1, + .dev = { + .platform_data = &saar_onenand_info, + }, + .resource = saar_resource_onenand, + .num_resources = ARRAY_SIZE(saar_resource_onenand), +}; + +static void __init saar_init_onenand(void) +{ + platform_device_register(&saar_device_onenand); +} +#else +static void __init saar_init_onenand(void) {} +#endif + static void __init saar_init(void) { /* initialize MFP configurations */ pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + platform_device_register(&smc91x_device); + saar_init_onenand(); + + saar_init_i2c(); + saar_init_lcd(); } MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") /* Maintainer: Eric Miao <eric.miao@marvell.com> */ - .phys_io = 0x40000000, - .boot_params = 0xa0000100, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, .init_machine = saar_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h deleted file mode 100644 index 047909a7665..00000000000 --- a/arch/arm/mach-pxa/sharpsl.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004-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 <asm/hardware/sharpsl_pm.h> - -/* - * SharpSL SSP Driver - */ -struct corgissp_machinfo { - int port; - int cs_lcdcon; - int cs_ads7846; - int cs_max1111; - int clk_lcdcon; - int clk_ads7846; - int clk_max1111; -}; - -void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo); - - -/* - * SharpSL/Corgi LCD Driver - */ -void corgi_lcdtg_suspend(void); -void corgi_lcdtg_hw_init(int mode); - - -/* - * SharpSL Battery/PM Driver - */ -#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) - -/* MAX1111 Channel Definitions */ -#define MAX1111_BATT_VOLT 4u -#define MAX1111_BATT_TEMP 2u -#define MAX1111_ACIN_VOLT 6u - -extern struct battery_thresh spitz_battery_levels_acin[]; -extern struct battery_thresh spitz_battery_levels_noac[]; -void sharpsl_pm_pxa_init(void); -void sharpsl_pm_pxa_remove(void); -int sharpsl_pm_pxa_read_max1111(int channel); - - diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index e804ae09370..051a6555cbf 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -15,22 +15,66 @@ #undef DEBUG #include <linux/module.h> -#include <linux/init.h> #include <linux/kernel.h> #include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/platform_device.h> #include <linux/apm-emulation.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/leds.h> +#include <linux/suspend.h> +#include <linux/gpio.h> +#include <linux/io.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <mach/pm.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> -#include <mach/sharpsl.h> -#include "sharpsl.h" +#include <mach/pxa2xx-regs.h> +#include <mach/regs-rtc.h> +#include <mach/sharpsl_pm.h> -struct battery_thresh spitz_battery_levels_acin[] = { +/* + * Constants + */ +#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */ +#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ +#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ +#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ + +#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ +#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ +#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ +#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ +#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */ +#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ +#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ +#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ + +/* + * Prototypes + */ +#ifdef CONFIG_PM +static int sharpsl_off_charge_battery(void); +static int sharpsl_check_battery_voltage(void); +#endif +static int sharpsl_check_battery_temp(void); +static int sharpsl_ac_check(void); +static int sharpsl_average_value(int ad); +static void sharpsl_average_clear(void); +static void sharpsl_charge_toggle(struct work_struct *private_); +static void sharpsl_battery_thread(struct work_struct *private_); + + +/* + * Variables + */ +struct sharpsl_pm_status sharpsl_pm; +static DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle); +static DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread); +DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); + + + +struct battery_thresh sharpsl_battery_levels_acin[] = { { 213, 100}, { 212, 98}, { 211, 95}, @@ -73,7 +117,7 @@ struct battery_thresh spitz_battery_levels_acin[] = { { 0, 0}, }; -struct battery_thresh spitz_battery_levels_noac[] = { +struct battery_thresh sharpsl_battery_levels_noac[] = { { 213, 100}, { 212, 98}, { 211, 95}, @@ -117,67 +161,795 @@ struct battery_thresh spitz_battery_levels_noac[] = { }; /* MAX1111 Commands */ -#define MAXCTRL_PD0 1u << 0 -#define MAXCTRL_PD1 1u << 1 -#define MAXCTRL_SGL 1u << 2 -#define MAXCTRL_UNI 1u << 3 +#define MAXCTRL_PD0 (1u << 0) +#define MAXCTRL_PD1 (1u << 1) +#define MAXCTRL_SGL (1u << 2) +#define MAXCTRL_UNI (1u << 3) #define MAXCTRL_SEL_SH 4 -#define MAXCTRL_STR 1u << 7 +#define MAXCTRL_STR (1u << 7) +extern int max1111_read_channel(int); /* * Read MAX1111 ADC */ int sharpsl_pm_pxa_read_max1111(int channel) { - if (machine_is_tosa()) // Ugly, better move this function into another module + /* Ugly, better move this function into another module */ + if (machine_is_tosa()) return 0; - return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1 - | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); + /* max1111 accepts channels from 0-3, however, + * it is encoded from 0-7 here in the code. + */ + return max1111_read_channel(channel >> 1); +} + +static int get_percentage(int voltage) +{ + int i = sharpsl_pm.machinfo->bat_levels - 1; + int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0; + struct battery_thresh *thresh; + + if (sharpsl_pm.charge_mode == CHRG_ON) + thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin; + else + thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac; + + while (i > 0 && (voltage > thresh[i].voltage)) + i--; + + return thresh[i].percentage; +} + +static int get_apm_status(int voltage) +{ + int low_thresh, high_thresh; + + if (sharpsl_pm.charge_mode == CHRG_ON) { + high_thresh = sharpsl_pm.machinfo->status_high_acin; + low_thresh = sharpsl_pm.machinfo->status_low_acin; + } else { + high_thresh = sharpsl_pm.machinfo->status_high_noac; + low_thresh = sharpsl_pm.machinfo->status_low_noac; + } + + if (voltage >= high_thresh) + return APM_BATTERY_STATUS_HIGH; + if (voltage >= low_thresh) + return APM_BATTERY_STATUS_LOW; + return APM_BATTERY_STATUS_CRITICAL; +} + +void sharpsl_battery_kick(void) +{ + schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); +} +EXPORT_SYMBOL(sharpsl_battery_kick); + + +static void sharpsl_battery_thread(struct work_struct *private_) +{ + int voltage, percent, apm_status, i; + + if (!sharpsl_pm.machinfo) + return; + + sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE); + + /* Corgi cannot confirm when battery fully charged so periodically kick! */ + if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) + && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) + schedule_delayed_work(&toggle_charger, 0); + + for (i = 0; i < 5; i++) { + voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); + if (voltage > 0) + break; + } + if (voltage <= 0) { + voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; + dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); + } + + voltage = sharpsl_average_value(voltage); + apm_status = get_apm_status(voltage); + percent = get_percentage(voltage); + + /* At low battery voltages, the voltage has a tendency to start + creeping back up so we try to avoid this here */ + if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) + || (apm_status == APM_BATTERY_STATUS_HIGH) + || percent <= sharpsl_pm.battstat.mainbat_percent) { + sharpsl_pm.battstat.mainbat_voltage = voltage; + sharpsl_pm.battstat.mainbat_status = apm_status; + sharpsl_pm.battstat.mainbat_percent = percent; + } + + dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage, + sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); + + /* Suspend if critical battery level */ + if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) + && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) + && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { + sharpsl_pm.flags |= SHARPSL_APM_QUEUED; + dev_err(sharpsl_pm.dev, "Fatal Off\n"); + apm_queue_event(APM_CRITICAL_SUSPEND); + } + + schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); +} + +void sharpsl_pm_led(int val) +{ + if (val == SHARPSL_LED_ERROR) { + dev_err(sharpsl_pm.dev, "Charging Error!\n"); + } else if (val == SHARPSL_LED_ON) { + dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); + led_trigger_event(sharpsl_charge_led_trigger, LED_FULL); + } else { + dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); + led_trigger_event(sharpsl_charge_led_trigger, LED_OFF); + } +} + +static void sharpsl_charge_on(void) +{ + dev_dbg(sharpsl_pm.dev, "Turning Charger On\n"); + + sharpsl_pm.full_count = 0; + sharpsl_pm.charge_mode = CHRG_ON; + schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250)); + schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500)); +} + +static void sharpsl_charge_off(void) +{ + dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n"); + + sharpsl_pm.machinfo->charge(0); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.charge_mode = CHRG_OFF; + + schedule_delayed_work(&sharpsl_bat, 0); +} + +static void sharpsl_charge_error(void) +{ + sharpsl_pm_led(SHARPSL_LED_ERROR); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.charge_mode = CHRG_ERROR; +} + +static void sharpsl_charge_toggle(struct work_struct *private_) +{ + dev_dbg(sharpsl_pm.dev, "Toggling Charger at time: %lx\n", jiffies); + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { + sharpsl_charge_off(); + return; + } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) { + sharpsl_charge_error(); + return; + } + + sharpsl_pm_led(SHARPSL_LED_ON); + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + + sharpsl_pm.charge_start_time = jiffies; } -void sharpsl_pm_pxa_init(void) +static void sharpsl_ac_timer(unsigned long data) { - pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); - pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN); - pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN); + int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); + + dev_dbg(sharpsl_pm.dev, "AC Status: %d\n", acin); + + sharpsl_average_clear(); + if (acin && (sharpsl_pm.charge_mode != CHRG_ON)) + sharpsl_charge_on(); + else if (sharpsl_pm.charge_mode == CHRG_ON) + sharpsl_charge_off(); + + schedule_delayed_work(&sharpsl_bat, 0); +} + + +static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id) +{ + /* Delay the event slightly to debounce */ + /* Must be a smaller delay than the chrg_full_isr below */ + mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); + + return IRQ_HANDLED; +} + +static void sharpsl_chrg_full_timer(unsigned long data) +{ + dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies); + + sharpsl_pm.full_count++; + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { + dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); + if (sharpsl_pm.charge_mode == CHRG_ON) + sharpsl_charge_off(); + } else if (sharpsl_pm.full_count < 2) { + dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); + schedule_delayed_work(&toggle_charger, 0); + } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { + dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); + schedule_delayed_work(&toggle_charger, 0); + } else { + sharpsl_charge_off(); + sharpsl_pm.charge_mode = CHRG_DONE; + dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n"); + } +} + +/* Charging Finished Interrupt (Not present on Corgi) */ +/* Can trigger at the same time as an AC status change so + delay until after that has been processed */ +static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id) +{ + if (sharpsl_pm.flags & SHARPSL_SUSPENDED) + return IRQ_HANDLED; + + /* delay until after any ac interrupt */ + mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500)); + + return IRQ_HANDLED; +} + +static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id) +{ + int is_fatal = 0; + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) { + dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); + is_fatal = 1; + } + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) { + dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); + is_fatal = 1; + } + + if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) { + sharpsl_pm.flags |= SHARPSL_APM_QUEUED; + apm_queue_event(APM_CRITICAL_SUSPEND); + } + + return IRQ_HANDLED; +} + +/* + * Maintain an average of the last 10 readings + */ +#define SHARPSL_CNV_VALUE_NUM 10 +static int sharpsl_ad_index; + +static void sharpsl_average_clear(void) +{ + sharpsl_ad_index = 0; +} + +static int sharpsl_average_value(int ad) +{ + int i, ad_val = 0; + static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1]; + + if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) { + sharpsl_ad_index = 0; + return ad; + } + + sharpsl_ad[sharpsl_ad_index] = ad; + sharpsl_ad_index++; + if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) { + for (i = 0; i < (SHARPSL_CNV_VALUE_NUM-1); i++) + sharpsl_ad[i] = sharpsl_ad[i+1]; + sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1; + } + for (i = 0; i < sharpsl_ad_index; i++) + ad_val += sharpsl_ad[i]; + + return ad_val / sharpsl_ad_index; +} + +/* + * Take an array of 5 integers, remove the maximum and minimum values + * and return the average. + */ +static int get_select_val(int *val) +{ + int i, j, k, temp, sum = 0; + + /* Find MAX val */ + temp = val[0]; + j = 0; + for (i = 1; i < 5; i++) { + if (temp < val[i]) { + temp = val[i]; + j = i; + } + } + + /* Find MIN val */ + temp = val[4]; + k = 4; + for (i = 3; i >= 0; i--) { + if (temp > val[i]) { + temp = val[i]; + k = i; + } + } + + for (i = 0; i < 5; i++) + if (i != j && i != k) + sum += val[i]; + + dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]); + + return sum/3; +} + +static int sharpsl_check_battery_temp(void) +{ + int val, i, buff[5]; + + /* Check battery temperature */ + for (i = 0; i < 5; i++) { + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); + sharpsl_pm.machinfo->measure_temp(1); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP); + sharpsl_pm.machinfo->measure_temp(0); + } + + val = get_select_val(buff); + + dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); + if (val > sharpsl_pm.machinfo->charge_on_temp) { + printk(KERN_WARNING "Not charging: temperature out of limits.\n"); + return -1; + } + + return 0; +} + +#ifdef CONFIG_PM +static int sharpsl_check_battery_voltage(void) +{ + int val, i, buff[5]; + + /* disable charge, enable discharge */ + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.machinfo->discharge(1); + mdelay(SHARPSL_WAIT_DISCHARGE_ON); + + if (sharpsl_pm.machinfo->discharge1) + sharpsl_pm.machinfo->discharge1(1); + + /* Check battery voltage */ + for (i = 0; i < 5; i++) { + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); + } + + if (sharpsl_pm.machinfo->discharge1) + sharpsl_pm.machinfo->discharge1(0); + + sharpsl_pm.machinfo->discharge(0); + + val = get_select_val(buff); + dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val); + + if (val < sharpsl_pm.machinfo->charge_on_volt) + return -1; + + return 0; +} +#endif + +static int sharpsl_ac_check(void) +{ + int temp, i, buff[5]; + + for (i = 0; i < 5; i++) { + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN); + } + + temp = get_select_val(buff); + dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n", temp); + + if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) { + dev_err(sharpsl_pm.dev, "Error: AC check failed: voltage %d.\n", temp); + return -1; + } + + return 0; +} + +#ifdef CONFIG_PM +static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state) +{ + sharpsl_pm.flags |= SHARPSL_SUSPENDED; + flush_delayed_work(&toggle_charger); + flush_delayed_work(&sharpsl_bat); + + if (sharpsl_pm.charge_mode == CHRG_ON) + sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; + else + sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; + + return 0; +} + +static int sharpsl_pm_resume(struct platform_device *pdev) +{ + /* Clear the reset source indicators as they break the bootloader upon reboot */ + RCSR = 0x0f; + sharpsl_average_clear(); + sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED; + sharpsl_pm.flags &= ~SHARPSL_SUSPENDED; + + return 0; +} + +static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) +{ + dev_dbg(sharpsl_pm.dev, "Time is: %08x\n", RCNR); + + dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n", sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); + /* not charging and AC-IN! */ + + if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) { + dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); + sharpsl_pm.charge_mode = CHRG_OFF; + sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; + sharpsl_off_charge_battery(); + } + + sharpsl_pm.machinfo->presuspend(); + + PEDR = 0xffffffff; /* clear it */ + + sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE; + if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) { + RTSR &= RTSR_ALE; + RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND; + dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n", RTAR); + sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE; + } else if (alarm_enable) { + RTSR &= RTSR_ALE; + RTAR = alarm_time; + dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n", RTAR); + } else { + dev_dbg(sharpsl_pm.dev, "No alarms set.\n"); + } + + pxa_pm_enter(state); + + sharpsl_pm.machinfo->postsuspend(); + + dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n", PEDR); +} + +static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) +{ + if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable)) { + if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) { + dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n"); + corgi_goto_sleep(alarm_time, alarm_enable, state); + return 1; + } + if (sharpsl_off_charge_battery()) { + dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n"); + corgi_goto_sleep(alarm_time, alarm_enable, state); + return 1; + } + dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); + } + + if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || + (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) { + dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); + corgi_goto_sleep(alarm_time, alarm_enable, state); + return 1; + } + + return 0; +} + +static int corgi_pxa_pm_enter(suspend_state_t state) +{ + unsigned long alarm_time = RTAR; + unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); + + dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n"); + + corgi_goto_sleep(alarm_time, alarm_status, state); + + while (corgi_enter_suspend(alarm_time, alarm_status, state)) + {} + + if (sharpsl_pm.machinfo->earlyresume) + sharpsl_pm.machinfo->earlyresume(); + + dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); + + return 0; +} + +static int sharpsl_off_charge_error(void) +{ + dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n"); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm_led(SHARPSL_LED_ERROR); + sharpsl_pm.charge_mode = CHRG_ERROR; + return 1; +} + +/* + * Charging Control while suspended + * Return 1 - go straight to sleep + * Return 0 - sleep or wakeup depending on other factors + */ +static int sharpsl_off_charge_battery(void) +{ + int time; + + dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); + + if (sharpsl_pm.charge_mode == CHRG_OFF) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); + + /* AC Check */ + if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0)) + return sharpsl_off_charge_error(); + + /* Start Charging */ + sharpsl_pm_led(SHARPSL_LED_ON); + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + + sharpsl_pm.charge_mode = CHRG_ON; + sharpsl_pm.full_count = 0; + + return 1; + } else if (sharpsl_pm.charge_mode != CHRG_ON) { + return 1; + } + + if (sharpsl_pm.full_count == 0) { + int time; + + dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); + + if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0)) + return sharpsl_off_charge_error(); + + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + sharpsl_pm.charge_mode = CHRG_ON; + + mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); + + time = RCNR; + while (1) { + /* Check if any wakeup event had occurred */ + if (sharpsl_pm.machinfo->charger_wakeup() != 0) + return 0; + /* Check for timeout */ + if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) + return 1; + if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n"); + sharpsl_pm.full_count++; + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + return 1; + } + } + } + + dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); + + mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); + + time = RCNR; + while (1) { + /* Check if any wakeup event had occurred */ + if (sharpsl_pm.machinfo->charger_wakeup()) + return 0; + /* Check for timeout */ + if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { + if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); + sharpsl_pm.full_count = 0; + } + sharpsl_pm.full_count++; + return 1; + } + if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.charge_mode = CHRG_DONE; + return 1; + } + } +} +#else +#define sharpsl_pm_suspend NULL +#define sharpsl_pm_resume NULL +#endif + +static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_percent); +} + +static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage); +} + +static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL); +static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL); + +extern void (*apm_get_power_status)(struct apm_power_info *); + +static void sharpsl_apm_get_power_status(struct apm_power_info *info) +{ + info->ac_line_status = sharpsl_pm.battstat.ac_status; + + if (sharpsl_pm.charge_mode == CHRG_ON) + info->battery_status = APM_BATTERY_STATUS_CHARGING; + else + info->battery_status = sharpsl_pm.battstat.mainbat_status; + + info->battery_flag = (1 << info->battery_status); + info->battery_life = sharpsl_pm.battstat.mainbat_percent; +} + +#ifdef CONFIG_PM +static const struct platform_suspend_ops sharpsl_pm_ops = { + .prepare = pxa_pm_prepare, + .finish = pxa_pm_finish, + .enter = corgi_pxa_pm_enter, + .valid = suspend_valid_only_mem, +}; +#endif + +static int sharpsl_pm_probe(struct platform_device *pdev) +{ + int ret, irq; + + if (!pdev->dev.platform_data) + return -EINVAL; + + sharpsl_pm.dev = &pdev->dev; + sharpsl_pm.machinfo = pdev->dev.platform_data; + sharpsl_pm.charge_mode = CHRG_OFF; + sharpsl_pm.flags = 0; + + init_timer(&sharpsl_pm.ac_timer); + sharpsl_pm.ac_timer.function = sharpsl_ac_timer; + + init_timer(&sharpsl_pm.chrg_full_timer); + sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; + + led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger); + + sharpsl_pm.machinfo->init(); + + gpio_request(sharpsl_pm.machinfo->gpio_acin, "AC IN"); + gpio_direction_input(sharpsl_pm.machinfo->gpio_acin); + gpio_request(sharpsl_pm.machinfo->gpio_batfull, "Battery Full"); + gpio_direction_input(sharpsl_pm.machinfo->gpio_batfull); + gpio_request(sharpsl_pm.machinfo->gpio_batlock, "Battery Lock"); + gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock); /* Register interrupt handlers */ - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); + irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_acin); + if (request_irq(irq, sharpsl_ac_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH); - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); + irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_batlock); + if (request_irq(irq, sharpsl_fatal_isr, IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING); if (sharpsl_pm.machinfo->gpio_fatal) { - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); + irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_fatal); + if (request_irq(irq, sharpsl_fatal_isr, IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING); } - if (sharpsl_pm.machinfo->batfull_irq) - { + if (sharpsl_pm.machinfo->batfull_irq) { /* Register interrupt handler. */ - if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) { - dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); + irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_batfull); + if (request_irq(irq, sharpsl_chrg_full_isr, IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) { + dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING); } + + ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage); + ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage); + if (ret != 0) + dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret); + + apm_get_power_status = sharpsl_apm_get_power_status; + +#ifdef CONFIG_PM + suspend_set_ops(&sharpsl_pm_ops); +#endif + + mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); + + return 0; } -void sharpsl_pm_pxa_remove(void) +static int sharpsl_pm_remove(struct platform_device *pdev) { - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); + suspend_set_ops(NULL); + + device_remove_file(&pdev->dev, &dev_attr_battery_percentage); + device_remove_file(&pdev->dev, &dev_attr_battery_voltage); + + led_trigger_unregister_simple(sharpsl_charge_led_trigger); + + free_irq(gpio_to_irq(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); + free_irq(gpio_to_irq(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); if (sharpsl_pm.machinfo->gpio_fatal) - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); + free_irq(gpio_to_irq(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); if (sharpsl_pm.machinfo->batfull_irq) - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); + free_irq(gpio_to_irq(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); + + gpio_free(sharpsl_pm.machinfo->gpio_batlock); + gpio_free(sharpsl_pm.machinfo->gpio_batfull); + gpio_free(sharpsl_pm.machinfo->gpio_acin); + + if (sharpsl_pm.machinfo->exit) + sharpsl_pm.machinfo->exit(); + + del_timer_sync(&sharpsl_pm.chrg_full_timer); + del_timer_sync(&sharpsl_pm.ac_timer); + + return 0; +} + +static struct platform_driver sharpsl_pm_driver = { + .probe = sharpsl_pm_probe, + .remove = sharpsl_pm_remove, + .suspend = sharpsl_pm_suspend, + .resume = sharpsl_pm_resume, + .driver = { + .name = "sharpsl-pm", + }, +}; + +static int sharpsl_pm_init(void) +{ + return platform_driver_register(&sharpsl_pm_driver); } + +static void sharpsl_pm_exit(void) +{ + platform_driver_unregister(&sharpsl_pm_driver); +} + +late_initcall(sharpsl_pm_init); +module_exit(sharpsl_pm_exit); diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index a62c8375eb5..1e544be9905 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -14,8 +14,7 @@ #include <linux/linkage.h> #include <asm/assembler.h> #include <mach/hardware.h> - -#include <mach/pxa-regs.h> +#include <mach/smemc.h> #include <mach/pxa2xx-regs.h> #define MDREFR_KDIV 0x200a4000 // all banks @@ -23,164 +22,31 @@ .text -pxa_cpu_save_cp: - @ get coprocessor registers - mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode - mrc p15, 0, r4, c15, c1, 0 @ CP access reg - mrc p15, 0, r5, c13, c0, 0 @ PID - mrc p15, 0, r6, c3, c0, 0 @ domain ID - mrc p15, 0, r7, c2, c0, 0 @ translation table base addr - mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg - mrc p15, 0, r9, c1, c0, 0 @ control reg - - bic r3, r3, #2 @ clear frequency change bit - - @ store them plus current virtual stack ptr on stack - mov r10, sp - stmfd sp!, {r3 - r10} - - mov pc, lr - -pxa_cpu_save_sp: - @ preserve phys address of stack - mov r0, sp - str lr, [sp, #-4]! - bl sleep_phys_sp - ldr r1, =sleep_save_sp - str r0, [r1] - ldr pc, [sp], #4 - #ifdef CONFIG_PXA3xx /* - * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4) - * - * NOTE: unfortunately, pxa_cpu_save_cp can not be reused here since - * the auxiliary control register address is different between pxa3xx - * and pxa{25x,27x} + * pxa3xx_finish_suspend() - forces CPU into sleep state (S2D3C4) */ - -ENTRY(pxa3xx_cpu_suspend) - -#ifndef CONFIG_IWMMXT - mra r2, r3, acc0 -#endif - stmfd sp!, {r2 - r12, lr} @ save registers on stack - - mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode - mrc p15, 0, r4, c15, c1, 0 @ CP access reg - mrc p15, 0, r5, c13, c0, 0 @ PID - mrc p15, 0, r6, c3, c0, 0 @ domain ID - mrc p15, 0, r7, c2, c0, 0 @ translation table base addr - mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg - mrc p15, 0, r9, c1, c0, 0 @ control reg - - bic r3, r3, #2 @ clear frequency change bit - - @ store them plus current virtual stack ptr on stack - mov r10, sp - stmfd sp!, {r3 - r10} - - @ store physical address of stack pointer - mov r0, sp - bl sleep_phys_sp - ldr r1, =sleep_save_sp - str r0, [r1] - - @ clean data cache - bl xsc3_flush_kern_cache_all - +ENTRY(pxa3xx_finish_suspend) mov r0, #0x06 @ S2D3C4 mode mcr p14, 0, r0, c7, c0, 0 @ enter sleep 20: b 20b @ waiting for sleep - - .data - .align 5 -/* - * pxa3xx_cpu_resume - */ - -ENTRY(pxa3xx_cpu_resume) - - mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off - msr cpsr_c, r0 - - ldr r0, sleep_save_sp @ stack phys addr - ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr - - mov r1, #0 - mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB - mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer - mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer - mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs - - mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode. - mcr p15, 0, r4, c15, c1, 0 @ CP access reg - mcr p15, 0, r5, c13, c0, 0 @ PID - mcr p15, 0, r6, c3, c0, 0 @ domain ID - mcr p15, 0, r7, c2, c0, 0 @ translation table base addr - mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg - - @ temporarily map resume_turn_on_mmu into the page table, - @ otherwise prefetch abort occurs after MMU is turned on - mov r1, r7 - bic r1, r1, #0x00ff - bic r1, r1, #0x3f00 - ldr r2, =0x542e - - adr r3, resume_turn_on_mmu - mov r3, r3, lsr #20 - orr r4, r2, r3, lsl #20 - ldr r5, [r1, r3, lsl #2] - str r4, [r1, r3, lsl #2] - - @ Mapping page table address in the page table - mov r6, r1, lsr #20 - orr r7, r2, r6, lsl #20 - ldr r8, [r1, r6, lsl #2] - str r7, [r1, r6, lsl #2] - - ldr r2, =pxa3xx_resume_after_mmu @ absolute virtual address - b resume_turn_on_mmu @ cache align execution - - .text -pxa3xx_resume_after_mmu: - /* restore the temporary mapping */ - str r5, [r1, r3, lsl #2] - str r8, [r1, r6, lsl #2] - b resume_after_mmu - #endif /* CONFIG_PXA3xx */ #ifdef CONFIG_PXA27x /* - * pxa27x_cpu_suspend() + * pxa27x_finish_suspend() * * Forces CPU into sleep state. * * r0 = value for PWRMODE M field for desired sleep state */ - -ENTRY(pxa27x_cpu_suspend) - -#ifndef CONFIG_IWMMXT - mra r2, r3, acc0 -#endif - stmfd sp!, {r2 - r12, lr} @ save registers on stack - - bl pxa_cpu_save_cp - - mov r5, r0 @ save sleep mode - bl pxa_cpu_save_sp - - @ clean data cache - bl xscale_flush_kern_cache_all - +ENTRY(pxa27x_finish_suspend) @ Put the processor to sleep @ (also workaround for sighting 28071) @ prepare value for sleep mode - mov r1, r5 @ sleep mode + mov r1, r0 @ sleep mode @ prepare pointer to physical address 0 (virtual mapping in generic.c) mov r2, #UNCACHED_PHYS_0 @@ -212,26 +78,16 @@ ENTRY(pxa27x_cpu_suspend) #ifdef CONFIG_PXA25x /* - * pxa25x_cpu_suspend() + * pxa25x_finish_suspend() * * Forces CPU into sleep state. * * r0 = value for PWRMODE M field for desired sleep state */ -ENTRY(pxa25x_cpu_suspend) - stmfd sp!, {r2 - r12, lr} @ save registers on stack - - bl pxa_cpu_save_cp - - mov r5, r0 @ save sleep mode - bl pxa_cpu_save_sp - - @ clean data cache - bl xscale_flush_kern_cache_all - +ENTRY(pxa25x_finish_suspend) @ prepare value for sleep mode - mov r1, r5 @ sleep mode + mov r1, r0 @ sleep mode @ prepare pointer to physical address 0 (virtual mapping in generic.c) mov r2, #UNCACHED_PHYS_0 @@ -313,67 +169,3 @@ pxa_cpu_do_suspend: mcr p14, 0, r1, c7, c0, 0 @ PWRMODE 20: b 20b @ loop waiting for sleep - -/* - * pxa_cpu_resume() - * - * entry point from bootloader into kernel during resume - * - * Note: Yes, part of the following code is located into the .data section. - * This is to allow sleep_save_sp to be accessed with a relative load - * while we can't rely on any MMU translation. We could have put - * sleep_save_sp in the .text section as well, but some setups might - * insist on it to be truly read-only. - */ - - .data - .align 5 -ENTRY(pxa_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off - msr cpsr_c, r0 - - ldr r0, sleep_save_sp @ stack phys addr - ldr r2, =resume_after_mmu @ its absolute virtual address - ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr - - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs - mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB - -#ifdef CONFIG_XSCALE_CACHE_ERRATA - bic r9, r9, #0x0004 @ see cpu_xscale_proc_init -#endif - - mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode. - mcr p15, 0, r4, c15, c1, 0 @ CP access reg - mcr p15, 0, r5, c13, c0, 0 @ PID - mcr p15, 0, r6, c3, c0, 0 @ domain ID - mcr p15, 0, r7, c2, c0, 0 @ translation table base addr - mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg - b resume_turn_on_mmu @ cache align execution - - .align 5 -resume_turn_on_mmu: - mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, caches, etc. - - @ Let us ensure we jump to resume_after_mmu only when the mcr above - @ actually took effect. They call it the "cpwait" operation. - mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15 - sub pc, r2, r1, lsr #32 @ jump to virtual addr - nop - nop - nop - -sleep_save_sp: - .word 0 @ preserve stack phys ptr here - - .text -resume_after_mmu: -#ifdef CONFIG_XSCALE_CACHE_ERRATA - bl cpu_xscale_proc_init -#endif - ldmfd sp!, {r2, r3} -#ifndef CONFIG_IWMMXT - mar acc0, r2, r3 -#endif - ldmfd sp!, {r4 - r12, pc} @ return to caller diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index ad346addc02..f38aa890b2c 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c @@ -6,83 +6,66 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> -#define SMEMC_PHYS_BASE (0x4A000000) -#define SMEMC_PHYS_SIZE (0x90) - -#define MSC0 (0x08) /* Static Memory Controller Register 0 */ -#define MSC1 (0x0C) /* Static Memory Controller Register 1 */ -#define SXCNFG (0x1C) /* Synchronous Static Memory Control Register */ -#define MEMCLKCFG (0x68) /* Clock Configuration */ -#define CSADRCFG0 (0x80) /* Address Configuration Register for CS0 */ -#define CSADRCFG1 (0x84) /* Address Configuration Register for CS1 */ -#define CSADRCFG2 (0x88) /* Address Configuration Register for CS2 */ -#define CSADRCFG3 (0x8C) /* Address Configuration Register for CS3 */ +#include <mach/hardware.h> +#include <mach/smemc.h> #ifdef CONFIG_PM -static void __iomem *smemc_mmio_base; - static unsigned long msc[2]; static unsigned long sxcnfg, memclkcfg; static unsigned long csadrcfg[4]; -static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state) +static int pxa3xx_smemc_suspend(void) { - msc[0] = __raw_readl(smemc_mmio_base + MSC0); - msc[1] = __raw_readl(smemc_mmio_base + MSC1); - sxcnfg = __raw_readl(smemc_mmio_base + SXCNFG); - memclkcfg = __raw_readl(smemc_mmio_base + MEMCLKCFG); - csadrcfg[0] = __raw_readl(smemc_mmio_base + CSADRCFG0); - csadrcfg[1] = __raw_readl(smemc_mmio_base + CSADRCFG1); - csadrcfg[2] = __raw_readl(smemc_mmio_base + CSADRCFG2); - csadrcfg[3] = __raw_readl(smemc_mmio_base + CSADRCFG3); + msc[0] = __raw_readl(MSC0); + msc[1] = __raw_readl(MSC1); + sxcnfg = __raw_readl(SXCNFG); + memclkcfg = __raw_readl(MEMCLKCFG); + csadrcfg[0] = __raw_readl(CSADRCFG0); + csadrcfg[1] = __raw_readl(CSADRCFG1); + csadrcfg[2] = __raw_readl(CSADRCFG2); + csadrcfg[3] = __raw_readl(CSADRCFG3); return 0; } -static int pxa3xx_smemc_resume(struct sys_device *dev) +static void pxa3xx_smemc_resume(void) { - __raw_writel(msc[0], smemc_mmio_base + MSC0); - __raw_writel(msc[1], smemc_mmio_base + MSC1); - __raw_writel(sxcnfg, smemc_mmio_base + SXCNFG); - __raw_writel(memclkcfg, smemc_mmio_base + MEMCLKCFG); - __raw_writel(csadrcfg[0], smemc_mmio_base + CSADRCFG0); - __raw_writel(csadrcfg[1], smemc_mmio_base + CSADRCFG1); - __raw_writel(csadrcfg[2], smemc_mmio_base + CSADRCFG2); - __raw_writel(csadrcfg[3], smemc_mmio_base + CSADRCFG3); - - return 0; + __raw_writel(msc[0], MSC0); + __raw_writel(msc[1], MSC1); + __raw_writel(sxcnfg, SXCNFG); + __raw_writel(memclkcfg, MEMCLKCFG); + __raw_writel(csadrcfg[0], CSADRCFG0); + __raw_writel(csadrcfg[1], CSADRCFG1); + __raw_writel(csadrcfg[2], CSADRCFG2); + __raw_writel(csadrcfg[3], CSADRCFG3); + /* CSMSADRCFG wakes up in its default state (0), so we need to set it */ + __raw_writel(0x2, CSMSADRCFG); } -static struct sysdev_class smemc_sysclass = { - .name = "smemc", +static struct syscore_ops smemc_syscore_ops = { .suspend = pxa3xx_smemc_suspend, .resume = pxa3xx_smemc_resume, }; -static struct sys_device smemc_sysdev = { - .id = 0, - .cls = &smemc_sysclass, -}; - static int __init smemc_init(void) { - int ret = 0; - if (cpu_is_pxa3xx()) { - smemc_mmio_base = ioremap(SMEMC_PHYS_BASE, SMEMC_PHYS_SIZE); - if (smemc_mmio_base == NULL) - return -ENODEV; - - ret = sysdev_class_register(&smemc_sysclass); - if (ret) - return ret; - - ret = sysdev_register(&smemc_sysdev); + /* + * The only documentation we have on the + * Chip Select Configuration Register (CSMSADRCFG) is that + * it must be programmed to 0x2. + * Moreover, in the bit definitions, the second bit + * (CSMSADRCFG[1]) is called "SETALWAYS". + * Other bits are reserved in this register. + */ + __raw_writel(0x2, CSMSADRCFG); + + register_syscore_ops(&smemc_syscore_ops); } - return ret; + return 0; } subsys_initcall(smemc_init); #endif diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index b569f3b4cf3..840c3a48e72 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -13,54 +13,132 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/delay.h> -#include <linux/major.h> -#include <linux/fs.h> -#include <linux/interrupt.h> -#include <linux/mmc/host.h> -#include <linux/pm.h> -#include <linux/backlight.h> +#include <linux/gpio_keys.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/platform_data/pca953x.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/mtd/physmap.h> +#include <linux/input/matrix_keypad.h> +#include <linux/regulator/machine.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/reboot.h> +#include <linux/memblock.h> #include <asm/setup.h> -#include <asm/memory.h> #include <asm/mach-types.h> -#include <mach/hardware.h> -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/system.h> - #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> +#include <asm/mach/sharpsl_param.h> +#include <asm/hardware/scoop.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> +#include <mach/pxa27x.h> #include <mach/pxa27x-udc.h> #include <mach/reset.h> -#include <mach/i2c.h> -#include <mach/irda.h> -#include <mach/mmc.h> -#include <mach/ohci.h> -#include <mach/udc.h> -#include <mach/pxafb.h> -#include <mach/akita.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/video-pxafb.h> #include <mach/spitz.h> -#include <mach/sharpsl.h> - -#include <asm/mach/sharpsl_param.h> -#include <asm/hardware/scoop.h> +#include <mach/sharpsl_pm.h> +#include <mach/smemc.h> #include "generic.h" #include "devices.h" -#include "sharpsl.h" -/* - * Spitz SCOOP Device #1 - */ -static struct resource spitz_scoop_resources[] = { +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long spitz_pin_config[] __initdata = { + /* Chip Selects */ + GPIO78_nCS_2, /* SCOOP #2 */ + GPIO79_nCS_3, /* NAND */ + GPIO80_nCS_4, /* SCOOP #1 */ + + /* LCD - 16bpp Active TFT */ + GPIOxx_LCD_TFT_16BPP, + + /* PC Card */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO104_PSKTSEL, + + /* I2S */ + GPIO28_I2S_BITCLK_OUT, + GPIO29_I2S_SDATA_IN, + GPIO30_I2S_SDATA_OUT, + GPIO31_I2S_SYNC, + + /* MMC */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + + /* GPIOs */ + GPIO9_GPIO, /* SPITZ_GPIO_nSD_DETECT */ + GPIO16_GPIO, /* SPITZ_GPIO_SYNC */ + GPIO81_GPIO, /* SPITZ_GPIO_nSD_WP */ + GPIO41_GPIO, /* SPITZ_GPIO_USB_CONNECT */ + GPIO37_GPIO, /* SPITZ_GPIO_USB_HOST */ + GPIO35_GPIO, /* SPITZ_GPIO_USB_DEVICE */ + GPIO22_GPIO, /* SPITZ_GPIO_HSYNC */ + GPIO94_GPIO, /* SPITZ_GPIO_CF_CD */ + GPIO105_GPIO, /* SPITZ_GPIO_CF_IRQ */ + GPIO106_GPIO, /* SPITZ_GPIO_CF2_IRQ */ + + /* GPIO matrix keypad */ + GPIO88_GPIO, /* column 0 */ + GPIO23_GPIO, /* column 1 */ + GPIO24_GPIO, /* column 2 */ + GPIO25_GPIO, /* column 3 */ + GPIO26_GPIO, /* column 4 */ + GPIO27_GPIO, /* column 5 */ + GPIO52_GPIO, /* column 6 */ + GPIO103_GPIO, /* column 7 */ + GPIO107_GPIO, /* column 8 */ + GPIO108_GPIO, /* column 9 */ + GPIO114_GPIO, /* column 10 */ + GPIO12_GPIO, /* row 0 */ + GPIO17_GPIO, /* row 1 */ + GPIO91_GPIO, /* row 2 */ + GPIO34_GPIO, /* row 3 */ + GPIO36_GPIO, /* row 4 */ + GPIO38_GPIO, /* row 5 */ + GPIO39_GPIO, /* row 6 */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, /* SPITZ_GPIO_KEY_INT */ + GPIO1_GPIO | WAKEUP_ON_EDGE_FALL, /* SPITZ_GPIO_RESET */ +}; + + +/****************************************************************************** + * Scoop GPIO expander + ******************************************************************************/ +#if defined(CONFIG_SHARP_SCOOP) || defined(CONFIG_SHARP_SCOOP_MODULE) +/* SCOOP Device #1 */ +static struct resource spitz_scoop_1_resources[] = { [0] = { .start = 0x10800000, .end = 0x10800fff, @@ -68,27 +146,26 @@ static struct resource spitz_scoop_resources[] = { }, }; -static struct scoop_config spitz_scoop_setup = { - .io_dir = SPITZ_SCP_IO_DIR, +static struct scoop_config spitz_scoop_1_setup = { + .io_dir = SPITZ_SCP_IO_DIR, .io_out = SPITZ_SCP_IO_OUT, - .suspend_clr = SPITZ_SCP_SUS_CLR, - .suspend_set = SPITZ_SCP_SUS_SET, + .suspend_clr = SPITZ_SCP_SUS_CLR, + .suspend_set = SPITZ_SCP_SUS_SET, + .gpio_base = SPITZ_SCP_GPIO_BASE, }; -struct platform_device spitzscoop_device = { +struct platform_device spitz_scoop_1_device = { .name = "sharp-scoop", .id = 0, .dev = { - .platform_data = &spitz_scoop_setup, + .platform_data = &spitz_scoop_1_setup, }, - .num_resources = ARRAY_SIZE(spitz_scoop_resources), - .resource = spitz_scoop_resources, + .num_resources = ARRAY_SIZE(spitz_scoop_1_resources), + .resource = spitz_scoop_1_resources, }; -/* - * Spitz SCOOP Device #2 - */ -static struct resource spitz_scoop2_resources[] = { +/* SCOOP Device #2 */ +static struct resource spitz_scoop_2_resources[] = { [0] = { .start = 0x08800040, .end = 0x08800fff, @@ -96,610 +173,846 @@ static struct resource spitz_scoop2_resources[] = { }, }; -static struct scoop_config spitz_scoop2_setup = { - .io_dir = SPITZ_SCP2_IO_DIR, +static struct scoop_config spitz_scoop_2_setup = { + .io_dir = SPITZ_SCP2_IO_DIR, .io_out = SPITZ_SCP2_IO_OUT, - .suspend_clr = SPITZ_SCP2_SUS_CLR, - .suspend_set = SPITZ_SCP2_SUS_SET, + .suspend_clr = SPITZ_SCP2_SUS_CLR, + .suspend_set = SPITZ_SCP2_SUS_SET, + .gpio_base = SPITZ_SCP2_GPIO_BASE, }; -struct platform_device spitzscoop2_device = { +struct platform_device spitz_scoop_2_device = { .name = "sharp-scoop", .id = 1, .dev = { - .platform_data = &spitz_scoop2_setup, + .platform_data = &spitz_scoop_2_setup, }, - .num_resources = ARRAY_SIZE(spitz_scoop2_resources), - .resource = spitz_scoop2_resources, + .num_resources = ARRAY_SIZE(spitz_scoop_2_resources), + .resource = spitz_scoop_2_resources, }; -#define SPITZ_PWR_SD 0x01 -#define SPITZ_PWR_CF 0x02 +static void __init spitz_scoop_init(void) +{ + platform_device_register(&spitz_scoop_1_device); + + /* Akita doesn't have the second SCOOP chip */ + if (!machine_is_akita()) + platform_device_register(&spitz_scoop_2_device); +} /* Power control is shared with between one of the CF slots and SD */ -static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr) +static void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) { - unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); - - if (new_cpr & 0x0007) { - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); - if (!(cpr & 0x0002) && !(cpr & 0x0004)) - mdelay(5); - if (device == SPITZ_PWR_CF) - cpr |= 0x0002; - if (device == SPITZ_PWR_SD) - cpr |= 0x0004; - write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); - } else { - if (device == SPITZ_PWR_CF) - cpr &= ~0x0002; - if (device == SPITZ_PWR_SD) - cpr &= ~0x0004; - if (!(cpr & 0x0002) && !(cpr & 0x0004)) { - write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000); - mdelay(1); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); - } else { - write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); - } + unsigned short cpr; + unsigned long flags; + + if (new_cpr & 0x7) { + gpio_set_value(SPITZ_GPIO_CF_POWER, 1); + mdelay(5); } -} -static void spitz_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2); - GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO85_nPCE_1_MD); - pxa_gpio_mode(GPIO54_nPCE_2_MD); - pxa_gpio_mode(GPIO104_pSKTSEL_MD); + local_irq_save(flags); + + cpr = read_scoop_reg(&spitz_scoop_1_device.dev, SCOOP_CPR); + + if (enable & new_cpr) + cpr |= new_cpr; + else + cpr &= ~enable; + + write_scoop_reg(&spitz_scoop_1_device.dev, SCOOP_CPR, cpr); + + local_irq_restore(flags); + + if (!(cpr & 0x7)) { + mdelay(1); + gpio_set_value(SPITZ_GPIO_CF_POWER, 0); + } } -static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr) +#else +static inline void spitz_scoop_init(void) {} +static inline void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) {} +#endif + +/****************************************************************************** + * PCMCIA + ******************************************************************************/ +#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE) +static void spitz_pcmcia_pwr(struct device *scoop, uint16_t cpr, int nr) { /* Only need to override behaviour for slot 0 */ if (nr == 0) - spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr); + spitz_card_pwr_ctrl( + cpr & (SCOOP_CPR_CF_3V | SCOOP_CPR_CF_XV), cpr); else write_scoop_reg(scoop, SCOOP_CPR, cpr); } static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { -{ - .dev = &spitzscoop_device.dev, - .irq = SPITZ_IRQ_GPIO_CF_IRQ, - .cd_irq = SPITZ_IRQ_GPIO_CF_CD, - .cd_irq_str = "PCMCIA0 CD", -},{ - .dev = &spitzscoop2_device.dev, - .irq = SPITZ_IRQ_GPIO_CF2_IRQ, - .cd_irq = -1, -}, + { + .dev = &spitz_scoop_1_device.dev, + .irq = SPITZ_IRQ_GPIO_CF_IRQ, + .cd_irq = SPITZ_IRQ_GPIO_CF_CD, + .cd_irq_str = "PCMCIA0 CD", + }, { + .dev = &spitz_scoop_2_device.dev, + .irq = SPITZ_IRQ_GPIO_CF2_IRQ, + .cd_irq = -1, + }, }; static struct scoop_pcmcia_config spitz_pcmcia_config = { - .devs = &spitz_pcmcia_scoop[0], - .num_devs = 2, - .pcmcia_init = spitz_pcmcia_init, - .power_ctrl = spitz_pcmcia_pwr, + .devs = &spitz_pcmcia_scoop[0], + .num_devs = 2, + .power_ctrl = spitz_pcmcia_pwr, }; -EXPORT_SYMBOL(spitzscoop_device); -EXPORT_SYMBOL(spitzscoop2_device); +static void __init spitz_pcmcia_init(void) +{ + /* Akita has only one PCMCIA slot used */ + if (machine_is_akita()) + spitz_pcmcia_config.num_devs = 1; + platform_scoop_config = &spitz_pcmcia_config; +} +#else +static inline void spitz_pcmcia_init(void) {} +#endif -/* - * Spitz SSP Device - * - * Set the parent as the scoop device because a lot of SSP devices - * also use scoop functions and this makes the power up/down order - * work correctly. - */ -struct platform_device spitzssp_device = { - .name = "corgi-ssp", - .dev = { - .parent = &spitzscoop_device.dev, - }, - .id = -1, +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE) + +#define SPITZ_KEY_CALENDAR KEY_F1 +#define SPITZ_KEY_ADDRESS KEY_F2 +#define SPITZ_KEY_FN KEY_F3 +#define SPITZ_KEY_CANCEL KEY_F4 +#define SPITZ_KEY_EXOK KEY_F5 +#define SPITZ_KEY_EXCANCEL KEY_F6 +#define SPITZ_KEY_EXJOGDOWN KEY_F7 +#define SPITZ_KEY_EXJOGUP KEY_F8 +#define SPITZ_KEY_JAP1 KEY_LEFTALT +#define SPITZ_KEY_JAP2 KEY_RIGHTCTRL +#define SPITZ_KEY_SYNC KEY_F9 +#define SPITZ_KEY_MAIL KEY_F10 +#define SPITZ_KEY_OK KEY_F11 +#define SPITZ_KEY_MENU KEY_F12 + +static const uint32_t spitz_keymap[] = { + KEY(0, 0, KEY_LEFTCTRL), + 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(0, 9, SPITZ_KEY_EXOK), /* EXOK */ + KEY(0, 10, SPITZ_KEY_EXCANCEL), /* EXCANCEL */ + 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(1, 9, SPITZ_KEY_EXJOGDOWN), /* EXJOGDOWN */ + KEY(1, 10, SPITZ_KEY_EXJOGUP), /* EXJOGUP */ + 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, SPITZ_KEY_ADDRESS), /* ADDRESS */ + 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, SPITZ_KEY_CALENDAR), /* CALENDAR */ + 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, 9, KEY_LEFTSHIFT), + KEY(5, 0, SPITZ_KEY_MAIL), /* 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, 10, SPITZ_KEY_FN), /* FN */ + KEY(6, 0, KEY_SYSRQ), + KEY(6, 1, SPITZ_KEY_JAP1), /* JAP1 */ + KEY(6, 2, SPITZ_KEY_JAP2), /* JAP2 */ + KEY(6, 3, SPITZ_KEY_CANCEL), /* CANCEL */ + KEY(6, 4, SPITZ_KEY_OK), /* OK */ + KEY(6, 5, SPITZ_KEY_MENU), /* MENU */ + KEY(6, 6, KEY_LEFT), + KEY(6, 7, KEY_DOWN), + KEY(6, 8, KEY_RIGHT), }; -struct corgissp_machinfo spitz_ssp_machinfo = { - .port = 2, - .cs_lcdcon = SPITZ_GPIO_LCDCON_CS, - .cs_ads7846 = SPITZ_GPIO_ADS7846_CS, - .cs_max1111 = SPITZ_GPIO_MAX1111_CS, - .clk_lcdcon = 520, - .clk_ads7846 = 14, - .clk_max1111 = 56, +static const struct matrix_keymap_data spitz_keymap_data = { + .keymap = spitz_keymap, + .keymap_size = ARRAY_SIZE(spitz_keymap), }; +static const uint32_t spitz_row_gpios[] = + { 12, 17, 91, 34, 36, 38, 39 }; +static const uint32_t spitz_col_gpios[] = + { 88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114 }; + +static struct matrix_keypad_platform_data spitz_mkp_pdata = { + .keymap_data = &spitz_keymap_data, + .row_gpios = spitz_row_gpios, + .col_gpios = spitz_col_gpios, + .num_row_gpios = ARRAY_SIZE(spitz_row_gpios), + .num_col_gpios = ARRAY_SIZE(spitz_col_gpios), + .col_scan_delay_us = 10, + .debounce_ms = 10, + .wakeup = 1, +}; -/* - * Spitz Backlight Device - */ -static void spitz_bl_kick_battery(void) -{ - void (*kick_batt)(void); +static struct platform_device spitz_mkp_device = { + .name = "matrix-keypad", + .id = -1, + .dev = { + .platform_data = &spitz_mkp_pdata, + }, +}; - kick_batt = symbol_get(sharpsl_battery_kick); - if (kick_batt) { - kick_batt(); - symbol_put(sharpsl_battery_kick); - } +static void __init spitz_mkp_init(void) +{ + platform_device_register(&spitz_mkp_device); } +#else +static inline void spitz_mkp_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button spitz_gpio_keys[] = { + { + .type = EV_PWR, + .code = KEY_SUSPEND, + .gpio = SPITZ_GPIO_ON_KEY, + .desc = "On Off", + .wakeup = 1, + }, + /* Two buttons detecting the lid state */ + { + .type = EV_SW, + .code = 0, + .gpio = SPITZ_GPIO_SWA, + .desc = "Display Down", + }, + { + .type = EV_SW, + .code = 1, + .gpio = SPITZ_GPIO_SWB, + .desc = "Lid Closed", + }, +}; -static struct generic_bl_info spitz_bl_machinfo = { - .name = "corgi-bl", - .default_intensity = 0x1f, - .limit_mask = 0x0b, - .max_intensity = 0x2f, - .kick_battery = spitz_bl_kick_battery, +static struct gpio_keys_platform_data spitz_gpio_keys_platform_data = { + .buttons = spitz_gpio_keys, + .nbuttons = ARRAY_SIZE(spitz_gpio_keys), }; -static struct platform_device spitzbl_device = { - .name = "generic-bl", - .dev = { - .platform_data = &spitz_bl_machinfo, +static struct platform_device spitz_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &spitz_gpio_keys_platform_data, }, - .id = -1, }; +static void __init spitz_keys_init(void) +{ + platform_device_register(&spitz_gpio_keys_device); +} +#else +static inline void spitz_keys_init(void) {} +#endif -/* - * Spitz Keyboard Device - */ -static struct platform_device spitzkbd_device = { - .name = "spitz-keyboard", - .id = -1, +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led spitz_gpio_leds[] = { + { + .name = "spitz:amber:charge", + .default_trigger = "sharpsl-charge", + .gpio = SPITZ_GPIO_LED_ORANGE, + }, + { + .name = "spitz:green:hddactivity", + .default_trigger = "ide-disk", + .gpio = SPITZ_GPIO_LED_GREEN, + }, }; +static struct gpio_led_platform_data spitz_gpio_leds_info = { + .leds = spitz_gpio_leds, + .num_leds = ARRAY_SIZE(spitz_gpio_leds), +}; -/* - * Spitz LEDs - */ -static struct platform_device spitzled_device = { - .name = "spitz-led", +static struct platform_device spitz_led_device = { + .name = "leds-gpio", .id = -1, + .dev = { + .platform_data = &spitz_gpio_leds_info, + }, }; -/* - * Spitz Touch Screen Device - */ - -static unsigned long (*get_hsync_invperiod)(struct device *dev); - -static void inline sharpsl_wait_sync(int gpio) +static void __init spitz_leds_init(void) { - while((GPLR(gpio) & GPIO_bit(gpio)) == 0); - while((GPLR(gpio) & GPIO_bit(gpio)) != 0); + platform_device_register(&spitz_led_device); } +#else +static inline void spitz_leds_init(void) {} +#endif -static struct device *spitz_pxafb_dev; - -static int is_pxafb_device(struct device * dev, void * data) +/****************************************************************************** + * SSP Devices + ******************************************************************************/ +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +static void spitz_ads7846_wait_for_hsync(void) { - struct platform_device *pdev = container_of(dev, struct platform_device, dev); + while (gpio_get_value(SPITZ_GPIO_HSYNC)) + cpu_relax(); - return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0); + while (!gpio_get_value(SPITZ_GPIO_HSYNC)) + cpu_relax(); } -static unsigned long spitz_get_hsync_invperiod(void) -{ -#ifdef CONFIG_FB_PXA - if (!spitz_pxafb_dev) { - spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device); - if (!spitz_pxafb_dev) - return 0; - } - if (!get_hsync_invperiod) - get_hsync_invperiod = symbol_get(pxafb_get_hsync_time); - if (!get_hsync_invperiod) -#endif - return 0; +static struct ads7846_platform_data spitz_ads7846_info = { + .model = 7846, + .vref_delay_usecs = 100, + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .pressure_max = 1024, + .gpio_pendown = SPITZ_GPIO_TP_INT, + .wait_for_sync = spitz_ads7846_wait_for_hsync, +}; - return get_hsync_invperiod(spitz_pxafb_dev); -} +static struct pxa2xx_spi_chip spitz_ads7846_chip = { + .gpio_cs = SPITZ_GPIO_ADS7846_CS, +}; -static void spitz_put_hsync(void) +static void spitz_bl_kick_battery(void) { - put_device(spitz_pxafb_dev); - if (get_hsync_invperiod) - symbol_put(pxafb_get_hsync_time); - spitz_pxafb_dev = NULL; - get_hsync_invperiod = NULL; -} + void (*kick_batt)(void); -static void spitz_wait_hsync(void) -{ - sharpsl_wait_sync(SPITZ_GPIO_HSYNC); + kick_batt = symbol_get(sharpsl_battery_kick); + if (kick_batt) { + kick_batt(); + symbol_put(sharpsl_battery_kick); + } } -static struct resource spitzts_resources[] = { - [0] = { - .start = SPITZ_IRQ_GPIO_TP_INT, - .end = SPITZ_IRQ_GPIO_TP_INT, - .flags = IORESOURCE_IRQ, - }, +static struct corgi_lcd_platform_data spitz_lcdcon_info = { + .init_mode = CORGI_LCD_MODE_VGA, + .max_intensity = 0x2f, + .default_intensity = 0x1f, + .limit_mask = 0x0b, + .gpio_backlight_cont = SPITZ_GPIO_BACKLIGHT_CONT, + .gpio_backlight_on = SPITZ_GPIO_BACKLIGHT_ON, + .kick_battery = spitz_bl_kick_battery, }; -static struct corgits_machinfo spitz_ts_machinfo = { - .get_hsync_invperiod = spitz_get_hsync_invperiod, - .put_hsync = spitz_put_hsync, - .wait_hsync = spitz_wait_hsync, +static struct pxa2xx_spi_chip spitz_lcdcon_chip = { + .gpio_cs = SPITZ_GPIO_LCDCON_CS, }; -static struct platform_device spitzts_device = { - .name = "corgi-ts", - .dev = { - .parent = &spitzssp_device.dev, - .platform_data = &spitz_ts_machinfo, - }, - .id = -1, - .num_resources = ARRAY_SIZE(spitzts_resources), - .resource = spitzts_resources, +static struct pxa2xx_spi_chip spitz_max1111_chip = { + .gpio_cs = SPITZ_GPIO_MAX1111_CS, }; +static struct spi_board_info spitz_spi_devices[] = { + { + .modalias = "ads7846", + .max_speed_hz = 1200000, + .bus_num = 2, + .chip_select = 0, + .platform_data = &spitz_ads7846_info, + .controller_data = &spitz_ads7846_chip, + .irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT), + }, { + .modalias = "corgi-lcd", + .max_speed_hz = 50000, + .bus_num = 2, + .chip_select = 1, + .platform_data = &spitz_lcdcon_info, + .controller_data = &spitz_lcdcon_chip, + }, { + .modalias = "max1111", + .max_speed_hz = 450000, + .bus_num = 2, + .chip_select = 2, + .controller_data = &spitz_max1111_chip, + }, +}; -/* - * 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 spitz_mci_platform_data; +static struct pxa2xx_spi_master spitz_spi_info = { + .num_chipselect = 3, +}; -static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, void *data) +static void __init spitz_spi_init(void) { - int err; + struct corgi_lcd_platform_data *lcd_data = &spitz_lcdcon_info; - /* setup GPIO for PXA27x MMC controller */ - pxa_gpio_mode(GPIO32_MMCCLK_MD); - pxa_gpio_mode(GPIO112_MMCCMD_MD); - pxa_gpio_mode(GPIO92_MMCDAT0_MD); - pxa_gpio_mode(GPIO109_MMCDAT1_MD); - pxa_gpio_mode(GPIO110_MMCDAT2_MD); - pxa_gpio_mode(GPIO111_MMCDAT3_MD); - pxa_gpio_mode(SPITZ_GPIO_nSD_DETECT | GPIO_IN); - pxa_gpio_mode(SPITZ_GPIO_nSD_WP | GPIO_IN); - - spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); - - err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC card detect", data); - if (err) - printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + if (machine_is_akita()) { + lcd_data->gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT; + lcd_data->gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON; + } - return err; + pxa2xx_set_spi_info(2, &spitz_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices)); } +#else +static inline void spitz_spi_init(void) {} +#endif -static void spitz_mci_setpower(struct device *dev, unsigned int vdd) +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +/* + * NOTE: The card detect interrupt isn't debounced so we delay it by 250ms to + * give the card a chance to fully insert/eject. + */ +static int spitz_mci_setpower(struct device *dev, unsigned int vdd) { struct pxamci_platform_data* p_d = dev->platform_data; - if (( 1 << vdd) & p_d->ocr_mask) - spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004); + if ((1 << vdd) & p_d->ocr_mask) + spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, SCOOP_CPR_SD_3V); else - spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000); -} - -static int spitz_mci_get_ro(struct device *dev) -{ - return GPLR(SPITZ_GPIO_nSD_WP) & GPIO_bit(SPITZ_GPIO_nSD_WP); -} + spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, 0x0); -static void spitz_mci_exit(struct device *dev, void *data) -{ - free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data); + return 0; } static struct pxamci_platform_data spitz_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = spitz_mci_init, - .get_ro = spitz_mci_get_ro, - .setpower = spitz_mci_setpower, - .exit = spitz_mci_exit, + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .setpower = spitz_mci_setpower, + .gpio_card_detect = SPITZ_GPIO_nSD_DETECT, + .gpio_card_ro = SPITZ_GPIO_nSD_WP, + .gpio_power = -1, }; +static void __init spitz_mmc_init(void) +{ + pxa_set_mci_info(&spitz_mci_platform_data); +} +#else +static inline void spitz_mmc_init(void) {} +#endif -/* - * USB Host (OHCI) - */ +/****************************************************************************** + * USB Host + ******************************************************************************/ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) static int spitz_ohci_init(struct device *dev) { - /* Only Port 2 is connected */ - pxa_gpio_mode(SPITZ_GPIO_USB_CONNECT | GPIO_IN); - pxa_gpio_mode(SPITZ_GPIO_USB_HOST | GPIO_OUT); - pxa_gpio_mode(SPITZ_GPIO_USB_DEVICE | GPIO_IN); - - /* Setup USB Port 2 Output Control Register */ - UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; + int err; - GPSR(SPITZ_GPIO_USB_HOST) = GPIO_bit(SPITZ_GPIO_USB_HOST); + err = gpio_request(SPITZ_GPIO_USB_HOST, "USB_HOST"); + if (err) + return err; - UHCHR = (UHCHR) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); + /* Only Port 2 is connected, setup USB Port 2 Output Control Register */ + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; - UHCRHDA |= UHCRHDA_NOCP; + return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1); +} - return 0; +static void spitz_ohci_exit(struct device *dev) +{ + gpio_free(SPITZ_GPIO_USB_HOST); } static struct pxaohci_platform_data spitz_ohci_platform_data = { .port_mode = PMM_NPS_MODE, .init = spitz_ohci_init, + .exit = spitz_ohci_exit, + .flags = ENABLE_PORT_ALL | NO_OC_PROTECTION, .power_budget = 150, }; - -/* - * Irda - */ -static void spitz_irda_transceiver_mode(struct device *dev, int mode) +static void __init spitz_uhc_init(void) { - if (mode & IR_OFF) - set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON); - else - reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON); - pxa2xx_transceiver_mode(dev, mode); -} - -#ifdef CONFIG_MACH_AKITA -static void akita_irda_transceiver_mode(struct device *dev, int mode) -{ - if (mode & IR_OFF) - akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON); - else - akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON); - pxa2xx_transceiver_mode(dev, mode); + pxa_set_ohci_info(&spitz_ohci_platform_data); } +#else +static inline void spitz_uhc_init(void) {} #endif +/****************************************************************************** + * IrDA + ******************************************************************************/ +#if defined(CONFIG_PXA_FICP) || defined(CONFIG_PXA_FICP_MODULE) static struct pxaficp_platform_data spitz_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_OFF, - .transceiver_mode = spitz_irda_transceiver_mode, + .transceiver_cap = IR_SIRMODE | IR_OFF, }; - -/* - * Spitz PXA Framebuffer - */ - -static void spitz_lcd_power(int on, struct fb_var_screeninfo *var) +static void __init spitz_irda_init(void) { - if (on) - corgi_lcdtg_hw_init(var->xres); + if (machine_is_akita()) + spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON; else - corgi_lcdtg_suspend(); + spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; + + pxa_set_ficp_info(&spitz_ficp_platform_data); } +#else +static inline void spitz_irda_init(void) {} +#endif +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static struct pxafb_mode_info spitz_pxafb_modes[] = { -{ - .pixclock = 19231, - .xres = 480, - .yres = 640, - .bpp = 16, - .hsync_len = 40, - .left_margin = 46, - .right_margin = 125, - .vsync_len = 3, - .upper_margin = 1, - .lower_margin = 0, - .sync = 0, -},{ - .pixclock = 134617, - .xres = 240, - .yres = 320, - .bpp = 16, - .hsync_len = 20, - .left_margin = 20, - .right_margin = 46, - .vsync_len = 2, - .upper_margin = 1, - .lower_margin = 0, - .sync = 0, -}, + { + .pixclock = 19231, + .xres = 480, + .yres = 640, + .bpp = 16, + .hsync_len = 40, + .left_margin = 46, + .right_margin = 125, + .vsync_len = 3, + .upper_margin = 1, + .lower_margin = 0, + .sync = 0, + }, { + .pixclock = 134617, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 20, + .left_margin = 20, + .right_margin = 46, + .vsync_len = 2, + .upper_margin = 1, + .lower_margin = 0, + .sync = 0, + }, }; static struct pxafb_mach_info spitz_pxafb_info = { - .modes = &spitz_pxafb_modes[0], - .num_modes = 2, + .modes = spitz_pxafb_modes, + .num_modes = ARRAY_SIZE(spitz_pxafb_modes), .fixed_modes = 1, - .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM, - .lccr3 = LCCR3_PixRsEdg | LCCR3_OutEnH, - .pxafb_lcd_power = spitz_lcd_power, -}; - - -static struct platform_device *devices[] __initdata = { - &spitzscoop_device, - &spitzssp_device, - &spitzkbd_device, - &spitzts_device, - &spitzbl_device, - &spitzled_device, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_ALTERNATE_MAPPING, }; -static void spitz_poweroff(void) +static void __init spitz_lcd_init(void) { - arm_machine_restart('g'); + pxa_set_fb_info(NULL, &spitz_pxafb_info); } +#else +static inline void spitz_lcd_init(void) {} +#endif -static void spitz_restart(char mode) -{ - /* Bootloader magic for a reboot */ - if((MSC0 & 0xffff0000) == 0x7ff00000) - MSC0 = (MSC0 & 0xffff) | 0x7ee00000; +/****************************************************************************** + * NAND Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_NAND_SHARPSL) || defined(CONFIG_MTD_NAND_SHARPSL_MODULE) +static struct mtd_partition spitz_nand_partitions[] = { + { + .name = "System Area", + .offset = 0, + .size = 7 * 1024 * 1024, + }, { + .name = "Root Filesystem", + .offset = 7 * 1024 * 1024, + }, { + .name = "Home Filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; - spitz_poweroff(); -} +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; -static void __init common_init(void) -{ - init_gpio_reset(SPITZ_GPIO_ON_RESET); - pm_power_off = spitz_poweroff; - arm_pm_restart = spitz_restart; +static struct nand_bbt_descr spitz_nand_bbt = { + .options = 0, + .offs = 4, + .len = 2, + .pattern = scan_ff_pattern +}; - PMCR = 0x00; +static struct nand_ecclayout akita_oobinfo = { + .oobfree = { {0x08, 0x09} }, + .eccbytes = 24, + .eccpos = { + 0x05, 0x01, 0x02, 0x03, 0x06, 0x07, 0x15, 0x11, + 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23, + 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37, + }, +}; - /* setup sleep mode values */ - PWER = 0x00000002; - PFER = 0x00000000; - PRER = 0x00000002; - PGSR0 = 0x0158C000; - PGSR1 = 0x00FF0080; - PGSR2 = 0x0001C004; +static struct sharpsl_nand_platform_data spitz_nand_pdata = { + .badblock_pattern = &spitz_nand_bbt, + .partitions = spitz_nand_partitions, + .nr_partitions = ARRAY_SIZE(spitz_nand_partitions), +}; - /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ - PCFR |= PCFR_OPDE; +static struct resource spitz_nand_resources[] = { + { + .start = PXA_CS3_PHYS, + .end = PXA_CS3_PHYS + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; - corgi_ssp_set_machinfo(&spitz_ssp_machinfo); +static struct platform_device spitz_nand_device = { + .name = "sharpsl-nand", + .id = -1, + .resource = spitz_nand_resources, + .num_resources = ARRAY_SIZE(spitz_nand_resources), + .dev = { + .platform_data = &spitz_nand_pdata, + } +}; - pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN); +static void __init spitz_nand_init(void) +{ + if (machine_is_spitz()) { + spitz_nand_partitions[1].size = 5 * 1024 * 1024; + } else if (machine_is_akita()) { + spitz_nand_partitions[1].size = 58 * 1024 * 1024; + spitz_nand_bbt.len = 1; + spitz_nand_pdata.ecc_layout = &akita_oobinfo; + } else if (machine_is_borzoi()) { + spitz_nand_partitions[1].size = 32 * 1024 * 1024; + spitz_nand_bbt.len = 1; + spitz_nand_pdata.ecc_layout = &akita_oobinfo; + } - platform_add_devices(devices, ARRAY_SIZE(devices)); - pxa_set_mci_info(&spitz_mci_platform_data); - pxa_set_ohci_info(&spitz_ohci_platform_data); - pxa_set_ficp_info(&spitz_ficp_platform_data); - set_pxa_fb_parent(&spitzssp_device.dev); - set_pxa_fb_info(&spitz_pxafb_info); - pxa_set_i2c_info(NULL); + platform_device_register(&spitz_nand_device); } +#else +static inline void spitz_nand_init(void) {} +#endif -#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI) -static void spitz_bl_set_intensity(int intensity) -{ - if (intensity > 0x10) - intensity += 0x10; +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition spitz_rom_parts[] = { + { + .name ="Boot PROM Filesystem", + .offset = 0x00140000, + .size = MTDPART_SIZ_FULL, + }, +}; - /* Bits 0-4 are accessed via the SSP interface */ - corgi_ssp_blduty_set(intensity & 0x1f); +static struct physmap_flash_data spitz_rom_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(spitz_rom_parts), + .parts = spitz_rom_parts, +}; - /* Bit 5 is via SCOOP */ - if (intensity & 0x0020) - reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT); - else - set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT); +static struct resource spitz_rom_resources[] = { + { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + }, +}; - if (intensity) - set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON); - else - reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON); -} +static struct platform_device spitz_rom_device = { + .name = "physmap-flash", + .id = -1, + .resource = spitz_rom_resources, + .num_resources = ARRAY_SIZE(spitz_rom_resources), + .dev = { + .platform_data = &spitz_rom_data, + }, +}; -static void __init spitz_init(void) +static void __init spitz_nor_init(void) { - platform_scoop_config = &spitz_pcmcia_config; + platform_device_register(&spitz_rom_device); +} +#else +static inline void spitz_nor_init(void) {} +#endif - spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; +/****************************************************************************** + * I2C devices + ******************************************************************************/ +#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) +static struct pca953x_platform_data akita_pca953x_pdata = { + .gpio_base = AKITA_IOEXP_GPIO_BASE, +}; - common_init(); +static struct i2c_board_info spitz_i2c_devs[] = { + { + .type = "wm8750", + .addr = 0x1b, + }, { + .type = "max7310", + .addr = 0x18, + .platform_data = &akita_pca953x_pdata, + }, +}; - platform_device_register(&spitzscoop2_device); -} -#endif +static struct regulator_consumer_supply isl6271a_consumers[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; -#ifdef CONFIG_MACH_AKITA -/* - * Akita IO Expander - */ -struct platform_device akitaioexp_device = { - .name = "akita-ioexp", - .id = -1, +static struct regulator_init_data isl6271a_info[] = { + { + .constraints = { + .name = "vcc_core range", + .min_uV = 850000, + .max_uV = 1600000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .consumer_supplies = isl6271a_consumers, + .num_consumer_supplies = ARRAY_SIZE(isl6271a_consumers), + } }; -EXPORT_SYMBOL_GPL(akitaioexp_device); +static struct i2c_board_info spitz_pi2c_devs[] = { + { + .type = "isl6271a", + .addr = 0x0c, + .platform_data = &isl6271a_info, + }, +}; -static void akita_bl_set_intensity(int intensity) +static void __init spitz_i2c_init(void) { - if (intensity > 0x10) - intensity += 0x10; + int size = ARRAY_SIZE(spitz_i2c_devs); - /* Bits 0-4 are accessed via the SSP interface */ - corgi_ssp_blduty_set(intensity & 0x1f); + /* Only Akita has the max7310 chip */ + if (!machine_is_akita()) + size--; - /* Bit 5 is via IO-Expander */ - if (intensity & 0x0020) - akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT); - else - akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT); + pxa_set_i2c_info(NULL); + pxa27x_set_i2c_power_info(NULL); + i2c_register_board_info(0, spitz_i2c_devs, size); + i2c_register_board_info(1, ARRAY_AND_SIZE(spitz_pi2c_devs)); +} +#else +static inline void spitz_i2c_init(void) {} +#endif - if (intensity) - akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON); - else - akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON); +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void spitz_poweroff(void) +{ + pxa_restart(REBOOT_GPIO, NULL); } -static void __init akita_init(void) +static void spitz_restart(enum reboot_mode mode, const char *cmd) { - spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode; + uint32_t msc0 = __raw_readl(MSC0); + /* Bootloader magic for a reboot */ + if ((msc0 & 0xffff0000) == 0x7ff00000) + __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0); - /* We just pretend the second element of the array doesn't exist */ - spitz_pcmcia_config.num_devs = 1; - platform_scoop_config = &spitz_pcmcia_config; - spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity; + spitz_poweroff(); +} + +static void __init spitz_init(void) +{ + init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0); + pm_power_off = spitz_poweroff; - platform_device_register(&akitaioexp_device); + PMCR = 0x00; - spitzscoop_device.dev.parent = &akitaioexp_device.dev; - common_init(); + /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ + PCFR |= PCFR_OPDE; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(spitz_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + spitz_spi_init(); + spitz_scoop_init(); + spitz_mkp_init(); + spitz_keys_init(); + spitz_leds_init(); + spitz_mmc_init(); + spitz_pcmcia_init(); + spitz_irda_init(); + spitz_uhc_init(); + spitz_lcd_init(); + spitz_nor_init(); + spitz_nand_init(); + spitz_i2c_init(); } -#endif -static void __init fixup_spitz(struct machine_desc *desc, - struct tag *tags, char **cmdline, struct meminfo *mi) +static void __init spitz_fixup(struct tag *tags, char **cmdline) { sharpsl_save_param(); - mi->nr_banks = 1; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (64*1024*1024); + memblock_add(0xa0000000, SZ_64M); } #ifdef CONFIG_MACH_SPITZ MACHINE_START(SPITZ, "SHARP Spitz") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = fixup_spitz, - .map_io = pxa_map_io, + .fixup = spitz_fixup, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = spitz_restart, MACHINE_END #endif #ifdef CONFIG_MACH_BORZOI MACHINE_START(BORZOI, "SHARP Borzoi") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = fixup_spitz, - .map_io = pxa_map_io, + .fixup = spitz_fixup, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = spitz_restart, MACHINE_END #endif #ifdef CONFIG_MACH_AKITA MACHINE_START(AKITA, "SHARP Akita") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .fixup = fixup_spitz, - .map_io = pxa_map_io, + .fixup = spitz_fixup, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, - .init_machine = akita_init, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_machine = spitz_init, + .init_time = pxa_timer_init, + .restart = spitz_restart, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 8a40505dfd2..e191f9996b2 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -14,6 +14,8 @@ #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> @@ -21,14 +23,12 @@ #include <asm/irq.h> #include <asm/mach-types.h> #include <mach/hardware.h> -#include <asm/hardware/scoop.h> -#include <mach/sharpsl.h> #include <mach/spitz.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> -#include "sharpsl.h" +#include <mach/pxa27x.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 */ @@ -39,55 +39,55 @@ static int spitz_last_ac_status; +static struct gpio spitz_charger_gpios[] = { + { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" }, + { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" }, + { SPITZ_GPIO_AC_IN, GPIOF_IN, "Charger Detection" }, + { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, + { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" }, + { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, +}; + static void spitz_charger_init(void) { - pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN); - pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN); - sharpsl_pm_pxa_init(); + gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios)); } static void spitz_measure_temp(int on) { - if (on) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON); + gpio_set_value(SPITZ_GPIO_ADC_TEMP_ON, on); } static void spitz_charge(int on) { if (on) { if (sharpsl_pm.flags & SHARPSL_SUSPENDED) { - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON); + gpio_set_value(SPITZ_GPIO_JK_B, 1); + gpio_set_value(SPITZ_GPIO_CHRG_ON, 0); } else { - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON); + gpio_set_value(SPITZ_GPIO_JK_B, 0); + gpio_set_value(SPITZ_GPIO_CHRG_ON, 0); } } else { - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON); + gpio_set_value(SPITZ_GPIO_JK_B, 0); + gpio_set_value(SPITZ_GPIO_CHRG_ON, 1); } } static void spitz_discharge(int on) { - if (on) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A); + gpio_set_value(SPITZ_GPIO_JK_A, on); } /* HACK - For unknown reasons, accurate voltage readings are only made with a load on the power bus which the green led on spitz provides */ static void spitz_discharge1(int on) { - if (on) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); + gpio_set_value(SPITZ_GPIO_LED_GREEN, on); } +static unsigned long gpio18_config = GPIO18_GPIO; + static void spitz_presuspend(void) { spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); @@ -109,13 +109,15 @@ static void spitz_presuspend(void) PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); - pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH); + pxa2xx_mfp_config(&gpio18_config, 1); + gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); + gpio_free(18); PRER = GPIO_bit(SPITZ_GPIO_KEY_INT); PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET); PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC; PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET); - PKSR = 0xffffffff; // clear + PKSR = 0xffffffff; /* clear */ /* nRESET_OUT Disable */ PSLR |= PSLR_SL_ROD; @@ -126,8 +128,6 @@ static void spitz_presuspend(void) static void spitz_postsuspend(void) { - pxa_gpio_mode(GPIO18_RDY_MD); - pxa_gpio_mode(10 | GPIO_IN); } static int spitz_should_wakeup(unsigned int resume_on_alarm) @@ -161,26 +161,30 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm) if (resume_on_alarm && (PEDR & PWER_RTC)) is_resume |= PWER_RTC; - dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume); + dev_dbg(sharpsl_pm.dev, "is_resume: %x\n", is_resume); return is_resume; } static unsigned long spitz_charger_wakeup(void) { - return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC)); + unsigned long ret; + ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT) + << GPIO_bit(SPITZ_GPIO_KEY_INT)) + | gpio_get_value(SPITZ_GPIO_SYNC)); + return ret; } unsigned long spitzpm_read_devdata(int type) { - switch(type) { + switch (type) { case SHARPSL_STATUS_ACIN: - return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0); + return !gpio_get_value(SPITZ_GPIO_AC_IN); case SHARPSL_STATUS_LOCK: - return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock); + return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); case SHARPSL_STATUS_CHRGFULL: - return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull); + return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull); case SHARPSL_STATUS_FATAL: - return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_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: @@ -193,7 +197,7 @@ unsigned long spitzpm_read_devdata(int type) struct sharpsl_charger_machinfo spitz_pm_machinfo = { .init = spitz_charger_init, - .exit = sharpsl_pm_pxa_remove, + .exit = NULL, .gpio_batlock = SPITZ_GPIO_BAT_COVER, .gpio_acin = SPITZ_GPIO_AC_IN, .gpio_batfull = SPITZ_GPIO_CHRG_FULL, @@ -208,8 +212,8 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = { .read_devdata = spitzpm_read_devdata, .charger_wakeup = spitz_charger_wakeup, .should_wakeup = spitz_should_wakeup, -#ifdef CONFIG_BACKLIGHT_CORGI - .backlight_limit = corgibl_limit_intensity, +#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, @@ -218,8 +222,8 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = { .fatal_acin_volt = SHARPSL_FATAL_ACIN_VOLT, .fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT, .bat_levels = 40, - .bat_levels_noac = spitz_battery_levels_noac, - .bat_levels_acin = spitz_battery_levels_acin, + .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, @@ -228,7 +232,7 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = { static struct platform_device *spitzpm_device; -static int __devinit spitzpm_init(void) +static int spitzpm_init(void) { int ret; @@ -251,7 +255,7 @@ static int __devinit spitzpm_init(void) static void spitzpm_exit(void) { - platform_device_unregister(spitzpm_device); + platform_device_unregister(spitzpm_device); } module_init(spitzpm_init); diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c deleted file mode 100644 index 9bd93c5f28b..00000000000 --- a/arch/arm/mach-pxa/ssp.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/ssp.c - * - * based on linux/arch/arm/mach-sa1100/ssp.c by Russell King - * - * Copyright (C) 2003 Russell King. - * Copyright (C) 2003 Wolfson Microelectronics PLC - * - * 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. - * - * PXA2xx SSP driver. This provides the generic core for simple - * IO-based SSP applications and allows easy port setup for DMA access. - * - * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/platform_device.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <mach/hardware.h> -#include <mach/ssp.h> -#include <mach/pxa-regs.h> -#include <mach/regs-ssp.h> - -#define TIMEOUT 100000 - -static irqreturn_t ssp_interrupt(int irq, void *dev_id) -{ - struct ssp_dev *dev = dev_id; - struct ssp_device *ssp = dev->ssp; - unsigned int status; - - status = __raw_readl(ssp->mmio_base + SSSR); - __raw_writel(status, ssp->mmio_base + SSSR); - - if (status & SSSR_ROR) - printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port); - - if (status & SSSR_TUR) - printk(KERN_WARNING "SSP(%d): transmitter underrun\n", dev->port); - - if (status & SSSR_BCE) - printk(KERN_WARNING "SSP(%d): bit count error\n", dev->port); - - return IRQ_HANDLED; -} - -/** - * ssp_write_word - write a word to the SSP port - * @data: 32-bit, MSB justified data to write. - * - * Wait for a free entry in the SSP transmit FIFO, and write a data - * word to the SSP port. - * - * The caller is expected to perform the necessary locking. - * - * Returns: - * %-ETIMEDOUT timeout occurred - * 0 success - */ -int ssp_write_word(struct ssp_dev *dev, u32 data) -{ - struct ssp_device *ssp = dev->ssp; - int timeout = TIMEOUT; - - while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) { - if (!--timeout) - return -ETIMEDOUT; - cpu_relax(); - } - - __raw_writel(data, ssp->mmio_base + SSDR); - - return 0; -} - -/** - * ssp_read_word - read a word from the SSP port - * - * Wait for a data word in the SSP receive FIFO, and return the - * received data. Data is LSB justified. - * - * Note: Currently, if data is not expected to be received, this - * function will wait for ever. - * - * The caller is expected to perform the necessary locking. - * - * Returns: - * %-ETIMEDOUT timeout occurred - * 32-bit data success - */ -int ssp_read_word(struct ssp_dev *dev, u32 *data) -{ - struct ssp_device *ssp = dev->ssp; - int timeout = TIMEOUT; - - while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) { - if (!--timeout) - return -ETIMEDOUT; - cpu_relax(); - } - - *data = __raw_readl(ssp->mmio_base + SSDR); - return 0; -} - -/** - * ssp_flush - flush the transmit and receive FIFOs - * - * Wait for the SSP to idle, and ensure that the receive FIFO - * is empty. - * - * The caller is expected to perform the necessary locking. - */ -int ssp_flush(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - int timeout = TIMEOUT * 2; - - /* ensure TX FIFO is empty instead of not full */ - if (cpu_is_pxa3xx()) { - while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) { - if (!--timeout) - return -ETIMEDOUT; - cpu_relax(); - } - timeout = TIMEOUT * 2; - } - - do { - while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) { - if (!--timeout) - return -ETIMEDOUT; - (void)__raw_readl(ssp->mmio_base + SSDR); - } - if (!--timeout) - return -ETIMEDOUT; - } while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY); - - return 0; -} - -/** - * ssp_enable - enable the SSP port - * - * Turn on the SSP port. - */ -void ssp_enable(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - uint32_t sscr0; - - sscr0 = __raw_readl(ssp->mmio_base + SSCR0); - sscr0 |= SSCR0_SSE; - __raw_writel(sscr0, ssp->mmio_base + SSCR0); -} - -/** - * ssp_disable - shut down the SSP port - * - * Turn off the SSP port, optionally powering it down. - */ -void ssp_disable(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - uint32_t sscr0; - - sscr0 = __raw_readl(ssp->mmio_base + SSCR0); - sscr0 &= ~SSCR0_SSE; - __raw_writel(sscr0, ssp->mmio_base + SSCR0); -} - -/** - * ssp_save_state - save the SSP configuration - * @ssp: pointer to structure to save SSP configuration - * - * Save the configured SSP state for suspend. - */ -void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state) -{ - struct ssp_device *ssp = dev->ssp; - - state->cr0 = __raw_readl(ssp->mmio_base + SSCR0); - state->cr1 = __raw_readl(ssp->mmio_base + SSCR1); - state->to = __raw_readl(ssp->mmio_base + SSTO); - state->psp = __raw_readl(ssp->mmio_base + SSPSP); - - ssp_disable(dev); -} - -/** - * ssp_restore_state - restore a previously saved SSP configuration - * @ssp: pointer to configuration saved by ssp_save_state - * - * Restore the SSP configuration saved previously by ssp_save_state. - */ -void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state) -{ - struct ssp_device *ssp = dev->ssp; - uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; - - __raw_writel(sssr, ssp->mmio_base + SSSR); - - __raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0); - __raw_writel(state->cr1, ssp->mmio_base + SSCR1); - __raw_writel(state->to, ssp->mmio_base + SSTO); - __raw_writel(state->psp, ssp->mmio_base + SSPSP); - __raw_writel(state->cr0, ssp->mmio_base + SSCR0); -} - -/** - * ssp_config - configure SSP port settings - * @mode: port operating mode - * @flags: port config flags - * @psp_flags: port PSP config flags - * @speed: port speed - * - * Port MUST be disabled by ssp_disable before making any config changes. - */ -int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) -{ - struct ssp_device *ssp = dev->ssp; - - dev->mode = mode; - dev->flags = flags; - dev->psp_flags = psp_flags; - dev->speed = speed; - - /* set up port type, speed, port settings */ - __raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0); - __raw_writel(dev->flags, ssp->mmio_base + SSCR1); - __raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP); - - return 0; -} - -/** - * ssp_init - setup the SSP port - * - * initialise and claim resources for the SSP port. - * - * Returns: - * %-ENODEV if the SSP port is unavailable - * %-EBUSY if the resources are already in use - * %0 on success - */ -int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) -{ - struct ssp_device *ssp; - int ret; - - ssp = ssp_request(port, "SSP"); - if (ssp == NULL) - return -ENODEV; - - dev->ssp = ssp; - dev->port = port; - - /* do we need to get irq */ - if (!(init_flags & SSP_NO_IRQ)) { - ret = request_irq(ssp->irq, ssp_interrupt, - 0, "SSP", dev); - if (ret) - goto out_region; - dev->irq = ssp->irq; - } else - dev->irq = NO_IRQ; - - /* turn on SSP port clock */ - clk_enable(ssp->clk); - return 0; - -out_region: - ssp_free(ssp); - return ret; -} - -/** - * ssp_exit - undo the effects of ssp_init - * - * release and free resources for the SSP port. - */ -void ssp_exit(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - - ssp_disable(dev); - if (dev->irq != NO_IRQ) - free_irq(dev->irq, dev); - clk_disable(ssp->clk); - ssp_free(ssp); -} - -static DEFINE_MUTEX(ssp_lock); -static LIST_HEAD(ssp_list); - -struct ssp_device *ssp_request(int port, const char *label) -{ - struct ssp_device *ssp = NULL; - - mutex_lock(&ssp_lock); - - list_for_each_entry(ssp, &ssp_list, node) { - if (ssp->port_id == port && ssp->use_count == 0) { - ssp->use_count++; - ssp->label = label; - break; - } - } - - mutex_unlock(&ssp_lock); - - if (&ssp->node == &ssp_list) - return NULL; - - return ssp; -} -EXPORT_SYMBOL(ssp_request); - -void ssp_free(struct ssp_device *ssp) -{ - mutex_lock(&ssp_lock); - if (ssp->use_count) { - ssp->use_count--; - ssp->label = NULL; - } else - dev_err(&ssp->pdev->dev, "device already free\n"); - mutex_unlock(&ssp_lock); -} -EXPORT_SYMBOL(ssp_free); - -static int __devinit ssp_probe(struct platform_device *pdev, int type) -{ - struct resource *res; - struct ssp_device *ssp; - int ret = 0; - - ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL); - if (ssp == NULL) { - dev_err(&pdev->dev, "failed to allocate memory"); - return -ENOMEM; - } - ssp->pdev = pdev; - - ssp->clk = clk_get(&pdev->dev, "SSPCLK"); - if (IS_ERR(ssp->clk)) { - ret = PTR_ERR(ssp->clk); - goto err_free; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no memory resource defined\n"); - ret = -ENODEV; - goto err_free_clk; - } - - res = request_mem_region(res->start, res->end - res->start + 1, - pdev->name); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request memory resource\n"); - ret = -EBUSY; - goto err_free_clk; - } - - ssp->phys_base = res->start; - - ssp->mmio_base = ioremap(res->start, res->end - res->start + 1); - if (ssp->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to ioremap() registers\n"); - ret = -ENODEV; - goto err_free_mem; - } - - ssp->irq = platform_get_irq(pdev, 0); - if (ssp->irq < 0) { - dev_err(&pdev->dev, "no IRQ resource defined\n"); - ret = -ENODEV; - goto err_free_io; - } - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no SSP RX DRCMR defined\n"); - ret = -ENODEV; - goto err_free_io; - } - ssp->drcmr_rx = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (res == NULL) { - dev_err(&pdev->dev, "no SSP TX DRCMR defined\n"); - ret = -ENODEV; - goto err_free_io; - } - ssp->drcmr_tx = res->start; - - /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id - * starts from 0, do a translation here - */ - ssp->port_id = pdev->id + 1; - ssp->use_count = 0; - ssp->type = type; - - mutex_lock(&ssp_lock); - list_add(&ssp->node, &ssp_list); - mutex_unlock(&ssp_lock); - - platform_set_drvdata(pdev, ssp); - return 0; - -err_free_io: - iounmap(ssp->mmio_base); -err_free_mem: - release_mem_region(res->start, res->end - res->start + 1); -err_free_clk: - clk_put(ssp->clk); -err_free: - kfree(ssp); - return ret; -} - -static int __devexit ssp_remove(struct platform_device *pdev) -{ - struct resource *res; - struct ssp_device *ssp; - - ssp = platform_get_drvdata(pdev); - if (ssp == NULL) - return -ENODEV; - - iounmap(ssp->mmio_base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); - - clk_put(ssp->clk); - - mutex_lock(&ssp_lock); - list_del(&ssp->node); - mutex_unlock(&ssp_lock); - - kfree(ssp); - return 0; -} - -static int __devinit pxa25x_ssp_probe(struct platform_device *pdev) -{ - return ssp_probe(pdev, PXA25x_SSP); -} - -static int __devinit pxa25x_nssp_probe(struct platform_device *pdev) -{ - return ssp_probe(pdev, PXA25x_NSSP); -} - -static int __devinit pxa27x_ssp_probe(struct platform_device *pdev) -{ - return ssp_probe(pdev, PXA27x_SSP); -} - -static struct platform_driver pxa25x_ssp_driver = { - .driver = { - .name = "pxa25x-ssp", - }, - .probe = pxa25x_ssp_probe, - .remove = __devexit_p(ssp_remove), -}; - -static struct platform_driver pxa25x_nssp_driver = { - .driver = { - .name = "pxa25x-nssp", - }, - .probe = pxa25x_nssp_probe, - .remove = __devexit_p(ssp_remove), -}; - -static struct platform_driver pxa27x_ssp_driver = { - .driver = { - .name = "pxa27x-ssp", - }, - .probe = pxa27x_ssp_probe, - .remove = __devexit_p(ssp_remove), -}; - -static int __init pxa_ssp_init(void) -{ - int ret = 0; - - ret = platform_driver_register(&pxa25x_ssp_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa25x_ssp_driver"); - return ret; - } - - ret = platform_driver_register(&pxa25x_nssp_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa25x_nssp_driver"); - return ret; - } - - ret = platform_driver_register(&pxa27x_ssp_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa27x_ssp_driver"); - return ret; - } - - return ret; -} - -static void __exit pxa_ssp_exit(void) -{ - platform_driver_unregister(&pxa25x_ssp_driver); - platform_driver_unregister(&pxa25x_nssp_driver); - platform_driver_unregister(&pxa27x_ssp_driver); -} - -arch_initcall(pxa_ssp_init); -module_exit(pxa_ssp_exit); - -EXPORT_SYMBOL(ssp_write_word); -EXPORT_SYMBOL(ssp_read_word); -EXPORT_SYMBOL(ssp_flush); -EXPORT_SYMBOL(ssp_enable); -EXPORT_SYMBOL(ssp_disable); -EXPORT_SYMBOL(ssp_save_state); -EXPORT_SYMBOL(ssp_restore_state); -EXPORT_SYMBOL(ssp_init); -EXPORT_SYMBOL(ssp_exit); -EXPORT_SYMBOL(ssp_config); - -MODULE_DESCRIPTION("PXA SSP driver"); -MODULE_AUTHOR("Liam Girdwood"); -MODULE_LICENSE("GPL"); - diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index f3821cfda72..29f5f5c180b 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -13,7 +13,6 @@ #include <asm/assembler.h> #include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-regs.h> .text diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c new file mode 100644 index 00000000000..01de542432a --- /dev/null +++ b/arch/arm/mach-pxa/stargate2.c @@ -0,0 +1,1028 @@ +/* + * linux/arch/arm/mach-pxa/stargate2.c + * + * Author: Ed C. Epp + * Created: Nov 05, 2002 + * Copyright: Intel Corp. + * + * Modified 2009: Jonathan Cameron <jic23@cam.ac.uk> + * + * 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/device.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/bitops.h> +#include <linux/fb.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/regulator/machine.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/plat-ram.h> +#include <linux/mtd/partitions.h> + +#include <linux/i2c/pxa-i2c.h> +#include <linux/i2c/pcf857x.h> +#include <linux/platform_data/at24.h> +#include <linux/smc91x.h> +#include <linux/gpio.h> +#include <linux/leds.h> + +#include <asm/types.h> +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <asm/irq.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 <linux/platform_data/mmc-pxamci.h> +#include <mach/udc.h> +#include <mach/pxa27x-udc.h> +#include <mach/smemc.h> + +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/mfd/da903x.h> +#include <linux/platform_data/sht15.h> + +#include "devices.h" +#include "generic.h" + +#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8) + +/* Bluetooth */ +#define SG2_BT_RESET 81 + +/* SD */ +#define SG2_GPIO_nSD_DETECT 90 +#define SG2_SD_POWER_ENABLE 89 + +static unsigned long sg2_im2_unified_pin_config[] __initdata = { + /* Device Identification for wakeup*/ + GPIO102_GPIO, + /* DA9030 */ + GPIO1_GPIO, + + /* MMC */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + + /* 802.15.4 radio - driver out of mainline */ + GPIO22_GPIO, /* CC_RSTN */ + GPIO114_GPIO, /* CC_FIFO */ + GPIO116_GPIO, /* CC_CCA */ + GPIO0_GPIO, /* CC_FIFOP */ + GPIO16_GPIO, /* CCSFD */ + GPIO115_GPIO, /* Power enable */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* SSP 3 - 802.15.4 radio */ + GPIO39_GPIO, /* Chip Select */ + GPIO34_SSP3_SCLK, + GPIO35_SSP3_TXD, + GPIO41_SSP3_RXD, + + /* SSP 2 to daughter boards */ + GPIO11_SSP2_RXD, + GPIO38_SSP2_TXD, + GPIO36_SSP2_SCLK, + GPIO37_GPIO, /* chip select */ + + /* SSP 1 - to daughter boards */ + GPIO24_GPIO, /* Chip Select */ + GPIO23_SSP1_SCLK, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* BTUART Basic Connector*/ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART - IM2 via debug board not sure on SG2*/ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* Basic sensor board */ + GPIO96_GPIO, /* accelerometer interrupt */ + GPIO99_GPIO, /* ADC interrupt */ + + /* SHT15 */ + GPIO100_GPIO, + GPIO98_GPIO, + + /* Basic sensor board */ + GPIO96_GPIO, /* accelerometer interrupt */ + GPIO99_GPIO, /* ADC interrupt */ + + /* Connector pins specified as gpios */ + GPIO94_GPIO, /* large basic connector pin 14 */ + GPIO10_GPIO, /* large basic connector pin 23 */ +}; + +static struct sht15_platform_data platform_data_sht15 = { + .gpio_data = 100, + .gpio_sck = 98, +}; + +static struct platform_device sht15 = { + .name = "sht15", + .id = -1, + .dev = { + .platform_data = &platform_data_sht15, + }, +}; + +static struct regulator_consumer_supply stargate2_sensor_3_con[] = { + REGULATOR_SUPPLY("vcc", "sht15"), +}; + +enum stargate2_ldos{ + vcc_vref, + vcc_cc2420, + /* a mote connector? */ + vcc_mica, + /* the CSR bluecore chip */ + vcc_bt, + /* The two voltages available to sensor boards */ + vcc_sensor_1_8, + vcc_sensor_3, + /* directly connected to the pxa27x */ + vcc_sram_ext, + vcc_pxa_pll, + vcc_pxa_usim, /* Reference voltage for certain gpios */ + vcc_pxa_mem, + vcc_pxa_flash, + vcc_pxa_core, /*Dc-Dc buck not yet supported */ + vcc_lcd, + vcc_bb, + vcc_bbio, /*not sure!*/ + vcc_io, /* cc2420 802.15.4 radio and pxa vcc_io ?*/ +}; + +/* The values of the various regulator constraints are obviously dependent + * on exactly what is wired to each ldo. Unfortunately this information is + * not generally available. More information has been requested from Xbow. + */ +static struct regulator_init_data stargate2_ldo_init_data[] = { + [vcc_bbio] = { + .constraints = { /* board default 1.8V */ + .name = "vcc_bbio", + .min_uV = 1800000, + .max_uV = 1800000, + }, + }, + [vcc_bb] = { + .constraints = { /* board default 2.8V */ + .name = "vcc_bb", + .min_uV = 2700000, + .max_uV = 3000000, + }, + }, + [vcc_pxa_flash] = { + .constraints = {/* default is 1.8V */ + .name = "vcc_pxa_flash", + .min_uV = 1800000, + .max_uV = 1800000, + }, + }, + [vcc_cc2420] = { /* also vcc_io */ + .constraints = { + /* board default is 2.8V */ + .name = "vcc_cc2420", + .min_uV = 2700000, + .max_uV = 3300000, + }, + }, + [vcc_vref] = { /* Reference for what? */ + .constraints = { /* default 1.8V */ + .name = "vcc_vref", + .min_uV = 1800000, + .max_uV = 1800000, + }, + }, + [vcc_sram_ext] = { + .constraints = { /* default 2.8V */ + .name = "vcc_sram_ext", + .min_uV = 2800000, + .max_uV = 2800000, + }, + }, + [vcc_mica] = { + .constraints = { /* default 2.8V */ + .name = "vcc_mica", + .min_uV = 2800000, + .max_uV = 2800000, + }, + }, + [vcc_bt] = { + .constraints = { /* default 2.8V */ + .name = "vcc_bt", + .min_uV = 2800000, + .max_uV = 2800000, + }, + }, + [vcc_lcd] = { + .constraints = { /* default 2.8V */ + .name = "vcc_lcd", + .min_uV = 2700000, + .max_uV = 3300000, + }, + }, + [vcc_io] = { /* Same or higher than everything + * bar vccbat and vccusb */ + .constraints = { /* default 2.8V */ + .name = "vcc_io", + .min_uV = 2692000, + .max_uV = 3300000, + }, + }, + [vcc_sensor_1_8] = { + .constraints = { /* default 1.8V */ + .name = "vcc_sensor_1_8", + .min_uV = 1800000, + .max_uV = 1800000, + }, + }, + [vcc_sensor_3] = { /* curiously default 2.8V */ + .constraints = { + .name = "vcc_sensor_3", + .min_uV = 2800000, + .max_uV = 3000000, + }, + .num_consumer_supplies = ARRAY_SIZE(stargate2_sensor_3_con), + .consumer_supplies = stargate2_sensor_3_con, + }, + [vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/ + .constraints = { + .name = "vcc_pxa_pll", + .min_uV = 1170000, + .max_uV = 1430000, + }, + }, + [vcc_pxa_usim] = { + .constraints = { /* default 1.8V */ + .name = "vcc_pxa_usim", + .min_uV = 1710000, + .max_uV = 2160000, + }, + }, + [vcc_pxa_mem] = { + .constraints = { /* default 1.8V */ + .name = "vcc_pxa_mem", + .min_uV = 1800000, + .max_uV = 1800000, + }, + }, +}; + +static struct mtd_partition stargate2flash_partitions[] = { + { + .name = "Bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = 0, + }, { + .name = "Kernel", + .size = 0x00200000, + .offset = 0x00040000, + .mask_flags = 0 + }, { + .name = "Filesystem", + .size = 0x01DC0000, + .offset = 0x00240000, + .mask_flags = 0 + }, +}; + +static struct resource flash_resources = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct flash_platform_data stargate2_flash_data = { + .map_name = "cfi_probe", + .parts = stargate2flash_partitions, + .nr_parts = ARRAY_SIZE(stargate2flash_partitions), + .name = "PXA27xOnChipROM", + .width = 2, +}; + +static struct platform_device stargate2_flash_device = { + .name = "pxa2xx-flash", + .id = 0, + .dev = { + .platform_data = &stargate2_flash_data, + }, + .resource = &flash_resources, + .num_resources = 1, +}; + +static struct pxa2xx_spi_master pxa_ssp_master_0_info = { + .num_chipselect = 1, +}; + +static struct pxa2xx_spi_master pxa_ssp_master_1_info = { + .num_chipselect = 1, +}; + +static struct pxa2xx_spi_master pxa_ssp_master_2_info = { + .num_chipselect = 1, +}; + +/* An upcoming kernel change will scrap SFRM usage so these + * drivers have been moved to use gpio's via cs_control */ +static struct pxa2xx_spi_chip staccel_chip_info = { + .tx_threshold = 8, + .rx_threshold = 8, + .dma_burst_size = 8, + .timeout = 235, + .gpio_cs = 24, +}; + +static struct pxa2xx_spi_chip cc2420_info = { + .tx_threshold = 8, + .rx_threshold = 8, + .dma_burst_size = 8, + .timeout = 235, + .gpio_cs = 39, +}; + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "lis3l02dq", + .max_speed_hz = 8000000,/* 8MHz max spi frequency at 3V */ + .bus_num = 1, + .chip_select = 0, + .controller_data = &staccel_chip_info, + .irq = PXA_GPIO_TO_IRQ(96), + }, { + .modalias = "cc2420", + .max_speed_hz = 6500000, + .bus_num = 3, + .chip_select = 0, + .controller_data = &cc2420_info, + }, +}; + +static void sg2_udc_command(int cmd) +{ + switch (cmd) { + case PXA2XX_UDC_CMD_CONNECT: + UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE; + break; + case PXA2XX_UDC_CMD_DISCONNECT: + UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE); + break; + } +} + +static struct i2c_pxa_platform_data i2c_pwr_pdata = { + .fast_mode = 1, +}; + +static struct i2c_pxa_platform_data i2c_pdata = { + .fast_mode = 1, +}; + +static void __init imote2_stargate2_init(void) +{ + + pxa2xx_mfp_config(ARRAY_AND_SIZE(sg2_im2_unified_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info); + pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info); + pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); + + + pxa27x_set_i2c_power_info(&i2c_pwr_pdata); + pxa_set_i2c_info(&i2c_pdata); +} + +#ifdef CONFIG_MACH_INTELMOTE2 +/* As the the imote2 doesn't currently have a conventional SD slot + * there is no option to hotplug cards, making all this rather simple + */ +static int imote2_mci_get_ro(struct device *dev) +{ + return 0; +} + +/* Rather simple case as hotplugging not possible */ +static struct pxamci_platform_data imote2_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */ + .get_ro = imote2_mci_get_ro, + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, +}; + +static struct gpio_led imote2_led_pins[] = { + { + .name = "imote2:red", + .gpio = 103, + .active_low = 1, + }, { + .name = "imote2:green", + .gpio = 104, + .active_low = 1, + }, { + .name = "imote2:blue", + .gpio = 105, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data imote2_led_data = { + .num_leds = ARRAY_SIZE(imote2_led_pins), + .leds = imote2_led_pins, +}; + +static struct platform_device imote2_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &imote2_led_data, + }, +}; + +static struct da903x_subdev_info imote2_da9030_subdevs[] = { + { + .name = "da903x-regulator", + .id = DA9030_ID_LDO2, + .platform_data = &stargate2_ldo_init_data[vcc_bbio], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO3, + .platform_data = &stargate2_ldo_init_data[vcc_bb], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO4, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO5, + .platform_data = &stargate2_ldo_init_data[vcc_cc2420], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO6, + .platform_data = &stargate2_ldo_init_data[vcc_vref], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO7, + .platform_data = &stargate2_ldo_init_data[vcc_sram_ext], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO8, + .platform_data = &stargate2_ldo_init_data[vcc_mica], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO9, + .platform_data = &stargate2_ldo_init_data[vcc_bt], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO10, + .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO11, + .platform_data = &stargate2_ldo_init_data[vcc_sensor_3], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO12, + .platform_data = &stargate2_ldo_init_data[vcc_lcd], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO15, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO17, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim], + }, { + .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */ + .id = DA9030_ID_LDO18, + .platform_data = &stargate2_ldo_init_data[vcc_io], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO19, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem], + }, +}; + +static struct da903x_platform_data imote2_da9030_pdata = { + .num_subdevs = ARRAY_SIZE(imote2_da9030_subdevs), + .subdevs = imote2_da9030_subdevs, +}; + +static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = { + { + .type = "da9030", + .addr = 0x49, + .platform_data = &imote2_da9030_pdata, + .irq = PXA_GPIO_TO_IRQ(1), + }, +}; + +static struct i2c_board_info __initdata imote2_i2c_board_info[] = { + { /* UCAM sensor board */ + .type = "max1239", + .addr = 0x35, + }, { /* ITS400 Sensor board only */ + .type = "max1363", + .addr = 0x34, + /* Through a nand gate - Also beware, on V2 sensor board the + * pull up resistors are missing. + */ + .irq = PXA_GPIO_TO_IRQ(99), + }, { /* ITS400 Sensor board only */ + .type = "tsl2561", + .addr = 0x49, + /* Through a nand gate - Also beware, on V2 sensor board the + * pull up resistors are missing. + */ + .irq = PXA_GPIO_TO_IRQ(99), + }, { /* ITS400 Sensor board only */ + .type = "tmp175", + .addr = 0x4A, + .irq = PXA_GPIO_TO_IRQ(96), + }, { /* IMB400 Multimedia board */ + .type = "wm8940", + .addr = 0x1A, + }, +}; + +static unsigned long imote2_pin_config[] __initdata = { + + /* Button */ + GPIO91_GPIO, + + /* LEDS */ + GPIO103_GPIO, /* red led */ + GPIO104_GPIO, /* green led */ + GPIO105_GPIO, /* blue led */ +}; + +static struct pxa2xx_udc_mach_info imote2_udc_info __initdata = { + .udc_command = sg2_udc_command, +}; + +static struct platform_device imote2_audio_device = { + .name = "imote2-audio", + .id = -1, +}; + +static struct platform_device *imote2_devices[] = { + &stargate2_flash_device, + &imote2_leds, + &sht15, + &imote2_audio_device, +}; + +static void __init imote2_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(imote2_pin_config)); + + imote2_stargate2_init(); + + platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices)); + + i2c_register_board_info(0, imote2_i2c_board_info, + ARRAY_SIZE(imote2_i2c_board_info)); + i2c_register_board_info(1, imote2_pwr_i2c_board_info, + ARRAY_SIZE(imote2_pwr_i2c_board_info)); + + pxa_set_mci_info(&imote2_mci_platform_data); + pxa_set_udc_info(&imote2_udc_info); +} +#endif + +#ifdef CONFIG_MACH_STARGATE2 + +static unsigned long stargate2_pin_config[] __initdata = { + + GPIO15_nCS_1, /* SRAM */ + /* SMC91x */ + GPIO80_nCS_4, + GPIO40_GPIO, /*cable detect?*/ + + /* Button */ + GPIO91_GPIO | WAKEUP_ON_LEVEL_HIGH, + + /* Compact Flash */ + GPIO79_PSKTSEL, + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO120_GPIO, /* Buff ctrl */ + GPIO108_GPIO, /* Power ctrl */ + GPIO82_GPIO, /* Reset */ + GPIO53_GPIO, /* SG2_S0_GPIO_DETECT */ + + /* MMC not shared with imote2 */ + GPIO90_GPIO, /* nSD detect */ + GPIO89_GPIO, /* SD_POWER_ENABLE */ + + /* Bluetooth */ + GPIO81_GPIO, /* reset */ +}; + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = (PXA_CS4_PHYS + 0x300), + .end = (PXA_CS4_PHYS + 0xfffff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(40), + .end = PXA_GPIO_TO_IRQ(40), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct smc91x_platdata stargate2_smc91x_info = { + .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT + | SMC91X_NOWAIT | SMC91X_USE_DMA, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &stargate2_smc91x_info, + }, +}; + + +/* + * The card detect interrupt isn't debounced so we delay it by 250ms + * to give the card a chance to fully insert / eject. + */ +static int stargate2_mci_init(struct device *dev, + irq_handler_t stargate2_detect_int, + void *data) +{ + int err; + + err = gpio_request(SG2_SD_POWER_ENABLE, "SG2_sd_power_enable"); + if (err) { + printk(KERN_ERR "Can't get the gpio for SD power control"); + goto return_err; + } + gpio_direction_output(SG2_SD_POWER_ENABLE, 0); + + err = gpio_request(SG2_GPIO_nSD_DETECT, "SG2_sd_detect"); + if (err) { + printk(KERN_ERR "Can't get the sd detect gpio"); + goto free_power_en; + } + gpio_direction_input(SG2_GPIO_nSD_DETECT); + + err = request_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), + stargate2_detect_int, + IRQ_TYPE_EDGE_BOTH, + "MMC card detect", + data); + if (err) { + printk(KERN_ERR "can't request MMC card detect IRQ\n"); + goto free_nsd_detect; + } + return 0; + + free_nsd_detect: + gpio_free(SG2_GPIO_nSD_DETECT); + free_power_en: + gpio_free(SG2_SD_POWER_ENABLE); + return_err: + return err; +} + +/** + * stargate2_mci_setpower() - set state of mmc power supply + * + * Very simple control. Either it is on or off and is controlled by + * a gpio pin */ +static int stargate2_mci_setpower(struct device *dev, unsigned int vdd) +{ + gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd); + return 0; +} + +static void stargate2_mci_exit(struct device *dev, void *data) +{ + free_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), data); + gpio_free(SG2_SD_POWER_ENABLE); + gpio_free(SG2_GPIO_nSD_DETECT); +} + +static struct pxamci_platform_data stargate2_mci_platform_data = { + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .init = stargate2_mci_init, + .setpower = stargate2_mci_setpower, + .exit = stargate2_mci_exit, +}; + + +/* + * SRAM - The Stargate 2 has 32MB of SRAM. + * + * Here it is made available as an MTD. This will then + * typically have a cifs filesystem created on it to provide + * fast temporary storage. + */ +static struct resource sram_resources = { + .start = PXA_CS1_PHYS, + .end = PXA_CS1_PHYS + SZ_32M-1, + .flags = IORESOURCE_MEM, +}; + +static struct platdata_mtd_ram stargate2_sram_pdata = { + .mapname = "Stargate2 SRAM", + .bankwidth = 2, +}; + +static struct platform_device stargate2_sram = { + .name = "mtd-ram", + .id = 0, + .resource = &sram_resources, + .num_resources = 1, + .dev = { + .platform_data = &stargate2_sram_pdata, + }, +}; + +static struct pcf857x_platform_data platform_data_pcf857x = { + .gpio_base = 128, + .n_latch = 0, + .setup = NULL, + .teardown = NULL, + .context = NULL, +}; + +static struct at24_platform_data pca9500_eeprom_pdata = { + .byte_len = 256, + .page_size = 4, +}; + +/** + * stargate2_reset_bluetooth() reset the bluecore to ensure consistent state + **/ +static int stargate2_reset_bluetooth(void) +{ + int err; + err = gpio_request(SG2_BT_RESET, "SG2_BT_RESET"); + if (err) { + printk(KERN_ERR "Could not get gpio for bluetooth reset\n"); + return err; + } + gpio_direction_output(SG2_BT_RESET, 1); + mdelay(5); + /* now reset it - 5 msec minimum */ + gpio_set_value(SG2_BT_RESET, 0); + mdelay(10); + gpio_set_value(SG2_BT_RESET, 1); + gpio_free(SG2_BT_RESET); + return 0; +} + +static struct led_info stargate2_leds[] = { + { + .name = "sg2:red", + .flags = DA9030_LED_RATE_ON, + }, { + .name = "sg2:blue", + .flags = DA9030_LED_RATE_ON, + }, { + .name = "sg2:green", + .flags = DA9030_LED_RATE_ON, + }, +}; + +static struct da903x_subdev_info stargate2_da9030_subdevs[] = { + { + .name = "da903x-led", + .id = DA9030_ID_LED_2, + .platform_data = &stargate2_leds[0], + }, { + .name = "da903x-led", + .id = DA9030_ID_LED_3, + .platform_data = &stargate2_leds[2], + }, { + .name = "da903x-led", + .id = DA9030_ID_LED_4, + .platform_data = &stargate2_leds[1], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO2, + .platform_data = &stargate2_ldo_init_data[vcc_bbio], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO3, + .platform_data = &stargate2_ldo_init_data[vcc_bb], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO4, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO5, + .platform_data = &stargate2_ldo_init_data[vcc_cc2420], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO6, + .platform_data = &stargate2_ldo_init_data[vcc_vref], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO7, + .platform_data = &stargate2_ldo_init_data[vcc_sram_ext], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO8, + .platform_data = &stargate2_ldo_init_data[vcc_mica], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO9, + .platform_data = &stargate2_ldo_init_data[vcc_bt], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO10, + .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO11, + .platform_data = &stargate2_ldo_init_data[vcc_sensor_3], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO12, + .platform_data = &stargate2_ldo_init_data[vcc_lcd], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO15, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO17, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim], + }, { + .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */ + .id = DA9030_ID_LDO18, + .platform_data = &stargate2_ldo_init_data[vcc_io], + }, { + .name = "da903x-regulator", + .id = DA9030_ID_LDO19, + .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem], + }, +}; + +static struct da903x_platform_data stargate2_da9030_pdata = { + .num_subdevs = ARRAY_SIZE(stargate2_da9030_subdevs), + .subdevs = stargate2_da9030_subdevs, +}; + +static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = { + { + .type = "da9030", + .addr = 0x49, + .platform_data = &stargate2_da9030_pdata, + .irq = PXA_GPIO_TO_IRQ(1), + }, +}; + +static struct i2c_board_info __initdata stargate2_i2c_board_info[] = { + /* Techically this a pca9500 - but it's compatible with the 8574 + * for gpio expansion and the 24c02 for eeprom access. + */ + { + .type = "pcf8574", + .addr = 0x27, + .platform_data = &platform_data_pcf857x, + }, { + .type = "24c02", + .addr = 0x57, + .platform_data = &pca9500_eeprom_pdata, + }, { + .type = "max1238", + .addr = 0x35, + }, { /* ITS400 Sensor board only */ + .type = "max1363", + .addr = 0x34, + /* Through a nand gate - Also beware, on V2 sensor board the + * pull up resistors are missing. + */ + .irq = PXA_GPIO_TO_IRQ(99), + }, { /* ITS400 Sensor board only */ + .type = "tsl2561", + .addr = 0x49, + /* Through a nand gate - Also beware, on V2 sensor board the + * pull up resistors are missing. + */ + .irq = PXA_GPIO_TO_IRQ(99), + }, { /* ITS400 Sensor board only */ + .type = "tmp175", + .addr = 0x4A, + .irq = PXA_GPIO_TO_IRQ(96), + }, +}; + +/* Board doesn't support cable detection - so always lie and say + * something is there. + */ +static int sg2_udc_detect(void) +{ + return 1; +} + +static struct pxa2xx_udc_mach_info stargate2_udc_info __initdata = { + .udc_is_connected = sg2_udc_detect, + .udc_command = sg2_udc_command, +}; + +static struct platform_device *stargate2_devices[] = { + &stargate2_flash_device, + &stargate2_sram, + &smc91x_device, + &sht15, +}; + +static void __init stargate2_init(void) +{ + /* This is probably a board specific hack as this must be set + prior to connecting the MFP stuff up. */ + __raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config)); + + imote2_stargate2_init(); + + platform_add_devices(ARRAY_AND_SIZE(stargate2_devices)); + + i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info)); + i2c_register_board_info(1, stargate2_pwr_i2c_board_info, + ARRAY_SIZE(stargate2_pwr_i2c_board_info)); + + pxa_set_mci_info(&stargate2_mci_platform_data); + + pxa_set_udc_info(&stargate2_udc_info); + + stargate2_reset_bluetooth(); +} +#endif + +#ifdef CONFIG_MACH_INTELMOTE2 +MACHINE_START(INTELMOTE2, "IMOTE 2") + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = imote2_init, + .atag_offset = 0x100, + .restart = pxa_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_STARGATE2 +MACHINE_START(STARGATE2, "Stargate 2") + .map_io = pxa27x_map_io, + .nr_irqs = STARGATE_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = stargate2_init, + .atag_offset = 0x100, + .restart = pxa_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 589d32b4fc4..a71da84e784 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -18,12 +18,14 @@ #include <linux/clk.h> #include <linux/gpio.h> #include <linux/smc91x.h> +#include <linux/pwm_backlight.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> -#include <mach/mfp-pxa930.h> + +#include <mach/pxa930.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/keypad-pxa27x.h> #include "devices.h" #include "generic.h" @@ -33,6 +35,45 @@ static mfp_cfg_t tavorevb_mfp_cfg[] __initdata = { /* Ethernet */ DF_nCS1_nCS3, GPIO47_GPIO, + + /* LCD */ + GPIO23_LCD_DD0, + GPIO24_LCD_DD1, + GPIO25_LCD_DD2, + GPIO26_LCD_DD3, + GPIO27_LCD_DD4, + GPIO28_LCD_DD5, + GPIO29_LCD_DD6, + GPIO44_LCD_DD7, + GPIO21_LCD_CS, + GPIO22_LCD_CS2, + + GPIO17_LCD_FCLK_RD, + GPIO18_LCD_LCLK_A0, + GPIO19_LCD_PCLK_WR, + + /* LCD Backlight */ + GPIO43_PWM3, /* primary backlight */ + GPIO32_PWM0, /* secondary backlight */ + + /* Keypad */ + GPIO0_KP_MKIN_0, + GPIO2_KP_MKIN_1, + GPIO4_KP_MKIN_2, + GPIO6_KP_MKIN_3, + GPIO8_KP_MKIN_4, + GPIO10_KP_MKIN_5, + GPIO12_KP_MKIN_6, + GPIO1_KP_MKOUT_0, + GPIO3_KP_MKOUT_1, + GPIO5_KP_MKOUT_2, + GPIO7_KP_MKOUT_3, + GPIO9_KP_MKOUT_4, + GPIO11_KP_MKOUT_5, + GPIO13_KP_MKOUT_6, + + GPIO14_KP_DKIN_2, + GPIO15_KP_DKIN_3, }; #define TAVOREVB_ETH_PHYS (0x14000000) @@ -44,8 +85,8 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), - .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), + .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)), + .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; @@ -64,21 +105,402 @@ static struct platform_device smc91x_device = { }, }; +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static const unsigned int tavorevb_matrix_key_map[] = { + /* KEY(row, col, key_code) */ + KEY(0, 4, KEY_A), KEY(0, 5, KEY_B), KEY(0, 6, KEY_C), + KEY(1, 4, KEY_E), KEY(1, 5, KEY_F), KEY(1, 6, KEY_G), + KEY(2, 4, KEY_I), KEY(2, 5, KEY_J), KEY(2, 6, KEY_K), + KEY(3, 4, KEY_M), KEY(3, 5, KEY_N), KEY(3, 6, KEY_O), + KEY(4, 5, KEY_R), KEY(4, 6, KEY_S), + KEY(5, 4, KEY_U), KEY(5, 4, KEY_V), KEY(5, 6, KEY_W), + + KEY(6, 4, KEY_Y), KEY(6, 5, KEY_Z), + + KEY(0, 3, KEY_0), KEY(2, 0, KEY_1), KEY(2, 1, KEY_2), KEY(2, 2, KEY_3), + KEY(2, 3, KEY_4), KEY(1, 0, KEY_5), KEY(1, 1, KEY_6), KEY(1, 2, KEY_7), + KEY(1, 3, KEY_8), KEY(0, 2, KEY_9), + + KEY(6, 6, KEY_SPACE), + KEY(0, 0, KEY_KPASTERISK), /* * */ + KEY(0, 1, KEY_KPDOT), /* # */ + + KEY(4, 1, KEY_UP), + KEY(4, 3, KEY_DOWN), + KEY(4, 0, KEY_LEFT), + KEY(4, 2, KEY_RIGHT), + KEY(6, 0, KEY_HOME), + KEY(3, 2, KEY_END), + KEY(6, 1, KEY_DELETE), + KEY(5, 2, KEY_BACK), + KEY(6, 3, KEY_CAPSLOCK), /* KEY_LEFTSHIFT), */ + + KEY(4, 4, KEY_ENTER), /* scroll push */ + KEY(6, 2, KEY_ENTER), /* keypad action */ + + KEY(3, 1, KEY_SEND), + KEY(5, 3, KEY_RECORD), + KEY(5, 0, KEY_VOLUMEUP), + KEY(5, 1, KEY_VOLUMEDOWN), + + KEY(3, 0, KEY_F22), /* soft1 */ + KEY(3, 3, KEY_F23), /* soft2 */ +}; + +static struct matrix_keymap_data tavorevb_matrix_keymap_data = { + .keymap = tavorevb_matrix_key_map, + .keymap_size = ARRAY_SIZE(tavorevb_matrix_key_map), +}; + +static struct pxa27x_keypad_platform_data tavorevb_keypad_info = { + .matrix_key_rows = 7, + .matrix_key_cols = 7, + .matrix_keymap_data = &tavorevb_matrix_keymap_data, + .debounce_interval = 30, +}; + +static void __init tavorevb_init_keypad(void) +{ + pxa_set_keypad_info(&tavorevb_keypad_info); +} +#else +static inline void tavorevb_init_keypad(void) {} +#endif /* CONFIG_KEYBOARD_PXA27x || CONFIG_KEYBOARD_PXA27x_MODULE */ + +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct platform_pwm_backlight_data tavorevb_backlight_data[] = { + [0] = { + /* primary backlight */ + .pwm_id = 2, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 100000, + .enable_gpio = -1, + }, + [1] = { + /* secondary backlight */ + .pwm_id = 0, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 100000, + .enable_gpio = -1, + }, +}; + +static struct platform_device tavorevb_backlight_devices[] = { + [0] = { + .name = "pwm-backlight", + .id = 0, + .dev = { + .platform_data = &tavorevb_backlight_data[0], + }, + }, + [1] = { + .name = "pwm-backlight", + .id = 1, + .dev = { + .platform_data = &tavorevb_backlight_data[1], + }, + }, +}; + +static uint16_t panel_init[] = { + /* DSTB OUT */ + SMART_CMD(0x00), + SMART_CMD_NOOP, + SMART_DELAY(1), + + SMART_CMD(0x00), + SMART_CMD_NOOP, + SMART_DELAY(1), + + SMART_CMD(0x00), + SMART_CMD_NOOP, + SMART_DELAY(1), + + /* STB OUT */ + SMART_CMD(0x00), + SMART_CMD(0x1D), + SMART_DAT(0x00), + SMART_DAT(0x05), + SMART_DELAY(1), + + /* P-ON Init sequence */ + SMART_CMD(0x00), /* OSC ON */ + SMART_CMD(0x00), + SMART_DAT(0x00), + SMART_DAT(0x01), + SMART_CMD(0x00), + SMART_CMD(0x01), /* SOURCE DRIVER SHIFT DIRECTION and display RAM setting */ + SMART_DAT(0x01), + SMART_DAT(0x27), + SMART_CMD(0x00), + SMART_CMD(0x02), /* LINE INV */ + SMART_DAT(0x02), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x03), /* IF mode(1) */ + SMART_DAT(0x01), /* 8bit smart mode(8-8),high speed write mode */ + SMART_DAT(0x30), + SMART_CMD(0x07), + SMART_CMD(0x00), /* RAM Write Mode */ + SMART_DAT(0x00), + SMART_DAT(0x03), + SMART_CMD(0x00), + + /* DISPLAY Setting, 262K, fixed(NO scroll), no split screen */ + SMART_CMD(0x07), + SMART_DAT(0x40), /* 16/18/19 BPP */ + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x08), /* BP, FP Seting, BP=2H, FP=3H */ + SMART_DAT(0x03), + SMART_DAT(0x02), + SMART_CMD(0x00), + SMART_CMD(0x0C), /* IF mode(2), using internal clock & MPU */ + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x0D), /* Frame setting, 1Min. Frequence, 16CLK */ + SMART_DAT(0x00), + SMART_DAT(0x10), + SMART_CMD(0x00), + SMART_CMD(0x12), /* Timing(1),ASW W=4CLK, ASW ST=1CLK */ + SMART_DAT(0x03), + SMART_DAT(0x02), + SMART_CMD(0x00), + SMART_CMD(0x13), /* Timing(2),OEV ST=0.5CLK, OEV ED=1CLK */ + SMART_DAT(0x01), + SMART_DAT(0x02), + SMART_CMD(0x00), + SMART_CMD(0x14), /* Timing(3), ASW HOLD=0.5CLK */ + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x15), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */ + SMART_DAT(0x20), + SMART_DAT(0x00), + SMART_CMD(0x00), + SMART_CMD(0x1C), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x03), + SMART_CMD(0x00), + SMART_DAT(0x04), + SMART_DAT(0x03), + SMART_CMD(0x03), + SMART_CMD(0x01), + SMART_DAT(0x03), + SMART_DAT(0x04), + SMART_CMD(0x03), + SMART_CMD(0x02), + SMART_DAT(0x04), + SMART_DAT(0x03), + SMART_CMD(0x03), + SMART_CMD(0x03), + SMART_DAT(0x03), + SMART_DAT(0x03), + SMART_CMD(0x03), + SMART_CMD(0x04), + SMART_DAT(0x01), + SMART_DAT(0x01), + SMART_CMD(0x03), + SMART_CMD(0x05), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x04), + SMART_CMD(0x02), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x04), + SMART_CMD(0x03), + SMART_DAT(0x01), + SMART_DAT(0x3F), + SMART_DELAY(0), + + /* DISP RAM setting: 240*320 */ + SMART_CMD(0x04), /* HADDR, START 0 */ + SMART_CMD(0x06), + SMART_DAT(0x00), + SMART_DAT(0x00), /* x1,3 */ + SMART_CMD(0x04), /* HADDR, END 4 */ + SMART_CMD(0x07), + SMART_DAT(0x00), + SMART_DAT(0xEF), /* x2, 7 */ + SMART_CMD(0x04), /* VADDR, START 8 */ + SMART_CMD(0x08), + SMART_DAT(0x00), /* y1, 10 */ + SMART_DAT(0x00), /* y1, 11 */ + SMART_CMD(0x04), /* VADDR, END 12 */ + SMART_CMD(0x09), + SMART_DAT(0x01), /* y2, 14 */ + SMART_DAT(0x3F), /* y2, 15 */ + SMART_CMD(0x02), /* RAM ADDR SETTING 16 */ + SMART_CMD(0x00), + SMART_DAT(0x00), + SMART_DAT(0x00), /* x1, 19 */ + SMART_CMD(0x02), /* RAM ADDR SETTING 20 */ + SMART_CMD(0x01), + SMART_DAT(0x00), /* y1, 22 */ + SMART_DAT(0x00), /* y1, 23 */ +}; + +static uint16_t panel_on[] = { + /* Power-IC ON */ + SMART_CMD(0x01), + SMART_CMD(0x02), + SMART_DAT(0x07), + SMART_DAT(0x7D), + SMART_CMD(0x01), + SMART_CMD(0x03), + SMART_DAT(0x00), + SMART_DAT(0x05), + SMART_CMD(0x01), + SMART_CMD(0x04), + SMART_DAT(0x00), + SMART_DAT(0x00), + SMART_CMD(0x01), + SMART_CMD(0x05), + SMART_DAT(0x00), + SMART_DAT(0x15), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0xC0), + SMART_DAT(0x10), + SMART_DELAY(30), + + /* DISP ON */ + SMART_CMD(0x01), + SMART_CMD(0x01), + SMART_DAT(0x00), + SMART_DAT(0x01), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0xFF), + SMART_DAT(0xFE), + SMART_DELAY(150), +}; + +static uint16_t panel_off[] = { + SMART_CMD(0x00), + SMART_CMD(0x1E), + SMART_DAT(0x00), + SMART_DAT(0x0A), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0xFF), + SMART_DAT(0xEE), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0xF8), + SMART_DAT(0x12), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0xE8), + SMART_DAT(0x11), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0xC0), + SMART_DAT(0x11), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0x40), + SMART_DAT(0x11), + SMART_CMD(0x01), + SMART_CMD(0x00), + SMART_DAT(0x00), + SMART_DAT(0x10), +}; + +static uint16_t update_framedata[] = { + /* write ram */ + SMART_CMD(0x02), + SMART_CMD(0x02), + + /* write frame data */ + SMART_CMD_WRITE_FRAME, +}; + +static void ltm020d550_lcd_power(int on, struct fb_var_screeninfo *var) +{ + struct fb_info *info = container_of(var, struct fb_info, var); + + if (on) { + pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_init)); + pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_on)); + } else { + pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_off)); + } + + if (pxafb_smart_flush(info)) + pr_err("%s: timed out\n", __func__); +} + +static void ltm020d550_update(struct fb_info *info) +{ + pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata)); + pxafb_smart_flush(info); +} + +static struct pxafb_mode_info toshiba_ltm020d550_modes[] = { + [0] = { + .xres = 240, + .yres = 320, + .bpp = 16, + .a0csrd_set_hld = 30, + .a0cswr_set_hld = 30, + .wr_pulse_width = 30, + .rd_pulse_width = 170, + .op_hold_time = 30, + .cmd_inh_time = 60, + + /* L_LCLK_A0 and L_LCLK_RD active low */ + .sync = FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT, + }, +}; + +static struct pxafb_mach_info tavorevb_lcd_info = { + .modes = toshiba_ltm020d550_modes, + .num_modes = 1, + .lcd_conn = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL, + .pxafb_lcd_power = ltm020d550_lcd_power, + .smart_update = ltm020d550_update, +}; + +static void __init tavorevb_init_lcd(void) +{ + platform_device_register(&tavorevb_backlight_devices[0]); + platform_device_register(&tavorevb_backlight_devices[1]); + pxa_set_fb_info(NULL, &tavorevb_lcd_info); +} +#else +static inline void tavorevb_init_lcd(void) {} +#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */ + static void __init tavorevb_init(void) { /* initialize MFP configurations */ pxa3xx_mfp_config(ARRAY_AND_SIZE(tavorevb_mfp_cfg)); + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + platform_device_register(&smc91x_device); + + tavorevb_init_lcd(); + tavorevb_init_keypad(); } MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)") /* Maintainer: Eric Miao <eric.miao@marvell.com> */ - .phys_io = 0x40000000, - .boot_params = 0xa0000100, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, .init_machine = tavorevb_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index b0d6b32654c..fca174e3865 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -16,14 +16,13 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/clockchips.h> -#include <linux/sched.h> -#include <linux/cnt32_to_63.h> +#include <linux/sched_clock.h> #include <asm/div64.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> -#include <mach/pxa-regs.h> -#include <asm/mach-types.h> +#include <mach/regs-ost.h> +#include <mach/irqs.h> /* * This is PXA's sched_clock implementation. This has a resolution @@ -34,28 +33,9 @@ * calls to sched_clock() which should always be the case in practice. */ -#define OSCR2NS_SCALE_FACTOR 10 - -static unsigned long oscr2ns_scale; - -static void __init set_oscr2ns_scale(unsigned long oscr_rate) -{ - unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR; - do_div(v, oscr_rate); - oscr2ns_scale = v; - /* - * We want an even value to automatically clear the top bit - * returned by cnt32_to_63() without an additional run time - * instruction. So if the LSB is 1 then round it up. - */ - if (oscr2ns_scale & 1) - oscr2ns_scale++; -} - -unsigned long long sched_clock(void) +static u64 notrace pxa_read_sched_clock(void) { - unsigned long long v = cnt32_to_63(OSCR); - return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR; + return readl_relaxed(OSCR); } @@ -67,8 +47,8 @@ pxa_ost0_interrupt(int irq, void *dev_id) struct clock_event_device *c = dev_id; /* Disarm the compare/match, signal the event. */ - OIER &= ~OIER_E0; - OSSR = OSSR_M0; + writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); + writel_relaxed(OSSR_M0, OSSR); c->event_handler(c); return IRQ_HANDLED; @@ -77,14 +57,12 @@ pxa_ost0_interrupt(int irq, void *dev_id) static int pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev) { - unsigned long flags, next, oscr; + unsigned long next, oscr; - raw_local_irq_save(flags); - OIER |= OIER_E0; - next = OSCR + delta; - OSMR0 = next; - oscr = OSCR; - raw_local_irq_restore(flags); + writel_relaxed(readl_relaxed(OIER) | OIER_E0, OIER); + next = readl_relaxed(OSCR) + delta; + writel_relaxed(next, OSMR0); + oscr = readl_relaxed(OSCR); return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; } @@ -92,23 +70,17 @@ pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev) static void pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) { - unsigned long irqflags; - switch (mode) { case CLOCK_EVT_MODE_ONESHOT: - raw_local_irq_save(irqflags); - OIER &= ~OIER_E0; - OSSR = OSSR_M0; - raw_local_irq_restore(irqflags); + writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); + writel_relaxed(OSSR_M0, OSSR); break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* initializing, released, or preparing for suspend */ - raw_local_irq_save(irqflags); - OIER &= ~OIER_E0; - OSSR = OSSR_M0; - raw_local_irq_restore(irqflags); + writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); + writel_relaxed(OSSR_M0, OSSR); break; case CLOCK_EVT_MODE_RESUME: @@ -117,83 +89,20 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) } } -static struct clock_event_device ckevt_pxa_osmr0 = { - .name = "osmr0", - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .rating = 200, - .cpumask = CPU_MASK_CPU0, - .set_next_event = pxa_osmr0_set_next_event, - .set_mode = pxa_osmr0_set_mode, -}; - -static cycle_t pxa_read_oscr(void) -{ - return OSCR; -} - -static struct clocksource cksrc_pxa_oscr0 = { - .name = "oscr0", - .rating = 200, - .read = pxa_read_oscr, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static struct irqaction pxa_ost0_irq = { - .name = "ost0", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = pxa_ost0_interrupt, - .dev_id = &ckevt_pxa_osmr0, -}; - -static void __init pxa_timer_init(void) -{ - unsigned long clock_tick_rate; - - OIER = 0; - OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; - - if (cpu_is_pxa21x() || cpu_is_pxa25x()) - clock_tick_rate = 3686400; - else if (machine_is_mainstone()) - clock_tick_rate = 3249600; - else - clock_tick_rate = 3250000; - - set_oscr2ns_scale(clock_tick_rate); - - ckevt_pxa_osmr0.mult = - div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); - ckevt_pxa_osmr0.max_delta_ns = - clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); - ckevt_pxa_osmr0.min_delta_ns = - clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1; - - cksrc_pxa_oscr0.mult = - clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift); - - setup_irq(IRQ_OST0, &pxa_ost0_irq); - - clocksource_register(&cksrc_pxa_oscr0); - clockevents_register_device(&ckevt_pxa_osmr0); -} - #ifdef CONFIG_PM static unsigned long osmr[4], oier, oscr; -static void pxa_timer_suspend(void) +static void pxa_timer_suspend(struct clock_event_device *cedev) { - osmr[0] = OSMR0; - osmr[1] = OSMR1; - osmr[2] = OSMR2; - osmr[3] = OSMR3; - oier = OIER; - oscr = OSCR; + osmr[0] = readl_relaxed(OSMR0); + osmr[1] = readl_relaxed(OSMR1); + osmr[2] = readl_relaxed(OSMR2); + osmr[3] = readl_relaxed(OSMR3); + oier = readl_relaxed(OIER); + oscr = readl_relaxed(OSCR); } -static void pxa_timer_resume(void) +static void pxa_timer_resume(struct clock_event_device *cedev) { /* * Ensure that we have at least MIN_OSCR_DELTA between match @@ -204,20 +113,50 @@ static void pxa_timer_resume(void) if (osmr[0] - oscr < MIN_OSCR_DELTA) osmr[0] += MIN_OSCR_DELTA; - OSMR0 = osmr[0]; - OSMR1 = osmr[1]; - OSMR2 = osmr[2]; - OSMR3 = osmr[3]; - OIER = oier; - OSCR = oscr; + writel_relaxed(osmr[0], OSMR0); + writel_relaxed(osmr[1], OSMR1); + writel_relaxed(osmr[2], OSMR2); + writel_relaxed(osmr[3], OSMR3); + writel_relaxed(oier, OIER); + writel_relaxed(oscr, OSCR); } #else #define pxa_timer_suspend NULL #define pxa_timer_resume NULL #endif -struct sys_timer pxa_timer = { - .init = pxa_timer_init, +static struct clock_event_device ckevt_pxa_osmr0 = { + .name = "osmr0", + .features = CLOCK_EVT_FEAT_ONESHOT, + .rating = 200, + .set_next_event = pxa_osmr0_set_next_event, + .set_mode = pxa_osmr0_set_mode, .suspend = pxa_timer_suspend, .resume = pxa_timer_resume, }; + +static struct irqaction pxa_ost0_irq = { + .name = "ost0", + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = pxa_ost0_interrupt, + .dev_id = &ckevt_pxa_osmr0, +}; + +void __init pxa_timer_init(void) +{ + unsigned long clock_tick_rate = get_clock_tick_rate(); + + writel_relaxed(0, OIER); + writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); + + sched_clock_register(pxa_read_sched_clock, 32, clock_tick_rate); + + ckevt_pxa_osmr0.cpumask = cpumask_of(0); + + setup_irq(IRQ_OST0, &pxa_ost0_irq); + + clocksource_mmio_init(OSCR, "oscr0", clock_tick_rate, 200, 32, + clocksource_mmio_readl_up); + clockevents_config_and_register(&ckevt_pxa_osmr0, clock_tick_rate, + MIN_OSCR_DELTA * 2, 0x7fffffff); +} diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index fb0294bd431..fc3646c2c69 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -35,21 +35,25 @@ static void tosa_bt_off(struct tosa_bt_data *data) gpio_set_value(data->gpio_reset, 0); } -static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) +static int tosa_bt_set_block(void *data, bool blocked) { - pr_info("BT_RADIO going: %s\n", - state == RFKILL_STATE_ON ? "on" : "off"); + pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on"); - if (state == RFKILL_STATE_ON) { + if (!blocked) { pr_info("TOSA_BT: going ON\n"); tosa_bt_on(data); } else { pr_info("TOSA_BT: going OFF\n"); tosa_bt_off(data); } + return 0; } +static const struct rfkill_ops tosa_bt_rfkill_ops = { + .set_block = tosa_bt_set_block, +}; + static int tosa_bt_probe(struct platform_device *dev) { int rc; @@ -70,19 +74,13 @@ static int tosa_bt_probe(struct platform_device *dev) if (rc) goto err_pwr_dir; - rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); + rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH, + &tosa_bt_rfkill_ops, data); if (!rfk) { rc = -ENOMEM; goto err_rfk_alloc; } - rfk->name = "tosa-bt"; - rfk->toggle_radio = tosa_bt_toggle_radio; - rfk->data = data; -#ifdef CONFIG_RFKILL_LEDS - rfk->led_trigger.name = "tosa-bt"; -#endif - rc = rfkill_register(rfk); if (rc) goto err_rfkill; @@ -92,9 +90,7 @@ static int tosa_bt_probe(struct platform_device *dev) return 0; err_rfkill: - if (rfk) - rfkill_free(rfk); - rfk = NULL; + rfkill_destroy(rfk); err_rfk_alloc: tosa_bt_off(data); err_pwr_dir: @@ -106,15 +102,17 @@ err_reset: return rc; } -static int __devexit tosa_bt_remove(struct platform_device *dev) +static int tosa_bt_remove(struct platform_device *dev) { struct tosa_bt_data *data = dev->dev.platform_data; struct rfkill *rfk = platform_get_drvdata(dev); platform_set_drvdata(dev, NULL); - if (rfk) + if (rfk) { rfkill_unregister(rfk); + rfkill_destroy(rfk); + } rfk = NULL; tosa_bt_off(data); @@ -127,7 +125,7 @@ static int __devexit tosa_bt_remove(struct platform_device *dev) static struct platform_driver tosa_bt_driver = { .probe = tosa_bt_probe, - .remove = __devexit_p(tosa_bt_remove), + .remove = tosa_bt_remove, .driver = { .name = "tosa-bt", diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 9f3ef9eb32e..c158a6e3e0a 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -25,23 +25,31 @@ #include <linux/mfd/tmio.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> #include <linux/pm.h> #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/gpio.h> #include <linux/pda_power.h> -#include <linux/rfkill.h> +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/input/matrix_keypad.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/reboot.h> +#include <linux/memblock.h> #include <asm/setup.h> #include <asm/mach-types.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa25x.h> + +#include <mach/pxa25x.h> #include <mach/reset.h> -#include <mach/irda.h> -#include <mach/i2c.h> -#include <mach/mmc.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/mmc-pxamci.h> #include <mach/udc.h> #include <mach/tosa_bt.h> +#include <mach/audio.h> +#include <mach/smemc.h> #include <asm/mach/arch.h> #include <mach/tosa.h> @@ -128,24 +136,24 @@ static unsigned long tosa_pin_config[] = { GPIO45_BTUART_RTS, /* Keybd */ - GPIO58_GPIO | MFP_LPM_DRIVE_LOW, - GPIO59_GPIO | MFP_LPM_DRIVE_LOW, - GPIO60_GPIO | MFP_LPM_DRIVE_LOW, - GPIO61_GPIO | MFP_LPM_DRIVE_LOW, - GPIO62_GPIO | MFP_LPM_DRIVE_LOW, - GPIO63_GPIO | MFP_LPM_DRIVE_LOW, - GPIO64_GPIO | MFP_LPM_DRIVE_LOW, - GPIO65_GPIO | MFP_LPM_DRIVE_LOW, - GPIO66_GPIO | MFP_LPM_DRIVE_LOW, - GPIO67_GPIO | MFP_LPM_DRIVE_LOW, - GPIO68_GPIO | MFP_LPM_DRIVE_LOW, - GPIO69_GPIO | MFP_LPM_DRIVE_LOW, - GPIO70_GPIO | MFP_LPM_DRIVE_LOW, - GPIO71_GPIO | MFP_LPM_DRIVE_LOW, - GPIO72_GPIO | MFP_LPM_DRIVE_LOW, - GPIO73_GPIO | MFP_LPM_DRIVE_LOW, - GPIO74_GPIO | MFP_LPM_DRIVE_LOW, - GPIO75_GPIO | MFP_LPM_DRIVE_LOW, + GPIO58_GPIO | MFP_LPM_DRIVE_LOW, /* Column 0 */ + GPIO59_GPIO | MFP_LPM_DRIVE_LOW, /* Column 1 */ + GPIO60_GPIO | MFP_LPM_DRIVE_LOW, /* Column 2 */ + GPIO61_GPIO | MFP_LPM_DRIVE_LOW, /* Column 3 */ + GPIO62_GPIO | MFP_LPM_DRIVE_LOW, /* Column 4 */ + GPIO63_GPIO | MFP_LPM_DRIVE_LOW, /* Column 5 */ + GPIO64_GPIO | MFP_LPM_DRIVE_LOW, /* Column 6 */ + GPIO65_GPIO | MFP_LPM_DRIVE_LOW, /* Column 7 */ + GPIO66_GPIO | MFP_LPM_DRIVE_LOW, /* Column 8 */ + GPIO67_GPIO | MFP_LPM_DRIVE_LOW, /* Column 9 */ + GPIO68_GPIO | MFP_LPM_DRIVE_LOW, /* Column 10 */ + GPIO69_GPIO | MFP_LPM_DRIVE_LOW, /* Row 0 */ + GPIO70_GPIO | MFP_LPM_DRIVE_LOW, /* Row 1 */ + GPIO71_GPIO | MFP_LPM_DRIVE_LOW, /* Row 2 */ + GPIO72_GPIO | MFP_LPM_DRIVE_LOW, /* Row 3 */ + GPIO73_GPIO | MFP_LPM_DRIVE_LOW, /* Row 4 */ + GPIO74_GPIO | MFP_LPM_DRIVE_LOW, /* Row 5 */ + GPIO75_GPIO | MFP_LPM_DRIVE_LOW, /* Row 6 */ /* SPI */ GPIO81_SSP2_CLK_OUT, @@ -235,58 +243,27 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = { /* * USB Device Controller */ -static struct pxa2xx_udc_mach_info udc_info __initdata = { +static struct gpio_vbus_mach_info tosa_udc_info = { .gpio_pullup = TOSA_GPIO_USB_PULLUP, .gpio_vbus = TOSA_GPIO_USB_IN, .gpio_vbus_inverted = 1, }; +static struct platform_device tosa_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &tosa_udc_info, + }, +}; + /* * MMC/SD Device */ -static struct pxamci_platform_data tosa_mci_platform_data; - static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data) { int err; - tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); - - err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect"); - if (err) { - printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n"); - goto err_gpio_detect; - } - err = gpio_direction_input(TOSA_GPIO_nSD_DETECT); - if (err) - goto err_gpio_detect_dir; - - err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC/SD card detect", data); - if (err) { - printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); - goto err_irq; - } - - err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect"); - if (err) { - printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n"); - goto err_gpio_wp; - } - err = gpio_direction_input(TOSA_GPIO_SD_WP); - if (err) - goto err_gpio_wp_dir; - - err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power"); - if (err) { - printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); - goto err_gpio_pwr; - } - err = gpio_direction_output(TOSA_GPIO_PWR_ON, 0); - if (err) - goto err_gpio_pwr_dir; - err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int"); if (err) { printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); @@ -301,51 +278,22 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void err_gpio_int_dir: gpio_free(TOSA_GPIO_nSD_INT); err_gpio_int: -err_gpio_pwr_dir: - gpio_free(TOSA_GPIO_PWR_ON); -err_gpio_pwr: -err_gpio_wp_dir: - gpio_free(TOSA_GPIO_SD_WP); -err_gpio_wp: - free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); -err_irq: -err_gpio_detect_dir: - gpio_free(TOSA_GPIO_nSD_DETECT); -err_gpio_detect: return err; } -static void tosa_mci_setpower(struct device *dev, unsigned int vdd) -{ - struct pxamci_platform_data* p_d = dev->platform_data; - - if (( 1 << vdd) & p_d->ocr_mask) { - gpio_set_value(TOSA_GPIO_PWR_ON, 1); - } else { - gpio_set_value(TOSA_GPIO_PWR_ON, 0); - } -} - -static int tosa_mci_get_ro(struct device *dev) -{ - return gpio_get_value(TOSA_GPIO_SD_WP); -} - static void tosa_mci_exit(struct device *dev, void *data) { gpio_free(TOSA_GPIO_nSD_INT); - gpio_free(TOSA_GPIO_PWR_ON); - gpio_free(TOSA_GPIO_SD_WP); - free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); - gpio_free(TOSA_GPIO_nSD_DETECT); } static struct pxamci_platform_data tosa_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = tosa_mci_init, - .get_ro = tosa_mci_get_ro, - .setpower = tosa_mci_setpower, - .exit = tosa_mci_exit, + .detect_delay_ms = 250, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = tosa_mci_init, + .exit = tosa_mci_exit, + .gpio_card_detect = TOSA_GPIO_nSD_DETECT, + .gpio_card_ro = TOSA_GPIO_SD_WP, + .gpio_power = TOSA_GPIO_PWR_ON, }; /* @@ -403,10 +351,11 @@ static void tosa_irda_shutdown(struct device *dev) } static struct pxaficp_platform_data tosa_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_OFF, - .transceiver_mode = tosa_irda_transceiver_mode, - .startup = tosa_irda_startup, - .shutdown = tosa_irda_shutdown, + .gpio_pwdown = -1, + .transceiver_cap = IR_SIRMODE | IR_OFF, + .transceiver_mode = tosa_irda_transceiver_mode, + .startup = tosa_irda_startup, + .shutdown = tosa_irda_shutdown, }; /* @@ -457,8 +406,8 @@ static struct pda_power_pdata tosa_power_data = { static struct resource tosa_power_resource[] = { { .name = "ac", - .start = gpio_to_irq(TOSA_GPIO_AC_IN), - .end = gpio_to_irq(TOSA_GPIO_AC_IN), + .start = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN), + .end = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, @@ -476,9 +425,87 @@ static struct platform_device tosa_power_device = { /* * Tosa Keyboard */ +static const uint32_t tosakbd_keymap[] = { + KEY(0, 1, KEY_W), + KEY(0, 5, KEY_K), + KEY(0, 6, KEY_BACKSPACE), + KEY(0, 7, KEY_P), + KEY(1, 0, KEY_Q), + KEY(1, 1, KEY_E), + KEY(1, 2, KEY_T), + KEY(1, 3, KEY_Y), + KEY(1, 5, KEY_O), + KEY(1, 6, KEY_I), + KEY(1, 7, KEY_COMMA), + KEY(2, 0, KEY_A), + KEY(2, 1, KEY_D), + KEY(2, 2, KEY_G), + KEY(2, 3, KEY_U), + KEY(2, 5, KEY_L), + KEY(2, 6, KEY_ENTER), + KEY(2, 7, KEY_DOT), + KEY(3, 0, KEY_Z), + KEY(3, 1, KEY_C), + KEY(3, 2, KEY_V), + KEY(3, 3, KEY_J), + KEY(3, 4, TOSA_KEY_ADDRESSBOOK), + KEY(3, 5, TOSA_KEY_CANCEL), + KEY(3, 6, TOSA_KEY_CENTER), + KEY(3, 7, TOSA_KEY_OK), + KEY(3, 8, KEY_LEFTSHIFT), + KEY(4, 0, KEY_S), + KEY(4, 1, KEY_R), + KEY(4, 2, KEY_B), + KEY(4, 3, KEY_N), + KEY(4, 4, TOSA_KEY_CALENDAR), + KEY(4, 5, TOSA_KEY_HOMEPAGE), + KEY(4, 6, KEY_LEFTCTRL), + KEY(4, 7, TOSA_KEY_LIGHT), + KEY(4, 9, KEY_RIGHTSHIFT), + KEY(5, 0, KEY_TAB), + KEY(5, 1, KEY_SLASH), + KEY(5, 2, KEY_H), + KEY(5, 3, KEY_M), + KEY(5, 4, TOSA_KEY_MENU), + KEY(5, 6, KEY_UP), + KEY(5, 10, TOSA_KEY_FN), + KEY(6, 0, KEY_X), + KEY(6, 1, KEY_F), + KEY(6, 2, KEY_SPACE), + KEY(6, 3, KEY_APOSTROPHE), + KEY(6, 4, TOSA_KEY_MAIL), + KEY(6, 5, KEY_LEFT), + KEY(6, 6, KEY_DOWN), + KEY(6, 7, KEY_RIGHT), +}; + +static struct matrix_keymap_data tosakbd_keymap_data = { + .keymap = tosakbd_keymap, + .keymap_size = ARRAY_SIZE(tosakbd_keymap), +}; + +static const int tosakbd_col_gpios[] = + { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68 }; +static const int tosakbd_row_gpios[] = + { 69, 70, 71, 72, 73, 74, 75 }; + +static struct matrix_keypad_platform_data tosakbd_pdata = { + .keymap_data = &tosakbd_keymap_data, + .row_gpios = tosakbd_row_gpios, + .col_gpios = tosakbd_col_gpios, + .num_row_gpios = ARRAY_SIZE(tosakbd_row_gpios), + .num_col_gpios = ARRAY_SIZE(tosakbd_col_gpios), + .col_scan_delay_us = 10, + .debounce_ms = 10, + .wakeup = 1, +}; + static struct platform_device tosakbd_device = { - .name = "tosa-keyboard", + .name = "matrix-keypad", .id = -1, + .dev = { + .platform_data = &tosakbd_pdata, + }, }; static struct gpio_keys_button tosa_gpio_keys[] = { @@ -612,7 +639,7 @@ static int tosa_tc6393xb_enable(struct platform_device *dev) rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); if (rc) goto err_req_suspend; - rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); + rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v"); if (rc) goto err_req_l3v; rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); @@ -706,16 +733,78 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = { .badblock_pattern = &tosa_tc6393xb_nand_bbt, }; -static struct tc6393xb_platform_data tosa_tc6393xb_setup = { +static int tosa_tc6393xb_setup(struct platform_device *dev) +{ + int rc; + + rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON"); + if (rc) + goto err_req; + + rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1); + if (rc) + goto err_dir; + + return rc; + +err_dir: + gpio_free(TOSA_GPIO_CARD_VCC_ON); +err_req: + return rc; +} + +static void tosa_tc6393xb_teardown(struct platform_device *dev) +{ + gpio_free(TOSA_GPIO_CARD_VCC_ON); +} + +#ifdef CONFIG_MFD_TC6393XB +static struct fb_videomode tosa_tc6393xb_lcd_mode[] = { + { + .xres = 480, + .yres = 640, + .pixclock = 0x002cdf00,/* PLL divisor */ + .left_margin = 0x004c, + .right_margin = 0x005b, + .upper_margin = 0x0001, + .lower_margin = 0x000d, + .hsync_len = 0x0002, + .vsync_len = 0x0001, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + },{ + .xres = 240, + .yres = 320, + .pixclock = 0x00e7f203,/* PLL divisor */ + .left_margin = 0x0024, + .right_margin = 0x002f, + .upper_margin = 0x0001, + .lower_margin = 0x000d, + .hsync_len = 0x0002, + .vsync_len = 0x0001, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + } +}; + +static struct tmio_fb_data tosa_tc6393xb_fb_config = { + .lcd_set_power = tc6393xb_lcd_set_power, + .lcd_mode = tc6393xb_lcd_mode, + .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode), + .modes = &tosa_tc6393xb_lcd_mode[0], + .height = 82, + .width = 60, +}; +#endif + +static struct tc6393xb_platform_data tosa_tc6393xb_data = { .scr_pll2cr = 0x0cc1, .scr_gper = 0x3300, - .scr_gpo_dsr = - TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), - .scr_gpo_doecr = - TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), .irq_base = IRQ_BOARD_START, .gpio_base = TOSA_TC6393XB_GPIO_BASE, + .setup = tosa_tc6393xb_setup, + .teardown = tosa_tc6393xb_teardown, .enable = tosa_tc6393xb_enable, .disable = tosa_tc6393xb_disable, @@ -723,6 +812,11 @@ static struct tc6393xb_platform_data tosa_tc6393xb_setup = { .resume = tosa_tc6393xb_resume, .nand_data = &tosa_tc6393xb_nand_config, +#ifdef CONFIG_MFD_TC6393XB + .fb_data = &tosa_tc6393xb_fb_config, +#endif + + .resume_restore = 1, }; @@ -730,7 +824,7 @@ static struct platform_device tc6393xb_device = { .name = "tc6393xb", .id = -1, .dev = { - .platform_data = &tosa_tc6393xb_setup, + .platform_data = &tosa_tc6393xb_data, }, .num_resources = ARRAY_SIZE(tc6393xb_resources), .resource = tc6393xb_resources, @@ -747,6 +841,60 @@ static struct platform_device tosa_bt_device = { .dev.platform_data = &tosa_bt_data, }; +static struct pxa2xx_spi_master pxa_ssp_master_info = { + .num_chipselect = 1, +}; + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "tosa-lcd", + // .platform_data + .max_speed_hz = 28750, + .bus_num = 2, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +static struct mtd_partition sharpsl_rom_parts[] = { + { + .name ="Boot PROM Filesystem", + .offset = 0x00160000, + .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 wm9712_device = { + .name = "wm9712-codec", + .id = -1, +}; + +static struct platform_device tosa_audio_device = { + .name = "tosa-audio", + .id = -1, +}; static struct platform_device *devices[] __initdata = { &tosascoop_device, @@ -757,71 +905,75 @@ static struct platform_device *devices[] __initdata = { &tosa_gpio_keys_device, &tosaled_device, &tosa_bt_device, + &sharpsl_rom_device, + &wm9712_device, + &tosa_gpio_vbus, + &tosa_audio_device, }; static void tosa_poweroff(void) { - arm_machine_restart('g'); + pxa_restart(REBOOT_GPIO, NULL); } -static void tosa_restart(char mode) +static void tosa_restart(enum reboot_mode mode, const char *cmd) { + uint32_t msc0 = __raw_readl(MSC0); + /* Bootloader magic for a reboot */ - if((MSC0 & 0xffff0000) == 0x7ff00000) - MSC0 = (MSC0 & 0xffff) | 0x7ee00000; + if((msc0 & 0xffff0000) == 0x7ff00000) + __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0); tosa_poweroff(); } static void __init tosa_init(void) { - int dummy; - pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + gpio_set_wake(MFP_PIN_GPIO1, 1); /* We can't pass to gpio-keys since it will drop the Reset altfunc */ - init_gpio_reset(TOSA_GPIO_ON_RESET); + init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0); pm_power_off = tosa_poweroff; - arm_pm_restart = tosa_restart; PCFR |= PCFR_OPDE; /* enable batt_fault */ PMCR = 0x01; - dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12); - dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12); - dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); - pxa_set_mci_info(&tosa_mci_platform_data); - pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(NULL); platform_scoop_config = &tosa_pcmcia_config; - clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL); + pxa2xx_set_spi_info(2, &pxa_ssp_master_info); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); + + clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); } -static void __init fixup_tosa(struct machine_desc *desc, - struct tag *tags, char **cmdline, struct meminfo *mi) +static void __init fixup_tosa(struct tag *tags, char **cmdline) { sharpsl_save_param(); - mi->nr_banks=1; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (64*1024*1024); + memblock_add(0xa0000000, SZ_64M); } MACHINE_START(TOSA, "SHARP Tosa") - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_tosa, - .map_io = pxa_map_io, + .map_io = pxa25x_map_io, + .nr_irqs = TOSA_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = tosa_init, - .timer = &pxa_timer, + .init_time = pxa_timer_init, + .restart = tosa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 3ed757e6bcc..872dcb20e75 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -15,23 +15,23 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/platform_device.h> -#include <linux/sysdev.h> #include <linux/interrupt.h> +#include <linux/export.h> #include <linux/sched.h> #include <linux/bitops.h> #include <linux/fb.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/serial_8250.h> -#include <linux/mtd/mtd.h> +#include <linux/gpio.h> +#include <linux/dm9000.h> #include <linux/mtd/physmap.h> #include <linux/mtd/partitions.h> +#include <linux/i2c/pxa-i2c.h> #include <asm/types.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> @@ -40,41 +40,131 @@ #include <asm/mach/irq.h> #include <asm/mach/flash.h> -#include <mach/pxa-regs.h> -#include <mach/pxa2xx-regs.h> -#include <mach/pxa2xx-gpio.h> +#include <mach/pxa27x.h> #include <mach/trizeps4.h> #include <mach/audio.h> -#include <mach/pxafb.h> -#include <mach/mmc.h> -#include <mach/irda.h> -#include <mach/ohci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/irda-pxaficp.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/smemc.h> #include "generic.h" #include "devices.h" -/******************************************************************************************** +/* comment out the following line if you want to use the + * Standard UART from PXA for serial / irda transmission + * and acivate it if you have status leds connected */ +#define STATUS_LEDS_ON_STUART_PINS 1 + +/***************************************************************************** + * MultiFunctionPins of CPU + *****************************************************************************/ +static unsigned long trizeps4_pin_config[] __initdata = { + /* Chip Selects */ + GPIO15_nCS_1, /* DiskOnChip CS */ + GPIO93_GPIO, /* TRIZEPS4_DOC_IRQ */ + GPIO94_GPIO, /* DOC lock */ + + GPIO78_nCS_2, /* DM9000 CS */ + GPIO101_GPIO, /* TRIZEPS4_ETH_IRQ */ + + GPIO79_nCS_3, /* Logic CS */ + GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, /* Logic irq */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* LCD - 16bpp Active TFT */ + GPIOxx_LCD_TFT_16BPP, + + /* UART */ + GPIO9_FFUART_CTS, + GPIO10_FFUART_DCD, + GPIO16_FFUART_TXD, + GPIO33_FFUART_DSR, + GPIO38_FFUART_RI, + GPIO82_FFUART_DTR, + GPIO83_FFUART_RTS, + GPIO96_FFUART_RXD, + + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, +#ifdef STATUS_LEDS_ON_STUART_PINS + GPIO46_GPIO, + GPIO47_GPIO, +#else + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, +#endif + /* PCMCIA */ + GPIO11_GPIO, /* TRIZEPS4_CD_IRQ */ + GPIO13_GPIO, /* TRIZEPS4_READY_NINT */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO102_nPCE_1, + GPIO104_PSKTSEL, + + /* MultiMediaCard */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + GPIO12_GPIO, /* TRIZEPS4_MMC_IRQ */ + + /* USB OHCI */ + GPIO88_USBH1_PWR, /* USBHPWR1 */ + GPIO89_USBH1_PEN, /* USBHPEN1 */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, +}; + +static unsigned long trizeps4wl_pin_config[] __initdata = { + /* SSP 2 */ + GPIO14_SSP2_SFRM, + GPIO19_SSP2_SCLK, + GPIO53_GPIO, /* TRIZEPS4_SPI_IRQ */ + GPIO86_SSP2_RXD, + GPIO87_SSP2_TXD, +}; + +/**************************************************************************** * ONBOARD FLASH - ********************************************************************************************/ + ****************************************************************************/ static struct mtd_partition trizeps4_partitions[] = { { .name = "Bootloader", .offset = 0x00000000, .size = 0x00040000, .mask_flags = MTD_WRITEABLE /* force read-only */ - },{ + }, { .name = "Backup", .offset = 0x00040000, .size = 0x00040000, - },{ + }, { .name = "Image", .offset = 0x00080000, .size = 0x01080000, - },{ + }, { .name = "IPSM", .offset = 0x01100000, .size = 0x00e00000, - },{ + }, { .name = "Registry", .offset = 0x01f00000, .size = MTDPART_SIZ_FULL, @@ -105,9 +195,9 @@ static struct platform_device flash_device = { .num_resources = 1, }; -/******************************************************************************************** +/**************************************************************************** * DAVICOM DM9000 Ethernet - ********************************************************************************************/ + ****************************************************************************/ static struct resource dm9000_resources[] = { [0] = { .start = TRIZEPS4_ETH_PHYS+0x300, @@ -122,67 +212,68 @@ static struct resource dm9000_resources[] = { [2] = { .start = TRIZEPS4_ETH_IRQ, .end = TRIZEPS4_ETH_IRQ, - .flags = (IORESOURCE_IRQ | IRQ_TYPE_EDGE_RISING), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; +static struct dm9000_plat_data tri_dm9000_platdata = { + .flags = DM9000_PLATF_32BITONLY, +}; + static struct platform_device dm9000_device = { .name = "dm9000", .id = -1, .num_resources = ARRAY_SIZE(dm9000_resources), .resource = dm9000_resources, + .dev = { + .platform_data = &tri_dm9000_platdata, + } }; -/******************************************************************************************** - * PXA270 serial ports - ********************************************************************************************/ -static struct plat_serial8250_port tri_serial_ports[] = { -#ifdef CONFIG_SERIAL_PXA - /* this uses the own PXA driver */ +/**************************************************************************** + * LED's on GPIO pins of PXA + ****************************************************************************/ +static struct gpio_led trizeps4_led[] = { +#ifdef STATUS_LEDS_ON_STUART_PINS { - 0, - }, -#else - /* this uses the generic 8520 driver */ - [0] = { - .membase = (void *)&FFUART, - .irq = IRQ_FFUART, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM32, - .regshift = 2, - .uartclk = (921600*16), - }, - [1] = { - .membase = (void *)&BTUART, - .irq = IRQ_BTUART, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM32, - .regshift = 2, - .uartclk = (921600*16), + .name = "led0:orange:heartbeat", /* */ + .default_trigger = "heartbeat", + .gpio = GPIO_HEARTBEAT_LED, + .active_low = 1, }, { - 0, + .name = "led1:yellow:cpubusy", /* */ + .default_trigger = "cpu-busy", + .gpio = GPIO_SYS_BUSY_LED, + .active_low = 1, }, #endif }; -static struct platform_device uart_devices = { - .name = "serial8250", - .id = 0, +static struct gpio_led_platform_data trizeps4_led_data = { + .leds = trizeps4_led, + .num_leds = ARRAY_SIZE(trizeps4_led), +}; + +static struct platform_device leds_devices = { + .name = "leds-gpio", + .id = -1, .dev = { - .platform_data = tri_serial_ports, + .platform_data = &trizeps4_led_data, }, - .num_resources = 0, - .resource = NULL, }; -static struct platform_device * trizeps4_devices[] __initdata = { +static struct platform_device *trizeps4_devices[] __initdata = { &flash_device, - &uart_devices, &dm9000_device, + &leds_devices, +}; + +static struct platform_device *trizeps4wl_devices[] __initdata = { + &flash_device, + &leds_devices, }; -#ifdef CONFIG_MACH_TRIZEPS4_CONXS static short trizeps_conxs_bcr; /* PCCARD power switching supports only 3,3V */ @@ -192,108 +283,62 @@ void board_pcmcia_power(int power) /* switch power on, put in reset and enable buffers */ trizeps_conxs_bcr |= power; trizeps_conxs_bcr |= ConXS_BCR_CF_RESET; - trizeps_conxs_bcr &= ~(ConXS_BCR_CF_BUF_EN); - ConXS_BCR = trizeps_conxs_bcr; + trizeps_conxs_bcr &= ~ConXS_BCR_CF_BUF_EN; + BCR_writew(trizeps_conxs_bcr); /* wait a little */ udelay(2000); /* take reset away */ - trizeps_conxs_bcr &= ~(ConXS_BCR_CF_RESET); - ConXS_BCR = trizeps_conxs_bcr; + trizeps_conxs_bcr &= ~ConXS_BCR_CF_RESET; + BCR_writew(trizeps_conxs_bcr); udelay(2000); } else { /* put in reset */ trizeps_conxs_bcr |= ConXS_BCR_CF_RESET; - ConXS_BCR = trizeps_conxs_bcr; + BCR_writew(trizeps_conxs_bcr); udelay(1000); /* switch power off */ - trizeps_conxs_bcr &= ~(0xf); - ConXS_BCR = trizeps_conxs_bcr; - + trizeps_conxs_bcr &= ~0xf; + BCR_writew(trizeps_conxs_bcr); } - pr_debug("%s: o%s 0x%x\n", __func__, power ? "n": "ff", trizeps_conxs_bcr); + pr_debug("%s: o%s 0x%x\n", __func__, power ? "n" : "ff", + trizeps_conxs_bcr); } +EXPORT_SYMBOL(board_pcmcia_power); /* backlight power switching for LCD panel */ static void board_backlight_power(int on) { - if (on) { + if (on) trizeps_conxs_bcr |= ConXS_BCR_L_DISP; - } else { + else trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP; - } - pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff", trizeps_conxs_bcr); - ConXS_BCR = trizeps_conxs_bcr; -} -/* Powersupply for MMC/SD cardslot */ -static void board_mci_power(struct device *dev, unsigned int vdd) -{ - struct pxamci_platform_data* p_d = dev->platform_data; - - if (( 1 << vdd) & p_d->ocr_mask) { - pr_debug("%s: on\n", __func__); - /* FIXME fill in values here */ - } else { - pr_debug("%s: off\n", __func__); - /* FIXME fill in values here */ - } -} - -static short trizeps_conxs_ircr; - -/* Switch modes and Power for IRDA receiver */ -static void board_irda_mode(struct device *dev, int mode) -{ - unsigned long flags; - - local_irq_save(flags); - if (mode & IR_SIRMODE) { - /* Slow mode */ - trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; - } else if (mode & IR_FIRMODE) { - /* Fast mode */ - trizeps_conxs_ircr |= ConXS_IRCR_MODE; - } - pxa2xx_transceiver_mode(dev, mode); - if (mode & IR_OFF) { - trizeps_conxs_ircr |= ConXS_IRCR_SD; - } else { - trizeps_conxs_ircr &= ~ConXS_IRCR_SD; - } - /* FIXME write values to register */ - local_irq_restore(flags); + pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff", + trizeps_conxs_bcr); + BCR_writew(trizeps_conxs_bcr); } -#else -/* for other baseboards define dummies */ -void board_pcmcia_power(int power) {;} -#define board_backlight_power NULL -#define board_mci_power NULL -#define board_irda_mode NULL - -#endif /* CONFIG_MACH_TRIZEPS4_CONXS */ -EXPORT_SYMBOL(board_pcmcia_power); +/* a I2C based RTC is known on CONXS board */ +static struct i2c_board_info trizeps4_i2c_devices[] __initdata = { + { I2C_BOARD_INFO("rtc-pcf8593", 0x51) } +}; -static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, void *data) +/**************************************************************************** + * MMC card slot external to module + ****************************************************************************/ +static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, + void *data) { int err; - /* setup GPIO for PXA27x MMC controller */ - pxa_gpio_mode(GPIO32_MMCCLK_MD); - pxa_gpio_mode(GPIO112_MMCCMD_MD); - pxa_gpio_mode(GPIO92_MMCDAT0_MD); - pxa_gpio_mode(GPIO109_MMCDAT1_MD); - pxa_gpio_mode(GPIO110_MMCDAT2_MD); - pxa_gpio_mode(GPIO111_MMCDAT3_MD); - - pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN); err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_RISING, - "MMC card detect", data); - if (err) - printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); - - return err; + IRQF_TRIGGER_RISING, "MMC card detect", data); + if (err) { + printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" + "MMC card detect IRQ\n"); + return -1; + } + return 0; } static void trizeps4_mci_exit(struct device *dev, void *data) @@ -303,39 +348,73 @@ static void trizeps4_mci_exit(struct device *dev, void *data) static struct pxamci_platform_data trizeps4_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .detect_delay_ms= 10, .init = trizeps4_mci_init, .exit = trizeps4_mci_exit, - .setpower = board_mci_power, + .get_ro = NULL, /* write-protection not supported */ + .setpower = NULL, /* power-switching not supported */ + .gpio_card_detect = -1, + .gpio_card_ro = -1, + .gpio_power = -1, }; -static struct pxaficp_platform_data trizeps4_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, - .transceiver_mode = board_irda_mode, -}; +/**************************************************************************** + * IRDA mode switching on stuart + ****************************************************************************/ +#ifndef STATUS_LEDS_ON_STUART_PINS +static short trizeps_conxs_ircr; -static int trizeps4_ohci_init(struct device *dev) +static int trizeps4_irda_startup(struct device *dev) { - /* setup Port1 GPIO pin. */ - pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ - pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ - - /* Set the Power Control Polarity Low and Power Sense - Polarity Low to active low. */ - UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); - + trizeps_conxs_ircr &= ~ConXS_IRCR_SD; + IRCR_writew(trizeps_conxs_ircr); return 0; } -static void trizeps4_ohci_exit(struct device *dev) +static void trizeps4_irda_shutdown(struct device *dev) { - ; + trizeps_conxs_ircr |= ConXS_IRCR_SD; + IRCR_writew(trizeps_conxs_ircr); +} + +static void trizeps4_irda_transceiver_mode(struct device *dev, int mode) +{ + unsigned long flags; + + local_irq_save(flags); + /* Switch mode */ + if (mode & IR_SIRMODE) + trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; /* Slow mode */ + else if (mode & IR_FIRMODE) + trizeps_conxs_ircr |= ConXS_IRCR_MODE; /* Fast mode */ + + /* Switch power */ + if (mode & IR_OFF) + trizeps_conxs_ircr |= ConXS_IRCR_SD; + else + trizeps_conxs_ircr &= ~ConXS_IRCR_SD; + + IRCR_writew(trizeps_conxs_ircr); + local_irq_restore(flags); + + pxa2xx_transceiver_mode(dev, mode); } +static struct pxaficp_platform_data trizeps4_ficp_platform_data = { + .gpio_pwdown = -1, + .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, + .transceiver_mode = trizeps4_irda_transceiver_mode, + .startup = trizeps4_irda_startup, + .shutdown = trizeps4_irda_shutdown, +}; +#endif + +/**************************************************************************** + * OHCI USB port + ****************************************************************************/ static struct pxaohci_platform_data trizeps4_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, - .init = trizeps4_ohci_init, - .exit = trizeps4_ohci_exit, + .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, }; static struct map_desc trizeps4_io_desc[] __initdata = { @@ -372,134 +451,127 @@ static struct map_desc trizeps4_io_desc[] __initdata = { }; static struct pxafb_mode_info sharp_lcd_mode = { - .pixclock = 78000, - .xres = 640, - .yres = 480, - .bpp = 8, - .hsync_len = 4, - .left_margin = 4, - .right_margin = 4, - .vsync_len = 2, - .upper_margin = 0, - .lower_margin = 0, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .cmap_greyscale = 0, + .pixclock = 78000, + .xres = 640, + .yres = 480, + .bpp = 8, + .hsync_len = 4, + .left_margin = 4, + .right_margin = 4, + .vsync_len = 2, + .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_lcd = { - .modes = &sharp_lcd_mode, - .num_modes = 1, - .cmap_inverse = 0, - .cmap_static = 0, - .lccr0 = LCCR0_Color | LCCR0_Pas | LCCR0_Dual, - .lccr3 = 0x0340ff02, - .pxafb_backlight_power = board_backlight_power, + .modes = &sharp_lcd_mode, + .num_modes = 1, + .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL, + .cmap_inverse = 0, + .cmap_static = 0, + .pxafb_backlight_power = board_backlight_power, }; static struct pxafb_mode_info toshiba_lcd_mode = { - .pixclock = 39720, - .xres = 640, - .yres = 480, - .bpp = 8, - .hsync_len = 63, - .left_margin = 12, - .right_margin = 12, - .vsync_len = 4, - .upper_margin = 32, - .lower_margin = 10, - .sync = 0, - .cmap_greyscale = 0, + .pixclock = 39720, + .xres = 640, + .yres = 480, + .bpp = 8, + .hsync_len = 63, + .left_margin = 12, + .right_margin = 12, + .vsync_len = 4, + .upper_margin = 32, + .lower_margin = 10, + .sync = 0, + .cmap_greyscale = 0, }; static struct pxafb_mach_info toshiba_lcd = { - .modes = &toshiba_lcd_mode, - .num_modes = 1, - .cmap_inverse = 0, - .cmap_static = 0, - .lccr0 = LCCR0_Color | LCCR0_Act, - .lccr3 = 0x03400002, - .pxafb_backlight_power = board_backlight_power, + .modes = &toshiba_lcd_mode, + .num_modes = 1, + .lcd_conn = (LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL), + .cmap_inverse = 0, + .cmap_static = 0, + .pxafb_backlight_power = board_backlight_power, }; static void __init trizeps4_init(void) { - platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4_pin_config)); + if (machine_is_trizeps4wl()) { + pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4wl_pin_config)); + platform_add_devices(trizeps4wl_devices, + ARRAY_SIZE(trizeps4wl_devices)); + } else { + platform_add_devices(trizeps4_devices, + ARRAY_SIZE(trizeps4_devices)); + } + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); -/* set_pxa_fb_info(&sharp_lcd); */ - set_pxa_fb_info(&toshiba_lcd); + if (0) /* dont know how to determine LCD */ + pxa_set_fb_info(NULL, &sharp_lcd); + else + pxa_set_fb_info(NULL, &toshiba_lcd); pxa_set_mci_info(&trizeps4_mci_platform_data); +#ifndef STATUS_LEDS_ON_STUART_PINS pxa_set_ficp_info(&trizeps4_ficp_platform_data); +#endif pxa_set_ohci_info(&trizeps4_ohci_platform_data); pxa_set_ac97_info(NULL); + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, trizeps4_i2c_devices, + ARRAY_SIZE(trizeps4_i2c_devices)); + + /* this is the reset value */ + trizeps_conxs_bcr = 0x00A0; + + BCR_writew(trizeps_conxs_bcr); + board_backlight_power(1); } static void __init trizeps4_map_io(void) { - pxa_map_io(); + pxa27x_map_io(); iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc)); - /* for DiskOnChip */ - pxa_gpio_mode(GPIO15_nCS_1_MD); - - /* for off-module PIC on ConXS board */ - pxa_gpio_mode(GPIO_PIC | GPIO_IN); - - /* UCB1400 irq */ - pxa_gpio_mode(GPIO_UCB1400 | GPIO_IN); - - /* for DM9000 LAN */ - pxa_gpio_mode(GPIO78_nCS_2_MD); - pxa_gpio_mode(GPIO_DM9000 | GPIO_IN); - - /* for PCMCIA device */ - pxa_gpio_mode(GPIO_PCD | GPIO_IN); - pxa_gpio_mode(GPIO_PRDY | GPIO_IN); - - /* for I2C adapter */ - pxa_gpio_mode(GPIO117_I2CSCL_MD); - pxa_gpio_mode(GPIO118_I2CSDA_MD); - - /* MMC_DET s.o. */ - pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN); - - /* whats that for ??? */ - pxa_gpio_mode(GPIO79_nCS_3_MD); - -#ifdef CONFIG_LEDS - pxa_gpio_mode( GPIO_SYS_BUSY_LED | GPIO_OUT); /* LED1 */ - pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT); /* LED2 */ -#endif -#ifdef CONFIG_MACH_TRIZEPS4_CONXS -#ifdef CONFIG_IDE_PXA_CF - /* if boot direct from compact flash dont disable power */ - trizeps_conxs_bcr = 0x0009; -#else - /* this is the reset value */ - trizeps_conxs_bcr = 0x00A0; -#endif - ConXS_BCR = trizeps_conxs_bcr; -#endif - -#warning FIXME - accessing PM registers directly is deprecated - PWER = 0x00000002; - PFER = 0x00000000; - PRER = 0x00000002; - PGSR0 = 0x0158C000; - PGSR1 = 0x00FF0080; - PGSR2 = 0x0001C004; - /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ - PCFR |= PCFR_OPDE; + if ((__raw_readl(MSC0) & 0x8) && (__raw_readl(BOOT_DEF) & 0x1)) { + /* if flash is 16 bit wide its a Trizeps4 WL */ + __machine_arch_type = MACH_TYPE_TRIZEPS4WL; + trizeps4_flash_data[0].width = 2; + } else { + /* if flash is 32 bit wide its a Trizeps4 */ + __machine_arch_type = MACH_TYPE_TRIZEPS4; + trizeps4_flash_data[0].width = 4; + } } MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module") /* MAINTAINER("Jürgen Schindele") */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = TRIZEPS4_SDRAM_BASE + 0x100, + .atag_offset = 0x100, .init_machine = trizeps4_init, .map_io = trizeps4_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, MACHINE_END +MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module") + /* MAINTAINER("Jürgen Schindele") */ + .atag_offset = 0x100, + .init_machine = trizeps4_init, + .map_io = trizeps4_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c new file mode 100644 index 00000000000..41f27f667ca --- /dev/null +++ b/arch/arm/mach-pxa/viper.c @@ -0,0 +1,1001 @@ +/* + * linux/arch/arm/mach-pxa/viper.c + * + * Support for the Arcom VIPER SBC. + * + * Author: Ian Campbell + * Created: Feb 03, 2003 + * Copyright: Arcom Control Systems + * + * Maintained by Marc Zyngier <maz@misterjones.org> + * <marc.zyngier@altran.com> + * + * Based on lubbock.c: + * 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. + */ + +#include <linux/types.h> +#include <linux/memory.h> +#include <linux/cpu.h> +#include <linux/cpufreq.h> +#include <linux/delay.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/major.h> +#include <linux/module.h> +#include <linux/pm.h> +#include <linux/sched.h> +#include <linux/gpio.h> +#include <linux/jiffies.h> +#include <linux/i2c-gpio.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/serial_8250.h> +#include <linux/smc91x.h> +#include <linux/pwm_backlight.h> +#include <linux/usb/isp116x.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/syscore_ops.h> + +#include <mach/pxa25x.h> +#include <mach/audio.h> +#include <linux/platform_data/video-pxafb.h> +#include <mach/regs-uart.h> +#include <linux/platform_data/pcmcia-pxa2xx_viper.h> +#include <mach/viper.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/sizes.h> +#include <asm/system_info.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include "generic.h" +#include "devices.h" + +static unsigned int icr; + +static void viper_icr_set_bit(unsigned int bit) +{ + icr |= bit; + VIPER_ICR = icr; +} + +static void viper_icr_clear_bit(unsigned int bit) +{ + icr &= ~bit; + VIPER_ICR = icr; +} + +/* This function is used from the pcmcia module to reset the CF */ +static void viper_cf_reset(int state) +{ + if (state) + viper_icr_set_bit(VIPER_ICR_CF_RST); + else + viper_icr_clear_bit(VIPER_ICR_CF_RST); +} + +static struct arcom_pcmcia_pdata viper_pcmcia_info = { + .cd_gpio = VIPER_CF_CD_GPIO, + .rdy_gpio = VIPER_CF_RDY_GPIO, + .pwr_gpio = VIPER_CF_POWER_GPIO, + .reset = viper_cf_reset, +}; + +static struct platform_device viper_pcmcia_device = { + .name = "viper-pcmcia", + .id = -1, + .dev = { + .platform_data = &viper_pcmcia_info, + }, +}; + +/* + * The CPLD version register was not present on VIPER boards prior to + * v2i1. On v1 boards where the version register is not present we + * will just read back the previous value from the databus. + * + * Therefore we do two reads. The first time we write 0 to the + * (read-only) register before reading and the second time we write + * 0xff first. If the two reads do not match or they read back as 0xff + * or 0x00 then we have version 1 hardware. + */ +static u8 viper_hw_version(void) +{ + u8 v1, v2; + unsigned long flags; + + local_irq_save(flags); + + VIPER_VERSION = 0; + v1 = VIPER_VERSION; + VIPER_VERSION = 0xff; + v2 = VIPER_VERSION; + + v1 = (v1 != v2 || v1 == 0xff) ? 0 : v1; + + local_irq_restore(flags); + return v1; +} + +/* CPU system core operations. */ +static int viper_cpu_suspend(void) +{ + viper_icr_set_bit(VIPER_ICR_R_DIS); + return 0; +} + +static void viper_cpu_resume(void) +{ + viper_icr_clear_bit(VIPER_ICR_R_DIS); +} + +static struct syscore_ops viper_cpu_syscore_ops = { + .suspend = viper_cpu_suspend, + .resume = viper_cpu_resume, +}; + +static unsigned int current_voltage_divisor; + +/* + * If force is not true then step from existing to new divisor. If + * force is true then jump straight to the new divisor. Stepping is + * used because if the jump in voltage is too large, the VCC can dip + * too low and the regulator cuts out. + * + * force can be used to initialize the divisor to a know state by + * setting the value for the current clock speed, since we are already + * running at that speed we know the voltage should be pretty close so + * the jump won't be too large + */ +static void viper_set_core_cpu_voltage(unsigned long khz, int force) +{ + int i = 0; + unsigned int divisor = 0; + const char *v; + + if (khz < 200000) { + v = "1.0"; divisor = 0xfff; + } else if (khz < 300000) { + v = "1.1"; divisor = 0xde5; + } else { + v = "1.3"; divisor = 0x325; + } + + pr_debug("viper: setting CPU core voltage to %sV at %d.%03dMHz\n", + v, (int)khz / 1000, (int)khz % 1000); + +#define STEP 0x100 + do { + int step; + + if (force) + step = divisor; + else if (current_voltage_divisor < divisor - STEP) + step = current_voltage_divisor + STEP; + else if (current_voltage_divisor > divisor + STEP) + step = current_voltage_divisor - STEP; + else + step = divisor; + force = 0; + + gpio_set_value(VIPER_PSU_CLK_GPIO, 0); + gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0); + + for (i = 1 << 11 ; i > 0 ; i >>= 1) { + udelay(1); + + gpio_set_value(VIPER_PSU_DATA_GPIO, step & i); + udelay(1); + + gpio_set_value(VIPER_PSU_CLK_GPIO, 1); + udelay(1); + + gpio_set_value(VIPER_PSU_CLK_GPIO, 0); + } + udelay(1); + + gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 1); + udelay(1); + + gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0); + + current_voltage_divisor = step; + } while (current_voltage_divisor != divisor); +} + +/* Interrupt handling */ +static unsigned long viper_irq_enabled_mask; +static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 }; +static const int viper_isa_irq_map[] = { + 0, /* ISA irq #0, invalid */ + 0, /* ISA irq #1, invalid */ + 0, /* ISA irq #2, invalid */ + 1 << 0, /* ISA irq #3 */ + 1 << 1, /* ISA irq #4 */ + 1 << 2, /* ISA irq #5 */ + 1 << 3, /* ISA irq #6 */ + 1 << 4, /* ISA irq #7 */ + 0, /* ISA irq #8, invalid */ + 1 << 8, /* ISA irq #9 */ + 1 << 5, /* ISA irq #10 */ + 1 << 6, /* ISA irq #11 */ + 1 << 7, /* ISA irq #12 */ + 0, /* ISA irq #13, invalid */ + 1 << 9, /* ISA irq #14 */ + 1 << 10, /* ISA irq #15 */ +}; + +static inline int viper_irq_to_bitmask(unsigned int irq) +{ + return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)]; +} + +static inline int viper_bit_to_irq(int bit) +{ + return viper_isa_irqs[bit] + PXA_ISA_IRQ(0); +} + +static void viper_ack_irq(struct irq_data *d) +{ + int viper_irq = viper_irq_to_bitmask(d->irq); + + if (viper_irq & 0xff) + VIPER_LO_IRQ_STATUS = viper_irq; + else + VIPER_HI_IRQ_STATUS = (viper_irq >> 8); +} + +static void viper_mask_irq(struct irq_data *d) +{ + viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(d->irq)); +} + +static void viper_unmask_irq(struct irq_data *d) +{ + viper_irq_enabled_mask |= viper_irq_to_bitmask(d->irq); +} + +static inline unsigned long viper_irq_pending(void) +{ + return (VIPER_HI_IRQ_STATUS << 8 | VIPER_LO_IRQ_STATUS) & + viper_irq_enabled_mask; +} + +static void viper_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long pending; + + pending = viper_irq_pending(); + do { + /* we're in a chained irq handler, + * so ack the interrupt by hand */ + desc->irq_data.chip->irq_ack(&desc->irq_data); + + if (likely(pending)) { + irq = viper_bit_to_irq(__ffs(pending)); + generic_handle_irq(irq); + } + pending = viper_irq_pending(); + } while (pending); +} + +static struct irq_chip viper_irq_chip = { + .name = "ISA", + .irq_ack = viper_ack_irq, + .irq_mask = viper_mask_irq, + .irq_unmask = viper_unmask_irq +}; + +static void __init viper_init_irq(void) +{ + int level; + int isa_irq; + + pxa25x_init_irq(); + + /* setup ISA IRQs */ + for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) { + isa_irq = viper_bit_to_irq(level); + irq_set_chip_and_handler(isa_irq, &viper_irq_chip, + handle_edge_irq); + set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); + } + + irq_set_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO), + viper_irq_handler); + irq_set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH); +} + +/* Flat Panel */ +static struct pxafb_mode_info fb_mode_info[] = { + { + .pixclock = 157500, + + .xres = 320, + .yres = 240, + + .bpp = 16, + + .hsync_len = 63, + .left_margin = 7, + .right_margin = 13, + + .vsync_len = 20, + .upper_margin = 0, + .lower_margin = 0, + + .sync = 0, + }, +}; + +static struct pxafb_mach_info fb_info = { + .modes = fb_mode_info, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +static int viper_backlight_init(struct device *dev) +{ + int ret; + + /* GPIO9 and 10 control FB backlight. Initialise to off */ + ret = gpio_request(VIPER_BCKLIGHT_EN_GPIO, "Backlight"); + if (ret) + goto err_request_bckl; + + ret = gpio_request(VIPER_LCD_EN_GPIO, "LCD"); + if (ret) + goto err_request_lcd; + + ret = gpio_direction_output(VIPER_BCKLIGHT_EN_GPIO, 0); + if (ret) + goto err_dir; + + ret = gpio_direction_output(VIPER_LCD_EN_GPIO, 0); + if (ret) + goto err_dir; + + return 0; + +err_dir: + gpio_free(VIPER_LCD_EN_GPIO); +err_request_lcd: + gpio_free(VIPER_BCKLIGHT_EN_GPIO); +err_request_bckl: + dev_err(dev, "Failed to setup LCD GPIOs\n"); + + return ret; +} + +static int viper_backlight_notify(struct device *dev, int brightness) +{ + gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness); + gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness); + + return brightness; +} + +static void viper_backlight_exit(struct device *dev) +{ + gpio_free(VIPER_LCD_EN_GPIO); + gpio_free(VIPER_BCKLIGHT_EN_GPIO); +} + +static struct platform_pwm_backlight_data viper_backlight_data = { + .pwm_id = 0, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 1000000, + .enable_gpio = -1, + .init = viper_backlight_init, + .notify = viper_backlight_notify, + .exit = viper_backlight_exit, +}; + +static struct platform_device viper_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa25x_device_pwm0.dev, + .platform_data = &viper_backlight_data, + }, +}; + +/* Ethernet */ +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = VIPER_ETH_PHYS + 0x300, + .end = VIPER_ETH_PHYS + 0x30f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO), + .end = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, + [2] = { + .name = "smc91x-data32", + .start = VIPER_ETH_DATA_PHYS, + .end = VIPER_ETH_DATA_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct smc91x_platdata viper_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &viper_smc91x_info, + }, +}; + +/* i2c */ +static struct i2c_gpio_platform_data i2c_bus_data = { + .sda_pin = VIPER_RTC_I2C_SDA_GPIO, + .scl_pin = VIPER_RTC_I2C_SCL_GPIO, + .udelay = 10, + .timeout = HZ, +}; + +static struct platform_device i2c_bus_device = { + .name = "i2c-gpio", + .id = 1, /* pxa2xx-i2c is bus 0, so start at 1 */ + .dev = { + .platform_data = &i2c_bus_data, + } +}; + +static struct i2c_board_info __initdata viper_i2c_devices[] = { + { + I2C_BOARD_INFO("ds1338", 0x68), + }, +}; + +/* + * Serial configuration: + * You can either have the standard PXA ports driven by the PXA driver, + * or all the ports (PXA + 16850) driven by the 8250 driver. + * Choose your poison. + */ + +static struct resource viper_serial_resources[] = { +#ifndef CONFIG_SERIAL_PXA + { + .start = 0x40100000, + .end = 0x4010001f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x40200000, + .end = 0x4020001f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x40700000, + .end = 0x4070001f, + .flags = IORESOURCE_MEM, + }, + { + .start = VIPER_UARTA_PHYS, + .end = VIPER_UARTA_PHYS + 0xf, + .flags = IORESOURCE_MEM, + }, + { + .start = VIPER_UARTB_PHYS, + .end = VIPER_UARTB_PHYS + 0xf, + .flags = IORESOURCE_MEM, + }, +#else + { + 0, + }, +#endif +}; + +static struct plat_serial8250_port serial_platform_data[] = { +#ifndef CONFIG_SERIAL_PXA + /* Internal UARTs */ + { + .membase = (void *)&FFUART, + .mapbase = __PREG(FFUART), + .irq = IRQ_FFUART, + .uartclk = 921600 * 16, + .regshift = 2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { + .membase = (void *)&BTUART, + .mapbase = __PREG(BTUART), + .irq = IRQ_BTUART, + .uartclk = 921600 * 16, + .regshift = 2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { + .membase = (void *)&STUART, + .mapbase = __PREG(STUART), + .irq = IRQ_STUART, + .uartclk = 921600 * 16, + .regshift = 2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + /* External UARTs */ + { + .mapbase = VIPER_UARTA_PHYS, + .irq = PXA_GPIO_TO_IRQ(VIPER_UARTA_GPIO), + .irqflags = IRQF_TRIGGER_RISING, + .uartclk = 1843200, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | + UPF_SKIP_TEST, + }, + { + .mapbase = VIPER_UARTB_PHYS, + .irq = PXA_GPIO_TO_IRQ(VIPER_UARTB_GPIO), + .irqflags = IRQF_TRIGGER_RISING, + .uartclk = 1843200, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | + UPF_SKIP_TEST, + }, +#endif + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, + .num_resources = ARRAY_SIZE(viper_serial_resources), + .resource = viper_serial_resources, +}; + +/* USB */ +static void isp116x_delay(struct device *dev, int delay) +{ + ndelay(delay); +} + +static struct resource isp116x_resources[] = { + [0] = { /* DATA */ + .start = VIPER_USB_PHYS + 0, + .end = VIPER_USB_PHYS + 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* ADDR */ + .start = VIPER_USB_PHYS + 2, + .end = VIPER_USB_PHYS + 3, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO), + .end = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, +}; + +/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */ +static struct isp116x_platform_data isp116x_platform_data = { + /* Enable internal resistors on downstream ports */ + .sel15Kres = 1, + /* On-chip overcurrent protection */ + .oc_enable = 1, + /* INT output polarity */ + .int_act_high = 1, + /* INT edge or level triggered */ + .int_edge_triggered = 0, + + /* WAKEUP pin connected - NOT SUPPORTED */ + /* .remote_wakeup_connected = 0, */ + /* Wakeup by devices on usb bus enabled */ + .remote_wakeup_enable = 0, + .delay = isp116x_delay, +}; + +static struct platform_device isp116x_device = { + .name = "isp116x-hcd", + .id = -1, + .num_resources = ARRAY_SIZE(isp116x_resources), + .resource = isp116x_resources, + .dev = { + .platform_data = &isp116x_platform_data, + }, + +}; + +/* MTD */ +static struct resource mtd_resources[] = { + [0] = { /* RedBoot config + filesystem flash */ + .start = VIPER_FLASH_PHYS, + .end = VIPER_FLASH_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* Boot flash */ + .start = VIPER_BOOT_PHYS, + .end = VIPER_BOOT_PHYS + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { /* + * SRAM size is actually 256KB, 8bits, with a sparse mapping + * (each byte is on a 16bit boundary). + */ + .start = _VIPER_SRAM_BASE, + .end = _VIPER_SRAM_BASE + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct mtd_partition viper_boot_flash_partition = { + .name = "RedBoot", + .size = SZ_1M, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force R/O */ +}; + +static struct physmap_flash_data viper_flash_data[] = { + [0] = { + .width = 2, + .parts = NULL, + .nr_parts = 0, + }, + [1] = { + .width = 2, + .parts = &viper_boot_flash_partition, + .nr_parts = 1, + }, +}; + +static struct platform_device viper_mtd_devices[] = { + [0] = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &viper_flash_data[0], + }, + .resource = &mtd_resources[0], + .num_resources = 1, + }, + [1] = { + .name = "physmap-flash", + .id = 1, + .dev = { + .platform_data = &viper_flash_data[1], + }, + .resource = &mtd_resources[1], + .num_resources = 1, + }, +}; + +static struct platform_device *viper_devs[] __initdata = { + &smc91x_device, + &i2c_bus_device, + &serial_device, + &isp116x_device, + &viper_mtd_devices[0], + &viper_mtd_devices[1], + &viper_backlight_device, + &viper_pcmcia_device, +}; + +static mfp_cfg_t viper_pin_config[] __initdata = { + /* Chip selects */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO33_nCS_5, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* FP Backlight */ + GPIO9_GPIO, /* VIPER_BCKLIGHT_EN_GPIO */ + GPIO10_GPIO, /* VIPER_LCD_EN_GPIO */ + GPIO16_PWM0_OUT, + + /* Ethernet PHY Ready */ + GPIO18_RDY, + + /* Serial shutdown */ + GPIO12_GPIO | MFP_LPM_DRIVE_HIGH, /* VIPER_UART_SHDN_GPIO */ + + /* Compact-Flash / PC104 */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO54_nPSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO8_GPIO, /* VIPER_CF_RDY_GPIO */ + GPIO32_GPIO, /* VIPER_CF_CD_GPIO */ + GPIO82_GPIO, /* VIPER_CF_POWER_GPIO */ + + /* Integrated UPS control */ + GPIO20_GPIO, /* VIPER_UPS_GPIO */ + + /* Vcc regulator control */ + GPIO6_GPIO, /* VIPER_PSU_DATA_GPIO */ + GPIO11_GPIO, /* VIPER_PSU_CLK_GPIO */ + GPIO19_GPIO, /* VIPER_PSU_nCS_LD_GPIO */ + + /* i2c busses */ + GPIO26_GPIO, /* VIPER_TPM_I2C_SDA_GPIO */ + GPIO27_GPIO, /* VIPER_TPM_I2C_SCL_GPIO */ + GPIO83_GPIO, /* VIPER_RTC_I2C_SDA_GPIO */ + GPIO84_GPIO, /* VIPER_RTC_I2C_SCL_GPIO */ + + /* PC/104 Interrupt */ + GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* VIPER_CPLD_GPIO */ +}; + +static unsigned long viper_tpm; + +static int __init viper_tpm_setup(char *str) +{ + return strict_strtoul(str, 10, &viper_tpm) >= 0; +} + +__setup("tpm=", viper_tpm_setup); + +static void __init viper_tpm_init(void) +{ + struct platform_device *tpm_device; + struct i2c_gpio_platform_data i2c_tpm_data = { + .sda_pin = VIPER_TPM_I2C_SDA_GPIO, + .scl_pin = VIPER_TPM_I2C_SCL_GPIO, + .udelay = 10, + .timeout = HZ, + }; + char *errstr; + + /* Allocate TPM i2c bus if requested */ + if (!viper_tpm) + return; + + tpm_device = platform_device_alloc("i2c-gpio", 2); + if (tpm_device) { + if (!platform_device_add_data(tpm_device, + &i2c_tpm_data, + sizeof(i2c_tpm_data))) { + if (platform_device_add(tpm_device)) { + errstr = "register TPM i2c bus"; + goto error_free_tpm; + } + } else { + errstr = "allocate TPM i2c bus data"; + goto error_free_tpm; + } + } else { + errstr = "allocate TPM i2c device"; + goto error_tpm; + } + + return; + +error_free_tpm: + kfree(tpm_device); +error_tpm: + pr_err("viper: Couldn't %s, giving up\n", errstr); +} + +static void __init viper_init_vcore_gpios(void) +{ + if (gpio_request(VIPER_PSU_DATA_GPIO, "PSU data")) + goto err_request_data; + + if (gpio_request(VIPER_PSU_CLK_GPIO, "PSU clock")) + goto err_request_clk; + + if (gpio_request(VIPER_PSU_nCS_LD_GPIO, "PSU cs")) + goto err_request_cs; + + if (gpio_direction_output(VIPER_PSU_DATA_GPIO, 0) || + gpio_direction_output(VIPER_PSU_CLK_GPIO, 0) || + gpio_direction_output(VIPER_PSU_nCS_LD_GPIO, 0)) + goto err_dir; + + /* c/should assume redboot set the correct level ??? */ + viper_set_core_cpu_voltage(get_clk_frequency_khz(0), 1); + + return; + +err_dir: + gpio_free(VIPER_PSU_nCS_LD_GPIO); +err_request_cs: + gpio_free(VIPER_PSU_CLK_GPIO); +err_request_clk: + gpio_free(VIPER_PSU_DATA_GPIO); +err_request_data: + pr_err("viper: Failed to setup vcore control GPIOs\n"); +} + +static void __init viper_init_serial_gpio(void) +{ + if (gpio_request(VIPER_UART_SHDN_GPIO, "UARTs shutdown")) + goto err_request; + + if (gpio_direction_output(VIPER_UART_SHDN_GPIO, 0)) + goto err_dir; + + return; + +err_dir: + gpio_free(VIPER_UART_SHDN_GPIO); +err_request: + pr_err("viper: Failed to setup UART shutdown GPIO\n"); +} + +#ifdef CONFIG_CPU_FREQ +static int viper_cpufreq_notifier(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + + /* TODO: Adjust timings??? */ + + switch (val) { + case CPUFREQ_PRECHANGE: + if (freq->old < freq->new) { + /* we are getting faster so raise the voltage + * before we change freq */ + viper_set_core_cpu_voltage(freq->new, 0); + } + break; + case CPUFREQ_POSTCHANGE: + if (freq->old > freq->new) { + /* we are slowing down so drop the power + * after we change freq */ + viper_set_core_cpu_voltage(freq->new, 0); + } + break; + default: + /* ignore */ + break; + } + + return 0; +} + +static struct notifier_block viper_cpufreq_notifier_block = { + .notifier_call = viper_cpufreq_notifier +}; + +static void __init viper_init_cpufreq(void) +{ + if (cpufreq_register_notifier(&viper_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER)) + pr_err("viper: Failed to setup cpufreq notifier\n"); +} +#else +static inline void viper_init_cpufreq(void) {} +#endif + +static void viper_power_off(void) +{ + pr_notice("Shutting off UPS\n"); + gpio_set_value(VIPER_UPS_GPIO, 1); + /* Spin to death... */ + while (1); +} + +static void __init viper_init(void) +{ + u8 version; + + pm_power_off = viper_power_off; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + /* Wake-up serial console */ + viper_init_serial_gpio(); + + pxa_set_fb_info(NULL, &fb_info); + + /* v1 hardware cannot use the datacs line */ + version = viper_hw_version(); + if (version == 0) + smc91x_device.num_resources--; + + pxa_set_i2c_info(NULL); + platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs)); + + viper_init_vcore_gpios(); + viper_init_cpufreq(); + + register_syscore_ops(&viper_cpu_syscore_ops); + + if (version) { + pr_info("viper: hardware v%di%d detected. " + "CPLD revision %d.\n", + VIPER_BOARD_VERSION(version), + VIPER_BOARD_ISSUE(version), + VIPER_CPLD_REVISION(version)); + system_rev = (VIPER_BOARD_VERSION(version) << 8) | + (VIPER_BOARD_ISSUE(version) << 4) | + VIPER_CPLD_REVISION(version); + } else { + pr_info("viper: No version register.\n"); + } + + i2c_register_board_info(1, ARRAY_AND_SIZE(viper_i2c_devices)); + + viper_tpm_init(); + pxa_set_ac97_info(NULL); +} + +static struct map_desc viper_io_desc[] __initdata = { + { + .virtual = VIPER_CPLD_BASE, + .pfn = __phys_to_pfn(VIPER_CPLD_PHYS), + .length = 0x00300000, + .type = MT_DEVICE, + }, + { + .virtual = VIPER_PC104IO_BASE, + .pfn = __phys_to_pfn(0x30000000), + .length = 0x00800000, + .type = MT_DEVICE, + }, +}; + +static void __init viper_map_io(void) +{ + pxa25x_map_io(); + + iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc)); + + PCFR |= PCFR_OPDE; +} + +MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC") + /* Maintainer: Marc Zyngier <maz@misterjones.org> */ + .atag_offset = 0x100, + .map_io = viper_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = viper_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = viper_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c new file mode 100644 index 00000000000..aa89488f961 --- /dev/null +++ b/arch/arm/mach-pxa/vpac270.c @@ -0,0 +1,725 @@ +/* + * Hardware definitions for Voipac PXA270 + * + * Copyright (C) 2010 + * 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/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <linux/usb/gpio_vbus.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/onenand.h> +#include <linux/dm9000.h> +#include <linux/ucb1400.h> +#include <linux/ata_platform.h> +#include <linux/regulator/max1586.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa27x.h> +#include <mach/audio.h> +#include <mach/vpac270.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <mach/pxa27x-udc.h> +#include <mach/udc.h> +#include <linux/platform_data/ata-pxa.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long vpac270_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, + GPIO53_GPIO, /* SD detect */ + GPIO52_GPIO, /* SD r/o switch */ + + /* GPIO KEYS */ + GPIO1_GPIO, /* USER BTN */ + + /* LEDs */ + GPIO15_GPIO, /* orange led */ + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO39_FFUART_TXD, + GPIO27_FFUART_RTS, + GPIO100_FFUART_CTS, + GPIO33_FFUART_DSR, + GPIO40_FFUART_DTR, + GPIO10_FFUART_DCD, + GPIO38_FFUART_RI, + + /* LCD */ + 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, + GPIO86_LCD_LDD_16, + GPIO87_LCD_LDD_17, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, + GPIO77_LCD_BIAS, + + /* PCMCIA */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO57_nIOIS16, + GPIO56_nPWAIT, + GPIO104_PSKTSEL, + GPIO84_GPIO, /* PCMCIA CD */ + GPIO35_GPIO, /* PCMCIA RDY */ + GPIO107_GPIO, /* PCMCIA PPEN */ + GPIO11_GPIO, /* PCMCIA RESET */ + GPIO17_GPIO, /* CF CD */ + GPIO12_GPIO, /* CF RDY */ + GPIO16_GPIO, /* CF RESET */ + + /* UHC */ + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + GPIO119_USBH2_PWR, + GPIO120_USBH2_PEN, + + /* UDC */ + GPIO41_GPIO, + + /* Ethernet */ + GPIO114_GPIO, /* 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, /* TS IRQ */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* IDE */ + GPIO36_GPIO, /* IDE IRQ */ + GPIO80_DREQ_1, +}; + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition vpac270_nor_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data vpac270_flash_data[] = { + { + .width = 2, /* bankwidth in bytes */ + .parts = vpac270_nor_partitions, + .nr_parts = ARRAY_SIZE(vpac270_nor_partitions) + } +}; + +static struct resource vpac270_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device vpac270_flash = { + .name = "physmap-flash", + .id = 0, + .resource = &vpac270_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = vpac270_flash_data, + }, +}; +static void __init vpac270_nor_init(void) +{ + platform_device_register(&vpac270_flash); +} +#else +static inline void vpac270_nor_init(void) {} +#endif + +/****************************************************************************** + * OneNAND Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE) +static struct mtd_partition vpac270_onenand_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct onenand_platform_data vpac270_onenand_info = { + .parts = vpac270_onenand_partitions, + .nr_parts = ARRAY_SIZE(vpac270_onenand_partitions), +}; + +static struct resource vpac270_onenand_resources[] = { + [0] = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_1M, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device vpac270_onenand = { + .name = "onenand-flash", + .id = -1, + .resource = vpac270_onenand_resources, + .num_resources = ARRAY_SIZE(vpac270_onenand_resources), + .dev = { + .platform_data = &vpac270_onenand_info, + }, +}; + +static void __init vpac270_onenand_init(void) +{ + platform_device_register(&vpac270_onenand); +} +#else +static void __init vpac270_onenand_init(void) {} +#endif + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data vpac270_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_power = -1, + .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, + .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, + .detect_delay_ms = 200, +}; + +static void __init vpac270_mmc_init(void) +{ + pxa_set_mci_info(&vpac270_mci_platform_data); +} +#else +static inline void vpac270_mmc_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button vpac270_pxa_buttons[] = { + {KEY_POWER, GPIO1_VPAC270_USER_BTN, 0, "USER BTN"}, +}; + +static struct gpio_keys_platform_data vpac270_pxa_keys_data = { + .buttons = vpac270_pxa_buttons, + .nbuttons = ARRAY_SIZE(vpac270_pxa_buttons), +}; + +static struct platform_device vpac270_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &vpac270_pxa_keys_data, + }, +}; + +static void __init vpac270_keys_init(void) +{ + platform_device_register(&vpac270_pxa_keys); +} +#else +static inline void vpac270_keys_init(void) {} +#endif + +/****************************************************************************** + * LED + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led vpac270_gpio_leds[] = { +{ + .name = "vpac270:orange:user", + .default_trigger = "none", + .gpio = GPIO15_VPAC270_LED_ORANGE, + .active_low = 1, +} +}; + +static struct gpio_led_platform_data vpac270_gpio_led_info = { + .leds = vpac270_gpio_leds, + .num_leds = ARRAY_SIZE(vpac270_gpio_leds), +}; + +static struct platform_device vpac270_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &vpac270_gpio_led_info, + } +}; + +static void __init vpac270_leds_init(void) +{ + platform_device_register(&vpac270_leds); +} +#else +static inline void vpac270_leds_init(void) {} +#endif + +/****************************************************************************** + * USB Host + ******************************************************************************/ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static int vpac270_ohci_init(struct device *dev) +{ + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; + return 0; +} + +static struct pxaohci_platform_data vpac270_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT2 | + POWER_CONTROL_LOW | POWER_SENSE_LOW, + .init = vpac270_ohci_init, +}; + +static void __init vpac270_uhc_init(void) +{ + pxa_set_ohci_info(&vpac270_ohci_info); +} +#else +static inline void vpac270_uhc_init(void) {} +#endif + +/****************************************************************************** + * USB Gadget + ******************************************************************************/ +#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) +static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = { + .gpio_vbus = GPIO41_VPAC270_UDC_DETECT, + .gpio_pullup = -1, +}; + +static struct platform_device vpac270_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &vpac270_gpio_vbus_info, + }, +}; + +static void vpac270_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 vpac270_udc_info __initdata = { + .udc_command = vpac270_udc_command, + .gpio_pullup = -1, +}; + +static void __init vpac270_udc_init(void) +{ + pxa_set_udc_info(&vpac270_udc_info); + platform_device_register(&vpac270_gpio_vbus); +} +#else +static inline void vpac270_udc_init(void) {} +#endif + +/****************************************************************************** + * Ethernet + ******************************************************************************/ +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource vpac270_dm9000_resources[] = { + [0] = { + .start = PXA_CS2_PHYS + 0x300, + .end = PXA_CS2_PHYS + 0x303, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_CS2_PHYS + 0x304, + .end = PXA_CS2_PHYS + 0x343, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, +}; + +static struct dm9000_plat_data vpac270_dm9000_platdata = { + .flags = DM9000_PLATF_32BITONLY, +}; + +static struct platform_device vpac270_dm9000_device = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(vpac270_dm9000_resources), + .resource = vpac270_dm9000_resources, + .dev = { + .platform_data = &vpac270_dm9000_platdata, + } +}; + +static void __init vpac270_eth_init(void) +{ + platform_device_register(&vpac270_dm9000_device); +} +#else +static inline void vpac270_eth_init(void) {} +#endif + +/****************************************************************************** + * Audio and Touchscreen + ******************************************************************************/ +#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ + defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static pxa2xx_audio_ops_t vpac270_ac97_pdata = { + .reset_gpio = 95, +}; + +static struct ucb1400_pdata vpac270_ucb1400_pdata = { + .irq = PXA_GPIO_TO_IRQ(GPIO113_VPAC270_TS_IRQ), +}; + +static struct platform_device vpac270_ucb1400_device = { + .name = "ucb1400_core", + .id = -1, + .dev = { + .platform_data = &vpac270_ucb1400_pdata, + }, +}; + +static void __init vpac270_ts_init(void) +{ + pxa_set_ac97_info(&vpac270_ac97_pdata); + platform_device_register(&vpac270_ucb1400_device); +} +#else +static inline void vpac270_ts_init(void) {} +#endif + +/****************************************************************************** + * RTC + ******************************************************************************/ +#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE) +static struct i2c_board_info __initdata vpac270_i2c_devs[] = { + { + I2C_BOARD_INFO("ds1339", 0x68), + }, +}; + +static void __init vpac270_rtc_init(void) +{ + i2c_register_board_info(0, ARRAY_AND_SIZE(vpac270_i2c_devs)); +} +#else +static inline void vpac270_rtc_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info vpac270_lcd_modes[] = { +{ + .pixclock = 57692, + .xres = 640, + .yres = 480, + .bpp = 32, + .depth = 18, + + .left_margin = 144, + .right_margin = 32, + .upper_margin = 13, + .lower_margin = 30, + + .hsync_len = 32, + .vsync_len = 2, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}, { /* CRT 640x480 */ + .pixclock = 35000, + .xres = 640, + .yres = 480, + .bpp = 16, + .depth = 16, + + .left_margin = 96, + .right_margin = 48, + .upper_margin = 33, + .lower_margin = 10, + + .hsync_len = 48, + .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}, { /* CRT 800x600 H=30kHz V=48HZ */ + .pixclock = 25000, + .xres = 800, + .yres = 600, + .bpp = 16, + .depth = 16, + + .left_margin = 50, + .right_margin = 1, + .upper_margin = 21, + .lower_margin = 12, + + .hsync_len = 8, + .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}, { /* CRT 1024x768 H=40kHz V=50Hz */ + .pixclock = 15000, + .xres = 1024, + .yres = 768, + .bpp = 16, + .depth = 16, + + .left_margin = 220, + .right_margin = 8, + .upper_margin = 33, + .lower_margin = 2, + + .hsync_len = 48, + .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +} +}; + +static struct pxafb_mach_info vpac270_lcd_screen = { + .modes = vpac270_lcd_modes, + .num_modes = ARRAY_SIZE(vpac270_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_18BPP, +}; + +static void vpac270_lcd_power(int on, struct fb_var_screeninfo *info) +{ + gpio_set_value(GPIO81_VPAC270_BKL_ON, on); +} + +static void __init vpac270_lcd_init(void) +{ + int ret; + + ret = gpio_request(GPIO81_VPAC270_BKL_ON, "BKL-ON"); + if (ret) { + pr_err("Requesting BKL-ON GPIO failed!\n"); + goto err; + } + + ret = gpio_direction_output(GPIO81_VPAC270_BKL_ON, 1); + if (ret) { + pr_err("Setting BKL-ON GPIO direction failed!\n"); + goto err2; + } + + vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power; + pxa_set_fb_info(NULL, &vpac270_lcd_screen); + return; + +err2: + gpio_free(GPIO81_VPAC270_BKL_ON); +err: + return; +} +#else +static inline void vpac270_lcd_init(void) {} +#endif + +/****************************************************************************** + * PATA IDE + ******************************************************************************/ +#if defined(CONFIG_PATA_PXA) || defined(CONFIG_PATA_PXA_MODULE) +static struct pata_pxa_pdata vpac270_pata_pdata = { + .reg_shift = 1, + .dma_dreq = 1, + .irq_flags = IRQF_TRIGGER_RISING, +}; + +static struct resource vpac270_ide_resources[] = { + [0] = { /* I/O Base address */ + .start = PXA_CS3_PHYS + 0x120, + .end = PXA_CS3_PHYS + 0x13f, + .flags = IORESOURCE_MEM + }, + [1] = { /* CTL Base address */ + .start = PXA_CS3_PHYS + 0x15c, + .end = PXA_CS3_PHYS + 0x15f, + .flags = IORESOURCE_MEM + }, + [2] = { /* DMA Base address */ + .start = PXA_CS3_PHYS + 0x20, + .end = PXA_CS3_PHYS + 0x2f, + .flags = IORESOURCE_DMA + }, + [3] = { /* IDE IRQ pin */ + .start = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ), + .end = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ), + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device vpac270_ide_device = { + .name = "pata_pxa", + .num_resources = ARRAY_SIZE(vpac270_ide_resources), + .resource = vpac270_ide_resources, + .dev = { + .platform_data = &vpac270_pata_pdata, + .coherent_dma_mask = 0xffffffff, + } +}; + +static void __init vpac270_ide_init(void) +{ + platform_device_register(&vpac270_ide_device); +} +#else +static inline void vpac270_ide_init(void) {} +#endif + +/****************************************************************************** + * Core power regulator + ******************************************************************************/ +#if defined(CONFIG_REGULATOR_MAX1586) || \ + defined(CONFIG_REGULATOR_MAX1586_MODULE) +static struct regulator_consumer_supply vpac270_max1587a_consumers[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +static struct regulator_init_data vpac270_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 = vpac270_max1587a_consumers, + .num_consumer_supplies = ARRAY_SIZE(vpac270_max1587a_consumers), +}; + +static struct max1586_subdev_data vpac270_max1587a_subdevs[] = { + { + .name = "vcc_core", + .id = MAX1586_V3, + .platform_data = &vpac270_max1587a_v3_info, + } +}; + +static struct max1586_platform_data vpac270_max1587a_info = { + .subdevs = vpac270_max1587a_subdevs, + .num_subdevs = ARRAY_SIZE(vpac270_max1587a_subdevs), + .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */ +}; + +static struct i2c_board_info __initdata vpac270_pi2c_board_info[] = { + { + I2C_BOARD_INFO("max1586", 0x14), + .platform_data = &vpac270_max1587a_info, + }, +}; + +static void __init vpac270_pmic_init(void) +{ + i2c_register_board_info(1, ARRAY_AND_SIZE(vpac270_pi2c_board_info)); +} +#else +static inline void vpac270_pmic_init(void) {} +#endif + + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init vpac270_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(vpac270_pin_config)); + + 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); + + vpac270_pmic_init(); + vpac270_lcd_init(); + vpac270_mmc_init(); + vpac270_nor_init(); + vpac270_onenand_init(); + vpac270_leds_init(); + vpac270_keys_init(); + vpac270_uhc_init(); + vpac270_udc_init(); + vpac270_eth_init(); + vpac270_ts_init(); + vpac270_rtc_init(); + vpac270_ide_init(); +} + +MACHINE_START(VPAC270, "Voipac PXA270") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = vpac270_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c new file mode 100644 index 00000000000..13b1d4586d7 --- /dev/null +++ b/arch/arm/mach-pxa/xcep.c @@ -0,0 +1,191 @@ +/* linux/arch/arm/mach-pxa/xcep.c + * + * Support for the Iskratel Electronics XCEP platform as used in + * the Libera instruments from Instrumentation Technologies. + * + * Author: Ales Bardorfer <ales@i-tech.si> + * Contributions by: Abbott, MG (Michael) <michael.abbott@diamond.ac.uk> + * Contributions by: Matej Kenda <matej.kenda@i-tech.si> + * Created: June 2006 + * Copyright: (C) 2006-2009 Instrumentation Technologies + * + * 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/i2c.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/smc91x.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/irq.h> +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/pxa25x.h> +#include <mach/smemc.h> + +#include "generic.h" + +#define XCEP_ETH_PHYS (PXA_CS3_PHYS + 0x00000300) +#define XCEP_ETH_PHYS_END (PXA_CS3_PHYS + 0x000fffff) +#define XCEP_ETH_ATTR (PXA_CS3_PHYS + 0x02000000) +#define XCEP_ETH_ATTR_END (PXA_CS3_PHYS + 0x020fffff) +#define XCEP_ETH_IRQ IRQ_GPIO0 + +/* XCEP CPLD base */ +#define XCEP_CPLD_BASE 0xf0000000 + + +/* Flash partitions. */ + +static struct mtd_partition xcep_partitions[] = { + { + .name = "Bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE + }, { + .name = "Bootloader ENV", + .size = 0x00040000, + .offset = 0x00040000, + .mask_flags = MTD_WRITEABLE + }, { + .name = "Kernel", + .size = 0x00100000, + .offset = 0x00080000, + }, { + .name = "Rescue fs", + .size = 0x00280000, + .offset = 0x00180000, + }, { + .name = "Filesystem", + .size = MTDPART_SIZ_FULL, + .offset = 0x00400000 + } +}; + +static struct physmap_flash_data xcep_flash_data[] = { + { + .width = 4, /* bankwidth in bytes */ + .parts = xcep_partitions, + .nr_parts = ARRAY_SIZE(xcep_partitions) + } +}; + +static struct resource flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = xcep_flash_data, + }, + .resource = &flash_resource, + .num_resources = 1, +}; + + + +/* SMC LAN91C111 network controller. */ + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = XCEP_ETH_PHYS, + .end = XCEP_ETH_PHYS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = XCEP_ETH_IRQ, + .end = XCEP_ETH_IRQ, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-attrib", + .start = XCEP_ETH_ATTR, + .end = XCEP_ETH_ATTR_END, + .flags = IORESOURCE_MEM, + }, +}; + +static struct smc91x_platdata xcep_smc91x_info = { + .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT | SMC91X_USE_DMA, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &xcep_smc91x_info, + }, +}; + + +static struct platform_device *devices[] __initdata = { + &flash_device, + &smc91x_device, +}; + + +/* We have to state that there are HWMON devices on the I2C bus on XCEP. + * Drivers for HWMON verify capabilities of the adapter when loading and + * refuse to attach if the adapter doesn't support HWMON class of devices. */ +static struct i2c_pxa_platform_data xcep_i2c_platform_data = { + .class = I2C_CLASS_HWMON +}; + + +static mfp_cfg_t xcep_pin_config[] __initdata = { + GPIO79_nCS_3, /* SMC 91C111 chip select. */ + GPIO80_nCS_4, /* CPLD chip select. */ + /* SSP communication to MSP430 */ + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + GPIO27_SSP1_EXTCLK +}; + +static void __init xcep_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(xcep_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + pxa_set_hwuart_info(NULL); + + /* See Intel XScale Developer's Guide for details */ + /* Set RDF and RDN to appropriate values (chip select 3 (smc91x)) */ + __raw_writel((__raw_readl(MSC1) & 0xffff) | 0xD5540000, MSC1); + /* Set RDF and RDN to appropriate values (chip select 5 (fpga)) */ + __raw_writel((__raw_readl(MSC2) & 0xffff) | 0x72A00000, MSC2); + + platform_add_devices(ARRAY_AND_SIZE(devices)); + pxa_set_i2c_info(&xcep_i2c_platform_data); +} + +MACHINE_START(XCEP, "Iskratel XCEP") + .atag_offset = 0x100, + .init_machine = xcep_init, + .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, + .init_time = pxa_timer_init, + .restart = pxa_restart, +MACHINE_END + diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c new file mode 100644 index 00000000000..e1a121b36cf --- /dev/null +++ b/arch/arm/mach-pxa/z2.c @@ -0,0 +1,734 @@ +/* + * linux/arch/arm/mach-pxa/z2.c + * + * Support for the Zipit Z2 Handheld device. + * + * Copyright (C) 2009-2010 Marek Vasut <marek.vasut@gmail.com> + * + * Based on research and code by: Ken McGuire + * Based on mainstone.c as modified for the Zipit Z2. + * + * 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/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/pwm_backlight.h> +#include <linux/z2_battery.h> +#include <linux/dma-mapping.h> +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/spi/libertas_spi.h> +#include <linux/spi/lms283gf05.h> +#include <linux/power_supply.h> +#include <linux/mtd/physmap.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/delay.h> +#include <linux/regulator/machine.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa27x.h> +#include <mach/mfp-pxa27x.h> +#include <mach/z2.h> +#include <linux/platform_data/video-pxafb.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <mach/pm.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long z2_pin_config[] = { + + /* LCD - 16bpp Active TFT */ + 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, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, + GPIO77_LCD_BIAS, + GPIO19_GPIO, /* LCD reset */ + GPIO88_GPIO, /* LCD chipselect */ + + /* PWM */ + GPIO115_PWM1_OUT, /* Keypad Backlight */ + GPIO11_PWM2_OUT, /* LCD Backlight */ + + /* MMC */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO96_GPIO, /* SD detect */ + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* Keypad */ + GPIO100_KP_MKIN_0, + GPIO101_KP_MKIN_1, + GPIO102_KP_MKIN_2, + GPIO34_KP_MKIN_3, + GPIO38_KP_MKIN_4, + GPIO16_KP_MKIN_5, + GPIO17_KP_MKIN_6, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, + GPIO35_KP_MKOUT_6, + GPIO41_KP_MKOUT_7, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* SSP1 */ + GPIO23_SSP1_SCLK, /* SSP1_SCK */ + GPIO25_SSP1_TXD, /* SSP1_TXD */ + GPIO26_SSP1_RXD, /* SSP1_RXD */ + + /* SSP2 */ + GPIO22_SSP2_SCLK, /* SSP2_SCK */ + GPIO13_SSP2_TXD, /* SSP2_TXD */ + GPIO40_SSP2_RXD, /* SSP2_RXD */ + + /* LEDs */ + GPIO10_GPIO, /* WiFi LED */ + GPIO83_GPIO, /* Charging LED */ + GPIO85_GPIO, /* Charged LED */ + + /* I2S */ + GPIO28_I2S_BITCLK_OUT, + GPIO29_I2S_SDATA_IN, + GPIO30_I2S_SDATA_OUT, + GPIO31_I2S_SYNC, + GPIO113_I2S_SYSCLK, + + /* MISC */ + GPIO0_GPIO, /* AC power detect */ + GPIO1_GPIO, /* Power button */ + GPIO37_GPIO, /* Headphone detect */ + GPIO98_GPIO, /* Lid switch */ + GPIO14_GPIO, /* WiFi Power */ + GPIO24_GPIO, /* WiFi CS */ + GPIO36_GPIO, /* WiFi IRQ */ + GPIO88_GPIO, /* LCD CS */ +}; + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct resource z2_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct mtd_partition z2_flash_parts[] = { + { + .name = "U-Boot Bootloader", + .offset = 0x0, + .size = 0x40000, + }, { + .name = "U-Boot Environment", + .offset = 0x40000, + .size = 0x20000, + }, { + .name = "Flash", + .offset = 0x60000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data z2_flash_data = { + .width = 2, + .parts = z2_flash_parts, + .nr_parts = ARRAY_SIZE(z2_flash_parts), +}; + +static struct platform_device z2_flash = { + .name = "physmap-flash", + .id = -1, + .resource = &z2_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &z2_flash_data, + }, +}; + +static void __init z2_nor_init(void) +{ + platform_device_register(&z2_flash); +} +#else +static inline void z2_nor_init(void) {} +#endif + +/****************************************************************************** + * Backlight + ******************************************************************************/ +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static struct platform_pwm_backlight_data z2_backlight_data[] = { + [0] = { + /* Keypad Backlight */ + .pwm_id = 1, + .max_brightness = 1023, + .dft_brightness = 0, + .pwm_period_ns = 1260320, + .enable_gpio = -1, + }, + [1] = { + /* LCD Backlight */ + .pwm_id = 2, + .max_brightness = 1023, + .dft_brightness = 512, + .pwm_period_ns = 1260320, + .enable_gpio = -1, + }, +}; + +static struct platform_device z2_backlight_devices[2] = { + { + .name = "pwm-backlight", + .id = 0, + .dev = { + .platform_data = &z2_backlight_data[1], + }, + }, + { + .name = "pwm-backlight", + .id = 1, + .dev = { + .platform_data = &z2_backlight_data[0], + }, + }, +}; +static void __init z2_pwm_init(void) +{ + platform_device_register(&z2_backlight_devices[0]); + platform_device_register(&z2_backlight_devices[1]); +} +#else +static inline void z2_pwm_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info z2_lcd_modes[] = { +{ + .pixclock = 192000, + .xres = 240, + .yres = 320, + .bpp = 16, + + .left_margin = 4, + .right_margin = 8, + .upper_margin = 4, + .lower_margin = 8, + + .hsync_len = 4, + .vsync_len = 4, +}, +}; + +static struct pxafb_mach_info z2_lcd_screen = { + .modes = z2_lcd_modes, + .num_modes = ARRAY_SIZE(z2_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_BIAS_ACTIVE_LOW | + LCD_ALTERNATE_MAPPING, +}; + +static void __init z2_lcd_init(void) +{ + pxa_set_fb_info(NULL, &z2_lcd_screen); +} +#else +static inline void z2_lcd_init(void) {} +#endif + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data z2_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = GPIO96_ZIPITZ2_SD_DETECT, + .gpio_power = -1, + .gpio_card_ro = -1, + .detect_delay_ms = 200, +}; + +static void __init z2_mmc_init(void) +{ + pxa_set_mci_info(&z2_mci_platform_data); +} +#else +static inline void z2_mmc_init(void) {} +#endif + +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led z2_gpio_leds[] = { +{ + .name = "z2:green:wifi", + .default_trigger = "none", + .gpio = GPIO10_ZIPITZ2_LED_WIFI, + .active_low = 1, +}, { + .name = "z2:green:charged", + .default_trigger = "mmc0", + .gpio = GPIO85_ZIPITZ2_LED_CHARGED, + .active_low = 1, +}, { + .name = "z2:amber:charging", + .default_trigger = "Z2-charging-or-full", + .gpio = GPIO83_ZIPITZ2_LED_CHARGING, + .active_low = 1, +}, +}; + +static struct gpio_led_platform_data z2_gpio_led_info = { + .leds = z2_gpio_leds, + .num_leds = ARRAY_SIZE(z2_gpio_leds), +}; + +static struct platform_device z2_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &z2_gpio_led_info, + } +}; + +static void __init z2_leds_init(void) +{ + platform_device_register(&z2_leds); +} +#else +static inline void z2_leds_init(void) {} +#endif + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static const unsigned int z2_matrix_keys[] = { + KEY(0, 0, KEY_OPTION), + KEY(1, 0, KEY_UP), + KEY(2, 0, KEY_DOWN), + KEY(3, 0, KEY_LEFT), + KEY(4, 0, KEY_RIGHT), + KEY(5, 0, KEY_END), + KEY(6, 0, KEY_KPPLUS), + + KEY(0, 1, KEY_HOME), + KEY(1, 1, KEY_Q), + KEY(2, 1, KEY_I), + KEY(3, 1, KEY_G), + KEY(4, 1, KEY_X), + KEY(5, 1, KEY_ENTER), + KEY(6, 1, KEY_KPMINUS), + + KEY(0, 2, KEY_PAGEUP), + KEY(1, 2, KEY_W), + KEY(2, 2, KEY_O), + KEY(3, 2, KEY_H), + KEY(4, 2, KEY_C), + KEY(5, 2, KEY_LEFTALT), + + KEY(0, 3, KEY_PAGEDOWN), + KEY(1, 3, KEY_E), + KEY(2, 3, KEY_P), + KEY(3, 3, KEY_J), + KEY(4, 3, KEY_V), + KEY(5, 3, KEY_LEFTSHIFT), + + KEY(0, 4, KEY_ESC), + KEY(1, 4, KEY_R), + KEY(2, 4, KEY_A), + KEY(3, 4, KEY_K), + KEY(4, 4, KEY_B), + KEY(5, 4, KEY_LEFTCTRL), + + KEY(0, 5, KEY_TAB), + KEY(1, 5, KEY_T), + KEY(2, 5, KEY_S), + KEY(3, 5, KEY_L), + KEY(4, 5, KEY_N), + KEY(5, 5, KEY_SPACE), + + KEY(0, 6, KEY_STOPCD), + KEY(1, 6, KEY_Y), + KEY(2, 6, KEY_D), + KEY(3, 6, KEY_BACKSPACE), + KEY(4, 6, KEY_M), + KEY(5, 6, KEY_COMMA), + + KEY(0, 7, KEY_PLAYCD), + KEY(1, 7, KEY_U), + KEY(2, 7, KEY_F), + KEY(3, 7, KEY_Z), + KEY(4, 7, KEY_SEMICOLON), + KEY(5, 7, KEY_DOT), +}; + +static struct matrix_keymap_data z2_matrix_keymap_data = { + .keymap = z2_matrix_keys, + .keymap_size = ARRAY_SIZE(z2_matrix_keys), +}; + +static struct pxa27x_keypad_platform_data z2_keypad_platform_data = { + .matrix_key_rows = 7, + .matrix_key_cols = 8, + .matrix_keymap_data = &z2_matrix_keymap_data, + + .debounce_interval = 30, +}; + +static void __init z2_mkp_init(void) +{ + pxa_set_keypad_info(&z2_keypad_platform_data); +} +#else +static inline void z2_mkp_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button z2_pxa_buttons[] = { + { + .code = KEY_POWER, + .gpio = GPIO1_ZIPITZ2_POWER_BUTTON, + .active_low = 0, + .desc = "Power Button", + .wakeup = 1, + .type = EV_KEY, + }, + { + .code = SW_LID, + .gpio = GPIO98_ZIPITZ2_LID_BUTTON, + .active_low = 1, + .desc = "Lid Switch", + .wakeup = 0, + .type = EV_SW, + }, +}; + +static struct gpio_keys_platform_data z2_pxa_keys_data = { + .buttons = z2_pxa_buttons, + .nbuttons = ARRAY_SIZE(z2_pxa_buttons), +}; + +static struct platform_device z2_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &z2_pxa_keys_data, + }, +}; + +static void __init z2_keys_init(void) +{ + platform_device_register(&z2_pxa_keys); +} +#else +static inline void z2_keys_init(void) {} +#endif + +/****************************************************************************** + * Battery + ******************************************************************************/ +#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) +static struct z2_battery_info batt_chip_info = { + .batt_I2C_bus = 0, + .batt_I2C_addr = 0x55, + .batt_I2C_reg = 2, + .charge_gpio = GPIO0_ZIPITZ2_AC_DETECT, + .min_voltage = 3475000, + .max_voltage = 4190000, + .batt_div = 59, + .batt_mult = 1000000, + .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION, + .batt_name = "Z2", +}; + +static struct i2c_board_info __initdata z2_i2c_board_info[] = { + { + I2C_BOARD_INFO("aer915", 0x55), + .platform_data = &batt_chip_info, + }, { + I2C_BOARD_INFO("wm8750", 0x1b), + }, + +}; + +static void __init z2_i2c_init(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(z2_i2c_board_info)); +} +#else +static inline void z2_i2c_init(void) {} +#endif + +/****************************************************************************** + * SSP Devices - WiFi and LCD control + ******************************************************************************/ +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +/* WiFi */ +static int z2_lbs_spi_setup(struct spi_device *spi) +{ + int ret = 0; + + ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power"); + if (ret) + goto err; + + ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1); + if (ret) + goto err2; + + /* Wait until card is powered on */ + mdelay(180); + + spi->bits_per_word = 16; + spi->mode = SPI_MODE_2, + + spi_setup(spi); + + return 0; + +err2: + gpio_free(GPIO14_ZIPITZ2_WIFI_POWER); +err: + return ret; +}; + +static int z2_lbs_spi_teardown(struct spi_device *spi) +{ + gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0); + gpio_free(GPIO14_ZIPITZ2_WIFI_POWER); + + return 0; +}; + +static struct pxa2xx_spi_chip z2_lbs_chip_info = { + .rx_threshold = 8, + .tx_threshold = 8, + .timeout = 1000, + .gpio_cs = GPIO24_ZIPITZ2_WIFI_CS, +}; + +static struct libertas_spi_platform_data z2_lbs_pdata = { + .use_dummy_writes = 1, + .setup = z2_lbs_spi_setup, + .teardown = z2_lbs_spi_teardown, +}; + +/* LCD */ +static struct pxa2xx_spi_chip lms283_chip_info = { + .rx_threshold = 1, + .tx_threshold = 1, + .timeout = 64, + .gpio_cs = GPIO88_ZIPITZ2_LCD_CS, +}; + +static const struct lms283gf05_pdata lms283_pdata = { + .reset_gpio = GPIO19_ZIPITZ2_LCD_RESET, +}; + +static struct spi_board_info spi_board_info[] __initdata = { +{ + .modalias = "libertas_spi", + .platform_data = &z2_lbs_pdata, + .controller_data = &z2_lbs_chip_info, + .irq = PXA_GPIO_TO_IRQ(GPIO36_ZIPITZ2_WIFI_IRQ), + .max_speed_hz = 13000000, + .bus_num = 1, + .chip_select = 0, +}, +{ + .modalias = "lms283gf05", + .controller_data = &lms283_chip_info, + .platform_data = &lms283_pdata, + .max_speed_hz = 400000, + .bus_num = 2, + .chip_select = 0, +}, +}; + +static struct pxa2xx_spi_master pxa_ssp1_master_info = { + .clock_enable = CKEN_SSP, + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct pxa2xx_spi_master pxa_ssp2_master_info = { + .clock_enable = CKEN_SSP2, + .num_chipselect = 1, +}; + +static void __init z2_spi_init(void) +{ + pxa2xx_set_spi_info(1, &pxa_ssp1_master_info); + pxa2xx_set_spi_info(2, &pxa_ssp2_master_info); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); +} +#else +static inline void z2_spi_init(void) {} +#endif + +/****************************************************************************** + * Core power regulator + ******************************************************************************/ +#if defined(CONFIG_REGULATOR_TPS65023) || \ + defined(CONFIG_REGULATOR_TPS65023_MODULE) +static struct regulator_consumer_supply z2_tps65021_consumers[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +static struct regulator_init_data z2_tps65021_info[] = { + { + .constraints = { + .name = "vcc_core range", + .min_uV = 800000, + .max_uV = 1600000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .consumer_supplies = z2_tps65021_consumers, + .num_consumer_supplies = ARRAY_SIZE(z2_tps65021_consumers), + }, { + .constraints = { + .name = "DCDC2", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + }, + }, { + .constraints = { + .name = "DCDC3", + .min_uV = 1800000, + .max_uV = 1800000, + .always_on = 1, + }, + }, { + .constraints = { + .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3150000, + .always_on = 1, + }, + }, { + .constraints = { + .name = "LDO2", + .min_uV = 1050000, + .max_uV = 3300000, + .always_on = 1, + }, + } +}; + +static struct i2c_board_info __initdata z2_pi2c_board_info[] = { + { + I2C_BOARD_INFO("tps65021", 0x48), + .platform_data = &z2_tps65021_info, + }, +}; + +static void __init z2_pmic_init(void) +{ + pxa27x_set_i2c_power_info(NULL); + i2c_register_board_info(1, ARRAY_AND_SIZE(z2_pi2c_board_info)); +} +#else +static inline void z2_pmic_init(void) {} +#endif + +#ifdef CONFIG_PM +static void z2_power_off(void) +{ + /* We're using deep sleep as poweroff, so clear PSPR to ensure that + * bootloader will jump to its entry point in resume handler + */ + PSPR = 0x0; + local_irq_disable(); + pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP); + pxa27x_cpu_pm_enter(PM_SUSPEND_MEM); +} +#else +#define z2_power_off NULL +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init z2_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(z2_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + z2_lcd_init(); + z2_mmc_init(); + z2_mkp_init(); + z2_i2c_init(); + z2_spi_init(); + z2_nor_init(); + z2_pwm_init(); + z2_leds_init(); + z2_keys_init(); + z2_pmic_init(); + + pm_power_off = z2_power_off; +} + +MACHINE_START(ZIPIT2, "Zipit Z2") + .atag_offset = 0x100, + .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, + .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = z2_init, + .restart = pxa_restart, +MACHINE_END diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c new file mode 100644 index 00000000000..205f9bf3821 --- /dev/null +++ b/arch/arm/mach-pxa/zeus.c @@ -0,0 +1,928 @@ +/* + * Support for the Arcom ZEUS. + * + * Copyright (C) 2006 Arcom Control Systems Ltd. + * + * Loosely based on Arcom's 2.6.16.28. + * Maintained by Marc Zyngier <maz@misterjones.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/cpufreq.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/pm.h> +#include <linux/gpio.h> +#include <linux/serial_8250.h> +#include <linux/dm9000.h> +#include <linux/mmc/host.h> +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/i2c.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/platform_data/pca953x.h> +#include <linux/apm-emulation.h> +#include <linux/can/platform/mcp251x.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> + +#include <asm/mach-types.h> +#include <asm/suspend.h> +#include <asm/system_info.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/pxa27x.h> +#include <mach/regs-uart.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <mach/pxa27x-udc.h> +#include <mach/udc.h> +#include <linux/platform_data/video-pxafb.h> +#include <mach/pm.h> +#include <mach/audio.h> +#include <linux/platform_data/pcmcia-pxa2xx_viper.h> +#include <mach/zeus.h> +#include <mach/smemc.h> + +#include "generic.h" + +/* + * Interrupt handling + */ + +static unsigned long zeus_irq_enabled_mask; +static const int zeus_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, }; +static const int zeus_isa_irq_map[] = { + 0, /* ISA irq #0, invalid */ + 0, /* ISA irq #1, invalid */ + 0, /* ISA irq #2, invalid */ + 1 << 0, /* ISA irq #3 */ + 1 << 1, /* ISA irq #4 */ + 1 << 2, /* ISA irq #5 */ + 1 << 3, /* ISA irq #6 */ + 1 << 4, /* ISA irq #7 */ + 0, /* ISA irq #8, invalid */ + 0, /* ISA irq #9, invalid */ + 1 << 5, /* ISA irq #10 */ + 1 << 6, /* ISA irq #11 */ + 1 << 7, /* ISA irq #12 */ +}; + +static inline int zeus_irq_to_bitmask(unsigned int irq) +{ + return zeus_isa_irq_map[irq - PXA_ISA_IRQ(0)]; +} + +static inline int zeus_bit_to_irq(int bit) +{ + return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0); +} + +static void zeus_ack_irq(struct irq_data *d) +{ + __raw_writew(zeus_irq_to_bitmask(d->irq), ZEUS_CPLD_ISA_IRQ); +} + +static void zeus_mask_irq(struct irq_data *d) +{ + zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(d->irq)); +} + +static void zeus_unmask_irq(struct irq_data *d) +{ + zeus_irq_enabled_mask |= zeus_irq_to_bitmask(d->irq); +} + +static inline unsigned long zeus_irq_pending(void) +{ + return __raw_readw(ZEUS_CPLD_ISA_IRQ) & zeus_irq_enabled_mask; +} + +static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long pending; + + pending = zeus_irq_pending(); + do { + /* we're in a chained irq handler, + * so ack the interrupt by hand */ + desc->irq_data.chip->irq_ack(&desc->irq_data); + + if (likely(pending)) { + irq = zeus_bit_to_irq(__ffs(pending)); + generic_handle_irq(irq); + } + pending = zeus_irq_pending(); + } while (pending); +} + +static struct irq_chip zeus_irq_chip = { + .name = "ISA", + .irq_ack = zeus_ack_irq, + .irq_mask = zeus_mask_irq, + .irq_unmask = zeus_unmask_irq, +}; + +static void __init zeus_init_irq(void) +{ + int level; + int isa_irq; + + pxa27x_init_irq(); + + /* Peripheral IRQs. It would be nice to move those inside driver + configuration, but it is not supported at the moment. */ + irq_set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), + IRQ_TYPE_EDGE_FALLING); + irq_set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING); + + /* Setup ISA IRQs */ + for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) { + isa_irq = zeus_bit_to_irq(level); + irq_set_chip_and_handler(isa_irq, &zeus_irq_chip, + handle_edge_irq); + set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); + } + + irq_set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler); +} + + +/* + * Platform devices + */ + +/* Flash */ +static struct resource zeus_mtd_resources[] = { + [0] = { /* NOR Flash (up to 64MB) */ + .start = ZEUS_FLASH_PHYS, + .end = ZEUS_FLASH_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* SRAM */ + .start = ZEUS_SRAM_PHYS, + .end = ZEUS_SRAM_PHYS + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct physmap_flash_data zeus_flash_data[] = { + [0] = { + .width = 2, + .parts = NULL, + .nr_parts = 0, + }, +}; + +static struct platform_device zeus_mtd_devices[] = { + [0] = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &zeus_flash_data[0], + }, + .resource = &zeus_mtd_resources[0], + .num_resources = 1, + }, +}; + +/* Serial */ +static struct resource zeus_serial_resources[] = { + { + .start = 0x10000000, + .end = 0x1000000f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x10800000, + .end = 0x1080000f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x11000000, + .end = 0x1100000f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x40100000, + .end = 0x4010001f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x40200000, + .end = 0x4020001f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x40700000, + .end = 0x4070001f, + .flags = IORESOURCE_MEM, + }, +}; + +static struct plat_serial8250_port serial_platform_data[] = { + /* External UARTs */ + /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */ + { /* COM1 */ + .mapbase = 0x10000000, + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTA_GPIO), + .irqflags = IRQF_TRIGGER_RISING, + .uartclk = 14745600, + .regshift = 1, + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { /* COM2 */ + .mapbase = 0x10800000, + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTB_GPIO), + .irqflags = IRQF_TRIGGER_RISING, + .uartclk = 14745600, + .regshift = 1, + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { /* COM3 */ + .mapbase = 0x11000000, + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTC_GPIO), + .irqflags = IRQF_TRIGGER_RISING, + .uartclk = 14745600, + .regshift = 1, + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { /* COM4 */ + .mapbase = 0x11800000, + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTD_GPIO), + .irqflags = IRQF_TRIGGER_RISING, + .uartclk = 14745600, + .regshift = 1, + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + /* Internal UARTs */ + { /* FFUART */ + .membase = (void *)&FFUART, + .mapbase = __PREG(FFUART), + .irq = IRQ_FFUART, + .uartclk = 921600 * 16, + .regshift = 2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { /* BTUART */ + .membase = (void *)&BTUART, + .mapbase = __PREG(BTUART), + .irq = IRQ_BTUART, + .uartclk = 921600 * 16, + .regshift = 2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { /* STUART */ + .membase = (void *)&STUART, + .mapbase = __PREG(STUART), + .irq = IRQ_STUART, + .uartclk = 921600 * 16, + .regshift = 2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + }, + { }, +}; + +static struct platform_device zeus_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_platform_data, + }, + .num_resources = ARRAY_SIZE(zeus_serial_resources), + .resource = zeus_serial_resources, +}; + +/* Ethernet */ +static struct resource zeus_dm9k0_resource[] = { + [0] = { + .start = ZEUS_ETH0_PHYS, + .end = ZEUS_ETH0_PHYS + 1, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = ZEUS_ETH0_PHYS + 2, + .end = ZEUS_ETH0_PHYS + 3, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO), + .end = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct resource zeus_dm9k1_resource[] = { + [0] = { + .start = ZEUS_ETH1_PHYS, + .end = ZEUS_ETH1_PHYS + 1, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = ZEUS_ETH1_PHYS + 2, + .end = ZEUS_ETH1_PHYS + 3, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO), + .end = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct dm9000_plat_data zeus_dm9k_platdata = { + .flags = DM9000_PLATF_16BITONLY, +}; + +static struct platform_device zeus_dm9k0_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(zeus_dm9k0_resource), + .resource = zeus_dm9k0_resource, + .dev = { + .platform_data = &zeus_dm9k_platdata, + } +}; + +static struct platform_device zeus_dm9k1_device = { + .name = "dm9000", + .id = 1, + .num_resources = ARRAY_SIZE(zeus_dm9k1_resource), + .resource = zeus_dm9k1_resource, + .dev = { + .platform_data = &zeus_dm9k_platdata, + } +}; + +/* External SRAM */ +static struct resource zeus_sram_resource = { + .start = ZEUS_SRAM_PHYS, + .end = ZEUS_SRAM_PHYS + ZEUS_SRAM_SIZE * 2 - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device zeus_sram_device = { + .name = "pxa2xx-8bit-sram", + .id = 0, + .num_resources = 1, + .resource = &zeus_sram_resource, +}; + +/* SPI interface on SSP3 */ +static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = { + .num_chipselect = 1, + .enable_dma = 1, +}; + +/* CAN bus on SPI */ +static struct regulator_consumer_supply can_regulator_consumer = + REGULATOR_SUPPLY("vdd", "spi3.0"); + +static struct regulator_init_data can_regulator_init_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = &can_regulator_consumer, + .num_consumer_supplies = 1, +}; + +static struct fixed_voltage_config can_regulator_pdata = { + .supply_name = "CAN_SHDN", + .microvolts = 3300000, + .gpio = ZEUS_CAN_SHDN_GPIO, + .init_data = &can_regulator_init_data, +}; + +static struct platform_device can_regulator_device = { + .name = "reg-fixed-volage", + .id = 0, + .dev = { + .platform_data = &can_regulator_pdata, + }, +}; + +static struct mcp251x_platform_data zeus_mcp2515_pdata = { + .oscillator_frequency = 16*1000*1000, +}; + +static struct spi_board_info zeus_spi_board_info[] = { + [0] = { + .modalias = "mcp2515", + .platform_data = &zeus_mcp2515_pdata, + .irq = PXA_GPIO_TO_IRQ(ZEUS_CAN_GPIO), + .max_speed_hz = 1*1000*1000, + .bus_num = 3, + .mode = SPI_MODE_0, + .chip_select = 0, + }, +}; + +/* Leds */ +static struct gpio_led zeus_leds[] = { + [0] = { + .name = "zeus:yellow:1", + .default_trigger = "heartbeat", + .gpio = ZEUS_EXT0_GPIO(3), + .active_low = 1, + }, + [1] = { + .name = "zeus:yellow:2", + .default_trigger = "default-on", + .gpio = ZEUS_EXT0_GPIO(4), + .active_low = 1, + }, + [2] = { + .name = "zeus:yellow:3", + .default_trigger = "default-on", + .gpio = ZEUS_EXT0_GPIO(5), + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data zeus_leds_info = { + .leds = zeus_leds, + .num_leds = ARRAY_SIZE(zeus_leds), +}; + +static struct platform_device zeus_leds_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &zeus_leds_info, + }, +}; + +static void zeus_cf_reset(int state) +{ + u16 cpld_state = __raw_readw(ZEUS_CPLD_CONTROL); + + if (state) + cpld_state |= ZEUS_CPLD_CONTROL_CF_RST; + else + cpld_state &= ~ZEUS_CPLD_CONTROL_CF_RST; + + __raw_writew(cpld_state, ZEUS_CPLD_CONTROL); +} + +static struct arcom_pcmcia_pdata zeus_pcmcia_info = { + .cd_gpio = ZEUS_CF_CD_GPIO, + .rdy_gpio = ZEUS_CF_RDY_GPIO, + .pwr_gpio = ZEUS_CF_PWEN_GPIO, + .reset = zeus_cf_reset, +}; + +static struct platform_device zeus_pcmcia_device = { + .name = "zeus-pcmcia", + .id = -1, + .dev = { + .platform_data = &zeus_pcmcia_info, + }, +}; + +static struct resource zeus_max6369_resource = { + .start = ZEUS_CPLD_EXTWDOG_PHYS, + .end = ZEUS_CPLD_EXTWDOG_PHYS, + .flags = IORESOURCE_MEM, +}; + +struct platform_device zeus_max6369_device = { + .name = "max6369_wdt", + .id = -1, + .resource = &zeus_max6369_resource, + .num_resources = 1, +}; + +/* AC'97 */ +static pxa2xx_audio_ops_t zeus_ac97_info = { + .reset_gpio = 95, +}; + + +/* + * USB host + */ + +static struct regulator_consumer_supply zeus_ohci_regulator_supplies[] = { + REGULATOR_SUPPLY("vbus2", "pxa27x-ohci"), +}; + +static struct regulator_init_data zeus_ohci_regulator_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(zeus_ohci_regulator_supplies), + .consumer_supplies = zeus_ohci_regulator_supplies, +}; + +static struct fixed_voltage_config zeus_ohci_regulator_config = { + .supply_name = "vbus2", + .microvolts = 5000000, /* 5.0V */ + .gpio = ZEUS_USB2_PWREN_GPIO, + .enable_high = 1, + .startup_delay = 0, + .init_data = &zeus_ohci_regulator_data, +}; + +static struct platform_device zeus_ohci_regulator_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &zeus_ohci_regulator_config, + }, +}; + +static struct pxaohci_platform_data zeus_ohci_platform_data = { + .port_mode = PMM_NPS_MODE, + /* Clear Power Control Polarity Low and set Power Sense + * Polarity Low. Supply power to USB ports. */ + .flags = ENABLE_PORT_ALL | POWER_SENSE_LOW, +}; + +static void zeus_register_ohci(void) +{ + /* Port 2 is shared between host and client interface. */ + UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE; + + pxa_set_ohci_info(&zeus_ohci_platform_data); +} + +/* + * Flat Panel + */ + +static void zeus_lcd_power(int on, struct fb_var_screeninfo *si) +{ + gpio_set_value(ZEUS_LCD_EN_GPIO, on); +} + +static void zeus_backlight_power(int on) +{ + gpio_set_value(ZEUS_BKLEN_GPIO, on); +} + +static int zeus_setup_fb_gpios(void) +{ + int err; + + if ((err = gpio_request(ZEUS_LCD_EN_GPIO, "LCD_EN"))) + goto out_err; + + if ((err = gpio_direction_output(ZEUS_LCD_EN_GPIO, 0))) + goto out_err_lcd; + + if ((err = gpio_request(ZEUS_BKLEN_GPIO, "BKLEN"))) + goto out_err_lcd; + + if ((err = gpio_direction_output(ZEUS_BKLEN_GPIO, 0))) + goto out_err_bkl; + + return 0; + +out_err_bkl: + gpio_free(ZEUS_BKLEN_GPIO); +out_err_lcd: + gpio_free(ZEUS_LCD_EN_GPIO); +out_err: + return err; +} + +static struct pxafb_mode_info zeus_fb_mode_info[] = { + { + .pixclock = 39722, + + .xres = 640, + .yres = 480, + + .bpp = 16, + + .hsync_len = 63, + .left_margin = 16, + .right_margin = 81, + + .vsync_len = 2, + .upper_margin = 12, + .lower_margin = 31, + + .sync = 0, + }, +}; + +static struct pxafb_mach_info zeus_fb_info = { + .modes = zeus_fb_mode_info, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, + .pxafb_lcd_power = zeus_lcd_power, + .pxafb_backlight_power = zeus_backlight_power, +}; + +/* + * 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 zeus_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .detect_delay_ms = 250, + .gpio_card_detect = ZEUS_MMC_CD_GPIO, + .gpio_card_ro = ZEUS_MMC_WP_GPIO, + .gpio_card_ro_invert = 1, + .gpio_power = -1 +}; + +/* + * USB Device Controller + */ +static void zeus_udc_command(int cmd) +{ + switch (cmd) { + case PXA2XX_UDC_CMD_DISCONNECT: + pr_info("zeus: disconnecting USB client\n"); + UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE; + break; + + case PXA2XX_UDC_CMD_CONNECT: + pr_info("zeus: connecting USB client\n"); + UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE; + break; + } +} + +static struct pxa2xx_udc_mach_info zeus_udc_info = { + .udc_command = zeus_udc_command, +}; + +static struct platform_device *zeus_devices[] __initdata = { + &zeus_serial_device, + &zeus_mtd_devices[0], + &zeus_dm9k0_device, + &zeus_dm9k1_device, + &zeus_sram_device, + &zeus_leds_device, + &zeus_pcmcia_device, + &zeus_max6369_device, + &can_regulator_device, + &zeus_ohci_regulator_device, +}; + +#ifdef CONFIG_PM +static void zeus_power_off(void) +{ + local_irq_disable(); + cpu_suspend(PWRMODE_DEEPSLEEP, pxa27x_finish_suspend); +} +#else +#define zeus_power_off NULL +#endif + +#ifdef CONFIG_APM_EMULATION +static void zeus_get_power_status(struct apm_power_info *info) +{ + /* Power supply is always present */ + info->ac_line_status = APM_AC_ONLINE; + info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT; +} + +static inline void zeus_setup_apm(void) +{ + apm_get_power_status = zeus_get_power_status; +} +#else +static inline void zeus_setup_apm(void) +{ +} +#endif + +static int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio, + unsigned ngpio, void *context) +{ + int i; + u8 pcb_info = 0; + + for (i = 0; i < 8; i++) { + int pcb_bit = gpio + i + 8; + + if (gpio_request(pcb_bit, "pcb info")) { + dev_err(&client->dev, "Can't request pcb info %d\n", i); + continue; + } + + if (gpio_direction_input(pcb_bit)) { + dev_err(&client->dev, "Can't read pcb info %d\n", i); + gpio_free(pcb_bit); + continue; + } + + pcb_info |= !!gpio_get_value(pcb_bit) << i; + + gpio_free(pcb_bit); + } + + dev_info(&client->dev, "Zeus PCB version %d issue %d\n", + pcb_info >> 4, pcb_info & 0xf); + + return 0; +} + +static struct pca953x_platform_data zeus_pca953x_pdata[] = { + [0] = { .gpio_base = ZEUS_EXT0_GPIO_BASE, }, + [1] = { + .gpio_base = ZEUS_EXT1_GPIO_BASE, + .setup = zeus_get_pcb_info, + }, + [2] = { .gpio_base = ZEUS_USER_GPIO_BASE, }, +}; + +static struct i2c_board_info __initdata zeus_i2c_devices[] = { + { + I2C_BOARD_INFO("pca9535", 0x21), + .platform_data = &zeus_pca953x_pdata[0], + }, + { + I2C_BOARD_INFO("pca9535", 0x22), + .platform_data = &zeus_pca953x_pdata[1], + }, + { + I2C_BOARD_INFO("pca9535", 0x20), + .platform_data = &zeus_pca953x_pdata[2], + .irq = PXA_GPIO_TO_IRQ(ZEUS_EXTGPIO_GPIO), + }, + { I2C_BOARD_INFO("lm75a", 0x48) }, + { I2C_BOARD_INFO("24c01", 0x50) }, + { I2C_BOARD_INFO("isl1208", 0x6f) }, +}; + +static mfp_cfg_t zeus_pin_config[] __initdata = { + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO80_nCS_4, + GPIO33_nCS_5, + + GPIO22_GPIO, + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + GPIO119_USBH2_PWR, + GPIO120_USBH2_PEN, + + GPIO86_LCD_LDD_16, + GPIO87_LCD_LDD_17, + + GPIO102_GPIO, + GPIO104_CIF_DD_2, + GPIO105_CIF_DD_1, + + GPIO81_SSP3_TXD, + GPIO82_SSP3_RXD, + GPIO83_SSP3_SFRM, + GPIO84_SSP3_SCLK, + + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO79_PSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + GPIO36_GPIO, /* CF CD */ + GPIO97_GPIO, /* CF PWREN */ + GPIO99_GPIO, /* CF RDY */ +}; + +/* + * DM9k MSCx settings: SRAM, 16 bits + * 17 cycles delay first access + * 5 cycles delay next access + * 13 cycles recovery time + * faster device + */ +#define DM9K_MSC_VALUE 0xe4c9 + +static void __init zeus_init(void) +{ + u16 dm9000_msc = DM9K_MSC_VALUE; + u32 msc0, msc1; + + system_rev = __raw_readw(ZEUS_CPLD_VERSION); + pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f)); + + /* Fix timings for dm9000s (CS1/CS2)*/ + msc0 = (__raw_readl(MSC0) & 0x0000ffff) | (dm9000_msc << 16); + msc1 = (__raw_readl(MSC1) & 0xffff0000) | dm9000_msc; + __raw_writel(msc0, MSC0); + __raw_writel(msc1, MSC1); + + pm_power_off = zeus_power_off; + zeus_setup_apm(); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config)); + + platform_add_devices(zeus_devices, ARRAY_SIZE(zeus_devices)); + + zeus_register_ohci(); + + if (zeus_setup_fb_gpios()) + pr_err("Failed to setup fb gpios\n"); + else + pxa_set_fb_info(NULL, &zeus_fb_info); + + pxa_set_mci_info(&zeus_mci_platform_data); + pxa_set_udc_info(&zeus_udc_info); + pxa_set_ac97_info(&zeus_ac97_info); + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices)); + pxa2xx_set_spi_info(3, &pxa2xx_spi_ssp3_master_info); + spi_register_board_info(zeus_spi_board_info, ARRAY_SIZE(zeus_spi_board_info)); +} + +static struct map_desc zeus_io_desc[] __initdata = { + { + .virtual = (unsigned long)ZEUS_CPLD_VERSION, + .pfn = __phys_to_pfn(ZEUS_CPLD_VERSION_PHYS), + .length = 0x1000, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)ZEUS_CPLD_ISA_IRQ, + .pfn = __phys_to_pfn(ZEUS_CPLD_ISA_IRQ_PHYS), + .length = 0x1000, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)ZEUS_CPLD_CONTROL, + .pfn = __phys_to_pfn(ZEUS_CPLD_CONTROL_PHYS), + .length = 0x1000, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)ZEUS_PC104IO, + .pfn = __phys_to_pfn(ZEUS_PC104IO_PHYS), + .length = 0x00800000, + .type = MT_DEVICE, + }, +}; + +static void __init zeus_map_io(void) +{ + pxa27x_map_io(); + + iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc)); + + /* Clear PSPR to ensure a full restart on wake-up. */ + PMCR = PSPR = 0; + + /* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */ + OSCC |= OSCC_OON; + + /* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...). + * float chip selects and PCMCIA */ + PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP; +} + +MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS") + /* Maintainer: Marc Zyngier <maz@misterjones.org> */ + .atag_offset = 0x100, + .map_io = zeus_map_io, + .nr_irqs = ZEUS_NR_IRQS, + .init_irq = zeus_init_irq, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, + .init_machine = zeus_init, + .restart = pxa_restart, +MACHINE_END + diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 0cb65b5772f..77daea478e8 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -18,26 +18,24 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/gpio.h> #include <linux/pwm_backlight.h> #include <linux/smc91x.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/hardware.h> +#include <mach/pxa3xx.h> #include <mach/audio.h> -#include <mach/gpio.h> -#include <mach/pxafb.h> +#include <linux/platform_data/video-pxafb.h> #include <mach/zylonite.h> -#include <mach/mmc.h> -#include <mach/pxa27x_keypad.h> -#include <mach/pxa3xx_nand.h> +#include <linux/platform_data/mmc-pxamci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/keypad-pxa27x.h> +#include <linux/platform_data/mtd-nand-pxa3xx.h> #include "devices.h" #include "generic.h" -#define MAX_SLOTS 3 -struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; - int gpio_eth_irq; int gpio_debug_led1; int gpio_debug_led2; @@ -47,6 +45,16 @@ int wm9713_irq; int lcd_id; int lcd_orientation; +struct platform_device pxa_device_wm9713_audio = { + .name = "wm9713-codec", + .id = -1, +}; + +static void __init zylonite_init_wm9713_audio(void) +{ + platform_device_register(&pxa_device_wm9713_audio); +} + static struct resource smc91x_resources[] = { [0] = { .start = ZYLONITE_ETH_PHYS + 0x300, @@ -117,6 +125,7 @@ static struct platform_pwm_backlight_data zylonite_backlight_data = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 10000, + .enable_gpio = -1, }; static struct platform_device zylonite_backlight_device = { @@ -200,7 +209,7 @@ static void __init zylonite_init_lcd(void) platform_device_register(&zylonite_backlight_device); if (lcd_id & 0x20) { - set_pxa_fb_info(&zylonite_sharp_lcd_info); + pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info); return; } @@ -212,88 +221,35 @@ static void __init zylonite_init_lcd(void) else zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode; - set_pxa_fb_info(&zylonite_toshiba_lcd_info); + pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info); } #else static inline void zylonite_init_lcd(void) {} #endif #if defined(CONFIG_MMC) -static int zylonite_mci_ro(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - - return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp); -} - -static int zylonite_mci_init(struct device *dev, - irq_handler_t zylonite_detect_int, - void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int err, cd_irq, gpio_cd, gpio_wp; - - cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd); - gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd; - gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp; - - /* - * setup GPIO for Zylonite MMC controller - */ - err = gpio_request(gpio_cd, "mmc card detect"); - if (err) - goto err_request_cd; - gpio_direction_input(gpio_cd); - - err = gpio_request(gpio_wp, "mmc write protect"); - if (err) - goto err_request_wp; - gpio_direction_input(gpio_wp); - - err = request_irq(cd_irq, zylonite_detect_int, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC card detect", data); - if (err) { - printk(KERN_ERR "%s: MMC/SD/SDIO: " - "can't request card detect IRQ\n", __func__); - goto err_request_irq; - } - - return 0; - -err_request_irq: - gpio_free(gpio_wp); -err_request_wp: - gpio_free(gpio_cd); -err_request_cd: - return err; -} - -static void zylonite_mci_exit(struct device *dev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int cd_irq, gpio_cd, gpio_wp; - - cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd); - gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd; - gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp; - - free_irq(cd_irq, data); - gpio_free(gpio_cd); - gpio_free(gpio_wp); -} - static struct pxamci_platform_data zylonite_mci_platform_data = { - .detect_delay = 20, + .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = zylonite_mci_init, - .exit = zylonite_mci_exit, - .get_ro = zylonite_mci_ro, + .gpio_card_detect = EXT_GPIO(0), + .gpio_card_ro = EXT_GPIO(2), + .gpio_power = -1, }; static struct pxamci_platform_data zylonite_mci2_platform_data = { - .detect_delay = 20, + .detect_delay_ms= 200, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = EXT_GPIO(1), + .gpio_card_ro = EXT_GPIO(3), + .gpio_power = -1, +}; + +static struct pxamci_platform_data zylonite_mci3_platform_data = { + .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = EXT_GPIO(30), + .gpio_card_ro = EXT_GPIO(31), + .gpio_power = -1, }; static void __init zylonite_init_mmc(void) @@ -301,14 +257,14 @@ static void __init zylonite_init_mmc(void) pxa_set_mci_info(&zylonite_mci_platform_data); pxa3xx_set_mci2_info(&zylonite_mci2_platform_data); if (cpu_is_pxa310()) - pxa3xx_set_mci3_info(&zylonite_mci_platform_data); + pxa3xx_set_mci3_info(&zylonite_mci3_platform_data); } #else static inline void zylonite_init_mmc(void) {} #endif #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) -static unsigned int zylonite_matrix_key_map[] = { +static const unsigned int zylonite_matrix_key_map[] = { /* KEY(row, col, key_code) */ KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D), KEY(1, 0, KEY_E), KEY(1, 1, KEY_F), KEY(1, 2, KEY_G), KEY(1, 5, KEY_H), @@ -351,11 +307,15 @@ static unsigned int zylonite_matrix_key_map[] = { KEY(0, 3, KEY_AUX), /* contact */ }; +static struct matrix_keymap_data zylonite_matrix_keymap_data = { + .keymap = zylonite_matrix_key_map, + .keymap_size = ARRAY_SIZE(zylonite_matrix_key_map), +}; + static struct pxa27x_keypad_platform_data zylonite_keypad_info = { .matrix_key_rows = 8, .matrix_key_cols = 8, - .matrix_key_map = zylonite_matrix_key_map, - .matrix_key_map_size = ARRAY_SIZE(zylonite_matrix_key_map), + .matrix_keymap_data = &zylonite_matrix_keymap_data, .enable_rotary0 = 1, .rotary0_up_key = KEY_UP, @@ -411,8 +371,9 @@ static struct mtd_partition zylonite_nand_partitions[] = { static struct pxa3xx_nand_platform_data zylonite_nand_info = { .enable_arbiter = 1, - .parts = zylonite_nand_partitions, - .nr_parts = ARRAY_SIZE(zylonite_nand_partitions), + .num_cs = 1, + .parts[0] = zylonite_nand_partitions, + .nr_parts[0] = ARRAY_SIZE(zylonite_nand_partitions), }; static void __init zylonite_init_nand(void) @@ -423,8 +384,27 @@ static void __init zylonite_init_nand(void) static inline void zylonite_init_nand(void) {} #endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static struct pxaohci_platform_data zylonite_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT2 | + POWER_CONTROL_LOW | POWER_SENSE_LOW, +}; + +static void __init zylonite_init_ohci(void) +{ + pxa_set_ohci_info(&zylonite_ohci_info); +} +#else +static inline void zylonite_init_ohci(void) {} +#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */ + static void __init zylonite_init(void) { + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + /* board-processor specific initialization */ zylonite_pxa300_init(); zylonite_pxa320_init(); @@ -433,8 +413,8 @@ static void __init zylonite_init(void) * Note: We depend that the bootloader set * the correct value to MSC register for SMC91x. */ - smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq); - smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); + smc91x_resources[1].start = PXA_GPIO_TO_IRQ(gpio_eth_irq); + smc91x_resources[1].end = PXA_GPIO_TO_IRQ(gpio_eth_irq); platform_device_register(&smc91x_device); pxa_set_ac97_info(NULL); @@ -443,14 +423,17 @@ static void __init zylonite_init(void) zylonite_init_keypad(); zylonite_init_nand(); zylonite_init_leds(); + zylonite_init_ohci(); + zylonite_init_wm9713_audio(); } MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") - .phys_io = 0x40000000, - .boot_params = 0xa0000100, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .map_io = pxa_map_io, + .atag_offset = 0x100, + .map_io = pxa3xx_map_io, + .nr_irqs = ZYLONITE_NR_IRQS, .init_irq = pxa3xx_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa3xx_handle_irq, + .init_time = pxa_timer_init, .init_machine = zylonite_init, + .restart = pxa_restart, MACHINE_END diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 095f5c64823..869bce7c3f2 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -17,11 +17,11 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/i2c.h> -#include <linux/i2c/pca953x.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/platform_data/pca953x.h> +#include <linux/gpio.h> -#include <asm/gpio.h> -#include <mach/mfp-pxa300.h> -#include <mach/i2c.h> +#include <mach/pxa300.h> #include <mach/zylonite.h> #include "generic.h" @@ -72,6 +72,13 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO25_AC97_SDATA_IN_0, GPIO27_AC97_SDATA_OUT, GPIO28_AC97_SYNC, + GPIO17_GPIO, /* SDATA_IN_1 but unused - configure to GPIO */ + + /* SSP3 */ + GPIO91_SSP3_SCLK, + GPIO92_SSP3_FRM, + GPIO93_SSP3_TXD, + GPIO94_SSP3_RXD, /* WM9713 IRQ */ GPIO26_GPIO, @@ -113,9 +120,17 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO13_MMC2_CLK, GPIO14_MMC2_CMD, + /* USB Host */ + GPIO0_2_USBH_PEN, + GPIO1_2_USBH_PWR, + /* Standard I2C */ GPIO21_I2C_SCL, GPIO22_I2C_SDA, + + /* GPIO */ + GPIO18_GPIO | MFP_PULL_HIGH, /* GPIO Expander #0 INT_N */ + GPIO19_GPIO | MFP_PULL_HIGH, /* GPIO Expander #1 INT_N */ }; static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { @@ -182,10 +197,12 @@ static void __init zylonite_detect_lcd_panel(void) for (i = 0; i < NUM_LCD_DETECT_PINS; i++) { id = id << 1; gpio = mfp_to_gpio(lcd_detect_pins[i]); + gpio_request(gpio, "LCD_ID_PINS"); gpio_direction_input(gpio); if (gpio_get_value(gpio)) id = id | 0x1; + gpio_free(gpio); } /* lcd id, flush out bit 1 */ @@ -209,17 +226,17 @@ static struct pca953x_platform_data gpio_exp[] = { }, }; -struct i2c_board_info zylonite_i2c_board_info[] = { +static struct i2c_board_info zylonite_i2c_board_info[] = { { .type = "pca9539", .addr = 0x74, .platform_data = &gpio_exp[0], - .irq = IRQ_GPIO(18), + .irq = PXA_GPIO_TO_IRQ(18), }, { .type = "pca9539", .addr = 0x75, .platform_data = &gpio_exp[1], - .irq = IRQ_GPIO(19), + .irq = PXA_GPIO_TO_IRQ(19), }, }; @@ -241,10 +258,6 @@ void __init zylonite_pxa300_init(void) /* detect LCD panel */ zylonite_detect_lcd_panel(); - /* MMC card detect & write protect for controller 0 */ - zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0); - zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2); - /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26); @@ -259,10 +272,6 @@ void __init zylonite_pxa300_init(void) if (cpu_is_pxa310()) { pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg)); gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102); - - /* MMC card detect & write protect for controller 2 */ - zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30); - zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31); } /* GPIOs for Debug LEDs */ diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 9879d7da2df..9942bac4cf7 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -16,9 +16,9 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/gpio.h> -#include <mach/gpio.h> -#include <mach/mfp-pxa320.h> +#include <mach/pxa320.h> #include <mach/zylonite.h> #include "generic.h" @@ -68,6 +68,13 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO38_AC97_SYNC, GPIO39_AC97_BITCLK, GPIO40_AC97_nACRESET, + GPIO36_GPIO, /* SDATA_IN_1 but unused - configure to GPIO */ + + /* SSP3 */ + GPIO89_SSP3_SCLK, + GPIO90_SSP3_FRM, + GPIO91_SSP3_TXD, + GPIO92_SSP3_RXD, /* WM9713 IRQ */ GPIO15_GPIO, @@ -117,6 +124,10 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO28_MMC2_CLK, GPIO29_MMC2_CMD, + /* USB Host */ + GPIO2_2_USBH_PEN, + GPIO3_2_USBH_PWR, + /* Debug LEDs */ GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH, GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH, @@ -165,10 +176,12 @@ static void __init zylonite_detect_lcd_panel(void) for (i = 0; i < NUM_LCD_DETECT_PINS; i++) { id = id << 1; gpio = mfp_to_gpio(lcd_detect_pins[i]); + gpio_request(gpio, "LCD_ID_PINS"); gpio_direction_input(gpio); if (gpio_get_value(gpio)) id = id | 0x1; + gpio_free(gpio); } /* lcd id, flush out bit 1 */ @@ -196,10 +209,6 @@ void __init zylonite_pxa320_init(void) gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2); gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2); - /* MMC card detect & write protect for controller 0 */ - zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1); - zylonite_mmc_slot[0].gpio_wp = mfp_to_gpio(MFP_PIN_GPIO5); - /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO15); } |
