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
,
83 static void h3xxx_mach_init(void)
85 sa11x0_register_mtd(&h3xxx_flash_data
, &h3xxx_flash_resource
, 1);
89 * low-level UART features
92 static void h3600_uart_set_mctrl(struct uart_port
*port
, u_int mctrl
)
94 if (port
->mapbase
== _Ser3UTCR0
) {
95 if (mctrl
& TIOCM_RTS
)
96 GPCR
= GPIO_H3600_COM_RTS
;
98 GPSR
= GPIO_H3600_COM_RTS
;
102 static u_int
h3600_uart_get_mctrl(struct uart_port
*port
)
104 u_int ret
= TIOCM_CD
| TIOCM_CTS
| TIOCM_DSR
;
106 if (port
->mapbase
== _Ser3UTCR0
) {
108 /* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
109 if (gplr
& GPIO_H3600_COM_DCD
)
111 if (gplr
& GPIO_H3600_COM_CTS
)
118 static void h3600_uart_pm(struct uart_port
*port
, u_int state
, u_int oldstate
)
120 if (port
->mapbase
== _Ser2UTCR0
) { /* TODO: REMOVE THIS */
121 assign_h3600_egpio(IPAQ_EGPIO_IR_ON
, !state
);
122 } else if (port
->mapbase
== _Ser3UTCR0
) {
123 assign_h3600_egpio(IPAQ_EGPIO_RS232_ON
, !state
);
128 * Enable/Disable wake up events for this serial port.
129 * Obviously, we only support this on the normal COM port.
131 static int h3600_uart_set_wake(struct uart_port
*port
, u_int enable
)
135 if (port
->mapbase
== _Ser3UTCR0
) {
137 PWER
|= PWER_GPIO23
| PWER_GPIO25
; /* DCD and CTS */
139 PWER
&= ~(PWER_GPIO23
| PWER_GPIO25
); /* DCD and CTS */
145 static struct sa1100_port_fns h3600_port_fns __initdata
= {
146 .set_mctrl
= h3600_uart_set_mctrl
,
147 .get_mctrl
= h3600_uart_get_mctrl
,
149 .set_wake
= h3600_uart_set_wake
,
153 * helper for sa1100fb
155 static void h3xxx_lcd_power(int enable
)
157 assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER
, enable
);
160 static struct map_desc h3600_io_desc
[] __initdata
= {
161 { /* static memory bank 2 CS#2 */
162 .virtual = H3600_BANK_2_VIRT
,
163 .pfn
= __phys_to_pfn(SA1100_CS2_PHYS
),
164 .length
= 0x02800000,
166 }, { /* static memory bank 4 CS#4 */
167 .virtual = H3600_BANK_4_VIRT
,
168 .pfn
= __phys_to_pfn(SA1100_CS4_PHYS
),
169 .length
= 0x00800000,
171 }, { /* EGPIO 0 CS#5 */
172 .virtual = H3600_EGPIO_VIRT
,
173 .pfn
= __phys_to_pfn(H3600_EGPIO_PHYS
),
174 .length
= 0x01000000,
180 * Common map_io initialization
183 static void __init
h3xxx_map_io(void)
186 iotable_init(h3600_io_desc
, ARRAY_SIZE(h3600_io_desc
));
188 sa1100_register_uart_fns(&h3600_port_fns
);
189 sa1100_register_uart(0, 3); /* Common serial port */
190 // sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
192 /* Ensure those pins are outputs and driving low */
193 PPDR
|= PPC_TXD4
| PPC_SCLK
| PPC_SFRM
;
194 PPSR
&= ~(PPC_TXD4
| PPC_SCLK
| PPC_SFRM
);
196 /* Configure suspend conditions */
198 PWER
= PWER_GPIO0
| PWER_RTC
;
202 sa1100fb_lcd_power
= h3xxx_lcd_power
;
205 /************************* H3100 *************************/
207 #ifdef CONFIG_SA1100_H3100
209 #define H3100_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
210 static unsigned int h3100_egpio
= 0;
212 static void h3100_control_egpio(enum ipaq_egpio_type x
, int setp
)
214 unsigned int egpio
= 0;
219 case IPAQ_EGPIO_LCD_POWER
:
220 egpio
|= EGPIO_H3600_LCD_ON
;
221 gpio
|= GPIO_H3100_LCD_3V_ON
;
223 case IPAQ_EGPIO_LCD_ENABLE
:
225 case IPAQ_EGPIO_CODEC_NRESET
:
226 egpio
|= EGPIO_H3600_CODEC_NRESET
;
228 case IPAQ_EGPIO_AUDIO_ON
:
229 gpio
|= GPIO_H3100_AUD_PWR_ON
232 case IPAQ_EGPIO_QMUTE
:
233 gpio
|= GPIO_H3100_QMUTE
;
235 case IPAQ_EGPIO_OPT_NVRAM_ON
:
236 egpio
|= EGPIO_H3600_OPT_NVRAM_ON
;
238 case IPAQ_EGPIO_OPT_ON
:
239 egpio
|= EGPIO_H3600_OPT_ON
;
241 case IPAQ_EGPIO_CARD_RESET
:
242 egpio
|= EGPIO_H3600_CARD_RESET
;
244 case IPAQ_EGPIO_OPT_RESET
:
245 egpio
|= EGPIO_H3600_OPT_RESET
;
247 case IPAQ_EGPIO_IR_ON
:
248 gpio
|= GPIO_H3100_IR_ON
;
250 case IPAQ_EGPIO_IR_FSEL
:
251 gpio
|= GPIO_H3100_IR_FSEL
;
253 case IPAQ_EGPIO_RS232_ON
:
254 egpio
|= EGPIO_H3600_RS232_ON
;
256 case IPAQ_EGPIO_VPP_ON
:
257 egpio
|= EGPIO_H3600_VPP_ON
;
262 local_irq_save(flags
);
264 h3100_egpio
|= egpio
;
267 h3100_egpio
&= ~egpio
;
270 H3100_EGPIO
= h3100_egpio
;
271 local_irq_restore(flags
);
275 #define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
278 | GPIO_H3100_LCD_3V_ON \
279 | GPIO_H3100_AUD_ON \
280 | GPIO_H3100_AUD_PWR_ON \
282 | GPIO_H3100_IR_FSEL)
284 static void __init
h3100_map_io(void)
288 /* Initialize h3100-specific values here */
289 GPCR
= 0x0fffffff; /* All outputs are set low by default */
290 GPDR
= GPIO_H3600_COM_RTS
| GPIO_H3600_L3_CLOCK
|
291 GPIO_H3600_L3_MODE
| GPIO_H3600_L3_DATA
|
292 GPIO_H3600_CLK_SET1
| GPIO_H3600_CLK_SET0
|
295 /* Older bootldrs put GPIO2-9 in alternate mode on the
296 assumption that they are used for video */
297 GAFR
&= ~H3100_DIRECT_EGPIO
;
299 H3100_EGPIO
= h3100_egpio
;
300 assign_h3600_egpio
= h3100_control_egpio
;
304 * This turns the IRDA power on or off on the Compaq H3100
306 static int h3100_irda_set_power(struct device
*dev
, unsigned int state
)
308 assign_h3100_egpio(IPAQ_EGPIO_IR_ON
, state
);
313 static void h3100_irda_set_speed(struct device
*dev
, unsigned int speed
)
315 assign_h3100_egpio(IPAQ_EGPIO_IR_FSEL
, !(speed
< 4000000));
318 static struct irda_platform_data h3100_irda_data
= {
319 .set_power
= h3100_irda_set_power
,
320 .set_speed
= h3100_irda_set_speed
,
323 static void h3100_mach_init(void)
326 sa11x0_register_irda(&h3100_irda_data
);
329 MACHINE_START(H3100
, "Compaq iPAQ H3100")
330 .phys_io
= 0x80000000,
331 .io_pg_offst
= ((0xf8000000) >> 18) & 0xfffc,
332 .boot_params
= 0xc0000100,
333 .map_io
= h3100_map_io
,
334 .init_irq
= sa1100_init_irq
,
335 .timer
= &sa1100_timer
,
336 .init_machine
= h3100_mach_init
,
339 #endif /* CONFIG_SA1100_H3100 */
341 /************************* H3600 *************************/
343 #ifdef CONFIG_SA1100_H3600
345 #define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
346 static unsigned int h3600_egpio
= EGPIO_H3600_RS232_ON
;
348 static void h3600_control_egpio(enum ipaq_egpio_type x
, int setp
)
350 unsigned int egpio
= 0;
354 case IPAQ_EGPIO_LCD_POWER
:
355 egpio
|= EGPIO_H3600_LCD_ON
|
356 EGPIO_H3600_LCD_PCI
|
357 EGPIO_H3600_LCD_5V_ON
|
360 case IPAQ_EGPIO_LCD_ENABLE
:
362 case IPAQ_EGPIO_CODEC_NRESET
:
363 egpio
|= EGPIO_H3600_CODEC_NRESET
;
365 case IPAQ_EGPIO_AUDIO_ON
:
366 egpio
|= EGPIO_H3600_AUD_AMP_ON
|
367 EGPIO_H3600_AUD_PWR_ON
;
369 case IPAQ_EGPIO_QMUTE
:
370 egpio
|= EGPIO_H3600_QMUTE
;
372 case IPAQ_EGPIO_OPT_NVRAM_ON
:
373 egpio
|= EGPIO_H3600_OPT_NVRAM_ON
;
375 case IPAQ_EGPIO_OPT_ON
:
376 egpio
|= EGPIO_H3600_OPT_ON
;
378 case IPAQ_EGPIO_CARD_RESET
:
379 egpio
|= EGPIO_H3600_CARD_RESET
;
381 case IPAQ_EGPIO_OPT_RESET
:
382 egpio
|= EGPIO_H3600_OPT_RESET
;
384 case IPAQ_EGPIO_IR_ON
:
385 egpio
|= EGPIO_H3600_IR_ON
;
387 case IPAQ_EGPIO_IR_FSEL
:
388 egpio
|= EGPIO_H3600_IR_FSEL
;
390 case IPAQ_EGPIO_RS232_ON
:
391 egpio
|= EGPIO_H3600_RS232_ON
;
393 case IPAQ_EGPIO_VPP_ON
:
394 egpio
|= EGPIO_H3600_VPP_ON
;
399 local_irq_save(flags
);
401 h3600_egpio
|= egpio
;
403 h3600_egpio
&= ~egpio
;
404 H3600_EGPIO
= h3600_egpio
;
405 local_irq_restore(flags
);
409 static void __init
h3600_map_io(void)
413 /* Initialize h3600-specific values here */
415 GPCR
= 0x0fffffff; /* All outputs are set low by default */
416 GPDR
= GPIO_H3600_COM_RTS
| GPIO_H3600_L3_CLOCK
|
417 GPIO_H3600_L3_MODE
| GPIO_H3600_L3_DATA
|
418 GPIO_H3600_CLK_SET1
| GPIO_H3600_CLK_SET0
|
419 GPIO_LDD15
| GPIO_LDD14
| GPIO_LDD13
| GPIO_LDD12
|
420 GPIO_LDD11
| GPIO_LDD10
| GPIO_LDD9
| GPIO_LDD8
;
422 H3600_EGPIO
= h3600_egpio
; /* Maintains across sleep? */
423 assign_h3600_egpio
= h3600_control_egpio
;
427 * This turns the IRDA power on or off on the Compaq H3600
429 static int h3600_irda_set_power(struct device
*dev
, unsigned int state
)
431 assign_h3600_egpio(IPAQ_EGPIO_IR_ON
, state
);
435 static void h3600_irda_set_speed(struct device
*dev
, unsigned int speed
)
437 assign_h3600_egpio(IPAQ_EGPIO_IR_FSEL
, !(speed
< 4000000));
440 static struct irda_platform_data h3600_irda_data
= {
441 .set_power
= h3600_irda_set_power
,
442 .set_speed
= h3600_irda_set_speed
,
445 static void h3600_mach_init(void)
448 sa11x0_register_irda(&h3600_irda_data
);
451 MACHINE_START(H3600
, "Compaq iPAQ H3600")
452 .phys_io
= 0x80000000,
453 .io_pg_offst
= ((0xf8000000) >> 18) & 0xfffc,
454 .boot_params
= 0xc0000100,
455 .map_io
= h3600_map_io
,
456 .init_irq
= sa1100_init_irq
,
457 .timer
= &sa1100_timer
,
458 .init_machine
= h3600_mach_init
,
461 #endif /* CONFIG_SA1100_H3600 */