From 6888f7a3d04510bc7c992b153e638743e3702ae6 Mon Sep 17 00:00:00 2001
From: z3deverp <z3@vmsv-debian.(none)>
Date: Thu, 4 Dec 2008 00:04:50 +0900
Subject: [PATCH] sha_pon basic support

---
 arch/arm/mach-pxa/Kconfig                |   12 +
 arch/arm/mach-pxa/Makefile               |    1 +
 arch/arm/mach-pxa/include/mach/sha_pon.h |   42 +++
 arch/arm/mach-pxa/sha_pon.c              |  535 ++++++++++++++++++++++++++++++
 4 files changed, 590 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
old mode 100644
new mode 100755
index e8ee7ec..b11a26e
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -293,6 +293,18 @@ config MACH_EZX_E2
 	default y
 	depends on PXA_EZX
 
+config ARCH_SHA_PON
+	bool "Sharp W-ZERO3 WS0xxSH series smartphone"
+	select PXA27x
+	select MACH_SHA_PON003
+	select MACH_SHA_PON004
+	select MACH_SHA_PON007
+	select MACH_SHA_PON011
+	select MACH_SHA_PON020
+	help
+	  Say Y here if you intend to run this kernel on a
+	  Sharp W-ZERO3 WS0xxSH series(Sha_pon0xx) smartphone.
+
 endmenu
 
 config PXA25x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
old mode 100644
new mode 100755
index 99ecbe7..44854d4
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_MACH_SAAR)		+= saar.o
 
 obj-$(CONFIG_MACH_ARMCORE)      += cm-x270.o
 obj-$(CONFIG_PXA_EZX)           += ezx.o
+obj-$(CONFIG_ARCH_SHA_PON)      += sha_pon.o
 
 # Support for blinky lights
 led-y := leds.o
