hh.org updates
[hh.org.git] / arch / arm / mach-pxa / h3900 / h3900.c
blob4e244d6fb2bb14eec0bab18472c7f62ba4e1f4f1
1 /*
2 * Hardware definitions for HP iPAQ Handheld Computers
4 * Copyright 2000-2003 Hewlett-Packard Company.
5 * Copyright 2003, 2004, 2005 Phil Blundell
7 * Use consistent with the GNU GPL is permitted,
8 * provided that this copyright notice is
9 * preserved in its entirety in all copies and derived works.
11 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
12 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
13 * FITNESS FOR ANY PARTICULAR PURPOSE.
15 * Author: Jamey Hicks.
17 * History:
19 * 2003-05-14 Joshua Wise Adapted for the HP iPAQ H1900
20 * 2002-08-23 Jamey Hicks Adapted for use with PXA250-based iPAQs
21 * 2001-10-?? Andrew Christian Added support for iPAQ H3800
22 * and abstracted EGPIO interface.
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/kernel.h>
28 #include <linux/tty.h>
29 #include <linux/sched.h>
30 #include <linux/delay.h>
31 #include <linux/pm.h>
32 #include <linux/bootmem.h>
33 #include <linux/lcd.h>
34 #include <linux/backlight.h>
35 #include <linux/fb.h>
36 #include <linux/input.h>
37 #include <linux/input_pda.h>
38 #include <linux/soc-old.h>
39 #include <linux/soc/tmio_mmc.h>
41 #include <asm/irq.h>
42 #include <asm/mach-types.h>
43 #include <asm/hardware.h>
44 #include <asm/setup.h>
46 #include <asm/mach/irq.h>
47 #include <asm/mach/arch.h>
48 #include <asm/mach/map.h>
49 #include <asm/arch/h3900-init.h>
50 #include <asm/arch/h3900-asic.h>
51 #include <asm/arch/ipaq.h>
52 #include <asm/arch/udc.h>
53 #include <asm/arch/pxafb.h>
55 #include <asm/arch/pxa-regs.h>
56 #include <asm/hardware/gpio_keys.h>
57 #include <asm/arch/irq.h>
58 #include <asm/types.h>
60 #include "../generic.h"
62 void h3900_ll_pm_init(void);
64 #ifdef DeadCode
66 static void h3900_control_egpio( enum ipaq_egpio_type x, int setp )
68 switch (x) {
69 case IPAQ_EGPIO_IR_ON:
70 CLEAR_ASIC3( GPIO3_IR_ON_N );
71 break;
72 case IPAQ_EGPIO_IR_FSEL:
73 break;
74 case IPAQ_EGPIO_RS232_ON:
75 SET_ASIC3( GPIO3_RS232_ON );
76 break;
77 case IPAQ_EGPIO_BLUETOOTH_ON:
78 SET_ASIC3( GPIO3_BT_PWR_ON );
79 break;
80 default:
81 printk("%s: unhandled egpio=%d\n", __FUNCTION__, x);
87 static void h3900_set_led (enum led_color color, int duty_time, int cycle_time)
89 if (duty_time) {
90 IPAQ_ASIC2_LED_TimeBase(color) = LED_EN | LED_AUTOSTOP | LED_ALWAYS | 1;
91 IPAQ_ASIC2_LED_PeriodTime(color) = cycle_time;
92 IPAQ_ASIC2_LED_DutyTime(color) = duty_time;
93 } else {
94 IPAQ_ASIC2_LED_TimeBase(color) = 0;
97 #endif
101 #if 0
103 * Common map_io initialization
105 static short ipaq_gpio_modes[] = {
106 GPIO1_RTS_MD,
107 GPIO18_RDY_MD,
108 GPIO15_nCS_1_MD,
109 GPIO33_nCS_5_MD,
110 GPIO48_nPOE_MD,
111 GPIO49_nPWE_MD,
112 GPIO50_nPIOR_MD,
113 GPIO51_nPIOW_MD,
114 GPIO52_nPCE_1_MD,
115 GPIO53_nPCE_2_MD,
116 GPIO54_pSKTSEL_MD,
117 GPIO55_nPREG_MD,
118 GPIO56_nPWAIT_MD,
119 GPIO57_nIOIS16_MD,
120 GPIO78_nCS_2_MD,
121 GPIO79_nCS_3_MD,
122 GPIO80_nCS_4_MD,
124 #endif
126 static void __init h3900_map_io(void)
128 #if 0
129 /* redundant? */
130 int i;
131 #endif
133 pxa_map_io();
135 /* Configure power management stuff. */
136 PWER = PWER_GPIO0 | PWER_RTC;
137 PFER = PWER_GPIO0 | PWER_RTC;
138 PRER = 0;
139 PCFR = PCFR_OPDE;
140 CKEN = CKEN6_FFUART;
142 PGSR0 = GPSRx_SleepValue;
143 PGSR1 = GPSRy_SleepValue;
144 PGSR2 = GPSRz_SleepValue;
146 #if 0
147 /* redundant? */
148 for (i = 0; i < ARRAY_SIZE(ipaq_gpio_modes); i++) {
149 int mode = ipaq_gpio_modes[i];
150 if (0)
151 printk("ipaq gpio_mode: gpio_nr=%d dir=%d fn=%d\n",
152 mode&GPIO_MD_MASK_NR, mode&GPIO_MD_MASK_DIR, mode&GPIO_MD_MASK_FN);
153 pxa_gpio_mode(mode);
155 #endif
157 /* Set up GPIO direction and alternate function registers */
158 GAFR0_L = GAFR0x_InitValue;
159 GAFR0_U = GAFR1x_InitValue;
160 GAFR1_L = GAFR0y_InitValue;
161 GAFR1_U = GAFR1y_InitValue;
162 GAFR2_L = GAFR0z_InitValue;
163 GAFR2_U = GAFR1z_InitValue;
165 GPDR0 = GPDRx_InitValue;
166 GPDR1 = GPDRy_InitValue;
167 GPDR2 = GPDRz_InitValue;
169 GPCR0 = 0x0fffffff; /* All outputs are set low by default */
171 /* Add wakeup on AC plug/unplug */
172 PWER |= PWER_GPIO8;
173 PFER |= PWER_GPIO8;
174 PRER |= PWER_GPIO8;
176 /* Select VLIO for ASIC3 */
177 MSC2 = (MSC2 & 0x0000ffff) | 0x74a40000;
179 pxa_gpio_mode(GPIO33_nCS_5_MD);
181 #if 0
182 /* Turn off all LEDs */
183 ipaq_set_led (GREEN_LED, 0, 0);
184 ipaq_set_led (BLUE_LED, 0, 0);
185 ipaq_set_led (YELLOW_LED, 0, 0);
186 #endif
189 extern struct platform_device h3900_bl;
190 static struct platform_device h3900_lcd = { .name = "h3900_lcd", };
192 static struct platform_device *h3900_asic2_devices[] __initdata = {
193 &h3900_lcd,
194 &h3900_bl,
197 static struct asic2_platform_data h3900_asic2_platform_data = {
198 .child_platform_devs = h3900_asic2_devices,
199 .num_child_platform_devs = ARRAY_SIZE(h3900_asic2_devices),
202 static struct resource asic2_resources[] = {
203 [0] = {
204 .start = 0x15000000,
205 .end = 0x157fffff,
206 .flags = IORESOURCE_MEM,
208 [1] = {
209 .start = IRQ_GPIO_H3900_ASIC2_INT,
210 .flags = IORESOURCE_IRQ,
214 struct platform_device h3900_asic2 = {
215 .name = "asic2",
216 .id = 0,
217 .num_resources = ARRAY_SIZE(asic2_resources),
218 .resource = asic2_resources,
219 .dev = { .platform_data = &h3900_asic2_platform_data, },
221 EXPORT_SYMBOL(h3900_asic2);
223 static struct asic3_platform_data asic3_platform_data = {
224 .gpio_a = {
225 .dir = ASIC3GPIO_INIT_DIR, /* All outputs */
227 .gpio_b = {
228 .dir = ASIC3GPIO_INIT_DIR, /* All outputs */
229 .init = GPIO3_IR_ON_N | GPIO3_RS232_ON | GPIO3_TEST_POINT_123,
230 .sleep_out = ASIC3GPIO_SLEEP_OUT,
231 .batt_fault_out = ASIC3GPIO_BATFALT_OUT,
233 .gpio_c = {
234 .dir = ASIC3GPIO_INIT_DIR, /* All outputs */
236 .gpio_d = {
237 .dir = ASIC3GPIO_INIT_DIR, /* All outputs */
241 static struct resource asic3_resources[] = {
242 [0] = {
243 .start = 0x14800000,
244 .end = 0x14ffffff,
245 .flags = IORESOURCE_MEM,
249 struct platform_device h3900_asic3 = {
250 .name = "asic3",
251 .id = 0,
252 .num_resources = ARRAY_SIZE(asic3_resources),
253 .resource = asic3_resources,
254 .dev = {
255 .platform_data = &asic3_platform_data,
258 EXPORT_SYMBOL(h3900_asic3);
260 static struct resource h3900_mmc_resources[] = {
261 [0] = {
262 .start = IRQ_GPIO (GPIO_NR_H3900_MMC_INT_N),
263 .end = IRQ_GPIO (GPIO_NR_H3900_MMC_INT_N),
264 .flags = IORESOURCE_IRQ,
267 struct platform_device h3900_mmc = {
268 .name = "h3900_mmc",
269 .id = 0,
270 .num_resources = ARRAY_SIZE(h3900_mmc_resources),
271 .resource = h3900_mmc_resources,
274 static struct gpio_keys_button h3900_button_table[] = {
275 { _KEY_POWER, GPIO_NR_H3900_POWER_BUTTON_N, 1 },
278 static struct gpio_keys_platform_data h3900_pxa_keys_data = {
279 .buttons = h3900_button_table,
280 .nbuttons = ARRAY_SIZE(h3900_button_table),
283 static struct platform_device h3900_pxa_keys = {
284 .name = "gpio-keys",
285 .dev = {
286 .platform_data = &h3900_pxa_keys_data,
290 static struct platform_device *devices[] __initdata = {
291 &h3900_asic2,
292 &h3900_asic3,
293 &h3900_pxa_keys,
294 &h3900_mmc,
297 static int h3900_udc_is_connected(void)
299 return 1; //FIXME - at least this could mimic the state set below...
302 static void h3900_udc_command (int cmd)
304 switch (cmd) {
305 case PXA2XX_UDC_CMD_DISCONNECT:
306 GPDR0 &= ~GPIO_H3900_USBP_PULLUP;
307 break;
308 case PXA2XX_UDC_CMD_CONNECT:
309 GPDR0 |= GPIO_H3900_USBP_PULLUP;
310 GPSR0 |= GPIO_H3900_USBP_PULLUP;
311 break;
312 default:
313 printk("_udc_control: unknown command!\n");
314 break;
318 static struct pxa2xx_udc_mach_info h3900_udc_mach_info = {
319 .udc_is_connected = h3900_udc_is_connected,
320 .udc_command = h3900_udc_command,
323 /* read LCCR0: 0x00000081 */
324 /* read LCCR1: 0x0b10093f -- BLW=0x0b, ELW=0x10, HSW=2, PPL=0x13f */
325 /* read LCCR2: 0x051008ef -- BFW=0x05, EFW=0x10, VSW=2, LPP=0xef */
326 /* read LCCR3: 0x0430000a */
327 static struct pxafb_mach_info h3900_fb_info = {
328 .pixclock = 221039, /* clock period in ps */
329 .bpp = 16,
330 .xres = 320,
331 .yres = 240,
332 .hsync_len = 3,
333 .vsync_len = 3,
334 .left_margin = 12,
335 .upper_margin = 4,
336 .right_margin = 17,
337 .lower_margin = 17,
338 .sync = 0, /* both horiz and vert active low sync */
339 .lccr0 = (LCCR0_PAS),
342 static void __init h3900_init (void)
344 platform_add_devices (devices, ARRAY_SIZE (devices));
345 pxa_set_udc_info (&h3900_udc_mach_info);
346 set_pxa_fb_info (&h3900_fb_info);
347 #ifdef CONFIG_PM
348 h3900_ll_pm_init();
349 #endif
352 MACHINE_START(H3900, "HP iPAQ H3900")
353 /* Maintainer HP Labs, Cambridge Research Labs */
354 .phys_io = 0x40000000,
355 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
356 .boot_params = 0xa0000100,
357 .map_io = h3900_map_io,
358 .init_irq = pxa_init_irq,
359 .timer = &pxa_timer,
360 .init_machine = h3900_init,
361 MACHINE_END