diff options
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 49 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/corgi.c | 37 | ||||
-rw-r--r-- | arch/arm/mach-pxa/corgi_lcd.c | 197 | ||||
-rw-r--r-- | arch/arm/mach-pxa/corgi_ssp.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-pxa/sharpsl.h | 34 | ||||
-rw-r--r-- | arch/arm/mach-pxa/spitz.c | 380 |
7 files changed, 714 insertions, 50 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 405a55f2287..3e5f69bb5ac 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -20,40 +20,66 @@ config ARCH_PXA_IDP select PXA25x config PXA_SHARPSL - bool "SHARP SL-5600 and SL-C7xx Models" - select PXA25x + bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models" select SHARP_SCOOP select SHARP_PARAM help Say Y here if you intend to run this kernel on a - Sharp SL-5600 (Poodle), Sharp SL-C700 (Corgi), - SL-C750 (Shepherd) or a Sharp SL-C760 (Husky) - handheld computer. + Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi), + SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita), + SL-C3000 (Spitz) or SL-C3100 (Borzoi) handheld computer. endchoice +if PXA_SHARPSL + +choice + prompt "Select target Sharp Zaurus device range" + +config PXA_SHARPSL_25x + bool "Sharp PXA25x models (SL-5600 and SL-C7xx)" + select PXA25x + +config PXA_SHARPSL_27x + bool "Sharp PXA270 models (SL-Cxx00)" + select PXA27x + +endchoice + +endif + endmenu config MACH_POODLE bool "Enable Sharp SL-5600 (Poodle) Support" - depends PXA_SHARPSL + depends PXA_SHARPSL_25x select SHARP_LOCOMO config MACH_CORGI bool "Enable Sharp SL-C700 (Corgi) Support" - depends PXA_SHARPSL + depends PXA_SHARPSL_25x select PXA_SHARP_C7xx config MACH_SHEPHERD bool "Enable Sharp SL-C750 (Shepherd) Support" - depends PXA_SHARPSL + depends PXA_SHARPSL_25x select PXA_SHARP_C7xx config MACH_HUSKY bool "Enable Sharp SL-C760 (Husky) Support" - depends PXA_SHARPSL + depends PXA_SHARPSL_25x select PXA_SHARP_C7xx +config MACH_SPITZ + bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" + depends PXA_SHARPSL_27x + select PXA_SHARP_Cxx00 + +config MACH_BORZOI + bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support" + depends PXA_SHARPSL_27x + select PXA_SHARP_Cxx00 + config PXA25x bool help @@ -74,4 +100,9 @@ config PXA_SHARP_C7xx help Enable support for all Sharp C7xx models +config PXA_SHARP_Cxx00 + bool + help + Enable common support for Sharp Cxx00 models + endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 33dae99ec2d..f609a0f232c 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o obj-$(CONFIG_ARCH_PXA_IDP) += idp.o obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o +obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o obj-$(CONFIG_MACH_POODLE) += poodle.o # Support for blinky lights diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 07b5dd45356..426c2bc517e 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -41,6 +41,7 @@ #include <asm/hardware/scoop.h> #include "generic.h" +#include "sharpsl.h" /* @@ -94,14 +95,30 @@ struct platform_device corgissp_device = { .id = -1, }; +struct corgissp_machinfo corgi_ssp_machinfo = { + .port = 1, + .cs_lcdcon = CORGI_GPIO_LCDCON_CS, + .cs_ads7846 = CORGI_GPIO_ADS7846_CS, + .cs_max1111 = CORGI_GPIO_MAX1111_CS, + .clk_lcdcon = 76, + .clk_ads7846 = 2, + .clk_max1111 = 8, +}; + /* * Corgi Backlight Device */ +static struct corgibl_machinfo corgi_bl_machinfo = { + .max_intensity = 0x2f, + .set_bl_intensity = corgi_bl_set_intensity, +}; + static struct platform_device corgibl_device = { .name = "corgi-bl", .dev = { .parent = &corgifb_device.dev, + .platform_data = &corgi_bl_machinfo, }, .id = -1, }; @@ -119,12 +136,29 @@ static struct platform_device corgikbd_device = { /* * Corgi Touch Screen Device */ +static struct resource corgits_resources[] = { + [0] = { + .start = CORGI_IRQ_GPIO_TP_INT, + .end = CORGI_IRQ_GPIO_TP_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct corgits_machinfo corgi_ts_machinfo = { + .get_hsync_len = corgi_get_hsync_len, + .put_hsync = corgi_put_hsync, + .wait_hsync = corgi_wait_hsync, +}; + static struct platform_device corgits_device = { .name = "corgi-ts", .dev = { .parent = &corgissp_device.dev, + .platform_data = &corgi_ts_machinfo, }, .id = -1, + .num_resources = ARRAY_SIZE(corgits_resources), + .resource = corgits_resources, }; @@ -225,7 +259,10 @@ static struct platform_device *devices[] __initdata = { static void __init corgi_init(void) { + corgi_ssp_set_machinfo(&corgi_ssp_machinfo); + pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); + pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN); pxa_set_udc_info(&udc_info); pxa_set_mci_info(&corgi_mci_platform_data); diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c index deac29c0029..c5efcd04fcb 100644 --- a/arch/arm/mach-pxa/corgi_lcd.c +++ b/arch/arm/mach-pxa/corgi_lcd.c @@ -1,10 +1,14 @@ /* * linux/drivers/video/w100fb.c * - * Corgi LCD Specific Code for ATI Imageon w100 (Wallaby) + * Corgi/Spitz LCD Specific Code * * Copyright (C) 2005 Richard Purdie * + * Connectivity: + * Corgi - LCD to ATI Imageon w100 (Wallaby) + * Spitz - LCD to PXA Framebuffer + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -14,9 +18,17 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/module.h> +#include <asm/mach-types.h> +#include <asm/arch/akita.h> #include <asm/arch/corgi.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/sharpsl.h> +#include <asm/arch/spitz.h> +#include <asm/hardware/scoop.h> #include <asm/mach/sharpsl_param.h> -#include <video/w100fb.h> +#include "generic.h" /* Register Addresses */ #define RESCTL_ADRS 0x00 @@ -134,10 +146,10 @@ static void lcdtg_set_common_voltage(u8 base_data, u8 data) } /* Set Phase Adjuct */ -static void lcdtg_set_phadadj(struct w100fb_par *par) +static void lcdtg_set_phadadj(int mode) { int adj; - switch(par->xres) { + switch(mode) { case 480: case 640: /* Setting for VGA */ @@ -161,7 +173,7 @@ static void lcdtg_set_phadadj(struct w100fb_par *par) static int lcd_inited; -static void lcdtg_hw_init(struct w100fb_par *par) +static void lcdtg_hw_init(int mode) { if (!lcd_inited) { int comadj; @@ -215,7 +227,7 @@ static void lcdtg_hw_init(struct w100fb_par *par) corgi_ssp_lcdtg_send(PICTRL_ADRS, 0); /* Set Phase Adjuct */ - lcdtg_set_phadadj(par); + lcdtg_set_phadadj(mode); /* Initialize for Input Signals from ATI */ corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE @@ -224,10 +236,10 @@ static void lcdtg_hw_init(struct w100fb_par *par) lcd_inited=1; } else { - lcdtg_set_phadadj(par); + lcdtg_set_phadadj(mode); } - switch(par->xres) { + switch(mode) { case 480: case 640: /* Set Lcd Resolution (VGA) */ @@ -242,7 +254,7 @@ static void lcdtg_hw_init(struct w100fb_par *par) } } -static void lcdtg_suspend(struct w100fb_par *par) +static void lcdtg_suspend(void) { /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ mdelay(34); @@ -276,15 +288,30 @@ static void lcdtg_suspend(struct w100fb_par *par) lcd_inited = 0; } -static struct w100_tg_info corgi_lcdtg_info = { - .change=lcdtg_hw_init, - .suspend=lcdtg_suspend, - .resume=lcdtg_hw_init, -}; /* * Corgi w100 Frame Buffer Device */ +#ifdef CONFIG_PXA_SHARP_C7xx + +#include <video/w100fb.h> + +static void w100_lcdtg_suspend(struct w100fb_par *par) +{ + lcdtg_suspend(); +} + +static void w100_lcdtg_init(struct w100fb_par *par) +{ + lcdtg_hw_init(par->xres); +} + + +static struct w100_tg_info corgi_lcdtg_info = { + .change = w100_lcdtg_init, + .suspend = w100_lcdtg_suspend, + .resume = w100_lcdtg_init, +}; static struct w100_mem_info corgi_fb_mem = { .ext_cntl = 0x00040003, @@ -394,3 +421,145 @@ struct platform_device corgifb_device = { }, }; +#endif + + +/* + * Spitz PXA Frame Buffer Device + */ +#ifdef CONFIG_PXA_SHARP_Cxx00 + +#include <asm/arch/pxafb.h> + +void spitz_lcd_power(int on) +{ + if (on) + lcdtg_hw_init(480); + else + lcdtg_suspend(); +} + +#endif + + +/* + * Corgi/Spitz Touchscreen to LCD interface + */ +static unsigned long (*get_hsync_time)(struct device *dev); + +static void inline sharpsl_wait_sync(int gpio) +{ + while((GPLR(gpio) & GPIO_bit(gpio)) == 0); + while((GPLR(gpio) & GPIO_bit(gpio)) != 0); +} + +#ifdef CONFIG_PXA_SHARP_C7xx +unsigned long corgi_get_hsync_len(void) +{ + if (!get_hsync_time) + get_hsync_time = symbol_get(w100fb_get_hsynclen); + if (!get_hsync_time) + return 0; + + return get_hsync_time(&corgifb_device.dev); +} + +void corgi_put_hsync(void) +{ + if (get_hsync_time) + symbol_put(w100fb_get_hsynclen); +} + +void corgi_wait_hsync(void) +{ + sharpsl_wait_sync(CORGI_GPIO_HSYNC); +} +#endif + +#ifdef CONFIG_PXA_SHARP_Cxx00 +unsigned long spitz_get_hsync_len(void) +{ + if (!get_hsync_time) + get_hsync_time = symbol_get(pxafb_get_hsync_time); + if (!get_hsync_time) + return 0; + + return pxafb_get_hsync_time(&pxafb_device.dev); +} + +void spitz_put_hsync(void) +{ + if (get_hsync_time) + symbol_put(pxafb_get_hsync_time); +} + +void spitz_wait_hsync(void) +{ + sharpsl_wait_sync(SPITZ_GPIO_HSYNC); +} +#endif + +/* + * Corgi/Spitz Backlight Power + */ +#ifdef CONFIG_PXA_SHARP_C7xx +void corgi_bl_set_intensity(int intensity) +{ + if (intensity > 0x10) + intensity += 0x10; + + /* Bits 0-4 are accessed via the SSP interface */ + corgi_ssp_blduty_set(intensity & 0x1f); + + /* Bit 5 is via SCOOP */ + if (intensity & 0x0020) + set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); + else + reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); +} +#endif + + +#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI) +void spitz_bl_set_intensity(int intensity) +{ + if (intensity > 0x10) + intensity += 0x10; + + /* Bits 0-4 are accessed via the SSP interface */ + corgi_ssp_blduty_set(intensity & 0x1f); + + /* Bit 5 is via SCOOP */ + if (intensity & 0x0020) + reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT); + else + set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT); + + if (intensity) + set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON); + else + reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON); +} +#endif + +#ifdef CONFIG_MACH_AKITA +void akita_bl_set_intensity(int intensity) +{ + if (intensity > 0x10) + intensity += 0x10; + + /* Bits 0-4 are accessed via the SSP interface */ + corgi_ssp_blduty_set(intensity & 0x1f); + + /* Bit 5 is via IO-Expander */ + if (intensity & 0x0020) + akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT); + else + akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT); + + if (intensity) + akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON); + else + akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON); +} +#endif diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 366a9bde3d8..0ef42828705 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -1,7 +1,7 @@ /* * SSP control code for Sharp Corgi devices * - * Copyright (c) 2004 Richard Purdie + * Copyright (c) 2004-2005 Richard Purdie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -17,14 +17,16 @@ #include <linux/delay.h> #include <linux/device.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/arch/ssp.h> -#include <asm/arch/corgi.h> #include <asm/arch/pxa-regs.h> +#include "sharpsl.h" static DEFINE_SPINLOCK(corgi_ssp_lock); static struct ssp_dev corgi_ssp_dev; static struct ssp_state corgi_ssp_state; +static struct corgissp_machinfo *ssp_machinfo; /* * There are three devices connected to the SSP interface: @@ -48,12 +50,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data) unsigned long ret,flag; spin_lock_irqsave(&corgi_ssp_lock, flag); - GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); ssp_write_word(&corgi_ssp_dev,data); ret = ssp_read_word(&corgi_ssp_dev); - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); spin_unlock_irqrestore(&corgi_ssp_lock, flag); return ret; @@ -66,12 +68,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data) void corgi_ssp_ads7846_lock(void) { spin_lock(&corgi_ssp_lock); - GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); } void corgi_ssp_ads7846_unlock(void) { - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); spin_unlock(&corgi_ssp_lock); } @@ -97,23 +99,27 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get); */ unsigned long corgi_ssp_dac_put(ulong data) { - unsigned long flag; + unsigned long flag, sscr1 = SSCR1_SPH; spin_lock_irqsave(&corgi_ssp_lock, flag); - GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); + + if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) + sscr1 = 0; ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76)); + ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon)); ssp_enable(&corgi_ssp_dev); + GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); ssp_write_word(&corgi_ssp_dev,data); /* Read null data back from device to prevent SSP overflow */ ssp_read_word(&corgi_ssp_dev); + GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); ssp_enable(&corgi_ssp_dev); - GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); + spin_unlock_irqrestore(&corgi_ssp_lock, flag); return 0; @@ -141,9 +147,9 @@ int corgi_ssp_max1111_get(ulong data) int voltage,voltage1,voltage2; spin_lock_irqsave(&corgi_ssp_lock, flag); - GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); + GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8)); + ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111)); ssp_enable(&corgi_ssp_dev); udelay(1); @@ -161,9 +167,9 @@ int corgi_ssp_max1111_get(ulong data) voltage2=ssp_read_word(&corgi_ssp_dev); ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); ssp_enable(&corgi_ssp_dev); - GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); spin_unlock_irqrestore(&corgi_ssp_lock, flag); if (voltage1 & 0xc0 || voltage2 & 0x3f) @@ -179,25 +185,31 @@ EXPORT_SYMBOL(corgi_ssp_max1111_get); /* * Support Routines */ -int __init corgi_ssp_probe(struct device *dev) + +void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo) +{ + ssp_machinfo = machinfo; +} + +static int __init corgi_ssp_probe(struct device *dev) { int ret; /* Chip Select - Disable All */ - GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */ - GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ - GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */ - GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ - GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS); /* output */ - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ + GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ + GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ + GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ + GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ - ret=ssp_init(&corgi_ssp_dev,1); + ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port); if (ret) printk(KERN_ERR "Unable to register SSP handler!\n"); else { ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); ssp_enable(&corgi_ssp_dev); } @@ -222,9 +234,9 @@ static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level) static int corgi_ssp_resume(struct device *dev, u32 level) { if (level == RESUME_POWER_ON) { - GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ - GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ + GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); ssp_enable(&corgi_ssp_dev); } diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h new file mode 100644 index 00000000000..3977a77aacd --- /dev/null +++ b/arch/arm/mach-pxa/sharpsl.h @@ -0,0 +1,34 @@ +/* + * SharpSL SSP Driver + */ + +struct corgissp_machinfo { + int port; + int cs_lcdcon; + int cs_ads7846; + int cs_max1111; + int clk_lcdcon; + int clk_ads7846; + int clk_max1111; +}; + +void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo); + +/* + * SharpSL Backlight + */ + +void corgi_bl_set_intensity(int intensity); +void spitz_bl_set_intensity(int intensity); +void akita_bl_set_intensity(int intensity); + +/* + * SharpSL Touchscreen Driver + */ + +unsigned long corgi_get_hsync_len(void); +unsigned long spitz_get_hsync_len(void); +void corgi_put_hsync(void); +void spitz_put_hsync(void); +void corgi_wait_hsync(void); +void spitz_wait_hsync(void); diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c new file mode 100644 index 00000000000..568afe3d6e1 --- /dev/null +++ b/arch/arm/mach-pxa/spitz.c @@ -0,0 +1,380 @@ +/* + * Support for Sharp SL-Cxx00 Series of PDAs + * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi) + * + * Copyright (c) 2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches/lubbock.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/delay.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/mmc/host.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/irq.h> +#include <asm/arch/mmc.h> +#include <asm/arch/udc.h> +#include <asm/arch/ohci.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/akita.h> +#include <asm/arch/spitz.h> +#include <asm/arch/sharpsl.h> + +#include <asm/mach/sharpsl_param.h> +#include <asm/hardware/scoop.h> + +#include "generic.h" +#include "sharpsl.h" + +/* + * Spitz SCOOP Device #1 + */ +static struct resource spitz_scoop_resources[] = { + [0] = { + .start = 0x10800000, + .end = 0x10800fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct scoop_config spitz_scoop_setup = { + .io_dir = SPITZ_SCP_IO_DIR, + .io_out = SPITZ_SCP_IO_OUT, + .suspend_clr = SPITZ_SCP_SUS_CLR, + .suspend_set = SPITZ_SCP_SUS_SET, +}; + +struct platform_device spitzscoop_device = { + .name = "sharp-scoop", + .id = 0, + .dev = { + .platform_data = &spitz_scoop_setup, + }, + .num_resources = ARRAY_SIZE(spitz_scoop_resources), + .resource = spitz_scoop_resources, +}; + +/* + * Spitz SCOOP Device #2 + */ +static struct resource spitz_scoop2_resources[] = { + [0] = { + .start = 0x08800040, + .end = 0x08800fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct scoop_config spitz_scoop2_setup = { + .io_dir = SPITZ_SCP2_IO_DIR, + .io_out = SPITZ_SCP2_IO_OUT, + .suspend_clr = SPITZ_SCP2_SUS_CLR, + .suspend_set = SPITZ_SCP2_SUS_SET, +}; + +struct platform_device spitzscoop2_device = { + .name = "sharp-scoop", + .id = 1, + .dev = { + .platform_data = &spitz_scoop2_setup, + }, + .num_resources = ARRAY_SIZE(spitz_scoop2_resources), + .resource = spitz_scoop2_resources, +}; + +static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { +{ + .dev = &spitzscoop_device.dev, + .irq = SPITZ_IRQ_GPIO_CF_IRQ, + .cd_irq = SPITZ_IRQ_GPIO_CF_CD, + .cd_irq_str = "PCMCIA0 CD", +},{ + .dev = &spitzscoop2_device.dev, + .irq = SPITZ_IRQ_GPIO_CF2_IRQ, + .cd_irq = -1, +}, +}; + + +/* + * Spitz SSP Device + * + * Set the parent as the scoop device because a lot of SSP devices + * also use scoop functions and this makes the power up/down order + * work correctly. + */ +struct platform_device spitzssp_device = { + .name = "corgi-ssp", + .dev = { + .parent = &spitzscoop_device.dev, + }, + .id = -1, +}; + +struct corgissp_machinfo spitz_ssp_machinfo = { + .port = 2, + .cs_lcdcon = SPITZ_GPIO_LCDCON_CS, + .cs_ads7846 = SPITZ_GPIO_ADS7846_CS, + .cs_max1111 = SPITZ_GPIO_MAX1111_CS, + .clk_lcdcon = 520, + .clk_ads7846 = 14, + .clk_max1111 = 56, +}; + + +/* + * Spitz Backlight Device + */ +static struct corgibl_machinfo spitz_bl_machinfo = { + .max_intensity = 0x2f, +}; + +static struct platform_device spitzbl_device = { + .name = "corgi-bl", + .dev = { + .platform_data = &spitz_bl_machinfo, + }, + .id = -1, +}; + + +/* + * Spitz Keyboard Device + */ +static struct platform_device spitzkbd_device = { + .name = "spitz-keyboard", + .id = -1, +}; + + +/* + * Spitz Touch Screen Device + */ +static struct resource spitzts_resources[] = { + [0] = { + .start = SPITZ_IRQ_GPIO_TP_INT, + .end = SPITZ_IRQ_GPIO_TP_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct corgits_machinfo spitz_ts_machinfo = { + .get_hsync_len = spitz_get_hsync_len, + .put_hsync = spitz_put_hsync, + .wait_hsync = spitz_wait_hsync, +}; + +static struct platform_device spitzts_device = { + .name = "corgi-ts", + .dev = { + .parent = &spitzssp_device.dev, + .platform_data = &spitz_ts_machinfo, + }, + .id = -1, + .num_resources = ARRAY_SIZE(spitzts_resources), + .resource = spitzts_resources, +}; + + +/* + * MMC/SD Device + * + * The card detect interrupt isn't debounced so we delay it by 250ms + * to give the card a chance to fully insert/eject. + */ + +static struct pxamci_platform_data spitz_mci_platform_data; + +static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(int, void *, struct pt_regs *), void *data) +{ + int err; + + /* setup GPIO for PXA27x MMC controller */ + pxa_gpio_mode(GPIO32_MMCCLK_MD); + pxa_gpio_mode(GPIO112_MMCCMD_MD); + pxa_gpio_mode(GPIO92_MMCDAT0_MD); + pxa_gpio_mode(GPIO109_MMCDAT1_MD); + pxa_gpio_mode(GPIO110_MMCDAT2_MD); + pxa_gpio_mode(GPIO111_MMCDAT3_MD); + pxa_gpio_mode(SPITZ_GPIO_nSD_DETECT | GPIO_IN); + pxa_gpio_mode(SPITZ_GPIO_nSD_WP | GPIO_IN); + + spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); + + err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT, + "MMC card detect", data); + if (err) { + printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + return -1; + } + + set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); + + return 0; +} + +/* Power control is shared with one of the CF slots so we have a mess */ +static void spitz_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data* p_d = dev->platform_data; + + unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); + + if (( 1 << vdd) & p_d->ocr_mask) { + /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ + set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); + mdelay(2); + write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04); + } else { + /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */ + write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04); + + if (!(cpr | 0x02)) { + mdelay(1); + reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); + } + } +} + +static int spitz_mci_get_ro(struct device *dev) +{ + return GPLR(SPITZ_GPIO_nSD_WP) & GPIO_bit(SPITZ_GPIO_nSD_WP); +} + +static void spitz_mci_exit(struct device *dev, void *data) +{ + free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data); +} + +static struct pxamci_platform_data spitz_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = spitz_mci_init, + .get_ro = spitz_mci_get_ro, + .setpower = spitz_mci_setpower, + .exit = spitz_mci_exit, +}; + + +/* + * Spitz PXA Framebuffer + */ +static struct pxafb_mach_info spitz_pxafb_info __initdata = { + .pixclock = 19231, + .xres = 480, + .yres = 640, + .bpp = 16, + .hsync_len = 40, + .left_margin = 46, + .right_margin = 125, + .vsync_len = 3, + .upper_margin = 1, + .lower_margin = 0, + .sync = 0, + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM, + .lccr3 = LCCR3_PixRsEdg | LCCR3_OutEnH, + .pxafb_lcd_power = spitz_lcd_power, +}; + + +static struct platform_device *devices[] __initdata = { + &spitzscoop_device, + &spitzssp_device, + &spitzkbd_device, + &spitzts_device, + &spitzbl_device, + &spitzbattery_device, +}; + +static void __init common_init(void) +{ + PMCR = 0x00; + + /* setup sleep mode values */ + PWER = 0x00000002; + PFER = 0x00000000; + PRER = 0x00000002; + PGSR0 = 0x0158C000; + PGSR1 = 0x00FF0080; + PGSR2 = 0x0001C004; + + /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ + PCFR |= PCFR_OPDE; + + corgi_ssp_set_machinfo(&spitz_ssp_machinfo); + + pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + pxa_set_mci_info(&spitz_mci_platform_data); + pxafb_device.dev.parent = &spitzssp_device.dev; + set_pxa_fb_info(&spitz_pxafb_info); +} + +static void __init spitz_init(void) +{ + scoop_num = 2; + scoop_devs = &spitz_pcmcia_scoop[0]; + spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; + + common_init(); + + platform_device_register(&spitzscoop2_device); +} + +static void __init fixup_spitz(struct machine_desc *desc, + struct tag *tags, char **cmdline, struct meminfo *mi) +{ + sharpsl_save_param(); + mi->nr_banks = 1; + mi->bank[0].start = 0xa0000000; + mi->bank[0].node = 0; + mi->bank[0].size = (64*1024*1024); +} + +#ifdef CONFIG_MACH_SPITZ +MACHINE_START(SPITZ, "SHARP Spitz") + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_spitz, + .map_io = pxa_map_io, + .init_irq = pxa_init_irq, + .init_machine = spitz_init, + .timer = &pxa_timer, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_BORZOI +MACHINE_START(BORZOI, "SHARP Borzoi") + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_spitz, + .map_io = pxa_map_io, + .init_irq = pxa_init_irq, + .init_machine = spitz_init, + .timer = &pxa_timer, +MACHINE_END +#endif |