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 struct ipaq_model_ops ipaq_model_ops
;
50 EXPORT_SYMBOL(ipaq_model_ops
);
52 static struct mtd_partition h3xxx_partitions
[] = {
54 .name
= "H3XXX boot firmware",
57 .mask_flags
= MTD_WRITEABLE
, /* force read-only */
59 #ifdef CONFIG_MTD_2PARTS_IPAQ
60 .name
= "H3XXX root jffs2",
61 .size
= MTDPART_SIZ_FULL
,
64 .name
= "H3XXX kernel",
68 .name
= "H3XXX params",
72 #ifdef CONFIG_JFFS2_FS
73 .name
= "H3XXX root jffs2",
74 .size
= MTDPART_SIZ_FULL
,
77 .name
= "H3XXX initrd",
81 .name
= "H3XXX root cramfs",
85 .name
= "H3XXX usr cramfs",
89 .name
= "H3XXX usr local",
90 .size
= MTDPART_SIZ_FULL
,
97 static void h3xxx_set_vpp(int vpp
)
99 assign_h3600_egpio(IPAQ_EGPIO_VPP_ON
, vpp
);
102 static struct flash_platform_data h3xxx_flash_data
= {
103 .map_name
= "cfi_probe",
104 .set_vpp
= h3xxx_set_vpp
,
105 .parts
= h3xxx_partitions
,
106 .nr_parts
= ARRAY_SIZE(h3xxx_partitions
),
109 static struct resource h3xxx_flash_resource
= {
110 .start
= SA1100_CS0_PHYS
,
111 .end
= SA1100_CS0_PHYS
+ SZ_32M
- 1,
112 .flags
= IORESOURCE_MEM
,
116 * This turns the IRDA power on or off on the Compaq H3600
118 static int h3600_irda_set_power(struct device
*dev
, unsigned int state
)
120 assign_h3600_egpio( IPAQ_EGPIO_IR_ON
, state
);
125 static void h3600_irda_set_speed(struct device
*dev
, unsigned int speed
)
127 if (speed
< 4000000) {
128 clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL
);
130 set_h3600_egpio(IPAQ_EGPIO_IR_FSEL
);
134 static struct irda_platform_data h3600_irda_data
= {
135 .set_power
= h3600_irda_set_power
,
136 .set_speed
= h3600_irda_set_speed
,
139 static void h3xxx_mach_init(void)
141 sa11x0_set_flash_data(&h3xxx_flash_data
, &h3xxx_flash_resource
, 1);
142 sa11x0_set_irda_data(&h3600_irda_data
);
146 * low-level UART features
149 static void h3600_uart_set_mctrl(struct uart_port
*port
, u_int mctrl
)
151 if (port
->mapbase
== _Ser3UTCR0
) {
152 if (mctrl
& TIOCM_RTS
)
153 GPCR
= GPIO_H3600_COM_RTS
;
155 GPSR
= GPIO_H3600_COM_RTS
;
159 static u_int
h3600_uart_get_mctrl(struct uart_port
*port
)
161 u_int ret
= TIOCM_CD
| TIOCM_CTS
| TIOCM_DSR
;
163 if (port
->mapbase
== _Ser3UTCR0
) {
165 /* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
166 if (gplr
& GPIO_H3600_COM_DCD
)
168 if (gplr
& GPIO_H3600_COM_CTS
)
175 static void h3600_uart_pm(struct uart_port
*port
, u_int state
, u_int oldstate
)
177 if (port
->mapbase
== _Ser2UTCR0
) { /* TODO: REMOVE THIS */
178 assign_h3600_egpio(IPAQ_EGPIO_IR_ON
, !state
);
179 } else if (port
->mapbase
== _Ser3UTCR0
) {
180 assign_h3600_egpio(IPAQ_EGPIO_RS232_ON
, !state
);
185 * Enable/Disable wake up events for this serial port.
186 * Obviously, we only support this on the normal COM port.
188 static int h3600_uart_set_wake(struct uart_port
*port
, u_int enable
)
192 if (port
->mapbase
== _Ser3UTCR0
) {
194 PWER
|= PWER_GPIO23
| PWER_GPIO25
; /* DCD and CTS */
196 PWER
&= ~(PWER_GPIO23
| PWER_GPIO25
); /* DCD and CTS */
202 static struct sa1100_port_fns h3600_port_fns __initdata
= {
203 .set_mctrl
= h3600_uart_set_mctrl
,
204 .get_mctrl
= h3600_uart_get_mctrl
,
206 .set_wake
= h3600_uart_set_wake
,
210 * helper for sa1100fb
212 static void h3xxx_lcd_power(int enable
)
214 assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER
, enable
);
217 static struct map_desc h3600_io_desc
[] __initdata
= {
218 { /* static memory bank 2 CS#2 */
219 .virtual = H3600_BANK_2_VIRT
,
220 .pfn
= __phys_to_pfn(SA1100_CS2_PHYS
),
221 .length
= 0x02800000,
223 }, { /* static memory bank 4 CS#4 */
224 .virtual = H3600_BANK_4_VIRT
,
225 .pfn
= __phys_to_pfn(SA1100_CS4_PHYS
),
226 .length
= 0x00800000,
228 }, { /* EGPIO 0 CS#5 */
229 .virtual = H3600_EGPIO_VIRT
,
230 .pfn
= __phys_to_pfn(H3600_EGPIO_PHYS
),
231 .length
= 0x01000000,
237 * Common map_io initialization
240 static void __init
h3xxx_map_io(void)
243 iotable_init(h3600_io_desc
, ARRAY_SIZE(h3600_io_desc
));
245 sa1100_register_uart_fns(&h3600_port_fns
);
246 sa1100_register_uart(0, 3); /* Common serial port */
247 // sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
249 /* Ensure those pins are outputs and driving low */
250 PPDR
|= PPC_TXD4
| PPC_SCLK
| PPC_SFRM
;
251 PPSR
&= ~(PPC_TXD4
| PPC_SCLK
| PPC_SFRM
);
253 /* Configure suspend conditions */
255 PWER
= PWER_GPIO0
| PWER_RTC
;
259 sa1100fb_lcd_power
= h3xxx_lcd_power
;
262 static __inline__
void do_blank(int setp
)
264 if (ipaq_model_ops
.blank_callback
)
265 ipaq_model_ops
.blank_callback(1-setp
);
268 /************************* H3100 *************************/
270 #ifdef CONFIG_SA1100_H3100
272 #define H3100_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
273 static unsigned int h3100_egpio
= 0;
275 static void h3100_control_egpio(enum ipaq_egpio_type x
, int setp
)
277 unsigned int egpio
= 0;
282 case IPAQ_EGPIO_LCD_POWER
:
283 egpio
|= EGPIO_H3600_LCD_ON
;
284 gpio
|= GPIO_H3100_LCD_3V_ON
;
287 case IPAQ_EGPIO_LCD_ENABLE
:
289 case IPAQ_EGPIO_CODEC_NRESET
:
290 egpio
|= EGPIO_H3600_CODEC_NRESET
;
292 case IPAQ_EGPIO_AUDIO_ON
:
293 gpio
|= GPIO_H3100_AUD_PWR_ON
296 case IPAQ_EGPIO_QMUTE
:
297 gpio
|= GPIO_H3100_QMUTE
;
299 case IPAQ_EGPIO_OPT_NVRAM_ON
:
300 egpio
|= EGPIO_H3600_OPT_NVRAM_ON
;
302 case IPAQ_EGPIO_OPT_ON
:
303 egpio
|= EGPIO_H3600_OPT_ON
;
305 case IPAQ_EGPIO_CARD_RESET
:
306 egpio
|= EGPIO_H3600_CARD_RESET
;
308 case IPAQ_EGPIO_OPT_RESET
:
309 egpio
|= EGPIO_H3600_OPT_RESET
;
311 case IPAQ_EGPIO_IR_ON
:
312 gpio
|= GPIO_H3100_IR_ON
;
314 case IPAQ_EGPIO_IR_FSEL
:
315 gpio
|= GPIO_H3100_IR_FSEL
;
317 case IPAQ_EGPIO_RS232_ON
:
318 egpio
|= EGPIO_H3600_RS232_ON
;
320 case IPAQ_EGPIO_VPP_ON
:
321 egpio
|= EGPIO_H3600_VPP_ON
;
326 local_irq_save(flags
);
328 h3100_egpio
|= egpio
;
331 h3100_egpio
&= ~egpio
;
334 H3100_EGPIO
= h3100_egpio
;
335 local_irq_restore(flags
);
339 static unsigned long h3100_read_egpio(void)
344 static int h3100_pm_callback(int req
)
346 if (ipaq_model_ops
.pm_callback_aux
)
347 return ipaq_model_ops
.pm_callback_aux(req
);
351 static struct ipaq_model_ops h3100_model_ops __initdata
= {
352 .generic_name
= "3100",
353 .control
= h3100_control_egpio
,
354 .read
= h3100_read_egpio
,
355 .pm_callback
= h3100_pm_callback
358 #define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
361 | GPIO_H3100_LCD_3V_ON \
362 | GPIO_H3100_AUD_ON \
363 | GPIO_H3100_AUD_PWR_ON \
365 | GPIO_H3100_IR_FSEL)
367 static void __init
h3100_map_io(void)
371 /* Initialize h3100-specific values here */
372 GPCR
= 0x0fffffff; /* All outputs are set low by default */
373 GPDR
= GPIO_H3600_COM_RTS
| GPIO_H3600_L3_CLOCK
|
374 GPIO_H3600_L3_MODE
| GPIO_H3600_L3_DATA
|
375 GPIO_H3600_CLK_SET1
| GPIO_H3600_CLK_SET0
|
378 /* Older bootldrs put GPIO2-9 in alternate mode on the
379 assumption that they are used for video */
380 GAFR
&= ~H3100_DIRECT_EGPIO
;
382 H3100_EGPIO
= h3100_egpio
;
383 ipaq_model_ops
= h3100_model_ops
;
386 MACHINE_START(H3100
, "Compaq iPAQ H3100")
387 .phys_io
= 0x80000000,
388 .io_pg_offst
= ((0xf8000000) >> 18) & 0xfffc,
389 .boot_params
= 0xc0000100,
390 .map_io
= h3100_map_io
,
391 .init_irq
= sa1100_init_irq
,
392 .timer
= &sa1100_timer
,
393 .init_machine
= h3xxx_mach_init
,
396 #endif /* CONFIG_SA1100_H3100 */
398 /************************* H3600 *************************/
400 #ifdef CONFIG_SA1100_H3600
402 #define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
403 static unsigned int h3600_egpio
= EGPIO_H3600_RS232_ON
;
405 static void h3600_control_egpio(enum ipaq_egpio_type x
, int setp
)
407 unsigned int egpio
= 0;
411 case IPAQ_EGPIO_LCD_POWER
:
412 egpio
|= EGPIO_H3600_LCD_ON
|
413 EGPIO_H3600_LCD_PCI
|
414 EGPIO_H3600_LCD_5V_ON
|
418 case IPAQ_EGPIO_LCD_ENABLE
:
420 case IPAQ_EGPIO_CODEC_NRESET
:
421 egpio
|= EGPIO_H3600_CODEC_NRESET
;
423 case IPAQ_EGPIO_AUDIO_ON
:
424 egpio
|= EGPIO_H3600_AUD_AMP_ON
|
425 EGPIO_H3600_AUD_PWR_ON
;
427 case IPAQ_EGPIO_QMUTE
:
428 egpio
|= EGPIO_H3600_QMUTE
;
430 case IPAQ_EGPIO_OPT_NVRAM_ON
:
431 egpio
|= EGPIO_H3600_OPT_NVRAM_ON
;
433 case IPAQ_EGPIO_OPT_ON
:
434 egpio
|= EGPIO_H3600_OPT_ON
;
436 case IPAQ_EGPIO_CARD_RESET
:
437 egpio
|= EGPIO_H3600_CARD_RESET
;
439 case IPAQ_EGPIO_OPT_RESET
:
440 egpio
|= EGPIO_H3600_OPT_RESET
;
442 case IPAQ_EGPIO_IR_ON
:
443 egpio
|= EGPIO_H3600_IR_ON
;
445 case IPAQ_EGPIO_IR_FSEL
:
446 egpio
|= EGPIO_H3600_IR_FSEL
;
448 case IPAQ_EGPIO_RS232_ON
:
449 egpio
|= EGPIO_H3600_RS232_ON
;
451 case IPAQ_EGPIO_VPP_ON
:
452 egpio
|= EGPIO_H3600_VPP_ON
;
457 local_irq_save(flags
);
459 h3600_egpio
|= egpio
;
461 h3600_egpio
&= ~egpio
;
462 H3600_EGPIO
= h3600_egpio
;
463 local_irq_restore(flags
);
467 static unsigned long h3600_read_egpio(void)
472 static int h3600_pm_callback(int req
)
474 if (ipaq_model_ops
.pm_callback_aux
)
475 return ipaq_model_ops
.pm_callback_aux(req
);
479 static struct ipaq_model_ops h3600_model_ops __initdata
= {
480 .generic_name
= "3600",
481 .control
= h3600_control_egpio
,
482 .read
= h3600_read_egpio
,
483 .pm_callback
= h3600_pm_callback
486 static void __init
h3600_map_io(void)
490 /* Initialize h3600-specific values here */
492 GPCR
= 0x0fffffff; /* All outputs are set low by default */
493 GPDR
= GPIO_H3600_COM_RTS
| GPIO_H3600_L3_CLOCK
|
494 GPIO_H3600_L3_MODE
| GPIO_H3600_L3_DATA
|
495 GPIO_H3600_CLK_SET1
| GPIO_H3600_CLK_SET0
|
496 GPIO_LDD15
| GPIO_LDD14
| GPIO_LDD13
| GPIO_LDD12
|
497 GPIO_LDD11
| GPIO_LDD10
| GPIO_LDD9
| GPIO_LDD8
;
499 H3600_EGPIO
= h3600_egpio
; /* Maintains across sleep? */
500 ipaq_model_ops
= h3600_model_ops
;
503 MACHINE_START(H3600
, "Compaq iPAQ H3600")
504 .phys_io
= 0x80000000,
505 .io_pg_offst
= ((0xf8000000) >> 18) & 0xfffc,
506 .boot_params
= 0xc0000100,
507 .map_io
= h3600_map_io
,
508 .init_irq
= sa1100_init_irq
,
509 .timer
= &sa1100_timer
,
510 .init_machine
= h3xxx_mach_init
,
513 #endif /* CONFIG_SA1100_H3600 */