2 * Hardware definitions for Compaq iPAQ H3xxx Handheld Computers
4 * Copyright 2000,1 Compaq Computer Corporation.
6 * Use consistent with the GNU GPL is permitted,
7 * provided that this copyright notice is
8 * preserved in its entirety in all copies and derived works.
10 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
11 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
12 * FITNESS FOR ANY PARTICULAR PURPOSE.
14 * Author: Jamey Hicks.
18 * 2001-10-?? Andrew Christian Added support for iPAQ H3800
19 * and abstracted EGPIO interface.
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/kernel.h>
25 #include <linux/tty.h>
27 #include <linux/device.h>
28 #include <linux/mtd/mtd.h>
29 #include <linux/mtd/partitions.h>
30 #include <linux/serial_core.h>
33 #include <mach/hardware.h>
34 #include <asm/mach-types.h>
35 #include <asm/setup.h>
37 #include <asm/mach/irq.h>
38 #include <asm/mach/arch.h>
39 #include <asm/mach/flash.h>
40 #include <asm/mach/irda.h>
41 #include <asm/mach/map.h>
42 #include <asm/mach/serial_sa1100.h>
44 #include <mach/h3600.h>
45 #include <mach/h3600_gpio.h>
49 void (*assign_h3600_egpio
)(enum ipaq_egpio_type x
, int level
);
50 EXPORT_SYMBOL(assign_h3600_egpio
);
52 static struct mtd_partition h3xxx_partitions
[] = {
54 .name
= "H3XXX boot firmware",
57 .mask_flags
= MTD_WRITEABLE
, /* force read-only */
59 .name
= "H3XXX rootfs",
60 .size
= MTDPART_SIZ_FULL
,
65 static void h3xxx_set_vpp(int vpp
)
67 assign_h3600_egpio(IPAQ_EGPIO_VPP_ON
, vpp
);
70 static struct flash_platform_data h3xxx_flash_data
= {
71 .map_name
= "cfi_probe",
72 .set_vpp
= h3xxx_set_vpp
,
73 .parts
= h3xxx_partitions
,
74 .nr_parts
= ARRAY_SIZE(h3xxx_partitions
),
77 static struct resource h3xxx_flash_resource
= {
78 .start
= SA1100_CS0_PHYS
,
79 .end
= SA1100_CS0_PHYS
+ SZ_32M
- 1,
80 .flags
= IORESOURCE_MEM
,
84 * This turns the IRDA power on or off on the Compaq H3600
86 static int h3600_irda_set_power(struct device
*dev
, unsigned int state
)
88 assign_h3600_egpio( IPAQ_EGPIO_IR_ON
, state
);
93 static void h3600_irda_set_speed(struct device
*dev
, unsigned int speed
)
95 assign_h3600_egpio(IPAQ_EGPIO_IR_FSEL
, !(speed
< 4000000));
98 static struct irda_platform_data h3600_irda_data
= {
99 .set_power
= h3600_irda_set_power
,
100 .set_speed
= h3600_irda_set_speed
,
103 static void h3xxx_mach_init(void)
105 sa11x0_set_flash_data(&h3xxx_flash_data
, &h3xxx_flash_resource
, 1);
106 sa11x0_set_irda_data(&h3600_irda_data
);
110 * low-level UART features
113 static void h3600_uart_set_mctrl(struct uart_port
*port
, u_int mctrl
)
115 if (port
->mapbase
== _Ser3UTCR0
) {
116 if (mctrl
& TIOCM_RTS
)
117 GPCR
= GPIO_H3600_COM_RTS
;
119 GPSR
= GPIO_H3600_COM_RTS
;
123 static u_int
h3600_uart_get_mctrl(struct uart_port
*port
)
125 u_int ret
= TIOCM_CD
| TIOCM_CTS
| TIOCM_DSR
;
127 if (port
->mapbase
== _Ser3UTCR0
) {
129 /* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
130 if (gplr
& GPIO_H3600_COM_DCD
)
132 if (gplr
& GPIO_H3600_COM_CTS
)
139 static void h3600_uart_pm(struct uart_port
*port
, u_int state
, u_int oldstate
)
141 if (port
->mapbase
== _Ser2UTCR0
) { /* TODO: REMOVE THIS */
142 assign_h3600_egpio(IPAQ_EGPIO_IR_ON
, !state
);
143 } else if (port
->mapbase
== _Ser3UTCR0
) {
144 assign_h3600_egpio(IPAQ_EGPIO_RS232_ON
, !state
);
149 * Enable/Disable wake up events for this serial port.
150 * Obviously, we only support this on the normal COM port.
152 static int h3600_uart_set_wake(struct uart_port
*port
, u_int enable
)
156 if (port
->mapbase
== _Ser3UTCR0
) {
158 PWER
|= PWER_GPIO23
| PWER_GPIO25
; /* DCD and CTS */
160 PWER
&= ~(PWER_GPIO23
| PWER_GPIO25
); /* DCD and CTS */
166 static struct sa1100_port_fns h3600_port_fns __initdata
= {
167 .set_mctrl
= h3600_uart_set_mctrl
,
168 .get_mctrl
= h3600_uart_get_mctrl
,
170 .set_wake
= h3600_uart_set_wake
,
174 * helper for sa1100fb
176 static void h3xxx_lcd_power(int enable
)
178 assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER
, enable
);
181 static struct map_desc h3600_io_desc
[] __initdata
= {
182 { /* static memory bank 2 CS#2 */
183 .virtual = H3600_BANK_2_VIRT
,
184 .pfn
= __phys_to_pfn(SA1100_CS2_PHYS
),
185 .length
= 0x02800000,
187 }, { /* static memory bank 4 CS#4 */
188 .virtual = H3600_BANK_4_VIRT
,
189 .pfn
= __phys_to_pfn(SA1100_CS4_PHYS
),
190 .length
= 0x00800000,
192 }, { /* EGPIO 0 CS#5 */
193 .virtual = H3600_EGPIO_VIRT
,
194 .pfn
= __phys_to_pfn(H3600_EGPIO_PHYS
),
195 .length
= 0x01000000,
201 * Common map_io initialization
204 static void __init
h3xxx_map_io(void)
207 iotable_init(h3600_io_desc
, ARRAY_SIZE(h3600_io_desc
));
209 sa1100_register_uart_fns(&h3600_port_fns
);
210 sa1100_register_uart(0, 3); /* Common serial port */
211 // sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
213 /* Ensure those pins are outputs and driving low */
214 PPDR
|= PPC_TXD4
| PPC_SCLK
| PPC_SFRM
;
215 PPSR
&= ~(PPC_TXD4
| PPC_SCLK
| PPC_SFRM
);
217 /* Configure suspend conditions */
219 PWER
= PWER_GPIO0
| PWER_RTC
;
223 sa1100fb_lcd_power
= h3xxx_lcd_power
;
226 /************************* H3100 *************************/
228 #ifdef CONFIG_SA1100_H3100
230 #define H3100_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
231 static unsigned int h3100_egpio
= 0;
233 static void h3100_control_egpio(enum ipaq_egpio_type x
, int setp
)
235 unsigned int egpio
= 0;
240 case IPAQ_EGPIO_LCD_POWER
:
241 egpio
|= EGPIO_H3600_LCD_ON
;
242 gpio
|= GPIO_H3100_LCD_3V_ON
;
244 case IPAQ_EGPIO_LCD_ENABLE
:
246 case IPAQ_EGPIO_CODEC_NRESET
:
247 egpio
|= EGPIO_H3600_CODEC_NRESET
;
249 case IPAQ_EGPIO_AUDIO_ON
:
250 gpio
|= GPIO_H3100_AUD_PWR_ON
253 case IPAQ_EGPIO_QMUTE
:
254 gpio
|= GPIO_H3100_QMUTE
;
256 case IPAQ_EGPIO_OPT_NVRAM_ON
:
257 egpio
|= EGPIO_H3600_OPT_NVRAM_ON
;
259 case IPAQ_EGPIO_OPT_ON
:
260 egpio
|= EGPIO_H3600_OPT_ON
;
262 case IPAQ_EGPIO_CARD_RESET
:
263 egpio
|= EGPIO_H3600_CARD_RESET
;
265 case IPAQ_EGPIO_OPT_RESET
:
266 egpio
|= EGPIO_H3600_OPT_RESET
;
268 case IPAQ_EGPIO_IR_ON
:
269 gpio
|= GPIO_H3100_IR_ON
;
271 case IPAQ_EGPIO_IR_FSEL
:
272 gpio
|= GPIO_H3100_IR_FSEL
;
274 case IPAQ_EGPIO_RS232_ON
:
275 egpio
|= EGPIO_H3600_RS232_ON
;
277 case IPAQ_EGPIO_VPP_ON
:
278 egpio
|= EGPIO_H3600_VPP_ON
;
283 local_irq_save(flags
);
285 h3100_egpio
|= egpio
;
288 h3100_egpio
&= ~egpio
;
291 H3100_EGPIO
= h3100_egpio
;
292 local_irq_restore(flags
);
296 #define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
299 | GPIO_H3100_LCD_3V_ON \
300 | GPIO_H3100_AUD_ON \
301 | GPIO_H3100_AUD_PWR_ON \
303 | GPIO_H3100_IR_FSEL)
305 static void __init
h3100_map_io(void)
309 /* Initialize h3100-specific values here */
310 GPCR
= 0x0fffffff; /* All outputs are set low by default */
311 GPDR
= GPIO_H3600_COM_RTS
| GPIO_H3600_L3_CLOCK
|
312 GPIO_H3600_L3_MODE
| GPIO_H3600_L3_DATA
|
313 GPIO_H3600_CLK_SET1
| GPIO_H3600_CLK_SET0
|
316 /* Older bootldrs put GPIO2-9 in alternate mode on the
317 assumption that they are used for video */
318 GAFR
&= ~H3100_DIRECT_EGPIO
;
320 H3100_EGPIO
= h3100_egpio
;
321 assign_h3600_egpio
= h3100_control_egpio
;
324 MACHINE_START(H3100
, "Compaq iPAQ H3100")
325 .phys_io
= 0x80000000,
326 .io_pg_offst
= ((0xf8000000) >> 18) & 0xfffc,
327 .boot_params
= 0xc0000100,
328 .map_io
= h3100_map_io
,
329 .init_irq
= sa1100_init_irq
,
330 .timer
= &sa1100_timer
,
331 .init_machine
= h3xxx_mach_init
,
334 #endif /* CONFIG_SA1100_H3100 */
336 /************************* H3600 *************************/
338 #ifdef CONFIG_SA1100_H3600
340 #define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
341 static unsigned int h3600_egpio
= EGPIO_H3600_RS232_ON
;
343 static void h3600_control_egpio(enum ipaq_egpio_type x
, int setp
)
345 unsigned int egpio
= 0;
349 case IPAQ_EGPIO_LCD_POWER
:
350 egpio
|= EGPIO_H3600_LCD_ON
|
351 EGPIO_H3600_LCD_PCI
|
352 EGPIO_H3600_LCD_5V_ON
|
355 case IPAQ_EGPIO_LCD_ENABLE
:
357 case IPAQ_EGPIO_CODEC_NRESET
:
358 egpio
|= EGPIO_H3600_CODEC_NRESET
;
360 case IPAQ_EGPIO_AUDIO_ON
:
361 egpio
|= EGPIO_H3600_AUD_AMP_ON
|
362 EGPIO_H3600_AUD_PWR_ON
;
364 case IPAQ_EGPIO_QMUTE
:
365 egpio
|= EGPIO_H3600_QMUTE
;
367 case IPAQ_EGPIO_OPT_NVRAM_ON
:
368 egpio
|= EGPIO_H3600_OPT_NVRAM_ON
;
370 case IPAQ_EGPIO_OPT_ON
:
371 egpio
|= EGPIO_H3600_OPT_ON
;
373 case IPAQ_EGPIO_CARD_RESET
:
374 egpio
|= EGPIO_H3600_CARD_RESET
;
376 case IPAQ_EGPIO_OPT_RESET
:
377 egpio
|= EGPIO_H3600_OPT_RESET
;
379 case IPAQ_EGPIO_IR_ON
:
380 egpio
|= EGPIO_H3600_IR_ON
;
382 case IPAQ_EGPIO_IR_FSEL
:
383 egpio
|= EGPIO_H3600_IR_FSEL
;
385 case IPAQ_EGPIO_RS232_ON
:
386 egpio
|= EGPIO_H3600_RS232_ON
;
388 case IPAQ_EGPIO_VPP_ON
:
389 egpio
|= EGPIO_H3600_VPP_ON
;
394 local_irq_save(flags
);
396 h3600_egpio
|= egpio
;
398 h3600_egpio
&= ~egpio
;
399 H3600_EGPIO
= h3600_egpio
;
400 local_irq_restore(flags
);
404 static void __init
h3600_map_io(void)
408 /* Initialize h3600-specific values here */
410 GPCR
= 0x0fffffff; /* All outputs are set low by default */
411 GPDR
= GPIO_H3600_COM_RTS
| GPIO_H3600_L3_CLOCK
|
412 GPIO_H3600_L3_MODE
| GPIO_H3600_L3_DATA
|
413 GPIO_H3600_CLK_SET1
| GPIO_H3600_CLK_SET0
|
414 GPIO_LDD15
| GPIO_LDD14
| GPIO_LDD13
| GPIO_LDD12
|
415 GPIO_LDD11
| GPIO_LDD10
| GPIO_LDD9
| GPIO_LDD8
;
417 H3600_EGPIO
= h3600_egpio
; /* Maintains across sleep? */
418 assign_h3600_egpio
= h3600_control_egpio
;
421 MACHINE_START(H3600
, "Compaq iPAQ H3600")
422 .phys_io
= 0x80000000,
423 .io_pg_offst
= ((0xf8000000) >> 18) & 0xfffc,
424 .boot_params
= 0xc0000100,
425 .map_io
= h3600_map_io
,
426 .init_irq
= sa1100_init_irq
,
427 .timer
= &sa1100_timer
,
428 .init_machine
= h3xxx_mach_init
,
431 #endif /* CONFIG_SA1100_H3600 */