• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/arm/mach-s3c2410/
1/* linux/arch/arm/mach-s3c2410/mach-h1940.c
2 *
3 * Copyright (c) 2003-2005 Simtec Electronics
4 *   Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://www.handhelds.org/projects/h1940.html
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/memblock.h>
19#include <linux/timer.h>
20#include <linux/init.h>
21#include <linux/sysdev.h>
22#include <linux/serial_core.h>
23#include <linux/platform_device.h>
24#include <linux/io.h>
25#include <linux/gpio.h>
26#include <linux/pwm_backlight.h>
27#include <video/platform_lcd.h>
28
29#include <linux/mmc/host.h>
30
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33#include <asm/mach/irq.h>
34
35#include <mach/hardware.h>
36#include <asm/irq.h>
37#include <asm/mach-types.h>
38
39#include <plat/regs-serial.h>
40#include <mach/regs-lcd.h>
41#include <mach/regs-clock.h>
42
43#include <mach/regs-gpio.h>
44#include <mach/gpio-fns.h>
45#include <mach/gpio-nrs.h>
46
47#include <mach/h1940.h>
48#include <mach/h1940-latch.h>
49#include <mach/fb.h>
50#include <plat/udc.h>
51#include <plat/iic.h>
52
53#include <plat/gpio-cfg.h>
54#include <plat/clock.h>
55#include <plat/devs.h>
56#include <plat/cpu.h>
57#include <plat/pll.h>
58#include <plat/pm.h>
59#include <plat/mci.h>
60#include <plat/ts.h>
61
62static struct map_desc h1940_iodesc[] __initdata = {
63	[0] = {
64		.virtual	= (unsigned long)H1940_LATCH,
65		.pfn		= __phys_to_pfn(H1940_PA_LATCH),
66		.length		= SZ_16K,
67		.type		= MT_DEVICE
68	},
69};
70
71#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
72#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
73#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
74
75static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
76	[0] = {
77		.hwport	     = 0,
78		.flags	     = 0,
79		.ucon	     = 0x3c5,
80		.ulcon	     = 0x03,
81		.ufcon	     = 0x51,
82	},
83	[1] = {
84		.hwport	     = 1,
85		.flags	     = 0,
86		.ucon	     = 0x245,
87		.ulcon	     = 0x03,
88		.ufcon	     = 0x00,
89	},
90	/* IR port */
91	[2] = {
92		.hwport	     = 2,
93		.flags	     = 0,
94		.uart_flags  = UPF_CONS_FLOW,
95		.ucon	     = 0x3c5,
96		.ulcon	     = 0x43,
97		.ufcon	     = 0x51,
98	}
99};
100
101/* Board control latch control */
102
103static unsigned int latch_state = H1940_LATCH_DEFAULT;
104
105void h1940_latch_control(unsigned int clear, unsigned int set)
106{
107	unsigned long flags;
108
109	local_irq_save(flags);
110
111	latch_state &= ~clear;
112	latch_state |= set;
113
114	__raw_writel(latch_state, H1940_LATCH);
115
116	local_irq_restore(flags);
117}
118
119EXPORT_SYMBOL_GPL(h1940_latch_control);
120
121static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
122{
123	printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
124
125	switch (cmd)
126	{
127		case S3C2410_UDC_P_ENABLE :
128			h1940_latch_control(0, H1940_LATCH_USB_DP);
129			break;
130		case S3C2410_UDC_P_DISABLE :
131			h1940_latch_control(H1940_LATCH_USB_DP, 0);
132			break;
133		case S3C2410_UDC_P_RESET :
134			break;
135		default:
136			break;
137	}
138}
139
140static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
141	.udc_command		= h1940_udc_pullup,
142	.vbus_pin		= S3C2410_GPG(5),
143	.vbus_pin_inverted	= 1,
144};
145
146static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
147		.delay = 10000,
148		.presc = 49,
149		.oversampling_shift = 2,
150		.cfg_gpio = s3c24xx_ts_cfg_gpio,
151};
152
153/**
154 * Set lcd on or off
155 **/
156static struct s3c2410fb_display h1940_lcd __initdata = {
157	.lcdcon5=	S3C2410_LCDCON5_FRM565 | \
158			S3C2410_LCDCON5_INVVLINE | \
159			S3C2410_LCDCON5_HWSWP,
160
161	.type =		S3C2410_LCDCON1_TFT,
162	.width =	240,
163	.height =	320,
164	.pixclock =	260000,
165	.xres =		240,
166	.yres =		320,
167	.bpp =		16,
168	.left_margin =	8,
169	.right_margin =	20,
170	.hsync_len =	4,
171	.upper_margin =	8,
172	.lower_margin = 7,
173	.vsync_len =	1,
174};
175
176static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
177	.displays = &h1940_lcd,
178	.num_displays = 1,
179	.default_display = 0,
180
181	.lpcsel=	0x02,
182	.gpccon=	0xaa940659,
183	.gpccon_mask=	0xffffffff,
184	.gpcup=		0x0000ffff,
185	.gpcup_mask=	0xffffffff,
186	.gpdcon=	0xaa84aaa0,
187	.gpdcon_mask=	0xffffffff,
188	.gpdup=		0x0000faff,
189	.gpdup_mask=	0xffffffff,
190};
191
192static struct platform_device h1940_device_leds = {
193	.name             = "h1940-leds",
194	.id               = -1,
195};
196
197static struct platform_device h1940_device_bluetooth = {
198	.name             = "h1940-bt",
199	.id               = -1,
200};
201
202static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
203	.gpio_detect   = S3C2410_GPF(5),
204	.gpio_wprotect = S3C2410_GPH(8),
205	.set_power     = NULL,
206	.ocr_avail     = MMC_VDD_32_33,
207};
208
209static int h1940_backlight_init(struct device *dev)
210{
211	gpio_request(S3C2410_GPB(0), "Backlight");
212
213	gpio_direction_output(S3C2410_GPB(0), 0);
214	s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
215	s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
216
217	return 0;
218}
219
220static void h1940_backlight_exit(struct device *dev)
221{
222	gpio_direction_output(S3C2410_GPB(0), 1);
223}
224
225static struct platform_pwm_backlight_data backlight_data = {
226	.pwm_id         = 0,
227	.max_brightness = 100,
228	.dft_brightness = 50,
229	/* tcnt = 0x31 */
230	.pwm_period_ns  = 36296,
231	.init           = h1940_backlight_init,
232	.exit           = h1940_backlight_exit,
233};
234
235static struct platform_device h1940_backlight = {
236	.name = "pwm-backlight",
237	.dev  = {
238		.parent = &s3c_device_timer[0].dev,
239		.platform_data = &backlight_data,
240	},
241	.id   = -1,
242};
243
244static void h1940_lcd_power_set(struct plat_lcd_data *pd,
245					unsigned int power)
246{
247	int value;
248
249	if (!power) {
250		/* set to 3ec */
251		gpio_direction_output(S3C2410_GPC(0), 0);
252		/* wait for 3ac */
253		do {
254			value = gpio_get_value(S3C2410_GPC(6));
255		} while (value);
256		/* set to 38c */
257		gpio_direction_output(S3C2410_GPC(5), 0);
258	} else {
259		/* Set to 3ac */
260		gpio_direction_output(S3C2410_GPC(5), 1);
261		/* Set to 3ad */
262		gpio_direction_output(S3C2410_GPC(0), 1);
263	}
264}
265
266static struct plat_lcd_data h1940_lcd_power_data = {
267	.set_power      = h1940_lcd_power_set,
268};
269
270static struct platform_device h1940_lcd_powerdev = {
271	.name                   = "platform-lcd",
272	.dev.parent             = &s3c_device_lcd.dev,
273	.dev.platform_data      = &h1940_lcd_power_data,
274};
275
276static struct platform_device *h1940_devices[] __initdata = {
277	&s3c_device_ohci,
278	&s3c_device_lcd,
279	&s3c_device_wdt,
280	&s3c_device_i2c0,
281	&s3c_device_iis,
282	&s3c_device_usbgadget,
283	&h1940_device_leds,
284	&h1940_device_bluetooth,
285	&s3c_device_sdi,
286	&s3c_device_rtc,
287	&s3c_device_timer[0],
288	&h1940_backlight,
289	&h1940_lcd_powerdev,
290	&s3c_device_adc,
291	&s3c_device_ts,
292};
293
294static void __init h1940_map_io(void)
295{
296	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
297	s3c24xx_init_clocks(0);
298	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
299
300	/* setup PM */
301
302#ifdef CONFIG_PM_H1940
303	memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
304#endif
305	s3c_pm_init();
306}
307
308/* H1940 and RX3715 need to reserve this for suspend */
309static void __init h1940_reserve(void)
310{
311	memblock_reserve(0x30003000, 0x1000);
312	memblock_reserve(0x30081000, 0x1000);
313}
314
315static void __init h1940_init_irq(void)
316{
317	s3c24xx_init_irq();
318}
319
320static void __init h1940_init(void)
321{
322	u32 tmp;
323
324	s3c24xx_fb_set_platdata(&h1940_fb_info);
325	s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
326 	s3c24xx_udc_set_platdata(&h1940_udc_cfg);
327	s3c24xx_ts_set_platdata(&h1940_ts_cfg);
328	s3c_i2c0_set_platdata(NULL);
329
330	/* Turn off suspend on both USB ports, and switch the
331	 * selectable USB port to USB device mode. */
332
333	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
334			      S3C2410_MISCCR_USBSUSPND0 |
335			      S3C2410_MISCCR_USBSUSPND1, 0x0);
336
337	tmp =   (0x78 << S3C24XX_PLLCON_MDIVSHIFT)
338	      | (0x02 << S3C24XX_PLLCON_PDIVSHIFT)
339	      | (0x03 << S3C24XX_PLLCON_SDIVSHIFT);
340	writel(tmp, S3C2410_UPLLCON);
341
342	gpio_request(S3C2410_GPC(0), "LCD power");
343	gpio_request(S3C2410_GPC(5), "LCD power");
344	gpio_request(S3C2410_GPC(6), "LCD power");
345
346	gpio_direction_input(S3C2410_GPC(6));
347
348	platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
349}
350
351MACHINE_START(H1940, "IPAQ-H1940")
352	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
353	.phys_io	= S3C2410_PA_UART,
354	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
355	.boot_params	= S3C2410_SDRAM_PA + 0x100,
356	.map_io		= h1940_map_io,
357	.reserve	= h1940_reserve,
358	.init_irq	= h1940_init_irq,
359	.init_machine	= h1940_init,
360	.timer		= &s3c24xx_timer,
361MACHINE_END
362