diff options
Diffstat (limited to 'arch/arm/mach-pxa')
43 files changed, 3451 insertions, 502 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 914bb33dab9..e8ee7ec9ff6 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -16,18 +16,24 @@ config CPU_PXA310 config CPU_PXA320 bool "PXA320 (codename Monahans-P)" +config CPU_PXA930 + bool "PXA930 (codename Tavor-P)" + endmenu endif -menu "Select target boards" - config ARCH_GUMSTIX bool "Gumstix XScale boards" help Say Y here if you intend to run this kernel on a Gumstix Full Function Minature Computer. +config MACH_GUMSTIX_F + bool "Basix, Connex, ws-200ax, ws-400ax systems" + depends on ARCH_GUMSTIX + select PXA25x + config ARCH_LUBBOCK bool "Intel DBPXA250 Development Platform" select PXA25x @@ -58,6 +64,57 @@ config PXA_SHARPSL SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa) handheld computer. +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" + depends on PXA_SHARPSL + select PXA25x + select PXA_SHARP_C7xx + +config MACH_SHEPHERD + bool "Enable Sharp SL-C750 (Shepherd) Support" + depends on PXA_SHARPSL + select PXA25x + select PXA_SHARP_C7xx + +config MACH_HUSKY + bool "Enable Sharp SL-C760 (Husky) Support" + depends on PXA_SHARPSL + select PXA25x + select PXA_SHARP_C7xx + +config MACH_AKITA + bool "Enable Sharp SL-1000 (Akita) Support" + depends on PXA_SHARPSL + select PXA27x + select PXA_SHARP_Cxx00 + select MACH_SPITZ + select I2C + select I2C_PXA + +config MACH_SPITZ + bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" + depends on PXA_SHARPSL + select PXA27x + select PXA_SHARP_Cxx00 + +config MACH_BORZOI + bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support" + depends on PXA_SHARPSL + select PXA27x + select PXA_SHARP_Cxx00 + +config MACH_TOSA + bool "Enable Sharp SL-6000x (Tosa) Support" + depends on PXA_SHARPSL + select PXA25x + config ARCH_PXA_ESERIES bool "PXA based Toshiba e-series PDAs" select PXA25x @@ -70,10 +127,19 @@ config MACH_E330 Say Y here if you intend to run this kernel on a Toshiba e330 family PDA. +config MACH_E350 + bool "Toshiba e350" + default y + depends on ARCH_PXA_ESERIES + help + Say Y here if you intend to run this kernel on a Toshiba + e350 family PDA. + config MACH_E740 bool "Toshiba e740" default y depends on ARCH_PXA_ESERIES + select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e740 family PDA. @@ -82,6 +148,7 @@ 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. @@ -98,6 +165,7 @@ 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. @@ -106,6 +174,10 @@ 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" select PXA27x @@ -115,7 +187,7 @@ config MACH_COLIBRI select PXA27x config MACH_ZYLONITE - bool "PXA3xx Development Platform" + bool "PXA3xx Development Platform (aka Zylonite)" select PXA3xx select HAVE_PWM @@ -124,6 +196,16 @@ config MACH_LITTLETON select PXA3xx select PXA_SSP +config MACH_TAVOREVB + bool "PXA930 Evaluation Board (aka TavorEVB)" + select PXA3xx + select PXA930 + +config MACH_SAAR + bool "PXA930 Handheld Platform (aka SAAR)" + select PXA3xx + select PXA930 + config MACH_ARMCORE bool "CompuLab CM-X270 modules" select PXA27x @@ -131,7 +213,6 @@ config MACH_ARMCORE config MACH_MAGICIAN bool "Enable HTC Magician Support" - depends on ARCH_PXA select PXA27x select IWMMXT @@ -139,18 +220,26 @@ config MACH_PCM027 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" select PXA27x select IWMMXT + select PXA_SSP -endmenu +config ARCH_PXA_PALM + bool "PXA based Palm PDAs" + select HAVE_PWM -choice - prompt "Used baseboard" - depends on MACH_PCM027 +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 - -endchoice + depends on MACH_PCM027 choice prompt "display on pcm990" @@ -167,88 +256,45 @@ config PCM990_DISPLAY_NONE endchoice -if ARCH_GUMSTIX - -choice - prompt "Select target Gumstix board" - -config MACH_GUMSTIX_F - bool "Basix, Connex, ws-200ax, ws-400ax systems" - select PXA25x - -endchoice - -endif +config PXA_EZX + bool "Motorola EZX Platform" + select PXA27x + select IWMMXT + select HAVE_PWM -if MACH_TRIZEPS4 +config MACH_EZX_A780 + bool "Motorola EZX A780" + default y + depends on PXA_EZX -choice - prompt "Select base board for Trizeps 4 module" +config MACH_EZX_E680 + bool "Motorola EZX E680" + default y + depends on PXA_EZX -config MACH_TRIZEPS4_CONXS - bool "ConXS Eval Board" +config MACH_EZX_A1200 + bool "Motorola EZX A1200" + default y + depends on PXA_EZX -config MACH_TRIZEPS4_ANY - bool "another Board" +config MACH_EZX_A910 + bool "Motorola EZX A910" + default y + depends on PXA_EZX -endchoice +config MACH_EZX_E6 + bool "Motorola EZX E6" + default y + depends on PXA_EZX -endif +config MACH_EZX_E2 + bool "Motorola EZX E2" + default y + depends on PXA_EZX endmenu -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" - depends on PXA_SHARPSL - select PXA25x - select PXA_SHARP_C7xx - -config MACH_SHEPHERD - bool "Enable Sharp SL-C750 (Shepherd) Support" - depends on PXA_SHARPSL - select PXA25x - select PXA_SHARP_C7xx - -config MACH_HUSKY - bool "Enable Sharp SL-C760 (Husky) Support" - depends on PXA_SHARPSL - select PXA25x - select PXA_SHARP_C7xx - -config MACH_AKITA - bool "Enable Sharp SL-1000 (Akita) Support" - depends on PXA_SHARPSL - select PXA27x - select PXA_SHARP_Cxx00 - select MACH_SPITZ - select I2C - select I2C_PXA - -config MACH_SPITZ - bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" - depends on PXA_SHARPSL - select PXA27x - select PXA_SHARP_Cxx00 - -config MACH_BORZOI - bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support" - depends on PXA_SHARPSL - select PXA27x - select PXA_SHARP_Cxx00 - -config MACH_TOSA - bool "Enable Sharp SL-6000x (Tosa) Support" - depends on PXA_SHARPSL - select PXA25x - config PXA25x bool help @@ -288,4 +334,13 @@ config PXA_PWM default BACKLIGHT_PWM help Enable support for PXA2xx/PXA3xx PWM controllers + +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. + endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c4dfbe87fc4..99ecbe7f850 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -4,7 +4,7 @@ # 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 + time.o gpio.o reset.o obj-$(CONFIG_PM) += pm.o sleep.o standby.o obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o @@ -18,6 +18,7 @@ obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.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 @@ -36,7 +37,12 @@ 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 +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 @@ -44,8 +50,11 @@ ifeq ($(CONFIG_MACH_ZYLONITE),y) obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o endif 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 @@ -59,3 +68,5 @@ obj-$(CONFIG_LEDS) += $(led-y) ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o endif + +obj-$(CONFIG_TOSA_BT) += tosa-bt.o diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index b4d04955dcb..630063ffa6f 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -101,21 +101,6 @@ unsigned long clk_get_rate(struct clk *clk) EXPORT_SYMBOL(clk_get_rate); -static void clk_gpio27_enable(struct clk *clk) -{ - pxa_gpio_mode(GPIO11_3_6MHz_MD); -} - -static void clk_gpio27_disable(struct clk *clk) -{ -} - -static const struct clkops clk_gpio27_ops = { - .enable = clk_gpio27_enable, - .disable = clk_gpio27_disable, -}; - - void clk_cken_enable(struct clk *clk) { CKEN |= 1 << clk->cken; @@ -131,14 +116,6 @@ const struct clkops clk_cken_ops = { .disable = clk_cken_disable, }; -static struct clk common_clks[] = { - { - .name = "GPIO27_CLK", - .ops = &clk_gpio27_ops, - .rate = 3686400, - }, -}; - void clks_register(struct clk *clks, size_t num) { int i; @@ -148,10 +125,3 @@ void clks_register(struct clk *clks, size_t num) list_add(&clks[i].node, &clocks); mutex_unlock(&clocks_mutex); } - -static int __init clk_init(void) -{ - clks_register(common_clks, ARRAY_SIZE(common_clks)); - return 0; -} -arch_initcall(clk_init); diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index 83cbfaba485..1ec8f9178aa 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -47,9 +47,42 @@ struct clk { .other = _other, \ } +#define INIT_CLK(_name, _ops, _rate, _delay, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .ops = _ops, \ + .rate = _rate, \ + .delay = _delay, \ + } + extern const struct clkops clk_cken_ops; void clk_cken_enable(struct clk *clk); void clk_cken_disable(struct clk *clk); +#ifdef CONFIG_PXA3xx +#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .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 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); diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c index 319c9ff3ab9..bcf0cde6ccc 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x270-pci.c @@ -5,7 +5,7 @@ * * Bits taken from various places. * - * Copyright (C) 2007 Compulab, Ltd. + * Copyright (C) 2007, 2008 Compulab, Ltd. * Mike Rapoport <mike@compulab.co.il> * * This program is free software; you can redistribute it and/or modify @@ -19,16 +19,16 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/irq.h> +#include <linux/gpio.h> #include <asm/mach/pci.h> -#include <asm/arch/cm-x270.h> #include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> #include <asm/mach-types.h> #include <asm/hardware/it8152.h> -unsigned long it8152_base_address = CMX270_IT8152_VIRT; +unsigned long it8152_base_address; +static int cmx270_it8152_irq_gpio; /* * Only first 64MB of memory can be accessed via PCI. @@ -42,7 +42,7 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, unsigned int sz = SZ_64M >> PAGE_SHIFT; if (machine_is_armcore()) { - pr_info("Adjusting zones for CM-x270\n"); + pr_info("Adjusting zones for CM-X270\n"); /* * Only adjust if > 64M on current system @@ -60,19 +60,20 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) { /* clear our parent irq */ - GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ); + GEDR(cmx270_it8152_irq_gpio) = GPIO_bit(cmx270_it8152_irq_gpio); it8152_irq_demux(irq, desc); } -void __cmx270_pci_init_irq(void) +void __cmx270_pci_init_irq(int irq_gpio) { it8152_init_irq(); - pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ)); - set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING); - set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ), - cmx270_it8152_irq_demux); + cmx270_it8152_irq_gpio = irq_gpio; + + set_irq_type(gpio_to_irq(irq_gpio), IRQT_RISING); + + set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux); } #ifdef CONFIG_PM @@ -115,8 +116,8 @@ 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-X270 is + unrealistic. Here we keep mapping for ATXBase and SB-X270. */ /* ATXBASE PCI slot */ if (slot == 7) diff --git a/arch/arm/mach-pxa/cm-x270-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h index ffe37b66f9a..48f532f4cb5 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.h +++ b/arch/arm/mach-pxa/cm-x270-pci.h @@ -1,13 +1,13 @@ -extern void __cmx270_pci_init_irq(void); +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 __cmx270_pci_init_irq -#define cmx270_pci_suspend __cmx270_pci_suspend -#define cmx270_pci_resume __cmx270_pci_resume +#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() do {} while (0) -#define cmx270_pci_suspend() do {} while (0) -#define cmx270_pci_resume() do {} while (0) +#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 01b9964acec..402e807eae5 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-pxa/cm-x270.c * - * Copyright (C) 2007 CompuLab, Ltd. + * Copyright (C) 2007, 2008 CompuLab, Ltd. * Mike Rapoport <mike@compulab.co.il> * * This program is free software; you can redistribute it and/or modify @@ -9,44 +9,156 @@ * published by the Free Software Foundation. */ -#include <linux/types.h> -#include <linux/pm.h> -#include <linux/fb.h> #include <linux/platform_device.h> -#include <linux/irq.h> #include <linux/sysdev.h> -#include <linux/io.h> -#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio.h> #include <linux/dm9000.h> #include <linux/rtc-v3020.h> -#include <linux/serial_8250.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 <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> -#include <asm/arch/pxa2xx-gpio.h> +#include <asm/arch/mfp-pxa27x.h> +#include <asm/arch/pxa-regs.h> #include <asm/arch/audio.h> #include <asm/arch/pxafb.h> #include <asm/arch/ohci.h> #include <asm/arch/mmc.h> #include <asm/arch/bitfield.h> -#include <asm/arch/cm-x270.h> #include <asm/hardware/it8152.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) + #define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) #define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) -static struct resource cmx270_dm9k_resource[] = { +/* 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) + +/* MMC power enable */ +#define GPIO105_MMC_POWER (105) + +static unsigned long cmx270_pin_config[] = { + /* AC'97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO98_AC97_SYSCLK, + GPIO113_AC97_nRESET, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* MCI controller */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + + /* LCD */ + 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, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* SSP1 */ + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO25_SSP1_TXD, + GPIO26_SSP1_RXD, + + /* SSP2 */ + GPIO19_SSP2_SCLK, + GPIO14_SSP2_SFRM, + GPIO87_SSP2_TXD, + GPIO88_SSP2_RXD, + + /* PC Card */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* SDRAM and local bus */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO33_nCS_5, + GPIO49_nPWE, + GPIO18_RDY, + + /* GPIO */ + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, + GPIO105_GPIO | MFP_LPM_DRIVE_HIGH, /* MMC/SD power */ + GPIO53_GPIO, /* PC card reset */ + + /* NAND controls */ + GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ + GPIO89_GPIO, /* NAND Ready/Busy */ + + /* interrupts */ + GPIO10_GPIO, /* DM9000 interrupt */ + GPIO83_GPIO, /* MMC card detect */ +}; + +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource cmx270_dm9000_resource[] = { [0] = { .start = DM9000_PHYS_BASE, .end = DM9000_PHYS_BASE + 4, @@ -64,31 +176,45 @@ static struct resource cmx270_dm9k_resource[] = { } }; -/* for the moment we limit ourselves to 32bit IO until some - * better IO routines can be written and tested - */ -static struct dm9000_plat_data cmx270_dm9k_platdata = { +static struct dm9000_plat_data cmx270_dm9000_platdata = { .flags = DM9000_PLATF_32BITONLY, }; -/* Ethernet device */ -static struct platform_device cmx270_device_dm9k = { +static struct platform_device cmx270_dm9000_device = { .name = "dm9000", .id = 0, - .num_resources = ARRAY_SIZE(cmx270_dm9k_resource), - .resource = cmx270_dm9k_resource, + .num_resources = ARRAY_SIZE(cmx270_dm9000_resource), + .resource = cmx270_dm9000_resource, .dev = { - .platform_data = &cmx270_dm9k_platdata, + .platform_data = &cmx270_dm9000_platdata, } }; -/* touchscreen controller */ +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, }; -/* RTC */ +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[] = { [0] = { .start = RTC_PHYS_BASE, @@ -111,28 +237,67 @@ static struct platform_device cmx270_rtc_device = { } }; -/* - * CM-X270 LEDs - */ +static void __init cmx270_init_rtc(void) +{ + platform_device_register(&cmx270_rtc_device); +} +#else +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 = "cm-x270-led", + .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; static struct resource cmx270_2700G_resource[] = { /* frame buffer memory including ODFB and External SDRAM */ [0] = { - .start = MARATHON_PHYS, - .end = MARATHON_PHYS + 0x02000000, + .start = PXA_CS2_PHYS, + .end = PXA_CS2_PHYS + 0x01ffffff, .flags = IORESOURCE_MEM, }, /* Marathon registers */ [1] = { - .start = MARATHON_PHYS + 0x03fe0000, - .end = MARATHON_PHYS + 0x03ffffff, + .start = PXA_CS2_PHYS + 0x03fe0000, + .end = PXA_CS2_PHYS + 0x03ffffff, .flags = IORESOURCE_MEM, }, }; @@ -200,43 +365,15 @@ static struct platform_device cmx270_2700G = { .id = -1, }; -static u64 ata_dma_mask = ~(u64)0; - -static struct platform_device cmx270_ata = { - .name = "pata_cm_x270", - .id = -1, - .dev = { - .dma_mask = &ata_dma_mask, - .coherent_dma_mask = 0xffffffff, - }, -}; - -/* platform devices */ -static struct platform_device *platform_devices[] __initdata = { - &cmx270_device_dm9k, - &cmx270_rtc_device, - &cmx270_2700G, - &cmx270_led_device, - &cmx270_ts_device, - &cmx270_ata, -}; - -/* Map PCI companion and IDE/General Purpose CS statically */ -static struct map_desc cmx270_io_desc[] __initdata = { - [0] = { /* IDE/general purpose space */ - .virtual = CMX270_IDE104_VIRT, - .pfn = __phys_to_pfn(CMX270_IDE104_PHYS), - .length = SZ_64M - SZ_8M, - .type = MT_DEVICE - }, - [1] = { /* PCI bridge */ - .virtual = CMX270_IT8152_VIRT, - .pfn = __phys_to_pfn(CMX270_IT8152_PHYS), - .length = SZ_64M, - .type = MT_DEVICE - }, -}; +static void __init cmx270_init_2700G(void) +{ + platform_device_register(&cmx270_2700G); +} +#else +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 @@ -446,7 +583,16 @@ static int __init cmx270_set_display(char *str) */ __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 */ @@ -461,35 +607,37 @@ static struct pxaohci_platform_data cmx270_ohci_platform_data = { .init = cmx270_ohci_init, }; +static void __init cmx270_init_ohci(void) +{ + pxa_set_ohci_info(&cmx270_ohci_platform_data); +} +#else +static inline void cmx270_init_ohci(void) {} +#endif +#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) static int cmx270_mci_init(struct device *dev, irq_handler_t cmx270_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); - - /* SB-X270 uses GPIO105 as SD power enable */ - pxa_gpio_mode(105 | GPIO_OUT); + err = gpio_request(GPIO105_MMC_POWER, "MMC/SD power"); + if (err) { + dev_warn(dev, "power gpio unavailable\n"); + return err; + } - /* card detect IRQ on GPIO 83 */ - pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ)); + 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) - printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't" - " request MMC card detect IRQ\n"); + 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; } @@ -499,17 +647,18 @@ 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) { - printk(KERN_DEBUG "%s: on\n", __func__); - GPCR(105) = GPIO_bit(105); + dev_dbg(dev, "power on\n"); + gpio_set_value(GPIO105_MMC_POWER, 0); } else { - GPSR(105) = GPIO_bit(105); - printk(KERN_DEBUG "%s: off\n", __func__); + 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 = { @@ -519,6 +668,14 @@ static struct pxamci_platform_data cmx270_mci_platform_data = { .exit = cmx270_mci_exit, }; +static void __init cmx270_init_mmc(void) +{ + pxa_set_mci_info(&cmx270_mci_platform_data); +} +#else +static inline void cmx270_init_mmc(void) {} +#endif + #ifdef CONFIG_PM static unsigned long sleep_save_msc[10]; @@ -580,53 +737,63 @@ static int __init cmx270_pm_init(void) static int __init cmx270_pm_init(void) { return 0; } #endif -static void __init cmx270_init(void) +#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) +static void __init cmx270_init_ac97(void) { - cmx270_pm_init(); - - set_pxa_fb_info(cmx270_display); - - /* register CM-X270 platform devices */ - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); pxa_set_ac97_info(NULL); +} +#else +static inline void cmx270_init_ac97(void) {} +#endif - /* set MCI and OHCI platform parameters */ - pxa_set_mci_info(&cmx270_mci_platform_data); - pxa_set_ohci_info(&cmx270_ohci_platform_data); - - /* This enables the STUART */ - pxa_gpio_mode(GPIO46_STRXD_MD); - pxa_gpio_mode(GPIO47_STTXD_MD); +static void __init cmx270_init(void) +{ + cmx270_pm_init(); - /* This enables the BTUART */ - pxa_gpio_mode(GPIO42_BTRXD_MD); - pxa_gpio_mode(GPIO43_BTTXD_MD); - pxa_gpio_mode(GPIO44_BTCTS_MD); - pxa_gpio_mode(GPIO45_BTRTS_MD); + pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); + + 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(); } static void __init cmx270_init_irq(void) { pxa27x_init_irq(); + cmx270_pci_init_irq(GPIO22_IT8152_IRQ); +} - cmx270_pci_init_irq(); +#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 + }, +}; - /* Setup interrupt for dm9000 */ - pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ)); - set_irq_type(CMX270_ETHIRQ, IRQT_RISING); +static void __init cmx270_map_io(void) +{ + pxa_map_io(); + iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); - /* Setup interrupt for 2700G */ - pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ)); - set_irq_type(CMX270_GFXIRQ, IRQT_FALLING); + it8152_base_address = CMX270_IT8152_VIRT; } - +#else static void __init cmx270_map_io(void) { pxa_map_io(); - iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); } - +#endif MACHINE_START(ARMCORE, "Compulab CM-x270") .boot_params = 0xa0000100, diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index b37671b7188..e58504edb14 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -465,6 +465,7 @@ static void corgi_irda_transceiver_mode(struct device *dev, int mode) 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); } static struct pxaficp_platform_data corgi_ficp_platform_data = { diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index a6f2390ce66..84489dc51d8 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -13,8 +13,10 @@ #include <asm/arch/mfp-pxa27x.h> #include <asm/arch/ohci.h> #include <asm/arch/pxa27x_keypad.h> +#include <asm/arch/pxa2xx_spi.h> #include <asm/arch/camera.h> #include <asm/arch/audio.h> +#include <asm/arch/pxa3xx_nand.h> #include "devices.h" #include "generic.h" @@ -830,4 +832,63 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) pxa_register_device(&pxa3xx_device_mci3, info); } +static struct resource pxa3xx_resources_nand[] = { + [0] = { + .start = 0x43100000, + .end = 0x43100053, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NAND, + .end = IRQ_NAND, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for Data DMA */ + .start = 97, + .end = 97, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for Command DMA */ + .start = 99, + .end = 99, + .flags = IORESOURCE_DMA, + }, +}; + +static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32); + +struct platform_device pxa3xx_device_nand = { + .name = "pxa3xx-nand", + .id = -1, + .dev = { + .dma_mask = &pxa3xx_nand_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_nand), + .resource = pxa3xx_resources_nand, +}; + +void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_nand, info); +} #endif /* CONFIG_PXA3xx */ + +/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. + * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ +void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) +{ + struct platform_device *pd; + + pd = platform_device_alloc("pxa2xx-spi", id); + if (pd == NULL) { + printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n", + id); + return; + } + + pd->dev.platform_data = info; + platform_device_add(pd); +} diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index b852eb18daa..887c738f591 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -31,4 +31,6 @@ extern struct platform_device pxa25x_device_pwm1; extern struct platform_device pxa27x_device_pwm0; extern struct platform_device pxa27x_device_pwm1; +extern struct platform_device pxa3xx_device_nand; + void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/e400_lcd.c b/arch/arm/mach-pxa/e400_lcd.c new file mode 100644 index 00000000000..16c02363062 --- /dev/null +++ b/arch/arm/mach-pxa/e400_lcd.c @@ -0,0 +1,56 @@ +/* + * 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 <asm/arch/pxa-regs.h> +#include <asm/arch/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 new file mode 100644 index 00000000000..26bd599af17 --- /dev/null +++ b/arch/arm/mach-pxa/e740_lcd.c @@ -0,0 +1,123 @@ +/* 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 new file mode 100644 index 00000000000..75edc3b5390 --- /dev/null +++ b/arch/arm/mach-pxa/e750_lcd.c @@ -0,0 +1,109 @@ +/* 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 new file mode 100644 index 00000000000..e6aeab0ebc2 --- /dev/null +++ b/arch/arm/mach-pxa/e800_lcd.c @@ -0,0 +1,159 @@ +/* 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 1bf68074992..e5cc6ca63c7 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -1,7 +1,7 @@ /* - * Support for CompuLab EM-x270 platform + * Support for CompuLab EM-X270 platform * - * Copyright (C) 2007 CompuLab, Ltd. + * Copyright (C) 2007, 2008 CompuLab, Ltd. * Author: Mike Rapoport <mike@compulab.co.il> * * This program is free software; you can redistribute it and/or modify @@ -14,31 +14,159 @@ #include <linux/dm9000.h> #include <linux/rtc-v3020.h> - #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> +#include <linux/gpio.h> #include <asm/mach-types.h> - #include <asm/mach/arch.h> +#include <asm/arch/mfp-pxa27x.h> #include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> #include <asm/arch/pxa27x-udc.h> #include <asm/arch/audio.h> #include <asm/arch/pxafb.h> #include <asm/arch/ohci.h> #include <asm/arch/mmc.h> -#include <asm/arch/bitfield.h> +#include <asm/arch/pxa27x_keypad.h> #include "generic.h" /* GPIO IRQ usage */ -#define EM_X270_MMC_PD (105) -#define EM_X270_ETHIRQ IRQ_GPIO(41) -#define EM_X270_MMC_IRQ IRQ_GPIO(13) +#define GPIO41_ETHIRQ (41) +#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[] = { + /* AC'97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO98_AC97_SYSCLK, + GPIO113_AC97_nRESET, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* MCI controller */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + + /* LCD */ + 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, + + /* QCI */ + GPIO84_CIF_FV, + GPIO25_CIF_LV, + GPIO53_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO81_CIF_DD_0, + GPIO55_CIF_DD_1, + GPIO51_CIF_DD_2, + GPIO50_CIF_DD_3, + GPIO52_CIF_DD_4, + GPIO48_CIF_DD_5, + GPIO17_CIF_DD_6, + GPIO12_CIF_DD_7, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* Keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO39_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, + GPIO91_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH, + GPIO36_KP_MKIN_7 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, + GPIO96_KP_MKOUT_6, + GPIO22_KP_MKOUT_7, + + /* SSP1 */ + GPIO26_SSP1_RXD, + GPIO23_SSP1_SCLK, + GPIO24_SSP1_SFRM, + GPIO57_SSP1_TXD, + + /* SSP2 */ + GPIO19_SSP2_SCLK, + GPIO14_SSP2_SFRM, + GPIO89_SSP2_TXD, + GPIO88_SSP2_RXD, + + /* SDRAM and local bus */ + GPIO15_nCS_1, + GPIO78_nCS_2, + GPIO79_nCS_3, + GPIO80_nCS_4, + GPIO49_nPWE, + GPIO18_RDY, + + /* GPIO */ + GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, + + /* power controls */ + GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ + GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */ + + /* NAND controls */ + GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ + GPIO56_GPIO, /* NAND Ready/Busy */ + + /* interrupts */ + GPIO13_GPIO, /* MMC card detect */ + GPIO41_GPIO, /* DM9000 interrupt */ +}; -static struct resource em_x270_dm9k_resource[] = { +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource em_x270_dm9000_resource[] = { [0] = { .start = PXA_CS2_PHYS, .end = PXA_CS2_PHYS + 3, @@ -56,32 +184,30 @@ static struct resource em_x270_dm9k_resource[] = { } }; -/* for the moment we limit ourselves to 32bit IO until some - * better IO routines can be written and tested - */ -static struct dm9000_plat_data em_x270_dm9k_platdata = { +static struct dm9000_plat_data em_x270_dm9000_platdata = { .flags = DM9000_PLATF_32BITONLY, }; -/* Ethernet device */ -static struct platform_device em_x270_dm9k = { +static struct platform_device em_x270_dm9000 = { .name = "dm9000", .id = 0, - .num_resources = ARRAY_SIZE(em_x270_dm9k_resource), - .resource = em_x270_dm9k_resource, + .num_resources = ARRAY_SIZE(em_x270_dm9000_resource), + .resource = em_x270_dm9000_resource, .dev = { - .platform_data = &em_x270_dm9k_platdata, + .platform_data = &em_x270_dm9000_platdata, } }; -/* WM9712 touchscreen controller. Hopefully the driver will make it to - * the mainstream sometime */ -static struct platform_device em_x270_ts = { - .name = "wm97xx-ts", - .id = -1, -}; +static void __init em_x270_init_dm9000(void) +{ + platform_device_register(&em_x270_dm9000); +} +#else +static inline void em_x270_init_dm9000(void) {} +#endif -/* RTC */ +/* V3020 RTC */ +#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) static struct resource em_x270_v3020_resource[] = { [0] = { .start = PXA_CS4_PHYS, @@ -104,20 +230,26 @@ static struct platform_device em_x270_rtc = { } }; -/* NAND flash */ -#define GPIO_NAND_CS (11) -#define GPIO_NAND_RB (56) +static void __init em_x270_init_rtc(void) +{ + platform_device_register(&em_x270_rtc); +} +#else +static inline void em_x270_init_rtc(void) {} +#endif +/* NAND flash */ +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) static inline void nand_cs_on(void) { - GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); + gpio_set_value(GPIO11_NAND_CS, 0); } static void nand_cs_off(void) { dsb(); - GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); + gpio_set_value(GPIO11_NAND_CS, 1); } /* hardware specific access to control-lines */ @@ -157,7 +289,7 @@ static int em_x270_nand_device_ready(struct mtd_info *mtd) { dsb(); - return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB); + return gpio_get_value(GPIO56_NAND_RB); } static struct mtd_partition em_x270_partition_info[] = { @@ -210,16 +342,35 @@ static struct platform_device em_x270_nand = { } }; -/* platform devices */ -static struct platform_device *platform_devices[] __initdata = { - &em_x270_dm9k, - &em_x270_ts, - &em_x270_rtc, - &em_x270_nand, -}; +static void __init em_x270_init_nand(void) +{ + int err; + err = gpio_request(GPIO11_NAND_CS, "NAND CS"); + if (err) { + pr_warning("EM-X270: failed to request NAND CS gpio\n"); + return; + } + + gpio_direction_output(GPIO11_NAND_CS, 1); + + err = gpio_request(GPIO56_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); + + platform_device_register(&em_x270_nand); +} +#else +static inline void em_x270_init_nand(void) {} +#endif /* PXA27x OHCI controller setup */ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) static int em_x270_ohci_init(struct device *dev) { /* Set the Power Control Polarity Low */ @@ -237,27 +388,23 @@ static struct pxaohci_platform_data em_x270_ohci_platform_data = { .init = em_x270_ohci_init, }; +static void __init em_x270_init_ohci(void) +{ + pxa_set_ohci_info(&em_x270_ohci_platform_data); +} +#else +static inline void em_x270_init_ohci(void) {} +#endif +/* MCI controller setup */ +#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) static int em_x270_mci_init(struct device *dev, irq_handler_t em_x270_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); - - /* EM-X270 uses GPIO13 as SD power enable */ - pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT); - - err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int, - IRQF_DISABLED | IRQF_TRIGGER_FALLING, - "MMC card detect", data); + int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "MMC card detect", data); if (err) { printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n", __func__, err); @@ -279,7 +426,8 @@ static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) static void em_x270_mci_exit(struct device *dev, void *data) { - free_irq(EM_X270_MMC_IRQ, data); + int irq = gpio_to_irq(GPIO13_MMC_CD); + free_irq(irq, data); } static struct pxamci_platform_data em_x270_mci_platform_data = { @@ -289,7 +437,16 @@ static struct pxamci_platform_data em_x270_mci_platform_data = { .exit = em_x270_mci_exit, }; +static void __init em_x270_init_mmc(void) +{ + pxa_set_mci_info(&em_x270_mci_platform_data); +} +#else +static inline void em_x270_init_mmc(void) {} +#endif + /* LCD 480x640 */ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static struct pxafb_mode_info em_x270_lcd_mode = { .pixclock = 50000, .bpp = 16, @@ -307,40 +464,96 @@ static struct pxafb_mode_info em_x270_lcd_mode = { static struct pxafb_mach_info em_x270_lcd = { .modes = &em_x270_lcd_mode, .num_modes = 1, - .cmap_inverse = 0, - .cmap_static = 0, - .lccr0 = LCCR0_PAS, - .lccr3 = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff), + .lcd_conn = LCD_COLOR_TFT_16BPP, }; - -static void __init em_x270_init(void) +static void __init em_x270_init_lcd(void) { - /* setup LCD */ set_pxa_fb_info(&em_x270_lcd); +} +#else +static inline void em_x270_init_lcd(void) {} +#endif - /* register EM-X270 platform devices */ - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) +static void __init em_x270_init_ac97(void) +{ pxa_set_ac97_info(NULL); +} +#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[] = { + 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), +}; - /* set MCI and OHCI platform parameters */ - pxa_set_mci_info(&em_x270_mci_platform_data); - pxa_set_ohci_info(&em_x270_ohci_platform_data); +struct pxa27x_keypad_platform_data em_x270_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), +}; + +static void __init em_x270_init_keypad(void) +{ + pxa_set_keypad_info(&em_x270_keypad_info); +} +#else +static inline void em_x270_init_keypad(void) {} +#endif - /* setup STUART GPIOs */ - pxa_gpio_mode(GPIO46_STRXD_MD); - pxa_gpio_mode(GPIO47_STTXD_MD); +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button gpio_keys_button[] = { + [0] = { + .desc = "sleep/wakeup", + .code = KEY_SUSPEND, + .type = EV_PWR, + .gpio = 1, + .wakeup = 1, + }, +}; - /* setup BTUART GPIOs */ - pxa_gpio_mode(GPIO42_BTRXD_MD); - pxa_gpio_mode(GPIO43_BTTXD_MD); - pxa_gpio_mode(GPIO44_BTCTS_MD); - pxa_gpio_mode(GPIO45_BTRTS_MD); +static struct gpio_keys_platform_data em_x270_gpio_keys_data = { + .buttons = gpio_keys_button, + .nbuttons = 1, +}; - /* Setup interrupt for dm9000 */ - set_irq_type(EM_X270_ETHIRQ, IRQT_RISING); +static struct platform_device em_x270_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &em_x270_gpio_keys_data, + }, +}; + +static void __init em_x270_init_gpio_keys(void) +{ + platform_device_register(&em_x270_gpio_keys); +} +#else +static inline void em_x270_init_gpio_keys(void) {} +#endif + +static void __init em_x270_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config)); + + em_x270_init_dm9000(); + em_x270_init_rtc(); + em_x270_init_nand(); + 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(); } -MACHINE_START(EM_X270, "Compulab EM-x270") +MACHINE_START(EM_X270, "Compulab EM-X270") .boot_params = 0xa0000100, .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index ee0ae93c876..c29b7b21c11 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -17,7 +17,7 @@ #include <asm/arch/hardware.h> #include <asm/mach-types.h> -#include <generic.h> +#include "generic.h" /* Only e800 has 128MB RAM */ static void __init eseries_fixup(struct machine_desc *desc, @@ -47,6 +47,19 @@ MACHINE_START(E330, "Toshiba e330") 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 + #ifdef CONFIG_MACH_E740 MACHINE_START(E740, "Toshiba e740") /* Maintainer: Ian Molton (spyro@f2s.com) */ diff --git a/arch/arm/mach-pxa/eseries_udc.c b/arch/arm/mach-pxa/eseries_udc.c new file mode 100644 index 00000000000..362847a1099 --- /dev/null +++ b/arch/arm/mach-pxa/eseries_udc.c @@ -0,0 +1,57 @@ +/* + * 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 <asm/arch/udc.h> +#include <asm/arch/eseries-gpio.h> +#include <asm/arch/hardware.h> +#include <asm/arch/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 new file mode 100644 index 00000000000..0143eed6539 --- /dev/null +++ b/arch/arm/mach-pxa/ezx.c @@ -0,0 +1,220 @@ +/* + * ezx.c - Common code for the EZX platform. + * + * Copyright (C) 2005-2006 Harald Welte <laforge@openezx.org>, + * 2007-2008 Daniel Ribeiro <drwyrm@gmail.com>, + * 2007-2008 Stefan Schmidt <stefan@datenfreihafen.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/pwm_backlight.h> + +#include <asm/setup.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/ohci.h> +#include <asm/arch/i2c.h> + +#include <asm/arch/mfp-pxa27x.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include "devices.h" +#include "generic.h" + +static struct platform_pwm_backlight_data ezx_backlight_data = { + .pwm_id = 0, + .max_brightness = 1023, + .dft_brightness = 1023, + .pwm_period_ns = 78770, +}; + +static struct platform_device ezx_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &ezx_backlight_data, + }, +}; + +static struct pxafb_mode_info mode_ezx_old = { + .pixclock = 150000, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 10, + .left_margin = 20, + .right_margin = 10, + .vsync_len = 2, + .upper_margin = 3, + .lower_margin = 2, + .sync = 0, +}; + +static struct pxafb_mach_info ezx_fb_info_1 = { + .modes = &mode_ezx_old, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_16BPP, +}; + +static struct pxafb_mode_info mode_72r89803y01 = { + .pixclock = 192308, + .xres = 240, + .yres = 320, + .bpp = 32, + .depth = 18, + .hsync_len = 10, + .left_margin = 20, + .right_margin = 10, + .vsync_len = 2, + .upper_margin = 3, + .lower_margin = 2, + .sync = 0, +}; + +static struct pxafb_mach_info ezx_fb_info_2 = { + .modes = &mode_72r89803y01, + .num_modes = 1, + .lcd_conn = LCD_COLOR_TFT_18BPP, +}; + +static struct platform_device *devices[] __initdata = { + &ezx_backlight_device, +}; + +static unsigned long ezx_pin_config[] __initdata = { + /* PWM backlight */ + GPIO16_PWM0_OUT, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* 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 void __init ezx_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); + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init ezx_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + /* 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); +} + +#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, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = &ezx_init, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_E680 +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, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = &ezx_init, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_A1200 +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, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = &ezx_init, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_A910 +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, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = &ezx_init, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_E6 +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, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = &ezx_init, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_EZX_E2 +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, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = &ezx_init, +MACHINE_END +#endif diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 530654474bb..dd759d03a9f 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/smc91x.h> #include <asm/types.h> #include <asm/setup.h> @@ -38,6 +39,7 @@ #include <asm/arch/pxafb.h> #include <asm/arch/ssp.h> #include <asm/arch/pxa27x_keypad.h> +#include <asm/arch/pxa3xx_nand.h> #include <asm/arch/littleton.h> #include "generic.h" @@ -101,18 +103,26 @@ static struct resource smc91x_resources[] = { [1] = { .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, } }; +static struct smc91x_platdata littleton_smc91x_info = { + .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | + SMC91X_NOWAIT | SMC91X_USE_DMA, +}; + static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &littleton_smc91x_info, + }, }; -#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULES) +#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)) @@ -311,9 +321,9 @@ static void littleton_init_lcd(void) } #else static inline void littleton_init_lcd(void) {}; -#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULES */ +#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */ -#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES) +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) static 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), @@ -361,6 +371,57 @@ static void __init littleton_init_keypad(void) static inline void littleton_init_keypad(void) {} #endif +#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +static struct mtd_partition littleton_nand_partitions[] = { + [0] = { + .name = "Bootloader", + .offset = 0, + .size = 0x060000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [1] = { + .name = "Kernel", + .offset = 0x060000, + .size = 0x200000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [2] = { + .name = "Filesystem", + .offset = 0x0260000, + .size = 0x3000000, /* 48M - rootfs */ + }, + [3] = { + .name = "MassStorage", + .offset = 0x3260000, + .size = 0x3d40000, + }, + [4] = { + .name = "BBT", + .offset = 0x6FA0000, + .size = 0x80000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* NOTE: we reserve some blocks at the end of the NAND flash for + * bad block management, and the max number of relocation blocks + * differs on different platforms. Please take care with it when + * defining the partition table. + */ +}; + +static struct pxa3xx_nand_platform_data littleton_nand_info = { + .enable_arbiter = 1, + .parts = littleton_nand_partitions, + .nr_parts = ARRAY_SIZE(littleton_nand_partitions), +}; + +static void __init littleton_init_nand(void) +{ + pxa3xx_set_nand_info(&littleton_nand_info); +} +#else +static inline void littleton_init_nand(void) {} +#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ + static void __init littleton_init(void) { /* initialize MFP configurations */ @@ -374,6 +435,7 @@ static void __init littleton_init(void) littleton_init_lcd(); littleton_init_keypad(); + littleton_init_nand(); } MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)") diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index a3fae413920..ac26423cd20 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -21,6 +21,7 @@ #include <linux/interrupt.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> +#include <linux/smc91x.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> @@ -226,14 +227,6 @@ static struct pxa2xx_spi_master pxa_ssp_master_info = { .num_chipselect = 0, }; -static struct platform_device pxa_ssp = { - .name = "pxa2xx-spi", - .id = 1, - .dev = { - .platform_data = &pxa_ssp_master_info, - }, -}; - static int lubbock_ads7846_pendown_state(void) { /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */ @@ -292,11 +285,18 @@ static struct resource smc91x_resources[] = { }, }; +static struct smc91x_platdata lubbock_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_2, +}; + static struct platform_device smc91x_device = { .name = "smc91x", .id = -1, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &lubbock_smc91x_info, + }, }; static struct resource flash_resources[] = { @@ -367,7 +367,6 @@ static struct platform_device *devices[] __initdata = { &smc91x_device, &lubbock_flash_device[0], &lubbock_flash_device[1], - &pxa_ssp, }; static struct pxafb_mode_info sharp_lm8v31_mode = { @@ -471,6 +470,7 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode) } else if (mode & IR_FIRMODE) { LUB_MISC_WR |= 1 << 4; } + pxa2xx_transceiver_mode(dev, mode); local_irq_restore(flags); } @@ -501,6 +501,7 @@ static void __init lubbock_init(void) lubbock_flash_data[flashboot].name = "boot-rom"; (void) platform_add_devices(devices, ARRAY_SIZE(devices)); + pxa2xx_set_spi_info(1, &pxa_ssp_master_info); spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); } diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 01b2fa79021..c9d274f0048 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -17,17 +17,15 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/delay.h> +#include <linux/gpio.h> #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/mfd/htc-egpio.h> #include <linux/mfd/htc-pasic3.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> #include <linux/mtd/physmap.h> #include <linux/pda_power.h> #include <linux/pwm_backlight.h> -#include <asm/gpio.h> #include <asm/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -44,7 +42,7 @@ #include "devices.h" #include "generic.h" -static unsigned long magician_pin_config[] = { +static unsigned long magician_pin_config[] __initdata = { /* SDRAM and Static Memory I/O Signals */ GPIO20_nSDCS_2, @@ -134,6 +132,7 @@ static unsigned long magician_pin_config[] = { 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 = { @@ -399,6 +398,7 @@ static struct platform_pwm_backlight_data backlight_data = { static struct platform_device backlight = { .name = "pwm-backlight", + .id = -1, .dev = { .parent = &pxa27x_device_pwm0.dev, .platform_data = &backlight_data, @@ -511,6 +511,37 @@ static struct platform_device pasic3 = { * 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; +} + static int magician_is_ac_online(void) { return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC); @@ -527,14 +558,24 @@ static void magician_set_charge(int 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); +} + static char *magician_supplicants[] = { "ds2760-battery.0", "backup-battery" }; 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), }; diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index f2e9e7c4da8..851ec2d9b69 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -26,6 +26,7 @@ #include <linux/input.h> #include <linux/gpio_keys.h> #include <linux/pwm_backlight.h> +#include <linux/smc91x.h> #include <asm/types.h> #include <asm/setup.h> @@ -110,9 +111,9 @@ static unsigned long mainstone_pin_config[] = { GPIO45_AC97_SYSCLK, /* Keypad */ - GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, - GPIO94_KP_DKIN_1 | WAKEUP_ON_LEVEL_HIGH, - GPIO95_KP_DKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO93_KP_DKIN_0, + GPIO94_KP_DKIN_1, + GPIO95_KP_DKIN_2, GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, @@ -240,11 +241,19 @@ static struct resource smc91x_resources[] = { } }; +static struct smc91x_platdata mainstone_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 = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &mainstone_smc91x_info, + }, }; static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv) @@ -455,6 +464,7 @@ static void mainstone_irda_transceiver_mode(struct device *dev, int mode) } else if (mode & IR_FIRMODE) { MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR; } + pxa2xx_transceiver_mode(dev, mode); if (mode & IR_OFF) { MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF; } else { @@ -513,7 +523,7 @@ static struct pxaohci_platform_data mainstone_ohci_platform_data = { .init = mainstone_ohci_init, }; -#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES) +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) static 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), diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index d1cdb4ecb0b..fd4545eab80 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -39,6 +39,28 @@ struct gpio_desc { 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 int __mfp_config_gpio(unsigned gpio, unsigned long c) { unsigned long gafr, mask = GPIO_bit(gpio); @@ -57,21 +79,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) else GPDR(gpio) &= ~mask; - /* low power state */ - switch (c & MFP_LPM_STATE_MASK) { - 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); + if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK)) return -EINVAL; - } /* give early warning if MFP_LPM_CAN_WAKEUP is set on the * configurations of those pins not able to wakeup @@ -91,6 +100,18 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) return 0; } +static inline int __mfp_validate(int mfp) +{ + int gpio = mfp_to_gpio(mfp); + + if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) { + pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio); + return -1; + } + + return gpio; +} + void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) { unsigned long flags; @@ -99,13 +120,9 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) for (i = 0, c = mfp_cfgs; i < num; i++, c++) { - gpio = mfp_to_gpio(MFP_PIN(*c)); - - if (!gpio_desc[gpio].valid) { - pr_warning("%s: GPIO%d is invalid pin\n", - __func__, gpio); + gpio = __mfp_validate(MFP_PIN(*c)); + if (gpio < 0) continue; - } local_irq_save(flags); @@ -116,6 +133,20 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) } } +void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm) +{ + unsigned long flags; + int gpio; + + gpio = __mfp_validate(mfp); + if (gpio < 0) + return; + + local_irq_save(flags); + __mfp_config_lpm(gpio, lpm); + local_irq_restore(flags); +} + int gpio_set_wake(unsigned int gpio, unsigned int on) { struct gpio_desc *d; diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c new file mode 100644 index 00000000000..408657a24f8 --- /dev/null +++ b/arch/arm/mach-pxa/palmtx.c @@ -0,0 +1,416 @@ +/* + * Hardware definitions for PalmTX + * + * Author: Marek Vasut <marek.vasut@gmail.com> + * + * Based on work of: + * Alex Osborne <ato@meshy.org> + * Cristiano P. <cristianop@users.sourceforge.net> + * Jan Herman <2hp@seznam.cz> + * Michal Hrusecky + * + * 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 <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/audio.h> +#include <asm/arch/palmtx.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/mfp-pxa27x.h> +#include <asm/arch/irda.h> +#include <asm/arch/pxa27x_keypad.h> +#include <asm/arch/udc.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmtx_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, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* IrDA */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* USB */ + GPIO13_GPIO, + + /* PCMCIA */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO79_PSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, +}; + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +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; + } + + 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 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 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 int palmtx_mci_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY); +} + +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, +}; + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +static unsigned int palmtx_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 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), + + .debounce_interval = 30, +}; + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +static struct gpio_keys_button palmtx_pxa_buttons[] = { + {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" }, +}; + +static struct gpio_keys_platform_data palmtx_pxa_keys_data = { + .buttons = palmtx_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmtx_pxa_buttons), +}; + +static struct platform_device palmtx_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmtx_pxa_keys_data, + }, +}; + +/****************************************************************************** + * 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) +{ + gpio_free(GPIO_NR_PALMTX_BL_POWER); + gpio_free(GPIO_NR_PALMTX_LCD_POWER); +} + +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, +}; + +/****************************************************************************** + * Power supply + ******************************************************************************/ +static int power_supply_init(struct device *dev) +{ + 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; +} + +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 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), +}; + +static struct platform_device power_supply = { + .name = "pda-power", + .id = -1, + .dev = { + .platform_data = &power_supply_info, + }, +}; + +/****************************************************************************** + * 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 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, +}; + +/****************************************************************************** + * 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, + .pfn = __phys_to_pfn(PALMTX_PCMCIA_PHYS), + .length = PALMTX_PCMCIA_SIZE, + .type = MT_DEVICE +}, +}; + +static void __init palmtx_map_io(void) +{ + pxa_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)); +} + +MACHINE_START(PALMTX, "Palm T|X") + .phys_io = PALMTX_PHYS_IO_START, + .io_pg_offst = io_p2v(0x40000000), + .boot_params = 0xa0000100, + .map_io = palmtx_map_io, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = palmtx_init +MACHINE_END diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index 3b945eb0aee..377f3be8ce5 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -24,7 +24,9 @@ #include <linux/platform_device.h> #include <linux/mtd/physmap.h> #include <linux/spi/spi.h> +#include <linux/spi/max7301.h> #include <linux/leds.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/arch/hardware.h> @@ -108,6 +110,32 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; +/* + * SPI host and devices + */ +static struct pxa2xx_spi_master pxa_ssp_master_info = { + .num_chipselect = 1, +}; + +static struct max7301_platform_data max7301_info = { + .base = -1, +}; + +/* bus_num must match id in pxa2xx_set_spi_info() call */ +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "max7301", + .platform_data = &max7301_info, + .max_speed_hz = 13000000, + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +/* + * NOR flash + */ static struct physmap_flash_data pcm027_flash_data = { .width = 4, }; @@ -190,6 +218,9 @@ static void __init pcm027_init(void) #ifdef CONFIG_MACH_PCM990_BASEBOARD pcm990_baseboard_init(); #endif + + pxa2xx_set_spi_info(1, &pxa_ssp_master_info); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); } static void __init pcm027_map_io(void) diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 5d87c7c866e..30023b00e47 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -33,14 +33,30 @@ #include <asm/arch/camera.h> #include <asm/mach/map.h> #include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> #include <asm/arch/audio.h> #include <asm/arch/mmc.h> #include <asm/arch/ohci.h> #include <asm/arch/pcm990_baseboard.h> #include <asm/arch/pxafb.h> +#include <asm/arch/mfp-pxa27x.h> #include "devices.h" +#include "generic.h" + +static unsigned long pcm990_pin_config[] __initdata = { + /* MMC */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + /* USB */ + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + /* PWM0 */ + GPIO16_PWM0_OUT, +}; /* * pcm990_lcd_power - control power supply to the LCD @@ -277,16 +293,6 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, { int err; - /* - * enable 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); - err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED, "MMC card detect", data); if (err) @@ -333,8 +339,6 @@ static struct pxamci_platform_data pcm990_mci_platform_data = { */ static int pcm990_ohci_init(struct device *dev) { - pxa_gpio_mode(PCM990_USB_OVERCURRENT); - pxa_gpio_mode(PCM990_USB_PWR_EN); /* * disable USB port 2 and 3 * power sense is active low @@ -361,23 +365,27 @@ static struct pxaohci_platform_data pcm990_ohci_platform_data = { * PXA27x Camera specific stuff */ #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) +static unsigned long pcm990_camera_pin_config[] = { + /* CIF */ + GPIO98_CIF_DD_0, + GPIO105_CIF_DD_1, + GPIO104_CIF_DD_2, + GPIO103_CIF_DD_3, + GPIO95_CIF_DD_4, + GPIO94_CIF_DD_5, + GPIO93_CIF_DD_6, + GPIO108_CIF_DD_7, + GPIO107_CIF_DD_8, + GPIO106_CIF_DD_9, + GPIO42_CIF_MCLK, + GPIO45_CIF_PCLK, + GPIO43_CIF_FV, + GPIO44_CIF_LV, +}; + static int pcm990_pxacamera_init(struct device *dev) { - pxa_gpio_mode(GPIO98_CIF_DD_0_MD); - pxa_gpio_mode(GPIO105_CIF_DD_1_MD); - pxa_gpio_mode(GPIO104_CIF_DD_2_MD); - pxa_gpio_mode(GPIO103_CIF_DD_3_MD); - pxa_gpio_mode(GPIO95_CIF_DD_4_MD); - pxa_gpio_mode(GPIO94_CIF_DD_5_MD); - pxa_gpio_mode(GPIO93_CIF_DD_6_MD); - pxa_gpio_mode(GPIO108_CIF_DD_7_MD); - pxa_gpio_mode(GPIO107_CIF_DD_8_MD); - pxa_gpio_mode(GPIO106_CIF_DD_9_MD); - pxa_gpio_mode(GPIO42_CIF_MCLK_MD); - pxa_gpio_mode(GPIO45_CIF_PCLK_MD); - pxa_gpio_mode(GPIO43_CIF_FV_MD); - pxa_gpio_mode(GPIO44_CIF_LV_MD); - + pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config)); return 0; } @@ -449,8 +457,10 @@ static struct map_desc pcm990_io_desc[] __initdata = { */ void __init pcm990_baseboard_init(void) { + pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config)); + /* register CPLD access */ - iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc)); + iotable_init(ARRAY_AND_SIZE(pcm990_io_desc)); /* register CPLD's IRQ controller */ pcm990_init_irq(); @@ -458,7 +468,6 @@ void __init pcm990_baseboard_init(void) #ifndef CONFIG_PCM990_DISPLAY_NONE set_pxa_fb_info(&pcm990_fbinfo); #endif - pxa_gpio_mode(GPIO16_PWM0_MD); platform_device_register(&pcm990_backlight_device); /* MMC */ @@ -473,9 +482,8 @@ void __init pcm990_baseboard_init(void) #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) pxa_set_camera_info(&pcm990_pxacamera_platform_data); - i2c_register_board_info(0, pcm990_i2c_devices, - ARRAY_SIZE(pcm990_i2c_devices)); + i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices)); #endif - printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n"); + printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n"); } diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index f81c10cafd4..39612cfa0b4 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -267,6 +267,7 @@ static void poodle_irda_transceiver_mode(struct device *dev, int mode) } 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 = { diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 4cd50e3005e..c5b845b935b 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -109,6 +109,52 @@ static const struct clkops clk_pxa25x_lcd_ops = { .getrate = clk_pxa25x_lcd_getrate, }; +static unsigned long gpio12_config_32k[] = { + GPIO12_32KHz, +}; + +static unsigned long gpio12_config_gpio[] = { + GPIO12_GPIO, +}; + +static void clk_gpio12_enable(struct clk *clk) +{ + pxa2xx_mfp_config(gpio12_config_32k, 1); +} + +static void clk_gpio12_disable(struct clk *clk) +{ + pxa2xx_mfp_config(gpio12_config_gpio, 1); +} + +static const struct clkops clk_pxa25x_gpio12_ops = { + .enable = clk_gpio12_enable, + .disable = clk_gpio12_disable, +}; + +static unsigned long gpio11_config_3m6[] = { + GPIO11_3_6MHz, +}; + +static unsigned long gpio11_config_gpio[] = { + GPIO11_GPIO, +}; + +static void clk_gpio11_enable(struct clk *clk) +{ + pxa2xx_mfp_config(gpio11_config_3m6, 1); +} + +static void clk_gpio11_disable(struct clk *clk) +{ + pxa2xx_mfp_config(gpio11_config_gpio, 1); +} + +static const struct clkops clk_pxa25x_gpio11_ops = { + .enable = clk_gpio11_enable, + .disable = clk_gpio11_disable, +}; + /* * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz) * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz @@ -128,6 +174,8 @@ static struct clk pxa25x_clks[] = { 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), @@ -145,7 +193,10 @@ static struct clk pxa25x_clks[] = { INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), }; -static struct clk gpio7_clk = INIT_CKOTHER("GPIO7_CK", &pxa25x_clks[4], NULL); +static struct clk pxa2xx_clk_aliases[] = { + INIT_CKOTHER("GPIO7_CLK", &pxa25x_clks[4], NULL), + INIT_CKOTHER("SA1111_CLK", &pxa25x_clks[5], NULL), +}; #ifdef CONFIG_PM @@ -293,7 +344,7 @@ 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_pxa25x()) + if (cpu_is_pxa255()) clks_register(&pxa25x_hwuart_clk, 1); if (cpu_is_pxa21x() || cpu_is_pxa25x()) { @@ -317,10 +368,10 @@ static int __init pxa25x_init(void) } /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ - if (cpu_is_pxa25x()) + if (cpu_is_pxa255()) ret = platform_device_register(&pxa_device_hwuart); - clks_register(&gpio7_clk, 1); + clks_register(pxa2xx_clk_aliases, ARRAY_SIZE(pxa2xx_clk_aliases)); return ret; } diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index 0a0d3877f21..da92e973388 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c @@ -15,10 +15,16 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/platform_device.h> #include <asm/hardware.h> +#include <asm/arch/pxa3xx-regs.h> #include <asm/arch/mfp-pxa300.h> +#include "generic.h" +#include "devices.h" +#include "clock.h" + static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO2, 0x00b4), @@ -79,15 +85,26 @@ 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 struct clk pxa310_clks[] = { + PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), +}; + 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)); } - if (cpu_is_pxa310()) + if (cpu_is_pxa310()) { pxa3xx_mfp_init_addr(pxa310_mfp_addr_map); + clks_register(ARRAY_AND_SIZE(pxa310_clks)); + } return 0; } diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c index 74128eb8f8d..c557c23a1ef 100644 --- a/arch/arm/mach-pxa/pxa320.c +++ b/arch/arm/mach-pxa/pxa320.c @@ -15,11 +15,17 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/platform_device.h> #include <asm/hardware.h> #include <asm/arch/mfp.h> +#include <asm/arch/pxa3xx-regs.h> #include <asm/arch/mfp-pxa320.h> +#include "generic.h" +#include "devices.h" +#include "clock.h" + static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO4, 0x0124), @@ -74,16 +80,17 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { MFP_ADDR_END, }; -static void __init pxa320_init_mfp(void) -{ - pxa3xx_init_mfp(); - pxa3xx_mfp_init_addr(pxa320_mfp_addr_map); -} +static struct clk pxa320_clks[] = { + PXA3xx_CKEN("NANDCLK", NAND, 104000000, 0, &pxa3xx_device_nand.dev), +}; static int __init pxa320_init(void) { - if (cpu_is_pxa320()) - pxa320_init_mfp(); + if (cpu_is_pxa320()) { + pxa3xx_init_mfp(); + pxa3xx_mfp_init_addr(pxa320_mfp_addr_map); + clks_register(ARRAY_AND_SIZE(pxa320_clks)); + } return 0; } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 15685d2b8f8..f491025a0c8 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -144,7 +144,7 @@ static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) return hsio_clk; } -static void clk_pxa3xx_cken_enable(struct clk *clk) +void clk_pxa3xx_cken_enable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); @@ -154,7 +154,7 @@ static void clk_pxa3xx_cken_enable(struct clk *clk) CKENB |= mask; } -static void clk_pxa3xx_cken_disable(struct clk *clk) +void clk_pxa3xx_cken_disable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); @@ -164,7 +164,7 @@ static void clk_pxa3xx_cken_disable(struct clk *clk) CKENB &= ~mask; } -static const struct clkops clk_pxa3xx_cken_ops = { +const struct clkops clk_pxa3xx_cken_ops = { .enable = clk_pxa3xx_cken_enable, .disable = clk_pxa3xx_cken_disable, }; @@ -196,24 +196,6 @@ static const struct clkops clk_pout_ops = { .disable = clk_pout_disable, }; -#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \ - { \ - .name = _name, \ - .dev = _dev, \ - .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, \ - } - static struct clk pxa3xx_clks[] = { { .name = "CLK_POUT", @@ -244,7 +226,6 @@ static struct clk pxa3xx_clks[] = { PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), - PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), }; #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c new file mode 100644 index 00000000000..9503897d049 --- /dev/null +++ b/arch/arm/mach-pxa/pxa930.c @@ -0,0 +1,190 @@ +/* + * linux/arch/arm/mach-pxa/pxa930.c + * + * Code specific to PXA930 + * + * Copyright (C) 2007-2008 Marvell Internation Ltd. + * + * 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/platform_device.h> +#include <linux/irq.h> +#include <linux/dma-mapping.h> + +#include <asm/hardware.h> +#include <asm/arch/mfp-pxa930.h> + +static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = { + + MFP_ADDR(GPIO0, 0x02e0), + MFP_ADDR(GPIO1, 0x02dc), + MFP_ADDR(GPIO2, 0x02e8), + MFP_ADDR(GPIO3, 0x02d8), + MFP_ADDR(GPIO4, 0x02e4), + MFP_ADDR(GPIO5, 0x02ec), + MFP_ADDR(GPIO6, 0x02f8), + MFP_ADDR(GPIO7, 0x02fc), + MFP_ADDR(GPIO8, 0x0300), + MFP_ADDR(GPIO9, 0x02d4), + MFP_ADDR(GPIO10, 0x02f4), + MFP_ADDR(GPIO11, 0x02f0), + MFP_ADDR(GPIO12, 0x0304), + MFP_ADDR(GPIO13, 0x0310), + MFP_ADDR(GPIO14, 0x0308), + MFP_ADDR(GPIO15, 0x030c), + MFP_ADDR(GPIO16, 0x04e8), + MFP_ADDR(GPIO17, 0x04f4), + MFP_ADDR(GPIO18, 0x04f8), + MFP_ADDR(GPIO19, 0x04fc), + MFP_ADDR(GPIO20, 0x0518), + MFP_ADDR(GPIO21, 0x051c), + MFP_ADDR(GPIO22, 0x04ec), + MFP_ADDR(GPIO23, 0x0500), + MFP_ADDR(GPIO24, 0x04f0), + MFP_ADDR(GPIO25, 0x0504), + MFP_ADDR(GPIO26, 0x0510), + MFP_ADDR(GPIO27, 0x0514), + MFP_ADDR(GPIO28, 0x0520), + MFP_ADDR(GPIO29, 0x0600), + MFP_ADDR(GPIO30, 0x0618), + MFP_ADDR(GPIO31, 0x0610), + MFP_ADDR(GPIO32, 0x060c), + MFP_ADDR(GPIO33, 0x061c), + MFP_ADDR(GPIO34, 0x0620), + MFP_ADDR(GPIO35, 0x0628), + MFP_ADDR(GPIO36, 0x062c), + MFP_ADDR(GPIO37, 0x0630), + MFP_ADDR(GPIO38, 0x0634), + MFP_ADDR(GPIO39, 0x0638), + MFP_ADDR(GPIO40, 0x063c), + MFP_ADDR(GPIO41, 0x0614), + MFP_ADDR(GPIO42, 0x0624), + MFP_ADDR(GPIO43, 0x0608), + MFP_ADDR(GPIO44, 0x0604), + MFP_ADDR(GPIO45, 0x050c), + MFP_ADDR(GPIO46, 0x0508), + MFP_ADDR(GPIO47, 0x02bc), + MFP_ADDR(GPIO48, 0x02b4), + MFP_ADDR(GPIO49, 0x02b8), + MFP_ADDR(GPIO50, 0x02c8), + MFP_ADDR(GPIO51, 0x02c0), + MFP_ADDR(GPIO52, 0x02c4), + MFP_ADDR(GPIO53, 0x02d0), + MFP_ADDR(GPIO54, 0x02cc), + MFP_ADDR(GPIO55, 0x029c), + MFP_ADDR(GPIO56, 0x02a0), + MFP_ADDR(GPIO57, 0x0294), + MFP_ADDR(GPIO58, 0x0298), + MFP_ADDR(GPIO59, 0x02a4), + MFP_ADDR(GPIO60, 0x02a8), + MFP_ADDR(GPIO61, 0x02b0), + MFP_ADDR(GPIO62, 0x02ac), + MFP_ADDR(GPIO63, 0x0640), + MFP_ADDR(GPIO64, 0x065c), + MFP_ADDR(GPIO65, 0x0648), + MFP_ADDR(GPIO66, 0x0644), + MFP_ADDR(GPIO67, 0x0674), + MFP_ADDR(GPIO68, 0x0658), + MFP_ADDR(GPIO69, 0x0654), + MFP_ADDR(GPIO70, 0x0660), + MFP_ADDR(GPIO71, 0x0668), + MFP_ADDR(GPIO72, 0x0664), + MFP_ADDR(GPIO73, 0x0650), + MFP_ADDR(GPIO74, 0x066c), + MFP_ADDR(GPIO75, 0x064c), + MFP_ADDR(GPIO76, 0x0670), + MFP_ADDR(GPIO77, 0x0678), + MFP_ADDR(GPIO78, 0x067c), + MFP_ADDR(GPIO79, 0x0694), + MFP_ADDR(GPIO80, 0x069c), + MFP_ADDR(GPIO81, 0x06a0), + MFP_ADDR(GPIO82, 0x06a4), + MFP_ADDR(GPIO83, 0x0698), + MFP_ADDR(GPIO84, 0x06bc), + MFP_ADDR(GPIO85, 0x06b4), + MFP_ADDR(GPIO86, 0x06b0), + MFP_ADDR(GPIO87, 0x06c0), + MFP_ADDR(GPIO88, 0x06c4), + MFP_ADDR(GPIO89, 0x06ac), + MFP_ADDR(GPIO90, 0x0680), + MFP_ADDR(GPIO91, 0x0684), + MFP_ADDR(GPIO92, 0x0688), + MFP_ADDR(GPIO93, 0x0690), + MFP_ADDR(GPIO94, 0x068c), + MFP_ADDR(GPIO95, 0x06a8), + MFP_ADDR(GPIO96, 0x06b8), + MFP_ADDR(GPIO97, 0x0410), + MFP_ADDR(GPIO98, 0x0418), + MFP_ADDR(GPIO99, 0x041c), + MFP_ADDR(GPIO100, 0x0414), + MFP_ADDR(GPIO101, 0x0408), + MFP_ADDR(GPIO102, 0x0324), + MFP_ADDR(GPIO103, 0x040c), + MFP_ADDR(GPIO104, 0x0400), + MFP_ADDR(GPIO105, 0x0328), + MFP_ADDR(GPIO106, 0x0404), + + MFP_ADDR(nXCVREN, 0x0204), + MFP_ADDR(DF_CLE_nOE, 0x020c), + MFP_ADDR(DF_nADV1_ALE, 0x0218), + MFP_ADDR(DF_SCLK_E, 0x0214), + MFP_ADDR(DF_SCLK_S, 0x0210), + MFP_ADDR(nBE0, 0x021c), + MFP_ADDR(nBE1, 0x0220), + MFP_ADDR(DF_nADV2_ALE, 0x0224), + MFP_ADDR(DF_INT_RnB, 0x0228), + MFP_ADDR(DF_nCS0, 0x022c), + MFP_ADDR(DF_nCS1, 0x0230), + MFP_ADDR(nLUA, 0x0254), + MFP_ADDR(nLLA, 0x0258), + MFP_ADDR(DF_nWE, 0x0234), + MFP_ADDR(DF_nRE_nOE, 0x0238), + MFP_ADDR(DF_ADDR0, 0x024c), + MFP_ADDR(DF_ADDR1, 0x0250), + MFP_ADDR(DF_ADDR2, 0x025c), + MFP_ADDR(DF_ADDR3, 0x0260), + MFP_ADDR(DF_IO0, 0x023c), + MFP_ADDR(DF_IO1, 0x0240), + MFP_ADDR(DF_IO2, 0x0244), + MFP_ADDR(DF_IO3, 0x0248), + MFP_ADDR(DF_IO4, 0x0264), + MFP_ADDR(DF_IO5, 0x0268), + MFP_ADDR(DF_IO6, 0x026c), + MFP_ADDR(DF_IO7, 0x0270), + MFP_ADDR(DF_IO8, 0x0274), + MFP_ADDR(DF_IO9, 0x0278), + MFP_ADDR(DF_IO10, 0x027c), + MFP_ADDR(DF_IO11, 0x0280), + MFP_ADDR(DF_IO12, 0x0284), + MFP_ADDR(DF_IO13, 0x0288), + MFP_ADDR(DF_IO14, 0x028c), + MFP_ADDR(DF_IO15, 0x0290), + + MFP_ADDR(GSIM_UIO, 0x0314), + MFP_ADDR(GSIM_UCLK, 0x0318), + MFP_ADDR(GSIM_UDET, 0x031c), + MFP_ADDR(GSIM_nURST, 0x0320), + + MFP_ADDR(PMIC_INT, 0x06c8), + + MFP_ADDR(RDY, 0x0200), + + MFP_ADDR_END, +}; + +static int __init pxa930_init(void) +{ + if (cpu_is_pxa930()) { + pxa3xx_init_mfp(); + pxa3xx_mfp_init_addr(pxa930_mfp_addr_map); + } + + return 0; +} + +core_initcall(pxa930_init); diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c new file mode 100644 index 00000000000..9d39dea57ce --- /dev/null +++ b/arch/arm/mach-pxa/reset.c @@ -0,0 +1,96 @@ +/* + * 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/module.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <asm/io.h> +#include <asm/proc-fns.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> + +static void do_hw_reset(void); + +static int reset_gpio = -1; + +int init_gpio_reset(int gpio) +{ + int rc; + + rc = gpio_request(gpio, "reset generator"); + if (rc) { + printk(KERN_ERR "Can't request reset_gpio\n"); + goto out; + } + + rc = gpio_direction_input(gpio); + if (rc) { + printk(KERN_ERR "Can't configure reset_gpio for input\n"); + gpio_free(gpio); + goto out; + } + +out: + if (!rc) + reset_gpio = gpio; + + return rc; +} + +/* + * Trigger GPIO reset. + * This covers various types of logic connecting gpio pin + * to RESET pins (nRESET or GPIO_RESET): + */ +static void do_gpio_reset(void) +{ + BUG_ON(reset_gpio == -1); + + /* drive it low */ + gpio_direction_output(reset_gpio, 0); + mdelay(2); + /* rising edge or drive high */ + gpio_set_value(reset_gpio, 1); + mdelay(2); + /* falling edge */ + gpio_set_value(reset_gpio, 0); + + /* give it some time */ + mdelay(10); + + WARN_ON(1); + /* fallback */ + do_hw_reset(); +} + +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 */ +} + +void arch_reset(char mode) +{ + if (cpu_is_pxa2xx()) + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + + switch (mode) { + case 's': + /* Jump into ROM at address 0 */ + cpu_reset(0); + break; + case 'h': + do_hw_reset(); + break; + case 'g': + do_gpio_reset(); + break; + } +} + diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c new file mode 100644 index 00000000000..d02bc6f8bb9 --- /dev/null +++ b/arch/arm/mach-pxa/saar.c @@ -0,0 +1,84 @@ +/* + * linux/arch/arm/mach-pxa/saar.c + * + * Support for the Marvell PXA930 Handheld Platform (aka SAAR) + * + * Copyright (C) 2007-2008 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/smc91x.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/hardware.h> +#include <asm/arch/pxa3xx-regs.h> +#include <asm/arch/mfp-pxa930.h> + +#include "devices.h" +#include "generic.h" + +/* SAAR MFP configurations */ +static mfp_cfg_t saar_mfp_cfg[] __initdata = { + /* Ethernet */ + DF_nCS1_nCS3, + GPIO97_GPIO, +}; + +#define SAAR_ETH_PHYS (0x14000000) + +static struct resource smc91x_resources[] = { + [0] = { + .start = (SAAR_ETH_PHYS + 0x300), + .end = (SAAR_ETH_PHYS + 0xfffff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), + .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct smc91x_platdata saar_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &saar_smc91x_info, + }, +}; + +static void __init saar_init(void) +{ + /* initialize MFP configurations */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg)); + + platform_device_register(&smc91x_device); +} + +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, + .init_irq = pxa3xx_init_irq, + .timer = &pxa_timer, + .init_machine = saar_init, +MACHINE_END diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index e7d0fcd9b43..762249c03de 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -38,6 +38,7 @@ #include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> +#include <asm/arch/pxa27x-udc.h> #include <asm/arch/irda.h> #include <asm/arch/mmc.h> #include <asm/arch/ohci.h> @@ -450,6 +451,7 @@ static void spitz_irda_transceiver_mode(struct device *dev, int mode) 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 @@ -459,6 +461,7 @@ static void akita_irda_transceiver_mode(struct device *dev, int mode) 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); } #endif @@ -529,11 +532,7 @@ static struct platform_device *devices[] __initdata = { static void spitz_poweroff(void) { - pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT); - GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET); - - mdelay(1000); - arm_machine_restart('h'); + arm_machine_restart('g'); } static void spitz_restart(char mode) @@ -547,6 +546,7 @@ static void spitz_restart(char mode) static void __init common_init(void) { + init_gpio_reset(SPITZ_GPIO_ON_RESET); pm_power_off = spitz_poweroff; arm_pm_restart = spitz_restart; diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 0bb31982fb6..89f38683787 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -14,13 +14,6 @@ * IO-based SSP applications and allows easy port setup for DMA access. * * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> - * - * Revision history: - * 22nd Aug 2003 Initial version. - * 20th Dec 2004 Added ssp_config for changing port config without - * closing the port. - * 4th Aug 2005 Added option to disable irq handler registration and - * cleaned up irq and clock detection. */ #include <linux/module.h> @@ -285,7 +278,7 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) goto out_region; dev->irq = ssp->irq; } else - dev->irq = 0; + dev->irq = NO_IRQ; /* turn on SSP port clock */ clk_enable(ssp->clk); @@ -306,7 +299,8 @@ void ssp_exit(struct ssp_dev *dev) struct ssp_device *ssp = dev->ssp; ssp_disable(dev); - free_irq(dev->irq, dev); + if (dev->irq != NO_IRQ) + free_irq(dev->irq, dev); clk_disable(ssp->clk); ssp_free(ssp); } @@ -360,6 +354,7 @@ static int __devinit ssp_probe(struct platform_device *pdev, int type) 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)) { diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c new file mode 100644 index 00000000000..ac283507e42 --- /dev/null +++ b/arch/arm/mach-pxa/tavorevb.c @@ -0,0 +1,84 @@ +/* + * linux/arch/arm/mach-pxa/tavorevb.c + * + * Support for the Marvell PXA930 Evaluation Board + * + * Copyright (C) 2007-2008 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/smc91x.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/hardware.h> +#include <asm/arch/pxa3xx-regs.h> +#include <asm/arch/mfp-pxa930.h> + +#include "devices.h" +#include "generic.h" + +/* Tavor EVB MFP configurations */ +static mfp_cfg_t tavorevb_mfp_cfg[] __initdata = { + /* Ethernet */ + DF_nCS1_nCS3, + GPIO47_GPIO, +}; + +#define TAVOREVB_ETH_PHYS (0x14000000) + +static struct resource smc91x_resources[] = { + [0] = { + .start = (TAVOREVB_ETH_PHYS + 0x300), + .end = (TAVOREVB_ETH_PHYS + 0xfffff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), + .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct smc91x_platdata tavorevb_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, + .dev = { + .platform_data = &tavorevb_smc91x_info, + }, +}; + +static void __init tavorevb_init(void) +{ + /* initialize MFP configurations */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(tavorevb_mfp_cfg)); + + platform_device_register(&smc91x_device); +} + +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, + .init_irq = pxa3xx_init_irq, + .timer = &pxa_timer, + .init_machine = tavorevb_init, +MACHINE_END diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c new file mode 100644 index 00000000000..7d8505466e5 --- /dev/null +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -0,0 +1,150 @@ +/* + * Bluetooth built-in chip control + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/rfkill.h> + +#include <asm/arch/tosa_bt.h> + +static void tosa_bt_on(struct tosa_bt_data *data) +{ + gpio_set_value(data->gpio_reset, 0); + gpio_set_value(data->gpio_pwr, 1); + gpio_set_value(data->gpio_reset, 1); + mdelay(20); + gpio_set_value(data->gpio_reset, 0); +} + +static void tosa_bt_off(struct tosa_bt_data *data) +{ + gpio_set_value(data->gpio_reset, 1); + mdelay(10); + gpio_set_value(data->gpio_pwr, 0); + gpio_set_value(data->gpio_reset, 0); +} + +static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) +{ + pr_info("BT_RADIO going: %s\n", + state == RFKILL_STATE_ON ? "on" : "off"); + + if (state == RFKILL_STATE_ON) { + 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 int tosa_bt_probe(struct platform_device *dev) +{ + int rc; + struct rfkill *rfk; + + struct tosa_bt_data *data = dev->dev.platform_data; + + rc = gpio_request(data->gpio_reset, "Bluetooth reset"); + if (rc) + goto err_reset; + rc = gpio_direction_output(data->gpio_reset, 0); + if (rc) + goto err_reset_dir; + rc = gpio_request(data->gpio_pwr, "Bluetooth power"); + if (rc) + goto err_pwr; + rc = gpio_direction_output(data->gpio_pwr, 0); + if (rc) + goto err_pwr_dir; + + rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); + 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; + + platform_set_drvdata(dev, rfk); + + return 0; + +err_rfkill: + if (rfk) + rfkill_free(rfk); + rfk = NULL; +err_rfk_alloc: + tosa_bt_off(data); +err_pwr_dir: + gpio_free(data->gpio_pwr); +err_pwr: +err_reset_dir: + gpio_free(data->gpio_reset); +err_reset: + return rc; +} + +static int __devexit 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) + rfkill_unregister(rfk); + rfk = NULL; + + tosa_bt_off(data); + + gpio_free(data->gpio_pwr); + gpio_free(data->gpio_reset); + + return 0; +} + +static struct platform_driver tosa_bt_driver = { + .probe = tosa_bt_probe, + .remove = __devexit_p(tosa_bt_remove), + + .driver = { + .name = "tosa-bt", + .owner = THIS_MODULE, + }, +}; + + +static int __init tosa_bt_init(void) +{ + return platform_driver_register(&tosa_bt_driver); +} + +static void __exit tosa_bt_exit(void) +{ + platform_driver_unregister(&tosa_bt_driver); +} + +module_init(tosa_bt_init); +module_exit(tosa_bt_exit); diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index ab4a9f57991..fea17ce6b55 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -18,30 +18,31 @@ #include <linux/major.h> #include <linux/fs.h> #include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/fb.h> #include <linux/mmc/host.h> +#include <linux/mfd/tc6393xb.h> +#include <linux/mfd/tmio.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> #include <linux/pm.h> -#include <linux/delay.h> #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/gpio.h> +#include <linux/pda_power.h> +#include <linux/rfkill.h> #include <asm/setup.h> -#include <asm/memory.h> #include <asm/mach-types.h> -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> #include <asm/arch/mfp-pxa25x.h> #include <asm/arch/irda.h> #include <asm/arch/i2c.h> #include <asm/arch/mmc.h> #include <asm/arch/udc.h> +#include <asm/arch/tosa_bt.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> #include <asm/arch/tosa.h> #include <asm/hardware/scoop.h> @@ -86,7 +87,7 @@ static unsigned long tosa_pin_config[] = { GPIO6_MMC_CLK, GPIO8_MMC_CS0, GPIO9_GPIO, /* Detect */ - // GPIO10 nSD_INT + GPIO10_GPIO, /* nSD_INT */ /* CF */ GPIO13_GPIO, /* CD_IRQ */ @@ -124,34 +125,34 @@ static unsigned long tosa_pin_config[] = { GPIO44_BTUART_CTS, GPIO45_BTUART_RTS, - /* IrDA */ - GPIO46_STUART_RXD, - GPIO47_STUART_TXD, - /* Keybd */ - 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, + 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, /* SPI */ GPIO81_SSP2_CLK_OUT, GPIO82_SSP2_FRM_OUT, GPIO83_SSP2_TXD, + + /* IrDA is managed in other way */ + GPIO46_GPIO, + GPIO47_GPIO, }; /* @@ -249,6 +250,15 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void 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); @@ -257,7 +267,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void goto err_irq; } - err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp"); + 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; @@ -266,7 +276,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void if (err) goto err_gpio_wp_dir; - err = gpio_request(TOSA_GPIO_PWR_ON, "sd_pwr"); + 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; @@ -275,8 +285,20 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void 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"); + goto err_gpio_int; + } + err = gpio_direction_input(TOSA_GPIO_nSD_INT); + if (err) + goto err_gpio_int_dir; + return 0; +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: @@ -285,6 +307,9 @@ err_gpio_wp_dir: 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; } @@ -306,9 +331,11 @@ static int tosa_mci_get_ro(struct device *dev) 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 = { @@ -322,29 +349,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = { /* * Irda */ +static void tosa_irda_transceiver_mode(struct device *dev, int mode) +{ + if (mode & IR_OFF) { + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0); + pxa2xx_transceiver_mode(dev, mode); + gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); + } else { + pxa2xx_transceiver_mode(dev, mode); + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1); + } +} + static int tosa_irda_startup(struct device *dev) { int ret; + ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX"); + if (ret) + goto err_tx; + ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); + if (ret) + goto err_tx_dir; + ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); if (ret) - return ret; + goto err_pwr; ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); if (ret) - gpio_free(TOSA_GPIO_IR_POWERDWN); + goto err_pwr_dir; - return ret; - } + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); -static void tosa_irda_shutdown(struct device *dev) -{ + return 0; + +err_pwr_dir: gpio_free(TOSA_GPIO_IR_POWERDWN); +err_pwr: +err_tx_dir: + gpio_free(TOSA_GPIO_IRDA_TX); +err_tx: + return ret; } -static void tosa_irda_transceiver_mode(struct device *dev, int mode) +static void tosa_irda_shutdown(struct device *dev) { - gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF)); + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); + gpio_free(TOSA_GPIO_IR_POWERDWN); + gpio_free(TOSA_GPIO_IRDA_TX); } static struct pxaficp_platform_data tosa_ficp_platform_data = { @@ -355,6 +408,70 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { }; /* + * Tosa AC IN + */ +static int tosa_power_init(struct device *dev) +{ + int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in"); + if (ret) + goto err_gpio_req; + + ret = gpio_direction_input(TOSA_GPIO_AC_IN); + if (ret) + goto err_gpio_in; + + return 0; + +err_gpio_in: + gpio_free(TOSA_GPIO_AC_IN); +err_gpio_req: + return ret; +} + +static void tosa_power_exit(struct device *dev) +{ + gpio_free(TOSA_GPIO_AC_IN); +} + +static int tosa_power_ac_online(void) +{ + return gpio_get_value(TOSA_GPIO_AC_IN) == 0; +} + +static char *tosa_ac_supplied_to[] = { + "main-battery", + "backup-battery", + "jacket-battery", +}; + +static struct pda_power_pdata tosa_power_data = { + .init = tosa_power_init, + .is_ac_online = tosa_power_ac_online, + .exit = tosa_power_exit, + .supplied_to = tosa_ac_supplied_to, + .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), +}; + +static struct resource tosa_power_resource[] = { + { + .name = "ac", + .start = gpio_to_irq(TOSA_GPIO_AC_IN), + .end = gpio_to_irq(TOSA_GPIO_AC_IN), + .flags = IORESOURCE_IRQ | + IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct platform_device tosa_power_device = { + .name = "pda-power", + .id = -1, + .dev.platform_data = &tosa_power_data, + .resource = tosa_power_resource, + .num_resources = ARRAY_SIZE(tosa_power_resource), +}; + +/* * Tosa Keyboard */ static struct platform_device tosakbd_device = { @@ -439,7 +556,7 @@ static struct gpio_led tosa_gpio_leds[] = { }, { .name = "tosa:blue:bluetooth", - .default_trigger = "none", + .default_trigger = "tosa-bt", .gpio = TOSA_GPIO_BT_LED, }, }; @@ -457,21 +574,184 @@ static struct platform_device tosaled_device = { }, }; +/* + * Toshiba Mobile IO Controller + */ +static struct resource tc6393xb_resources[] = { + [0] = { + .start = TOSA_LCDC_PHYS, + .end = TOSA_LCDC_PHYS + 0x3ffffff, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = TOSA_IRQ_GPIO_TC6393XB_INT, + .end = TOSA_IRQ_GPIO_TC6393XB_INT, + .flags = IORESOURCE_IRQ, + }, +}; + + +static int tosa_tc6393xb_enable(struct platform_device *dev) +{ + int rc; + + rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr"); + if (rc) + goto err_req_pclr; + rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); + if (rc) + goto err_req_suspend; + rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); + if (rc) + goto err_req_l3v; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); + if (rc) + goto err_dir_l3v; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0); + if (rc) + goto err_dir_suspend; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0); + if (rc) + goto err_dir_pclr; + + mdelay(1); + + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); + + mdelay(10); + + gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1); + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); + + return 0; +err_dir_pclr: +err_dir_suspend: +err_dir_l3v: + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); +err_req_l3v: + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); +err_req_suspend: + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); +err_req_pclr: + return rc; +} + +static int tosa_tc6393xb_disable(struct platform_device *dev) +{ + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); + + return 0; +} + +static int tosa_tc6393xb_resume(struct platform_device *dev) +{ + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); + mdelay(10); + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); + mdelay(10); + + return 0; +} + +static int tosa_tc6393xb_suspend(struct platform_device *dev) +{ + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0); + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0); + return 0; +} + +static struct mtd_partition tosa_nand_partition[] = { + { + .name = "smf", + .offset = 0, + .size = 7 * 1024 * 1024, + }, + { + .name = "root", + .offset = MTDPART_OFS_APPEND, + .size = 28 * 1024 * 1024, + }, + { + .name = "home", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = { + .options = 0, + .offs = 4, + .len = 2, + .pattern = scan_ff_pattern +}; + +static struct tmio_nand_data tosa_tc6393xb_nand_config = { + .num_partitions = ARRAY_SIZE(tosa_nand_partition), + .partition = tosa_nand_partition, + .badblock_pattern = &tosa_tc6393xb_nand_bbt, +}; + +static struct tc6393xb_platform_data tosa_tc6393xb_setup = { + .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, + + .enable = tosa_tc6393xb_enable, + .disable = tosa_tc6393xb_disable, + .suspend = tosa_tc6393xb_suspend, + .resume = tosa_tc6393xb_resume, + + .nand_data = &tosa_tc6393xb_nand_config, +}; + + +static struct platform_device tc6393xb_device = { + .name = "tc6393xb", + .id = -1, + .dev = { + .platform_data = &tosa_tc6393xb_setup, + }, + .num_resources = ARRAY_SIZE(tc6393xb_resources), + .resource = tc6393xb_resources, +}; + +static struct tosa_bt_data tosa_bt_data = { + .gpio_pwr = TOSA_GPIO_BT_PWR_EN, + .gpio_reset = TOSA_GPIO_BT_RESET, +}; + +static struct platform_device tosa_bt_device = { + .name = "tosa-bt", + .id = -1, + .dev.platform_data = &tosa_bt_data, +}; + + static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, + &tc6393xb_device, + &tosa_power_device, &tosakbd_device, &tosa_gpio_keys_device, &tosaled_device, + &tosa_bt_device, }; static void tosa_poweroff(void) { - gpio_direction_output(TOSA_GPIO_ON_RESET, 0); - gpio_set_value(TOSA_GPIO_ON_RESET, 1); - - mdelay(1000); - arm_machine_restart('h'); + arm_machine_restart('g'); } static void tosa_restart(char mode) @@ -485,10 +765,14 @@ static void tosa_restart(char mode) static void __init tosa_init(void) { + int dummy; + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); 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); + pm_power_off = tosa_poweroff; arm_pm_restart = tosa_restart; @@ -497,6 +781,10 @@ static void __init tosa_init(void) /* 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); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 61e24402308..dee7bf36f01 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -254,6 +254,7 @@ static void board_irda_mode(struct device *dev, int mode) /* Fast mode */ trizeps_conxs_ircr |= ConXS_IRCR_MODE; } + pxa2xx_transceiver_mode(dev, mode); if (mode & IR_OFF) { trizeps_conxs_ircr |= ConXS_IRCR_SD; } else { diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 66b446ca273..8fca6d890b7 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/pwm_backlight.h> +#include <linux/smc91x.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -29,6 +30,7 @@ #include <asm/arch/zylonite.h> #include <asm/arch/mmc.h> #include <asm/arch/pxa27x_keypad.h> +#include <asm/arch/pxa3xx_nand.h> #include "devices.h" #include "generic.h" @@ -37,6 +39,8 @@ struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; int gpio_eth_irq; +int gpio_debug_led1; +int gpio_debug_led2; int wm9713_irq; @@ -56,13 +60,57 @@ static struct resource smc91x_resources[] = { } }; +static struct smc91x_platdata zylonite_smc91x_info = { + .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | + SMC91X_NOWAIT | SMC91X_USE_DMA, +}; + static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, + .dev = { + .platform_data = &zylonite_smc91x_info, + }, +}; + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led zylonite_debug_leds[] = { + [0] = { + .name = "zylonite:yellow:1", + .default_trigger = "heartbeat", + }, + [1] = { + .name = "zylonite:yellow:2", + .default_trigger = "default-on", + }, }; +static struct gpio_led_platform_data zylonite_debug_leds_info = { + .leds = zylonite_debug_leds, + .num_leds = ARRAY_SIZE(zylonite_debug_leds), +}; + +static struct platform_device zylonite_device_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &zylonite_debug_leds_info, + } +}; + +static void __init zylonite_init_leds(void) +{ + zylonite_debug_leds[0].gpio = gpio_debug_led1; + zylonite_debug_leds[1].gpio = gpio_debug_led2; + + platform_device_register(&zylonite_device_leds); +} +#else +static inline void zylonite_init_leds(void) {} +#endif + #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static struct platform_pwm_backlight_data zylonite_backlight_data = { .pwm_id = 3, @@ -259,7 +307,7 @@ static void __init zylonite_init_mmc(void) static inline void zylonite_init_mmc(void) {} #endif -#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES) +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) static 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), @@ -324,6 +372,57 @@ static void __init zylonite_init_keypad(void) static inline void zylonite_init_keypad(void) {} #endif +#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +static struct mtd_partition zylonite_nand_partitions[] = { + [0] = { + .name = "Bootloader", + .offset = 0, + .size = 0x060000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [1] = { + .name = "Kernel", + .offset = 0x060000, + .size = 0x200000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + [2] = { + .name = "Filesystem", + .offset = 0x0260000, + .size = 0x3000000, /* 48M - rootfs */ + }, + [3] = { + .name = "MassStorage", + .offset = 0x3260000, + .size = 0x3d40000, + }, + [4] = { + .name = "BBT", + .offset = 0x6FA0000, + .size = 0x80000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* NOTE: we reserve some blocks at the end of the NAND flash for + * bad block management, and the max number of relocation blocks + * differs on different platforms. Please take care with it when + * defining the partition table. + */ +}; + +static struct pxa3xx_nand_platform_data zylonite_nand_info = { + .enable_arbiter = 1, + .parts = zylonite_nand_partitions, + .nr_parts = ARRAY_SIZE(zylonite_nand_partitions), +}; + +static void __init zylonite_init_nand(void) +{ + pxa3xx_set_nand_info(&zylonite_nand_info); +} +#else +static inline void zylonite_init_nand(void) {} +#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ + static void __init zylonite_init(void) { /* board-processor specific initialization */ @@ -342,6 +441,8 @@ static void __init zylonite_init(void) zylonite_init_lcd(); zylonite_init_mmc(); zylonite_init_keypad(); + zylonite_init_nand(); + zylonite_init_leds(); } MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 6f7ae972b8d..b28d46e081d 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -16,9 +16,12 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/i2c.h> +#include <linux/i2c/pca953x.h> #include <asm/gpio.h> #include <asm/arch/mfp-pxa300.h> +#include <asm/arch/i2c.h> #include <asm/arch/zylonite.h> #include "generic.h" @@ -109,6 +112,10 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO12_MMC2_DAT3, GPIO13_MMC2_CLK, GPIO14_MMC2_CMD, + + /* Standard I2C */ + GPIO21_I2C_SCL, + GPIO22_I2C_SDA, }; static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { @@ -192,6 +199,39 @@ static void __init zylonite_detect_lcd_panel(void) pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]); } +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static struct pca953x_platform_data gpio_exp[] = { + [0] = { + .gpio_base = 128, + }, + [1] = { + .gpio_base = 144, + }, +}; + +struct i2c_board_info zylonite_i2c_board_info[] = { + { + .type = "pca9539", + .addr = 0x74, + .platform_data = &gpio_exp[0], + .irq = IRQ_GPIO(18), + }, { + .type = "pca9539", + .addr = 0x75, + .platform_data = &gpio_exp[1], + .irq = IRQ_GPIO(19), + }, +}; + +static void __init zylonite_init_i2c(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(zylonite_i2c_board_info)); +} +#else +static inline void zylonite_init_i2c(void) {} +#endif + void __init zylonite_pxa300_init(void) { if (cpu_is_pxa300() || cpu_is_pxa310()) { @@ -207,6 +247,8 @@ void __init zylonite_pxa300_init(void) /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26); + + zylonite_init_i2c(); } if (cpu_is_pxa300()) { @@ -222,4 +264,8 @@ void __init zylonite_pxa300_init(void) zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30); zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31); } + + /* GPIOs for Debug LEDs */ + gpio_debug_led1 = EXT_GPIO(25); + gpio_debug_led2 = EXT_GPIO(26); } diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 2b4fc34919a..2b7fba7a292 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -116,6 +116,10 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO27_MMC2_DAT3, GPIO28_MMC2_CLK, GPIO29_MMC2_CMD, + + /* Debug LEDs */ + GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH, + GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH, }; #define NUM_LCD_DETECT_PINS 7 @@ -189,6 +193,8 @@ void __init zylonite_pxa320_init(void) /* GPIO pin assignment */ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); + 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); |