diff options
Diffstat (limited to 'arch/arm/mach-pxa')
36 files changed, 2380 insertions, 644 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 6c162f8fdcea..7f9664dee670 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -20,15 +20,17 @@ endmenu endif -choice - prompt "Select target board" - 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 @@ -37,10 +39,12 @@ config ARCH_LUBBOCK config MACH_LOGICPD_PXA270 bool "LogicPD PXA270 Card Engine Development Platform" select PXA27x + select HAVE_PWM config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform" select PXA27x + select HAVE_PWM config ARCH_PXA_IDP bool "Accelent Xscale IDP" @@ -57,6 +61,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 @@ -105,6 +160,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 @@ -116,6 +175,7 @@ config MACH_COLIBRI config MACH_ZYLONITE bool "PXA3xx Development Platform" select PXA3xx + select HAVE_PWM config MACH_LITTLETON bool "PXA3xx Form Factor Platform (aka Littleton)" @@ -129,7 +189,6 @@ config MACH_ARMCORE config MACH_MAGICIAN bool "Enable HTC Magician Support" - depends on ARCH_PXA select PXA27x select IWMMXT @@ -137,109 +196,81 @@ config MACH_PCM027 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" select PXA27x select IWMMXT + select PXA_SSP -endchoice +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" - -endchoice - -if PXA_SHARPSL + select HAVE_PWM + depends on MACH_PCM027 choice - prompt "Select target Sharp Zaurus device range" + prompt "display on pcm990" + depends on MACH_PCM990_BASEBOARD -config PXA_SHARPSL_25x - bool "Sharp PXA25x models (SL-5600, SL-C7xx and SL-C6000x)" - select PXA25x +config PCM990_DISPLAY_SHARP + bool "sharp lq084v1dg21 stn display" -config PXA_SHARPSL_27x - bool "Sharp PXA270 models (SL-Cxx00)" - select PXA27x +config PCM990_DISPLAY_NEC + bool "nec nl6448bc20_18d tft display" -endchoice - -endif - -if ARCH_GUMSTIX - -choice - prompt "Select target Gumstix board" - -config MACH_GUMSTIX_F - bool "Basix, Connex, ws-200ax, ws-400ax systems" - select PXA25x +config PCM990_DISPLAY_NONE + bool "no display" 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_25x - select SHARP_LOCOMO - select PXA_SSP - -config MACH_CORGI - bool "Enable Sharp SL-C700 (Corgi) Support" - depends on PXA_SHARPSL_25x - select PXA_SHARP_C7xx - -config MACH_SHEPHERD - bool "Enable Sharp SL-C750 (Shepherd) Support" - depends on PXA_SHARPSL_25x - select PXA_SHARP_C7xx - -config MACH_HUSKY - bool "Enable Sharp SL-C760 (Husky) Support" - depends on PXA_SHARPSL_25x - select PXA_SHARP_C7xx - -config MACH_AKITA - bool "Enable Sharp SL-1000 (Akita) Support" - depends on PXA_SHARPSL_27x - 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_27x - select PXA_SHARP_Cxx00 - -config MACH_BORZOI - bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support" - depends on PXA_SHARPSL_27x - select PXA_SHARP_Cxx00 - -config MACH_TOSA - bool "Enable Sharp SL-6000x (Tosa) Support" - depends on PXA_SHARPSL_25x - config PXA25x bool help @@ -274,6 +305,12 @@ config PXA_SSP help Enable support for PXA2xx SSP ports +config PXA_PWM + tristate + 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 @@ -281,4 +318,5 @@ config TOSA_BT 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 18e0b249f7ca..b282412a01f5 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -10,10 +10,11 @@ obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o # Generic drivers that other drivers may depend upon obj-$(CONFIG_PXA_SSP) += ssp.o +obj-$(CONFIG_PXA_PWM) += pwm.o # SoC-specific code -obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o -obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa27x.o +obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o +obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o obj-$(CONFIG_CPU_PXA300) += pxa300.o obj-$(CONFIG_CPU_PXA320) += pxa320.o @@ -36,6 +37,7 @@ 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_MACH_PALMTX)+= palmtx.o ifeq ($(CONFIG_MACH_ZYLONITE),y) obj-y += zylonite.o @@ -45,6 +47,7 @@ endif obj-$(CONFIG_MACH_LITTLETON) += littleton.o obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o +obj-$(CONFIG_PXA_EZX) += ezx.o # Support for blinky lights led-y := leds.o diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index e97dc59813c8..630063ffa6fc 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -12,7 +12,7 @@ #include <linux/platform_device.h> #include <linux/delay.h> -#include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include <asm/hardware.h> @@ -47,6 +47,9 @@ struct clk *clk_get(struct device *dev, const char *id) clk = p; mutex_unlock(&clocks_mutex); + if (!IS_ERR(clk) && clk->ops == NULL) + clk = clk->other; + return clk; } EXPORT_SYMBOL(clk_get); @@ -98,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; @@ -128,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; @@ -145,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 bc6b77e1592e..32d0c074b351 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -15,6 +15,7 @@ struct clk { unsigned int cken; unsigned int delay; unsigned int enabled; + struct clk *other; }; #define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ @@ -35,6 +36,26 @@ struct clk { .cken = CKEN_##_cken, \ } +/* + * This is a placeholder to alias one clock device+name pair + * to another struct clk. + */ +#define INIT_CKOTHER(_name, _other, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .other = _other, \ + } + +#define 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); diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c index ac7f05f9f3eb..bcf0cde6ccc9 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. @@ -41,36 +41,39 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, { unsigned int sz = SZ_64M >> PAGE_SHIFT; - pr_info("Adjusting zones for CM-x270\n"); + if (machine_is_armcore()) { + pr_info("Adjusting zones for CM-X270\n"); - /* - * Only adjust if > 64M on current system - */ - if (node || (zone_size[0] <= sz)) - return; - - zone_size[1] = zone_size[0] - sz; - zone_size[0] = sz; - zhole_size[1] = zhole_size[0]; - zhole_size[0] = 0; + /* + * Only adjust if > 64M on current system + */ + if (node || (zone_size[0] <= sz)) + return; + + zone_size[1] = zone_size[0] - sz; + zone_size[0] = sz; + zhole_size[1] = zhole_size[0]; + zhole_size[0] = 0; + } } static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) { /* 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 @@ -113,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 ffe37b66f9a0..48f532f4cb51 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 6d4416a4f378..402e807eae54 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,43 +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, @@ -59,41 +172,49 @@ static struct resource cmx270_dm9k_resource[] = { [2] = { .start = CMX270_ETHIRQ, .end = CMX270_ETHIRQ, - .flags = IORESOURCE_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; -/* 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, } }; -/* audio device */ -static struct platform_device cmx270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; +static void __init cmx270_init_dm9000(void) +{ + platform_device_register(&cmx270_dm9000_device); +} +#else +static inline void cmx270_init_dm9000(void) {} +#endif -/* touchscreen controller */ +/* 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, @@ -116,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, }, }; @@ -205,44 +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_audio_device, - &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 @@ -452,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 */ @@ -467,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; } @@ -505,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 = { @@ -525,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]; @@ -586,52 +737,63 @@ static int __init cmx270_pm_init(void) static int __init cmx270_pm_init(void) { return 0; } #endif +#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) +static void __init cmx270_init_ac97(void) +{ + pxa_set_ac97_info(NULL); +} +#else +static inline void cmx270_init_ac97(void) {} +#endif + static void __init cmx270_init(void) { cmx270_pm_init(); - set_pxa_fb_info(cmx270_display); - - /* register CM-X270 platform devices */ - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); - - /* 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); - - /* 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 b757dd756655..b37671b71886 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -36,6 +36,7 @@ #include <asm/mach/irq.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include <asm/arch/irda.h> #include <asm/arch/mmc.h> diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 0a85f706e887..e91c0f26c412 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -26,6 +26,7 @@ #include <asm/arch/sharpsl.h> #include <asm/arch/corgi.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include "sharpsl.h" @@ -204,7 +205,9 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .read_devdata = corgipm_read_devdata, .charger_wakeup = corgi_charger_wakeup, .should_wakeup = corgi_should_wakeup, +#ifdef CONFIG_BACKLIGHT_CORGI .backlight_limit = corgibl_limit_intensity, +#endif .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, @@ -226,6 +229,10 @@ static int __devinit corgipm_init(void) { int ret; + if (!machine_is_corgi() && !machine_is_shepherd() + && !machine_is_husky()) + return -ENODEV; + corgipm_device = platform_device_alloc("sharpsl-pm", -1); if (!corgipm_device) return -ENOMEM; diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index d6c05b6eab35..abc161dd083a 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -10,11 +10,15 @@ #include <asm/arch/mmc.h> #include <asm/arch/irda.h> #include <asm/arch/i2c.h> +#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 "devices.h" +#include "generic.h" void __init pxa_register_device(struct platform_device *dev, void *data) { @@ -91,8 +95,19 @@ static struct resource pxa2xx_udc_resources[] = { static u64 udc_dma_mask = ~(u32)0; -struct platform_device pxa_device_udc = { - .name = "pxa2xx-udc", +struct platform_device pxa25x_device_udc = { + .name = "pxa25x-udc", + .id = -1, + .resource = pxa2xx_udc_resources, + .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), + .dev = { + .platform_data = &pxa_udc_info, + .dma_mask = &udc_dma_mask, + } +}; + +struct platform_device pxa27x_device_udc = { + .name = "pxa27x-udc", .id = -1, .resource = pxa2xx_udc_resources, .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), @@ -233,8 +248,15 @@ struct platform_device pxa_device_i2c = { .num_resources = ARRAY_SIZE(pxai2c_resources), }; +static unsigned long pxa27x_i2c_mfp_cfg[] = { + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, +}; + void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) { + if (cpu_is_pxa27x()) + pxa2xx_mfp_config(ARRAY_AND_SIZE(pxa27x_i2c_mfp_cfg)); pxa_register_device(&pxa_device_i2c, info); } @@ -278,8 +300,69 @@ struct platform_device pxa_device_rtc = { .id = -1, }; +static struct resource pxa_ac97_resources[] = { + [0] = { + .start = 0x40500000, + .end = 0x40500000 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa_ac97_dmamask = 0xffffffffUL; + +struct platform_device pxa_device_ac97 = { + .name = "pxa2xx-ac97", + .id = -1, + .dev = { + .dma_mask = &pxa_ac97_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa_ac97_resources), + .resource = pxa_ac97_resources, +}; + +void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops) +{ + pxa_register_device(&pxa_device_ac97, ops); +} + #ifdef CONFIG_PXA25x +static struct resource pxa25x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm0 = { + .name = "pxa25x-pwm", + .id = 0, + .resource = pxa25x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm0), +}; + +static struct resource pxa25x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm1 = { + .name = "pxa25x-pwm", + .id = 1, + .resource = pxa25x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm1), +}; + static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32); static struct resource pxa25x_resource_ssp[] = { @@ -568,6 +651,36 @@ struct platform_device pxa27x_device_ssp3 = { .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), }; +static struct resource pxa27x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm0 = { + .name = "pxa27x-pwm", + .id = 0, + .resource = pxa27x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm0), +}; + +static struct resource pxa27x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm1 = { + .name = "pxa27x-pwm", + .id = 1, + .resource = pxa27x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), +}; + static struct resource pxa27x_resource_camera[] = { [0] = { .start = 0x50000000, @@ -719,3 +832,20 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *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 fcab017f27ee..b852eb18daa5 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -1,7 +1,8 @@ extern struct platform_device pxa_device_mci; extern struct platform_device pxa3xx_device_mci2; extern struct platform_device pxa3xx_device_mci3; -extern struct platform_device pxa_device_udc; +extern struct platform_device pxa25x_device_udc; +extern struct platform_device pxa27x_device_udc; extern struct platform_device pxa_device_fb; extern struct platform_device pxa_device_ffuart; extern struct platform_device pxa_device_btuart; @@ -11,6 +12,7 @@ extern struct platform_device pxa_device_i2c; extern struct platform_device pxa_device_i2s; extern struct platform_device pxa_device_ficp; extern struct platform_device pxa_device_rtc; +extern struct platform_device pxa_device_ac97; extern struct platform_device pxa27x_device_i2c_power; extern struct platform_device pxa27x_device_ohci; @@ -24,4 +26,9 @@ extern struct platform_device pxa27x_device_ssp2; extern struct platform_device pxa27x_device_ssp3; extern struct platform_device pxa3xx_device_ssp4; +extern struct platform_device pxa25x_device_pwm0; +extern struct platform_device pxa25x_device_pwm1; +extern struct platform_device pxa27x_device_pwm0; +extern struct platform_device pxa27x_device_pwm1; + void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index edc4f07a230d..e5cc6ca63c75 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,29 +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, @@ -50,42 +180,34 @@ static struct resource em_x270_dm9k_resource[] = { [2] = { .start = EM_X270_ETHIRQ, .end = EM_X270_ETHIRQ, - .flags = IORESOURCE_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; -/* 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, } }; -/* audio device */ -static struct platform_device em_x270_audio = { - .name = "pxa2xx-ac97", - .id = -1, -}; - -/* 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, @@ -108,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 */ @@ -161,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[] = { @@ -214,17 +342,35 @@ static struct platform_device em_x270_nand = { } }; -/* platform devices */ -static struct platform_device *platform_devices[] __initdata = { - &em_x270_dm9k, - &em_x270_audio, - &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 */ @@ -242,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); @@ -284,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 = { @@ -294,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, @@ -312,39 +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 + +#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), +}; - /* register EM-X270 platform devices */ - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +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), +}; - /* set MCI and OHCI platform parameters */ - pxa_set_mci_info(&em_x270_mci_platform_data); - pxa_set_ohci_info(&em_x270_ohci_platform_data); +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 + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button gpio_keys_button[] = { + [0] = { + .desc = "sleep/wakeup", + .code = KEY_SUSPEND, + .type = EV_PWR, + .gpio = 1, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data em_x270_gpio_keys_data = { + .buttons = gpio_keys_button, + .nbuttons = 1, +}; - /* setup STUART GPIOs */ - pxa_gpio_mode(GPIO46_STRXD_MD); - pxa_gpio_mode(GPIO47_STTXD_MD); +static struct platform_device em_x270_gpio_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &em_x270_gpio_keys_data, + }, +}; - /* 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 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 - /* Setup interrupt for dm9000 */ - set_irq_type(EM_X270_ETHIRQ, IRQT_RISING); +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/ezx.c b/arch/arm/mach-pxa/ezx.c new file mode 100644 index 000000000000..0143eed65398 --- /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/generic.c b/arch/arm/mach-pxa/generic.c index 44617938f3f1..ca053226fba0 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -60,23 +60,6 @@ unsigned int get_memclk_frequency_10khz(void) EXPORT_SYMBOL(get_memclk_frequency_10khz); /* - * Routine to safely enable or disable a clock in the CKEN - */ -void __pxa_set_cken(int clock, int enable) -{ - unsigned long flags; - local_irq_save(flags); - - if (enable) - CKEN |= (1 << clock); - else - CKEN &= ~(1 << clock); - - local_irq_restore(flags); -} -EXPORT_SYMBOL(__pxa_set_cken); - -/* * Intel PXA2xx internal register mapping. * * Note 1: not all PXA2xx variants implement all those addresses. diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index a9a0c3fab159..fbff557bb225 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -21,7 +21,6 @@ #include <asm/irq.h> #include <asm/mach/irq.h> #include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> #include "generic.h" diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index a20e4b1649d6..cc1c4fa06145 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -23,6 +23,7 @@ #include <linux/ioport.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> +#include <linux/pwm_backlight.h> #include <asm/types.h> #include <asm/setup.h> @@ -134,9 +135,12 @@ static struct sys_device lpd270_irq_device = { static int __init lpd270_irq_device_init(void) { - int ret = sysdev_class_register(&lpd270_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&lpd270_irq_device); + int ret = -ENODEV; + if (machine_is_logicpd_pxa270()) { + ret = sysdev_class_register(&lpd270_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&lpd270_irq_device); + } return ret; } @@ -164,11 +168,6 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -static struct platform_device lpd270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct resource lpd270_flash_resources[] = { [0] = { .start = PXA_CS0_PHYS, @@ -233,21 +232,20 @@ static struct platform_device lpd270_flash_device[2] = { }, }; -static void lpd270_backlight_power(int on) -{ - if (on) { - pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN_PWM0, 1); - PWM_CTRL0 = 0; - PWM_PWDUTY0 = 0x3ff; - PWM_PERVAL0 = 0x3ff; - } else { - PWM_CTRL0 = 0; - PWM_PWDUTY0 = 0x0; - PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN_PWM0, 0); - } -} +static struct platform_pwm_backlight_data lpd270_backlight_data = { + .pwm_id = 0, + .max_brightness = 1, + .dft_brightness = 1, + .pwm_period_ns = 78770, +}; + +static struct platform_device lpd270_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &lpd270_backlight_data, + }, +}; /* 5.7" TFT QVGA (LoLo display number 1) */ static struct pxafb_mode_info sharp_lq057q3dc02_mode = { @@ -269,7 +267,6 @@ static struct pxafb_mach_info sharp_lq057q3dc02 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 12.1" TFT SVGA (LoLo display number 2) */ @@ -292,7 +289,6 @@ static struct pxafb_mach_info sharp_lq121s1dg31 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 3.6" TFT QVGA (LoLo display number 3) */ @@ -315,7 +311,6 @@ static struct pxafb_mach_info sharp_lq036q1da01 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 6.4" TFT VGA (LoLo display number 5) */ @@ -338,7 +333,6 @@ static struct pxafb_mach_info sharp_lq64d343 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 10.4" TFT VGA (LoLo display number 7) */ @@ -361,7 +355,6 @@ static struct pxafb_mach_info sharp_lq10d368 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 3.5" TFT QVGA (LoLo display number 8) */ @@ -384,7 +377,6 @@ static struct pxafb_mach_info sharp_lq035q7db02_20 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; static struct pxafb_mach_info *lpd270_lcd_to_use; @@ -414,7 +406,7 @@ __setup("lcd=", lpd270_set_lcd); static struct platform_device *platform_devices[] __initdata = { &smc91x_device, - &lpd270_audio_device, + &lpd270_backlight_device, &lpd270_flash_device[0], &lpd270_flash_device[1], }; @@ -454,9 +446,12 @@ static void __init lpd270_init(void) * On LogicPD PXA270, we route AC97_SYSCLK via GPIO45. */ pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); + pxa_gpio_mode(GPIO16_PWM0_MD); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); + if (lpd270_lcd_to_use != NULL) set_pxa_fb_info(lpd270_lcd_to_use); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 7b9bdd0c6665..e041cceab16b 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -43,6 +43,7 @@ #include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> #include <asm/arch/mfp-pxa25x.h> +#include <asm/arch/audio.h> #include <asm/arch/lubbock.h> #include <asm/arch/udc.h> #include <asm/arch/irda.h> @@ -196,11 +197,6 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { // no D+ pullup; lubbock can't connect/disconnect in software }; -static struct platform_device lub_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct resource sa1111_resources[] = { [0] = { .start = 0x10000000, @@ -230,14 +226,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 */ @@ -368,11 +356,9 @@ static struct platform_device lubbock_flash_device[2] = { static struct platform_device *devices[] __initdata = { &sa1111_device, - &lub_audio_device, &smc91x_device, &lubbock_flash_device[0], &lubbock_flash_device[1], - &pxa_ssp, }; static struct pxafb_mode_info sharp_lm8v31_mode = { @@ -494,6 +480,7 @@ static void __init lubbock_init(void) set_pxa_fb_info(&sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data); + pxa_set_ac97_info(NULL); lubbock_flash_data[0].width = lubbock_flash_data[1].width = (BOOT_DEF & 1) ? 2 : 4; @@ -505,6 +492,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 badba064dc04..bad5821be41a 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -17,31 +17,32 @@ #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> #include <asm/arch/magician.h> #include <asm/arch/mfp-pxa27x.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxafb.h> #include <asm/arch/i2c.h> #include <asm/arch/mmc.h> #include <asm/arch/irda.h> #include <asm/arch/ohci.h> +#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, @@ -348,40 +349,59 @@ static struct pxafb_mach_info samsung_info = { * Backlight */ -static void magician_set_bl_intensity(int intensity) +static int magician_backlight_init(struct device *dev) { - if (intensity) { - PWM_CTRL0 = 1; - PWM_PERVAL0 = 0xc8; - if (intensity > 0xc7) { - PWM_PWDUTY0 = intensity - 0x48; - gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1); - } else { - PWM_PWDUTY0 = intensity; - gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0); - } - gpio_set_value(EGPIO_MAGICIAN_BL_POWER, 1); - pxa_set_cken(CKEN_PWM0, 1); + int ret; + + ret = gpio_request(EGPIO_MAGICIAN_BL_POWER, "BL_POWER"); + if (ret) + goto err; + ret = gpio_request(EGPIO_MAGICIAN_BL_POWER2, "BL_POWER2"); + if (ret) + goto err2; + return 0; + +err2: + gpio_free(EGPIO_MAGICIAN_BL_POWER); +err: + return ret; +} + +static int magician_backlight_notify(int brightness) +{ + gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness); + if (brightness >= 200) { + gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1); + return brightness - 72; } else { - /* PWM_PWDUTY0 = intensity; */ - gpio_set_value(EGPIO_MAGICIAN_BL_POWER, 0); - pxa_set_cken(CKEN_PWM0, 0); + gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0); + return brightness; } } -static struct generic_bl_info backlight_info = { - .default_intensity = 0x64, - .limit_mask = 0x0b, - .max_intensity = 0xc7+0x48, - .set_bl_intensity = magician_set_bl_intensity, +static void magician_backlight_exit(struct device *dev) +{ + gpio_free(EGPIO_MAGICIAN_BL_POWER); + gpio_free(EGPIO_MAGICIAN_BL_POWER2); +} + +static struct platform_pwm_backlight_data backlight_data = { + .pwm_id = 0, + .max_brightness = 272, + .dft_brightness = 100, + .pwm_period_ns = 30923, + .init = magician_backlight_init, + .notify = magician_backlight_notify, + .exit = magician_backlight_exit, }; static struct platform_device backlight = { - .name = "generic-bl", + .name = "pwm-backlight", + .id = -1, .dev = { - .platform_data = &backlight_info, + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &backlight_data, }, - .id = -1, }; /* @@ -490,6 +510,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); @@ -506,14 +557,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 7399fb34da4e..f2e9e7c4da8e 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -23,9 +23,9 @@ #include <linux/ioport.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> -#include <linux/backlight.h> #include <linux/input.h> #include <linux/gpio_keys.h> +#include <linux/pwm_backlight.h> #include <asm/types.h> #include <asm/setup.h> @@ -280,12 +280,6 @@ static pxa2xx_audio_ops_t mst_audio_ops = { .resume = mst_audio_resume, }; -static struct platform_device mst_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, - .dev = { .platform_data = &mst_audio_ops }, -}; - static struct resource flash_resources[] = { [0] = { .start = PXA_CS0_PHYS, @@ -349,56 +343,27 @@ static struct platform_device mst_flash_device[2] = { }, }; -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE -static int mainstone_backlight_update_status(struct backlight_device *bl) -{ - int brightness = bl->props.brightness; - - if (bl->props.power != FB_BLANK_UNBLANK || - bl->props.fb_blank != FB_BLANK_UNBLANK) - brightness = 0; - - if (brightness != 0) - pxa_set_cken(CKEN_PWM0, 1); - - PWM_CTRL0 = 0; - PWM_PWDUTY0 = brightness; - PWM_PERVAL0 = bl->props.max_brightness; - - if (brightness == 0) - pxa_set_cken(CKEN_PWM0, 0); - return 0; /* pointless return value */ -} - -static int mainstone_backlight_get_brightness(struct backlight_device *bl) -{ - return PWM_PWDUTY0; -} +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct platform_pwm_backlight_data mainstone_backlight_data = { + .pwm_id = 0, + .max_brightness = 1023, + .dft_brightness = 1023, + .pwm_period_ns = 78770, +}; -static /*const*/ struct backlight_ops mainstone_backlight_ops = { - .update_status = mainstone_backlight_update_status, - .get_brightness = mainstone_backlight_get_brightness, +static struct platform_device mainstone_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &mainstone_backlight_data, + }, }; static void __init mainstone_backlight_register(void) { - struct backlight_device *bl; - - bl = backlight_device_register("mainstone-bl", &pxa_device_fb.dev, - NULL, &mainstone_backlight_ops); - if (IS_ERR(bl)) { - printk(KERN_ERR "mainstone: unable to register backlight: %ld\n", - PTR_ERR(bl)); - return; - } - - /* - * broken design - register-then-setup interfaces are - * utterly broken by definition. - */ - bl->props.max_brightness = 1023; - bl->props.brightness = 1023; - backlight_update_status(bl); + int ret = platform_device_register(&mainstone_backlight_device); + if (ret) + printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret); } #else #define mainstone_backlight_register() do { } while (0) @@ -528,7 +493,6 @@ static struct platform_device mst_gpio_keys_device = { static struct platform_device *platform_devices[] __initdata = { &smc91x_device, - &mst_audio_device, &mst_flash_device[0], &mst_flash_device[1], &mst_gpio_keys_device, @@ -638,6 +602,7 @@ static void __init mainstone_init(void) pxa_set_ficp_info(&mainstone_ficp_platform_data); pxa_set_ohci_info(&mainstone_ohci_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(&mst_audio_ops); mainstone_init_keypad(); } diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 22097a1707cc..d1cdb4ecb0b8 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -20,6 +20,7 @@ #include <asm/arch/hardware.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/mfp-pxa2xx.h> #include "generic.h" diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c new file mode 100644 index 000000000000..408657a24f8c --- /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 3b945eb0aee3..377f3be8ce57 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 49d951db0f3d..30023b00e476 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -24,6 +24,7 @@ #include <linux/platform_device.h> #include <linux/ide.h> #include <linux/i2c.h> +#include <linux/pwm_backlight.h> #include <media/soc_camera.h> @@ -32,13 +33,120 @@ #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, +}; /* - * The PCM-990 development baseboard uses PCM-027's hardeware in the + * pcm990_lcd_power - control power supply to the LCD + * @on: 0 = switch off, 1 = switch on + * + * Called by the pxafb driver + */ +#ifndef CONFIG_PCM990_DISPLAY_NONE +static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var) +{ + if (on) { + /* enable LCD-Latches + * power on LCD + */ + __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = + PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON; + } else { + /* disable LCD-Latches + * power off LCD + */ + __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = 0x00; + } +} +#endif + +#if defined(CONFIG_PCM990_DISPLAY_SHARP) +static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = { + .pixclock = 28000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 20, + .left_margin = 103, + .right_margin = 47, + .vsync_len = 6, + .upper_margin = 28, + .lower_margin = 5, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info pcm990_fbinfo __initdata = { + .modes = &fb_info_sharp_lq084v1dg21, + .num_modes = 1, + .lccr0 = LCCR0_PAS, + .lccr3 = LCCR3_PCP, + .pxafb_lcd_power = pcm990_lcd_power, +}; +#elif defined(CONFIG_PCM990_DISPLAY_NEC) +struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = { + .pixclock = 39720, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 32, + .left_margin = 16, + .right_margin = 48, + .vsync_len = 2, + .upper_margin = 12, + .lower_margin = 17, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info pcm990_fbinfo __initdata = { + .modes = &fb_info_nec_nl6448bc20_18d, + .num_modes = 1, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PixFlEdg, + .pxafb_lcd_power = pcm990_lcd_power, +}; +#endif + +static struct platform_pwm_backlight_data pcm990_backlight_data = { + .pwm_id = 0, + .max_brightness = 1023, + .dft_brightness = 1023, + .pwm_period_ns = 78770, +}; + +static struct platform_device pcm990_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &pcm990_backlight_data, + }, +}; + +/* + * The PCM-990 development baseboard uses PCM-027's hardware in the * following way: * * - LCD support is in use @@ -185,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) @@ -241,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 @@ -269,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; } @@ -333,36 +433,6 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = { #endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ /* - * AC97 support - * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ - */ -static struct resource pxa27x_ac97_resources[] = { - [0] = { - .start = 0x40500000, - .end = 0x40500000 + 0xfff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_AC97, - .end = IRQ_AC97, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 pxa_ac97_dmamask = 0xffffffffUL; - -static struct platform_device pxa27x_device_ac97 = { - .name = "pxa2xx-ac97", - .id = -1, - .dev = { - .dma_mask = &pxa_ac97_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(pxa27x_ac97_resources), - .resource = pxa27x_ac97_resources, -}; - -/* * enable generic access to the base board control CPLDs U6 and U7 */ static struct map_desc pcm990_io_desc[] __initdata = { @@ -387,13 +457,18 @@ 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(); - platform_device_register(&pxa27x_device_ac97); +#ifndef CONFIG_PCM990_DISPLAY_NONE + set_pxa_fb_info(&pcm990_fbinfo); +#endif + platform_device_register(&pcm990_backlight_device); /* MMC */ pxa_set_mci_info(&pcm990_mci_platform_data); @@ -402,13 +477,13 @@ void __init pcm990_baseboard_init(void) pxa_set_ohci_info(&pcm990_ohci_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(NULL); #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 0b30f25cff3c..f81c10cafd48 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -32,6 +32,7 @@ #include <asm/mach/irq.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/udc.h> diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c new file mode 100644 index 000000000000..ce28cd9fed16 --- /dev/null +++ b/arch/arm/mach-pxa/pwm.c @@ -0,0 +1,319 @@ +/* + * linux/arch/arm/mach-pxa/pwm.c + * + * simple driver for PWM (Pulse Width Modulator) controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 2008-02-13 initial version + * eric miao <eric.miao@marvell.com> + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/pwm.h> + +#include <asm/div64.h> +#include <asm/arch/pxa-regs.h> + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +struct pwm_device { + struct list_head node; + struct platform_device *pdev; + + const char *label; + struct clk *clk; + int clk_enabled; + void __iomem *mmio_base; + + unsigned int use_count; + unsigned int pwm_id; +}; + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + + c = clk_get_rate(pwm->clk); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 0) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + clk_enable(pwm->clk); + __raw_writel(prescale, pwm->mmio_base + PWMCR); + __raw_writel(dc, pwm->mmio_base + PWMDCR); + __raw_writel(pv, pwm->mmio_base + PWMPCR); + clk_disable(pwm->clk); + + return 0; +} +EXPORT_SYMBOL(pwm_config); + +int pwm_enable(struct pwm_device *pwm) +{ + int rc = 0; + + if (!pwm->clk_enabled) { + rc = clk_enable(pwm->clk); + if (!rc) + pwm->clk_enabled = 1; + } + return rc; +} +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + if (pwm->clk_enabled) { + clk_disable(pwm->clk); + pwm->clk_enabled = 0; + } +} +EXPORT_SYMBOL(pwm_disable); + +static DEFINE_MUTEX(pwm_lock); +static LIST_HEAD(pwm_list); + +struct pwm_device *pwm_request(int pwm_id, const char *label) +{ + struct pwm_device *pwm; + int found = 0; + + mutex_lock(&pwm_lock); + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->pwm_id == pwm_id) { + found = 1; + break; + } + } + + if (found) { + if (pwm->use_count == 0) { + pwm->use_count++; + pwm->label = label; + } else + pwm = ERR_PTR(-EBUSY); + } else + pwm = ERR_PTR(-ENOENT); + + mutex_unlock(&pwm_lock); + return pwm; +} +EXPORT_SYMBOL(pwm_request); + +void pwm_free(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + + if (pwm->use_count) { + pwm->use_count--; + pwm->label = NULL; + } else + pr_warning("PWM device already freed\n"); + + mutex_unlock(&pwm_lock); +} +EXPORT_SYMBOL(pwm_free); + +static inline void __add_pwm(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + list_add_tail(&pwm->node, &pwm_list); + mutex_unlock(&pwm_lock); +} + +static struct pwm_device *pwm_probe(struct platform_device *pdev, + unsigned int pwm_id, struct pwm_device *parent_pwm) +{ + struct pwm_device *pwm; + struct resource *r; + int ret = 0; + + pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (pwm == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return ERR_PTR(-ENOMEM); + } + + pwm->clk = clk_get(&pdev->dev, "PWMCLK"); + if (IS_ERR(pwm->clk)) { + ret = PTR_ERR(pwm->clk); + goto err_free; + } + pwm->clk_enabled = 0; + + pwm->use_count = 0; + pwm->pwm_id = pwm_id; + pwm->pdev = pdev; + + if (parent_pwm != NULL) { + /* registers for the second PWM has offset of 0x10 */ + pwm->mmio_base = parent_pwm->mmio_base + 0x10; + __add_pwm(pwm); + return pwm; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + if (r == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + if (pwm->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + __add_pwm(pwm); + platform_set_drvdata(pdev, pwm); + return pwm; + +err_free_mem: + release_mem_region(r->start, r->end - r->start + 1); +err_free_clk: + clk_put(pwm->clk); +err_free: + kfree(pwm); + return ERR_PTR(ret); +} + +static int __devinit pxa25x_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL); + + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + return 0; +} + +static int __devinit pxa27x_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm; + + pwm = pwm_probe(pdev, pdev->id, NULL); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + pwm = pwm_probe(pdev, pdev->id + 2, pwm); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + return 0; +} + +static int __devexit pwm_remove(struct platform_device *pdev) +{ + struct pwm_device *pwm; + struct resource *r; + + pwm = platform_get_drvdata(pdev); + if (pwm == NULL) + return -ENODEV; + + mutex_lock(&pwm_lock); + list_del(&pwm->node); + mutex_unlock(&pwm_lock); + + iounmap(pwm->mmio_base); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, r->end - r->start + 1); + + clk_put(pwm->clk); + kfree(pwm); + return 0; +} + +static struct platform_driver pxa25x_pwm_driver = { + .driver = { + .name = "pxa25x-pwm", + }, + .probe = pxa25x_pwm_probe, + .remove = __devexit_p(pwm_remove), +}; + +static struct platform_driver pxa27x_pwm_driver = { + .driver = { + .name = "pxa27x-pwm", + }, + .probe = pxa27x_pwm_probe, + .remove = __devexit_p(pwm_remove), +}; + +static int __init pwm_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&pxa25x_pwm_driver); + if (ret) { + printk(KERN_ERR "failed to register pxa25x_pwm_driver\n"); + return ret; + } + + ret = platform_driver_register(&pxa27x_pwm_driver); + if (ret) { + printk(KERN_ERR "failed to register pxa27x_pwm_driver\n"); + return ret; + } + + return ret; +} +arch_initcall(pwm_init); + +static void __exit pwm_exit(void) +{ + platform_driver_unregister(&pxa25x_pwm_driver); + platform_driver_unregister(&pxa27x_pwm_driver); +} +module_exit(pwm_exit); + +MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e5b417d14bb0..c5b845b935bb 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -26,6 +26,7 @@ #include <asm/hardware.h> #include <asm/arch/irqs.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/mfp-pxa25x.h> #include <asm/arch/pm.h> #include <asm/arch/dma.h> @@ -108,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 @@ -117,29 +164,40 @@ static struct clk pxa25x_hwuart_clk = INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) ; +/* + * PXA 2xx clock declarations. Order is important (see aliases below) + * Please be careful not to disrupt the ordering. + */ static struct clk pxa25x_clks[] = { INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), - INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), + INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa25x_device_udc.dev), + INIT_CLK("GPIO11_CLK", &clk_pxa25x_gpio11_ops, 3686400, 0, NULL), + INIT_CLK("GPIO12_CLK", &clk_pxa25x_gpio12_ops, 32768, 0, NULL), INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), + INIT_CKEN("PWMCLK", PWM0, 3686400, 0, &pxa25x_device_pwm0.dev), + INIT_CKEN("PWMCLK", PWM1, 3686400, 0, &pxa25x_device_pwm1.dev), INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), /* - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), */ INIT_CKEN("FICPCLK", FICP, 47923000, 0, 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 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x @@ -260,7 +318,7 @@ void __init pxa25x_init_irq(void) } static struct platform_device *pxa25x_devices[] __initdata = { - &pxa_device_udc, + &pxa25x_device_udc, &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, @@ -269,6 +327,8 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_ssp, &pxa25x_device_nssp, &pxa25x_device_assp, + &pxa25x_device_pwm0, + &pxa25x_device_pwm1, }; static struct sys_device pxa25x_sysdev[] = { @@ -284,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()) { @@ -308,9 +368,11 @@ 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(pxa2xx_clk_aliases, ARRAY_SIZE(pxa2xx_clk_aliases)); + return ret; } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e945836e129..d5d14ea33f27 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -146,7 +146,7 @@ static struct clk pxa27x_clks[] = { INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev), + INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa27x_device_udc.dev), INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), @@ -157,12 +157,13 @@ static struct clk pxa27x_clks[] = { INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), + INIT_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), + INIT_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), INIT_CKEN("AC97CONFCLK", AC97CONF, 24576000, 0, NULL), /* - INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), @@ -349,11 +350,14 @@ struct platform_device pxa27x_device_i2c_power = { void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) { + local_irq_disable(); + PCFR |= PCFR_PI2CEN; + local_irq_enable(); pxa27x_device_i2c_power.dev.platform_data = info; } static struct platform_device *devices[] __initdata = { - &pxa_device_udc, + &pxa27x_device_udc, &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, @@ -363,6 +367,8 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp1, &pxa27x_device_ssp2, &pxa27x_device_ssp3, + &pxa27x_device_pwm0, + &pxa27x_device_pwm1, }; static struct sys_device pxa27x_sysdev[] = { diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c new file mode 100644 index 000000000000..d4f6415e8413 --- /dev/null +++ b/arch/arm/mach-pxa/pxa2xx.c @@ -0,0 +1,46 @@ +/* + * linux/arch/arm/mach-pxa/pxa2xx.c + * + * code specific to pxa2xx + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/device.h> + +#include <asm/arch/mfp-pxa2xx.h> +#include <asm/arch/mfp-pxa25x.h> +#include <asm/arch/irda.h> + +static unsigned long pxa2xx_mfp_fir[] = { + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, +}; + +static unsigned long pxa2xx_mfp_sir[] = { + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, +}; + +static unsigned long pxa2xx_mfp_off[] = { + GPIO46_GPIO | MFP_LPM_DRIVE_LOW, + GPIO47_GPIO | MFP_LPM_DRIVE_LOW, +}; + +void pxa2xx_transceiver_mode(struct device *dev, int mode) +{ + if (mode & IR_OFF) { + pxa2xx_mfp_config(pxa2xx_mfp_off, ARRAY_SIZE(pxa2xx_mfp_off)); + } else if (mode & IR_SIRMODE) { + pxa2xx_mfp_config(pxa2xx_mfp_sir, ARRAY_SIZE(pxa2xx_mfp_sir)); + } else if (mode & IR_FIRMODE) { + pxa2xx_mfp_config(pxa2xx_mfp_fir, ARRAY_SIZE(pxa2xx_mfp_fir)); + } else + BUG(); +} diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 644550bfa330..15685d2b8f8c 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -231,7 +231,7 @@ static struct clk pxa3xx_clks[] = { PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL), PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), + PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa27x_device_udc.dev), PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev), PXA3xx_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev), @@ -239,6 +239,8 @@ static struct clk pxa3xx_clks[] = { PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev), + PXA3xx_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), + PXA3xx_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), @@ -520,7 +522,7 @@ void __init pxa3xx_init_irq(void) */ static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, @@ -530,6 +532,8 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp2, &pxa27x_device_ssp3, &pxa3xx_device_ssp4, + &pxa27x_device_pwm0, + &pxa27x_device_pwm1, }; static struct sys_device pxa3xx_sysdev[] = { diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 23f050feb208..360354084ae4 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -26,6 +26,7 @@ #include <asm/arch/sharpsl.h> #include <asm/arch/spitz.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include "sharpsl.h" @@ -207,7 +208,9 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = { .read_devdata = spitzpm_read_devdata, .charger_wakeup = spitz_charger_wakeup, .should_wakeup = spitz_should_wakeup, +#ifdef CONFIG_BACKLIGHT_CORGI .backlight_limit = corgibl_limit_intensity, +#endif .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, @@ -229,6 +232,10 @@ static int __devinit spitzpm_init(void) { int ret; + if (!machine_is_spitz() && !machine_is_akita() + && !machine_is_borzoi()) + return -ENODEV; + spitzpm_device = platform_device_alloc("sharpsl-pm", -1); if (!spitzpm_device) return -ENOMEM; diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 00af7f2fed66..0bb31982fb6f 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -330,7 +330,7 @@ struct ssp_device *ssp_request(int port, const char *label) mutex_unlock(&ssp_lock); - if (ssp->port_id != port) + if (&ssp->node == &ssp_list) return NULL; return ssp; diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index 167412e6bec8..40bb70eff3fe 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -14,6 +14,7 @@ #include <asm/hardware.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> .text @@ -35,20 +36,20 @@ ENTRY(pxa_cpu_standby) #ifdef CONFIG_PXA3xx -#define MDCNFG 0x0000 -#define MDCNFG_DMCEN (1 << 30) -#define DDR_HCAL 0x0060 -#define DDR_HCAL_HCRNG 0x1f -#define DDR_HCAL_HCPROG (1 << 28) -#define DDR_HCAL_HCEN (1 << 31) -#define DMCIER 0x0070 -#define DMCIER_EDLP (1 << 29) -#define DMCISR 0x0078 -#define RCOMP 0x0100 -#define RCOMP_SWEVAL (1 << 31) +#define PXA3_MDCNFG 0x0000 +#define PXA3_MDCNFG_DMCEN (1 << 30) +#define PXA3_DDR_HCAL 0x0060 +#define PXA3_DDR_HCAL_HCRNG 0x1f +#define PXA3_DDR_HCAL_HCPROG (1 << 28) +#define PXA3_DDR_HCAL_HCEN (1 << 31) +#define PXA3_DMCIER 0x0070 +#define PXA3_DMCIER_EDLP (1 << 29) +#define PXA3_DMCISR 0x0078 +#define PXA3_RCOMP 0x0100 +#define PXA3_RCOMP_SWEVAL (1 << 31) ENTRY(pm_enter_standby_start) - mov r1, #0xf6000000 @ DMEMC_REG_BASE (MDCNFG) + mov r1, #0xf6000000 @ DMEMC_REG_BASE (PXA3_MDCNFG) add r1, r1, #0x00100000 /* @@ -59,54 +60,54 @@ ENTRY(pm_enter_standby_start) * This also means that only the dynamic memory controller * can be reliably accessed in the code following standby. */ - ldr r2, [r1] @ Dummy read MDCNFG + ldr r2, [r1] @ Dummy read PXA3_MDCNFG mcr p14, 0, r0, c7, c0, 0 .rept 8 nop .endr - ldr r0, [r1, #DDR_HCAL] @ Clear (and wait for) HCEN - bic r0, r0, #DDR_HCAL_HCEN - str r0, [r1, #DDR_HCAL] -1: ldr r0, [r1, #DDR_HCAL] - tst r0, #DDR_HCAL_HCEN + ldr r0, [r1, #PXA3_DDR_HCAL] @ Clear (and wait for) HCEN + bic r0, r0, #PXA3_DDR_HCAL_HCEN + str r0, [r1, #PXA3_DDR_HCAL] +1: ldr r0, [r1, #PXA3_DDR_HCAL] + tst r0, #PXA3_DDR_HCAL_HCEN bne 1b - ldr r0, [r1, #RCOMP] @ Initiate RCOMP - orr r0, r0, #RCOMP_SWEVAL - str r0, [r1, #RCOMP] + ldr r0, [r1, #PXA3_RCOMP] @ Initiate RCOMP + orr r0, r0, #PXA3_RCOMP_SWEVAL + str r0, [r1, #PXA3_RCOMP] - mov r0, #~0 @ Clear interrupts - str r0, [r1, #DMCISR] + mov r0, #~0 @ Clear interrupts + str r0, [r1, #PXA3_DMCISR] - ldr r0, [r1, #DMCIER] @ set DMIER[EDLP] - orr r0, r0, #DMCIER_EDLP - str r0, [r1, #DMCIER] + ldr r0, [r1, #PXA3_DMCIER] @ set DMIER[EDLP] + orr r0, r0, #PXA3_DMCIER_EDLP + str r0, [r1, #PXA3_DMCIER] - ldr r0, [r1, #DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN - bic r0, r0, #DDR_HCAL_HCRNG - orr r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG - str r0, [r1, #DDR_HCAL] + ldr r0, [r1, #PXA3_DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN + bic r0, r0, #PXA3_DDR_HCAL_HCRNG + orr r0, r0, #PXA3_DDR_HCAL_HCEN | PXA3_DDR_HCAL_HCPROG + str r0, [r1, #PXA3_DDR_HCAL] -1: ldr r0, [r1, #DMCISR] - tst r0, #DMCIER_EDLP +1: ldr r0, [r1, #PXA3_DMCISR] + tst r0, #PXA3_DMCIER_EDLP beq 1b - ldr r0, [r1, #MDCNFG] @ set MDCNFG[DMCEN] - orr r0, r0, #MDCNFG_DMCEN - str r0, [r1, #MDCNFG] -1: ldr r0, [r1, #MDCNFG] - tst r0, #MDCNFG_DMCEN + ldr r0, [r1, #PXA3_MDCNFG] @ set PXA3_MDCNFG[DMCEN] + orr r0, r0, #PXA3_MDCNFG_DMCEN + str r0, [r1, #PXA3_MDCNFG] +1: ldr r0, [r1, #PXA3_MDCNFG] + tst r0, #PXA3_MDCNFG_DMCEN beq 1b - ldr r0, [r1, #DDR_HCAL] @ set DDR_HCAL[HCRNG] + ldr r0, [r1, #PXA3_DDR_HCAL] @ set PXA3_DDR_HCAL[HCRNG] orr r0, r0, #2 @ HCRNG - str r0, [r1, #DDR_HCAL] + str r0, [r1, #PXA3_DDR_HCAL] - ldr r0, [r1, #DMCIER] @ Clear the interrupt + ldr r0, [r1, #PXA3_DMCIER] @ Clear the interrupt bic r0, r0, #0x20000000 - str r0, [r1, #DMCIER] + str r0, [r1, #PXA3_DMCIER] mov pc, lr ENTRY(pm_enter_standby_end) diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 931885d86b91..61e244023089 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -41,6 +41,7 @@ #include <asm/mach/flash.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include <asm/arch/trizeps4.h> #include <asm/arch/audio.h> @@ -175,19 +176,10 @@ static struct platform_device uart_devices = { .resource = NULL, }; -/******************************************************************************************** - * PXA270 ac97 sound codec - ********************************************************************************************/ -static struct platform_device ac97_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct platform_device * trizeps4_devices[] __initdata = { &flash_device, &uart_devices, &dm9000_device, - &ac97_audio_device, }; #ifdef CONFIG_MACH_TRIZEPS4_CONXS @@ -438,6 +430,7 @@ static void __init trizeps4_init(void) pxa_set_mci_info(&trizeps4_mci_platform_data); pxa_set_ficp_info(&trizeps4_ficp_platform_data); pxa_set_ohci_info(&trizeps4_ohci_platform_data); + pxa_set_ac97_info(NULL); } static void __init trizeps4_map_io(void) @@ -487,6 +480,7 @@ static void __init trizeps4_map_io(void) ConXS_BCR = trizeps_conxs_bcr; #endif +#warning FIXME - accessing PM registers directly is deprecated PWER = 0x00000002; PFER = 0x00000000; PRER = 0x00000002; diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 4a0028087ea6..66b446ca273d 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -18,22 +18,24 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/pwm_backlight.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/hardware.h> +#include <asm/arch/audio.h> #include <asm/arch/gpio.h> #include <asm/arch/pxafb.h> #include <asm/arch/zylonite.h> #include <asm/arch/mmc.h> #include <asm/arch/pxa27x_keypad.h> +#include "devices.h" #include "generic.h" #define MAX_SLOTS 3 struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; -int gpio_backlight; int gpio_eth_irq; int wm9713_irq; @@ -62,10 +64,20 @@ static struct platform_device smc91x_device = { }; #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) -static void zylonite_backlight_power(int on) -{ - gpio_set_value(gpio_backlight, on); -} +static struct platform_pwm_backlight_data zylonite_backlight_data = { + .pwm_id = 3, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 10000, +}; + +static struct platform_device zylonite_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm1.dev, + .platform_data = &zylonite_backlight_data, + }, +}; static struct pxafb_mode_info toshiba_ltm035a776c_mode = { .pixclock = 110000, @@ -98,7 +110,6 @@ static struct pxafb_mode_info toshiba_ltm04c380k_mode = { static struct pxafb_mach_info zylonite_toshiba_lcd_info = { .num_modes = 1, .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, - .pxafb_backlight_power = zylonite_backlight_power, }; static struct pxafb_mode_info sharp_ls037_modes[] = { @@ -134,13 +145,11 @@ static struct pxafb_mach_info zylonite_sharp_lcd_info = { .modes = sharp_ls037_modes, .num_modes = 2, .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, - .pxafb_backlight_power = zylonite_backlight_power, }; static void __init zylonite_init_lcd(void) { - /* backlight GPIO: output, default on */ - gpio_direction_output(gpio_backlight, 1); + platform_device_register(&zylonite_backlight_device); if (lcd_id & 0x20) { set_pxa_fb_info(&zylonite_sharp_lcd_info); @@ -329,6 +338,7 @@ static void __init zylonite_init(void) smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); platform_device_register(&smc91x_device); + pxa_set_ac97_info(NULL); zylonite_init_lcd(); zylonite_init_mmc(); zylonite_init_keypad(); diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 324fb9daae28..6f7ae972b8db 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -50,6 +50,7 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO75_LCD_BIAS, GPIO76_LCD_VSYNC, GPIO127_LCD_CS_N, + GPIO20_PWM3_OUT, /* backlight */ /* BTUART */ GPIO111_UART2_RTS, @@ -200,9 +201,6 @@ void __init zylonite_pxa300_init(void) /* detect LCD panel */ zylonite_detect_lcd_panel(); - /* GPIO pin assignment */ - gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); - /* MMC card detect & write protect for controller 0 */ zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0); zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2); diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 193d07903b06..2b4fc34919ac 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -49,6 +49,7 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO15_2_LCD_LCLK, GPIO16_2_LCD_PCLK, GPIO17_2_LCD_BIAS, + GPIO14_PWM3_OUT, /* backlight */ /* FFUART */ GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL, @@ -187,7 +188,6 @@ void __init zylonite_pxa320_init(void) zylonite_detect_lcd_panel(); /* GPIO pin assignment */ - gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14); gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); /* MMC card detect & write protect for controller 0 */ |