2 * Support for Sharp SL-C7xx PDAs
3 * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky)
5 * Copyright (c) 2004-2005 Richard Purdie
7 * Based on Sharp's 2.4 kernel patches/lubbock.c
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/device.h>
18 #include <linux/major.h>
20 #include <linux/interrupt.h>
21 #include <linux/mmc/host.h>
23 #include <asm/setup.h>
24 #include <asm/memory.h>
25 #include <asm/mach-types.h>
26 #include <asm/hardware.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/map.h>
32 #include <asm/mach/irq.h>
34 #include <asm/arch/pxa-regs.h>
35 #include <asm/arch/irq.h>
36 #include <asm/arch/mmc.h>
37 #include <asm/arch/udc.h>
38 #include <asm/arch/corgi.h>
40 #include <asm/mach/sharpsl_param.h>
41 #include <asm/hardware/scoop.h>
42 #include <video/w100fb.h>
50 static struct resource corgi_scoop_resources
[] = {
54 .flags
= IORESOURCE_MEM
,
58 static struct scoop_config corgi_scoop_setup
= {
59 .io_dir
= CORGI_SCOOP_IO_DIR
,
60 .io_out
= CORGI_SCOOP_IO_OUT
,
63 struct platform_device corgiscoop_device
= {
64 .name
= "sharp-scoop",
67 .platform_data
= &corgi_scoop_setup
,
69 .num_resources
= ARRAY_SIZE(corgi_scoop_resources
),
70 .resource
= corgi_scoop_resources
,
77 * Set the parent as the scoop device because a lot of SSP devices
78 * also use scoop functions and this makes the power up/down order
81 static struct platform_device corgissp_device
= {
84 .parent
= &corgiscoop_device
.dev
,
91 * Corgi w100 Frame Buffer Device
93 static struct w100fb_mach_info corgi_fb_info
= {
94 .w100fb_ssp_send
= corgi_ssp_lcdtg_send
,
99 static struct resource corgi_fb_resources
[] = {
103 .flags
= IORESOURCE_MEM
,
107 static struct platform_device corgifb_device
= {
111 .platform_data
= &corgi_fb_info
,
112 .parent
= &corgissp_device
.dev
,
114 .num_resources
= ARRAY_SIZE(corgi_fb_resources
),
115 .resource
= corgi_fb_resources
,
120 * Corgi Backlight Device
122 static struct platform_device corgibl_device
= {
125 .parent
= &corgifb_device
.dev
,
134 * The card detect interrupt isn't debounced so we delay it by HZ/4
135 * to give the card a chance to fully insert/eject.
137 static struct mmc_detect
{
138 struct timer_list detect_timer
;
142 static void mmc_detect_callback(unsigned long data
)
144 mmc_detect_change(mmc_detect
.devid
);
147 static irqreturn_t
corgi_mmc_detect_int(int irq
, void *devid
, struct pt_regs
*regs
)
149 mmc_detect
.devid
=devid
;
150 mod_timer(&mmc_detect
.detect_timer
, jiffies
+ HZ
/4);
154 static int corgi_mci_init(struct device
*dev
, irqreturn_t (*unused_detect_int
)(int, void *, struct pt_regs
*), void *data
)
158 /* setup GPIO for PXA25x MMC controller */
159 pxa_gpio_mode(GPIO6_MMCCLK_MD
);
160 pxa_gpio_mode(GPIO8_MMCCS0_MD
);
161 pxa_gpio_mode(CORGI_GPIO_nSD_DETECT
| GPIO_IN
);
162 pxa_gpio_mode(CORGI_GPIO_SD_PWR
| GPIO_OUT
);
164 init_timer(&mmc_detect
.detect_timer
);
165 mmc_detect
.detect_timer
.function
= mmc_detect_callback
;
166 mmc_detect
.detect_timer
.data
= (unsigned long) &mmc_detect
;
168 err
= request_irq(CORGI_IRQ_GPIO_nSD_DETECT
, corgi_mmc_detect_int
, SA_INTERRUPT
,
169 "MMC card detect", data
);
171 printk(KERN_ERR
"corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
175 set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT
, IRQT_BOTHEDGE
);
180 static void corgi_mci_setpower(struct device
*dev
, unsigned int vdd
)
182 struct pxamci_platform_data
* p_d
= dev
->platform_data
;
184 if (( 1 << vdd
) & p_d
->ocr_mask
) {
185 printk(KERN_DEBUG
"%s: on\n", __FUNCTION__
);
186 GPSR1
= GPIO_bit(CORGI_GPIO_SD_PWR
);
188 printk(KERN_DEBUG
"%s: off\n", __FUNCTION__
);
189 GPCR1
= GPIO_bit(CORGI_GPIO_SD_PWR
);
193 static void corgi_mci_exit(struct device
*dev
, void *data
)
195 free_irq(CORGI_IRQ_GPIO_nSD_DETECT
, data
);
196 del_timer(&mmc_detect
.detect_timer
);
199 static struct pxamci_platform_data corgi_mci_platform_data
= {
200 .ocr_mask
= MMC_VDD_32_33
|MMC_VDD_33_34
,
201 .init
= corgi_mci_init
,
202 .setpower
= corgi_mci_setpower
,
203 .exit
= corgi_mci_exit
,
208 * USB Device Controller
210 static void corgi_udc_command(int cmd
)
213 case PXA2XX_UDC_CMD_CONNECT
:
214 GPSR(CORGI_GPIO_USB_PULLUP
) = GPIO_bit(CORGI_GPIO_USB_PULLUP
);
216 case PXA2XX_UDC_CMD_DISCONNECT
:
217 GPCR(CORGI_GPIO_USB_PULLUP
) = GPIO_bit(CORGI_GPIO_USB_PULLUP
);
222 static struct pxa2xx_udc_mach_info udc_info __initdata
= {
223 /* no connect GPIO; corgi can't tell connection status */
224 .udc_command
= corgi_udc_command
,
228 static struct platform_device
*devices
[] __initdata
= {
235 static void __init
corgi_init(void)
237 corgi_fb_info
.comadj
=sharpsl_param
.comadj
;
238 corgi_fb_info
.phadadj
=sharpsl_param
.phadadj
;
240 pxa_gpio_mode(CORGI_GPIO_USB_PULLUP
| GPIO_OUT
);
241 pxa_set_udc_info(&udc_info
);
242 pxa_set_mci_info(&corgi_mci_platform_data
);
244 platform_add_devices(devices
, ARRAY_SIZE(devices
));
247 static void __init
fixup_corgi(struct machine_desc
*desc
,
248 struct tag
*tags
, char **cmdline
, struct meminfo
*mi
)
250 sharpsl_save_param();
252 mi
->bank
[0].start
= 0xa0000000;
253 mi
->bank
[0].node
= 0;
254 if (machine_is_corgi())
255 mi
->bank
[0].size
= (32*1024*1024);
257 mi
->bank
[0].size
= (64*1024*1024);
260 static void __init
corgi_init_irq(void)
265 static struct map_desc corgi_io_desc
[] __initdata
= {
266 /* virtual physical length */
267 /* { 0xf1000000, 0x08000000, 0x01000000, MT_DEVICE },*/ /* LCDC (readable for Qt driver) */
268 /* { 0xef700000, 0x10800000, 0x00001000, MT_DEVICE },*/ /* SCOOP */
269 { 0xef800000, 0x00000000, 0x00800000, MT_DEVICE
}, /* Boot Flash */
272 static void __init
corgi_map_io(void)
275 iotable_init(corgi_io_desc
,ARRAY_SIZE(corgi_io_desc
));
277 /* setup sleep mode values */
284 /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
288 #ifdef CONFIG_MACH_CORGI
289 MACHINE_START(CORGI
, "SHARP Corgi")
290 BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
293 INITIRQ(corgi_init_irq
)
294 .init_machine
= corgi_init
,
299 #ifdef CONFIG_MACH_SHEPHERD
300 MACHINE_START(SHEPHERD
, "SHARP Shepherd")
301 BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
304 INITIRQ(corgi_init_irq
)
305 .init_machine
= corgi_init
,
310 #ifdef CONFIG_MACH_HUSKY
311 MACHINE_START(HUSKY
, "SHARP Husky")
312 BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
315 INITIRQ(corgi_init_irq
)
316 .init_machine
= corgi_init
,