summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Kconfig49
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/corgi.c37
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c197
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c66
-rw-r--r--arch/arm/mach-pxa/sharpsl.h34
-rw-r--r--arch/arm/mach-pxa/spitz.c380
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