diff --git a/arch/arm/mach-pxa/include/mach/sha_pon.h b/arch/arm/mach-pxa/include/mach/sha_pon.h
new file mode 100755
index 0000000..9261226
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/sha_pon.h
@@ -0,0 +1,42 @@
+/*
+ *  linux/include/asm-arm/arch-pxa/sha_pon.h
+ *
+ *  SHA_PON specific bits definition
+ *
+ *  Auther: zaki
+ *
+ *  Based on linux/include/asm-arm/arch-aaec2000/aaed2000.h
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_SHA_PON_H
+#define __ASM_ARCH_SHA_PON_H
+
+
+/* External GPIOs. */
+
+#define EXT_GPIO_PBASE	PXA_CS2_PHYS
+#define EXT_GPIO_VBASE	0xf8100000
+#define EXT_GPIO_LENGTH	0x00100000
+
+#define __ext_gpio_p2v(x)	((x) - EXT_GPIO_PBASE + EXT_GPIO_VBASE)
+#define __ext_gpio_v2p(x)	((x) + EXT_GPIO_PBASE - EXT_GPIO_VBASE)
+
+#define __EXT_GPIO_REG(x)	(*((volatile u8 *)__ext_gpio_p2v(x)))
+#define __EXT_GPIO_PREG(x)	(__ext_gpio_v2p((u32)&(x)))
+
+
+#define SHA_PON_CPLD00	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x00)
+#define SHA_PON_CPLD04	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x04)
+#define SHA_PON_CPLD08	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x08)
+#define SHA_PON_CPLD0c	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x0c)
+#define SHA_PON_CPLD10	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x10)
+#define SHA_PON_CPLD14	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x14)
+#define SHA_PON_CPLD18	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x18)
+#define SHA_PON_CPLD1c	__EXT_GPIO_REG(EXT_GPIO_PBASE+0x1c)
+
+
+#endif /* __ARM_ARCH_SHA_PON_H */
diff --git a/arch/arm/mach-pxa/sha_pon.c b/arch/arm/mach-pxa/sha_pon.c
new file mode 100755
index 0000000..4e221ab
--- /dev/null
+++ b/arch/arm/mach-pxa/sha_pon.c
@@ -0,0 +1,535 @@
+/*
+ * linux/arch/arm/mach-pxa/sha_pon.c
+ *
+ * Support for the Sharp W-ZERO3 series(sha_pon0**).
+ * based on lpd270.c, corgi.c
+ *
+ * Author:	zaki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define	UDC	0	/* 0:disable udc driver */
+#define	TS	0	/* 0:disable touchscreen driver */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/pxafb.h>
+#if UDC
+#include <mach/udc.h>
+#endif
+#include <mach/ohci.h>
+#include <mach/i2c.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/camera.h>
+#include <mach/audio.h>
+#include <mach/system.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#include <mach/sha_pon.h>
+#if TS
+#include "sha_pon.h"
+#endif
+
+
+static struct map_desc sha_pon_io_desc[] __initdata = {
+	{
+	.virtual	= EXT_GPIO_VBASE,
+	.pfn            = __phys_to_pfn(EXT_GPIO_PBASE),
+	.length         = EXT_GPIO_LENGTH,
+	.type           = MT_DEVICE
+	},
+};
+
+
+/*
+ * Keyboard Device
+ */
+static struct platform_device sha_ponkbd_device = {
+	.name		= "sha_pon-keyboard",
+	.id		= -1,
+};
+
+
+/* sha_pon003, sha_pon004 LCD panel */
+static struct pxafb_mode_info sharp_ls037v7dw01_mode = {
+	.pixclock       = 39700,
+	.xres           = 480,
+	.yres           = 640,
+	.bpp            = 16,
+	.hsync_len      = 2,
+	.left_margin    = 78+64,	/* datasheet value +/- tuned value */
+	.right_margin   = 88-64,	/* datasheet value +/- tuned value */
+	.vsync_len      = 1,
+	.upper_margin   = 2,
+	.lower_margin   = 6,
+	.sync           = 0,	/*FB_SYNC_HOR_LOW_ACT | FB_SYNC_VERT_LOW_ACT*/
+};
+
+static struct pxafb_mach_info sharp_ls037v7dw01 = {
+	.modes		= &sharp_ls037v7dw01_mode,
+	.num_modes	= 1,
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_RISE | LCD_ALTERNATE_MAPPING
+};
+
+
+/* sha_pon007 LCD panel */
+#define	sharp_ls028v7pw01	sharp_ls037v7dw01	/* compatible LCD panel */
+
+
+/* sha_pon011 LCD panel */
+static struct pxafb_mode_info pxa_sharp_ws011sh_mode = {
+	.pixclock       = 31384,	/* guessed value */
+	.xres           = 480,
+	.yres           = 800,
+	.bpp            = 16,
+	.hsync_len      = 2,	/* guessed value */
+	.left_margin    = 78-57,	/* guessed value +/- tuned value */
+	.right_margin   = 88+57,	/* guessed value +/- tuned value */
+	.vsync_len      = 1,	/* guessed value */
+	.upper_margin   = 2,	/* guessed value */
+	.lower_margin   = 6,	/* guessed value */
+	.sync           = 0,	/*FB_SYNC_HOR_LOW_ACT | FB_SYNC_VERT_LOW_ACT*/
+};
+
+static struct pxafb_mach_info pxa_sharp_ws011sh = {
+	.modes		= &pxa_sharp_ws011sh_mode,
+	.num_modes	= 1,
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_RISE | LCD_ALTERNATE_MAPPING
+};
+
+
+#if TS
+/* SSP Device */
+struct sha_ponssp_machinfo sha_pon003ssp_machinfo = {	/* not tested */
+        .port		= 2, /* guessed value */
+	.cs_tsc2046	= SHA_PON_GPIO_TSC2046_CS,
+	.clk_tsc2046	= 6, /* datasheet value : div >= source13MHz / dclk2.5MHz(max) = 5.2 */
+	.cs_unknown	= SHA_PON_GPIO_UNKNOWN_CS,
+};
+
+
+struct sha_ponssp_machinfo sha_pon007ssp_machinfo = {
+        .port		= 2, /* guessed value */
+	.cs_tsc2046	= SHA_PON_GPIO_TSC2046_CS,
+	.clk_tsc2046	= 6, /* datasheet value : div >= source13MHz / dclk2.5MHz(max) = 5.2 */
+	.cs_unknown	= SHA_PON_GPIO_UNKNOWN_CS,
+};
+
+
+struct sha_ponssp_machinfo sha_pon011ssp_machinfo = {	/* not tested */
+        .port		= 2, /* guessed value */
+	.cs_tsc2046	= SHA_PON_GPIO_TSC2046_CS,
+	.clk_tsc2046	= 6, /* datasheet value : div >= source13MHz / dclk2.5MHz(max) = 5.2 */
+	.cs_unknown	= SHA_PON_GPIO_UNKNOWN_CS,
+};
+
+
+struct platform_device sha_ponssp_device = {
+	.name		= "sha_pon-ssp",
+	.id		= -1,
+};
+
+
+/* Touch Screen Device */
+static int sha_pon003ts_status(void)
+{
+	/* true:pendown, false:penup */
+	return( 0 );	/* FIXME */
+}
+
+
+static int sha_pon007ts_status(void)
+{
+	/* true:pendown, false:penup */
+	return( (GPLR(SHA_PON007_GPIO_TP) & GPIO_bit(SHA_PON007_GPIO_TP)) == 0 );
+}
+
+
+static int sha_pon011ts_status(void)
+{
+	/* true:pendown, false:penup */
+	return( 0 );	/* FIXME */
+}
+
+
+static struct platform_device sha_pon003ts_device = {
+	.name		= "sha_pon-ts",
+	.dev		= {
+ 		.parent = &sha_ponssp_device.dev,
+		.platform_data	= sha_pon003ts_status,
+	},
+	.id		= -1,
+};
+
+static struct platform_device sha_pon007ts_device = {
+	.name		= "sha_pon-ts",
+	.dev		= {
+ 		.parent = &sha_ponssp_device.dev,
+		.platform_data	= sha_pon007ts_status,
+	},
+	.id		= -1,
+};
+
+static struct platform_device sha_pon011ts_device = {
+	.name		= "sha_pon-ts",
+	.dev		= {
+ 		.parent = &sha_ponssp_device.dev,
+		.platform_data	= sha_pon011ts_status,
+	},
+	.id		= -1,
+};
+#endif
+
+/* W-SIM */
+static void sha_pon_reset_wsim(void)
+{
+#if 0		/* FIXME: LCD is blank on only 003,004...why? */
+
+	/* Power-ON-reset W-SIM device as a modem connected to FFUART */
+	/* power down */
+	SHA_PON_CPLD10 = 0x00;
+	/* wait to discharge power */
+	mdelay(800*4);		/* tested value=800msec(min) --> margine factor=4 */
+	/* power up */
+	SHA_PON_CPLD10 = 0x10;
+
+#endif
+}
+
+
+#if UDC
+/* USB gadget */
+static void sha_pon_udc_command(int cmd)
+{
+	switch( cmd ) {
+	case PXA2XX_UDC_CMD_CONNECT:
+		/* enable USB port2, Differencial, Device mode, D+ Pullup(Full speed) */
+		UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+		break;
+	case PXA2XX_UDC_CMD_DISCONNECT:
+		/* disable USB port2 */
+		UP2OCR = 0;
+		break;
+	}
+}
+
+static struct pxa2xx_udc_mach_info sha_pon_udc_info = {
+	.udc_command = sha_pon_udc_command,
+};
+#endif
+
+
+/* USB Host */
+static int sha_pon_usb_init(struct device *dev)
+{
+	/* enable USB port2, Differencial, Host mode, D+/D- Pulldown */
+	UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
+	
+	/* enable power for USB port2 */
+	UHCHR &= ~(UHCHR_SSEP2 | UHCHR_SSE);
+	
+	/* TEST: enable power for USB port1 */
+	/* must be disabled if detect over curent at port 1 */
+	UHCHR &= ~(UHCHR_SSEP1);
+	
+	return(0);
+}
+
+static void sha_pon_usb_exit(struct device *dev)
+{
+	/* TEST: disable power for USB port1 */
+	UHCHR |= (UHCHR_SSEP1);
+
+	/* disable power for USB port2 */
+	UHCHR |= (UHCHR_SSEP2 | UHCHR_SSE);
+	
+	/* disable USB port2 */
+	UP2OCR = 0;
+
+}
+
+
+static struct pxaohci_platform_data sha_pon_usb_info = {
+	.init		= sha_pon_usb_init,
+	.exit		= sha_pon_usb_exit,
+	.port_mode	= PMM_NPS_MODE,		/* FIXME: Non-power switching mode */
+	/* 
+	 * WS003SH/WS004SH:
+	 *    .power_budget=0 because VBUS is for only internal device.
+	 * WS007SH/WS011SH:
+	 *    VBUS power supply is max100mA.(Sharp's web support page)
+	 *    but,,, .power_budget=0 !! because of convenience. :-)
+	 */
+	.power_budget	= 0,			/* VBUS power supply per port(unit:mA) */
+};
+
+
+/* MMC */
+static int sha_pon_mci_get_ro(struct device *dev)
+{
+	/* nimiSD or microSD do not have write-protect function */
+	return 0;	/* read/write */
+}
+
+
+static struct pxamci_platform_data sha_pon_mmc_info = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,		/* available voltages */
+	.get_ro		= sha_pon_mci_get_ro,			/* readonly detection */
+#if 0
+	unsigned long detect_delay;		/* delay in jiffies before detecting cards after interrupt */
+	int (*init)(struct device *, irq_handler_t , void *);
+	void (*setpower)(struct device *, unsigned int);
+	void (*exit)(struct device *, void *);
+#endif
+};
+
+
+/* Irda */
+static struct pxaficp_platform_data sha_pon_irda_info = {
+#if 0
+	int transceiver_cap;
+	void (*transceiver_mode)(struct device *dev, int mode);
+	int (*startup)(struct device *dev);
+	void (*shutdown)(struct device *dev);
+#endif
+};
+
+
+/* Camera */
+static struct pxacamera_platform_data sha_pon_camera_info = {
+#if 0
+	int (*init)(struct device *);
+	int (*power)(struct device *, int);
+	int (*reset)(struct device *, int);
+
+	unsigned long flags;
+	unsigned long mclk_10khz;
+#endif
+};
+
+
+/* Audio */
+pxa2xx_audio_ops_t sha_pon_audio_info = {
+#if 0
+	int (*startup)(struct snd_pcm_substream *, void *);
+	void (*shutdown)(struct snd_pcm_substream *, void *);
+	void (*suspend)(void *);
+	void (*resume)(void *);
+	void *priv;
+#endif
+};
+
+
+static struct platform_device *devices003[] __initdata = {
+	&sha_ponkbd_device,
+#if TS
+	&sha_ponssp_device,
+	&sha_pon003ts_device,
+#endif
+};
+
+static struct platform_device *devices007[] __initdata = {
+	&sha_ponkbd_device,
+#if TS
+	&sha_ponssp_device,
+	&sha_pon007ts_device,
+#endif
+};
+
+static struct platform_device *devices011[] __initdata = {
+	&sha_ponkbd_device,
+#if TS
+	&sha_ponssp_device,
+	&sha_pon011ts_device,
+#endif
+};
+
+
+static unsigned long sha_pon_mfp[] __initdata = {
+	
+	/* FFUART */
+	GPIO98_FFUART_RTS,
+	GPIO99_FFUART_TXD,
+};
+
+
+static void __init sha_pon003_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(sha_pon_mfp));
+	set_pxa_fb_info(&sharp_ls037v7dw01);
+#if UDC
+	pxa_set_udc_info(&sha_pon_udc_info);
+#endif
+	pxa_set_ohci_info(&sha_pon_usb_info);
+#if TS
+	sha_pon_ssp_set_machinfo(&sha_pon003ssp_machinfo);
+#endif
+	pxa_set_mci_info(&sha_pon_mmc_info);
+	pxa_set_camera_info(&sha_pon_camera_info);
+	pxa_set_ac97_info(&sha_pon_audio_info);
+	platform_add_devices(devices003, ARRAY_SIZE(devices003));
+}
+
+
+static void __init sha_pon007_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(sha_pon_mfp));
+	set_pxa_fb_info(&sharp_ls028v7pw01);
+
+#if UDC
+	pxa_set_udc_info(&sha_pon_udc_info);
+#endif
+	pxa_set_ohci_info(&sha_pon_usb_info);
+#if TS
+	sha_pon_ssp_set_machinfo(&sha_pon007ssp_machinfo);
+#endif
+	pxa_set_mci_info(&sha_pon_mmc_info);
+	pxa_set_camera_info(&sha_pon_camera_info);
+	pxa_set_ac97_info(&sha_pon_audio_info);
+	platform_add_devices(devices007, ARRAY_SIZE(devices007));
+}
+
+
+static void __init sha_pon011_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(sha_pon_mfp));
+	set_pxa_fb_info(&pxa_sharp_ws011sh);
+#if UDC
+	pxa_set_udc_info(&sha_pon_udc_info);
+#endif
+	pxa_set_ohci_info(&sha_pon_usb_info);
+#if TS
+	sha_pon_ssp_set_machinfo(&sha_pon011ssp_machinfo);
+#endif
+	pxa_set_mci_info(&sha_pon_mmc_info);
+	pxa_set_camera_info(&sha_pon_camera_info);
+	pxa_set_ac97_info(&sha_pon_audio_info);
+/*
+	pxa_set_ficp_info(&sha_pon_irda_info);
+*/
+	platform_add_devices(devices011, ARRAY_SIZE(devices011));
+}
+
+
+static void __init sha_pon_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(sha_pon_io_desc, ARRAY_SIZE(sha_pon_io_desc));
+	
+	/* for use I SRAM as framebuffer.  */
+	PSLR = (PSLR&~0x002ff0f3) | 0x00000F04;
+			/* SL_R0-3 = 1111 : SRAM0-3 retains state in sleep mode */
+			/* SL_PI = 01 : PI power domain retains state in sleep mode */
+			/*   PI domain -- PWR_I2C & timer13M */
+			/* write 0 to reserve bit */
+	
+	PSTR = 0x00000f04;		/* test value */
+	PCFR = 0x00000000;		/* test value */
+
+#if 0	/* cannot access pxafb register at this, because pxafb is'nt initialized yet... */
+	/* FIXME: LCCR4-bit31 PCDDIV=1 is better than PCDDIV=0, if pxafb.c allows. */
+#define PXAFB_LCCR4       __REG(0x44000010)  /* LCD Controller Control Register 4 */
+	PXAFB_LCCR4 = 0x00000000L;		/* PCDDIV=1(WM)->0(Linux) */
+#endif
+
+
+#if TS
+#if 0	/* GPIO for detect touchscreen, default:input */
+	pxa_gpio_mode( SHA_PON007_GPIO_TP | GPIO_IN );	/* test for 007 */
+#endif
+#endif
+
+	sha_pon_reset_wsim();
+
+	/* initialize sleep mode regs (wake-up sources, etc) : NOT tested */
+/*
+	PGSR0 = 0x00008800;
+	PGSR1 = 0x00000002;
+	PGSR2 = 0x0001FC00;
+	PGSR3 = 0x00001F81;
+	PWER  = 0xC0000002;
+	PRER  = 0x00000002;
+	PFER  = 0x00000002;
+*/
+
+}
+
+
+MACHINE_START(SHA_PON003, "Sharp W-ZERO3 WS003SH")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000000,
+	.map_io		= sha_pon_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= sha_pon003_init,
+MACHINE_END
+
+
+MACHINE_START(SHA_PON004, "Sharp W-ZERO3 WS004SH")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000000,
+	.map_io		= sha_pon_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= sha_pon003_init,
+MACHINE_END
+
+
+MACHINE_START(SHA_PON007, "Sharp W-ZERO3[es] WS007SH")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000000,
+	.map_io		= sha_pon_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= sha_pon007_init,
+MACHINE_END
+
+
+MACHINE_START(SHA_PON011, "Sharp Advanced/W-ZERO3[es] WS011SH")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000000,
+	.map_io		= sha_pon_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= sha_pon011_init,
+MACHINE_END
+
+
+MACHINE_START(SHA_PON020, "Sharp WILLCOM 03 WS020SH")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000000,
+	.map_io		= sha_pon_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= sha_pon011_init,
+MACHINE_END
+
-- 
1.4.4.4

