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.
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>
32 #include <linux/bootmem.h>
33 #include <linux/lcd.h>
34 #include <linux/backlight.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>
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);
66 static void h3900_control_egpio( enum ipaq_egpio_type x
, int setp
)
69 case IPAQ_EGPIO_IR_ON
:
70 CLEAR_ASIC3( GPIO3_IR_ON_N
);
72 case IPAQ_EGPIO_IR_FSEL
:
74 case IPAQ_EGPIO_RS232_ON
:
75 SET_ASIC3( GPIO3_RS232_ON
);
77 case IPAQ_EGPIO_BLUETOOTH_ON
:
78 SET_ASIC3( GPIO3_BT_PWR_ON
);
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
)
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
;
94 IPAQ_ASIC2_LED_TimeBase(color
) = 0;
103 * Common map_io initialization
105 static short ipaq_gpio_modes
[] = {
126 static void __init
h3900_map_io(void)
135 /* Configure power management stuff. */
136 PWER
= PWER_GPIO0
| PWER_RTC
;
137 PFER
= PWER_GPIO0
| PWER_RTC
;
142 PGSR0
= GPSRx_SleepValue
;
143 PGSR1
= GPSRy_SleepValue
;
144 PGSR2
= GPSRz_SleepValue
;
148 for (i
= 0; i
< ARRAY_SIZE(ipaq_gpio_modes
); i
++) {
149 int mode
= ipaq_gpio_modes
[i
];
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
);
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 */
176 /* Select VLIO for ASIC3 */
177 MSC2
= (MSC2
& 0x0000ffff) | 0x74a40000;
179 pxa_gpio_mode(GPIO33_nCS_5_MD
);
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);
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
= {
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
[] = {
206 .flags
= IORESOURCE_MEM
,
209 .start
= IRQ_GPIO_H3900_ASIC2_INT
,
210 .flags
= IORESOURCE_IRQ
,
214 struct platform_device h3900_asic2
= {
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
= {
225 .dir
= ASIC3GPIO_INIT_DIR
, /* All outputs */
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
,
234 .dir
= ASIC3GPIO_INIT_DIR
, /* All outputs */
237 .dir
= ASIC3GPIO_INIT_DIR
, /* All outputs */
241 static struct resource asic3_resources
[] = {
245 .flags
= IORESOURCE_MEM
,
249 struct platform_device h3900_asic3
= {
252 .num_resources
= ARRAY_SIZE(asic3_resources
),
253 .resource
= asic3_resources
,
255 .platform_data
= &asic3_platform_data
,
258 EXPORT_SYMBOL(h3900_asic3
);
260 static struct resource h3900_mmc_resources
[] = {
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
= {
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
= {
286 .platform_data
= &h3900_pxa_keys_data
,
290 static struct platform_device
*devices
[] __initdata
= {
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
)
305 case PXA2XX_UDC_CMD_DISCONNECT
:
306 GPDR0
&= ~GPIO_H3900_USBP_PULLUP
;
308 case PXA2XX_UDC_CMD_CONNECT
:
309 GPDR0
|= GPIO_H3900_USBP_PULLUP
;
310 GPSR0
|= GPIO_H3900_USBP_PULLUP
;
313 printk("_udc_control: unknown command!\n");
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 */
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
);
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
,
360 .init_machine
= h3900_init
,