2 * linux/arch/arm/mach-sa1100/trizeps.c
5 * Andreas Hofer <ho@dsa-ac.de>,
6 * Peter Lueg <pl@dsa-ac.de>,
7 * Guennadi Liakhovetski <gl@dsa-ac.de>
9 * This file contains all Trizeps-specific tweaks.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/sched.h>
18 #include <linux/tty.h>
19 #include <linux/module.h>
20 #include <linux/errno.h>
21 #include <linux/delay.h>
24 #include <asm/mach-types.h>
25 #include <asm/hardware.h>
26 #include <asm/arch/trizeps.h>
27 #include <asm/setup.h>
29 #include <asm/pgtable.h>
31 #include <asm/mach/arch.h>
32 #include <asm/mach/map.h>
33 #include <asm/mach/irq.h>
34 #include <asm/mach/serial_sa1100.h>
35 #include <linux/serial_core.h>
36 #include <linux/serial_reg.h>
37 #include <asm/arch/serial.h>
41 #include <asm/arch/irqs.h>
47 #define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
49 #define DPRINTK( x... )
52 static struct tri_uart_cts_data_t tri_uart_cts_data[] = {
53 { TRIZEPS_GPIO_UART1_CTS, 0, NULL, NULL,"int. UART1 cts" },
54 { TRIZEPS_GPIO_UART2_CTS, 0, NULL, NULL,"int. UART2 cts" },
55 { TRIZEPS_GPIO_UART3_CTS, 0, NULL, NULL,"int. UART3 cts" }
58 static void trizeps_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
60 struct tri_uart_cts_data_t * uart_data = (struct tri_uart_cts_data_t *)dev_id;
61 int cts = (!(GPLR & uart_data->cts_gpio));
63 /* NOTE: I suppose that we will not get any interrupts
64 if the GPIO is not changed, so maybe
65 the cts_prev_state can be removed ... */
66 if (cts != uart_data->cts_prev_state) {
68 uart_data->cts_prev_state = cts;
69 uart_handle_cts_change(uart_data->port, cts);
70 DPRINTK("(IRQ %d) changed (cts=%d) stop=%d\n",
71 irq, cts, uart_data->info->tty->hw_stopped);
76 trizeps_register_cts_intr(int gpio,
78 struct tri_uart_cts_data_t *uart_data)
84 set_irq_type(irq, IRQT_BOTHEDGE);
86 ret = request_irq(irq, trizeps_cts_intr,
87 SA_INTERRUPT, uart_data->name, uart_data);
89 printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n", ret);
94 static void trizeps_set_mctrl(struct uart_port *port, u_int mctrl)
96 if (port->mapbase == _Ser1UTCR0)
99 if (mctrl & TIOCM_RTS)
100 GPCR |= TRIZEPS_GPIO_UART1_RTS;
102 GPSR |= TRIZEPS_GPIO_UART1_RTS;
104 DPRINTK("2 ttySA%d Set RTS %s\n",port->line,
105 mctrl & TIOCM_RTS ? "low" : "high");
108 else if (port->mapbase == _Ser3UTCR0)
118 static u_int trizeps_get_mctrl(struct uart_port *port)
120 int result = TIOCM_CD | TIOCM_DSR;
122 if (port->mapbase == _Ser1UTCR0)
124 if (!(GPLR & TRIZEPS_GPIO_UART1_CTS))
127 else if (port->mapbase == _Ser2UTCR0)
131 else if (port->mapbase == _Ser3UTCR0)
140 DPRINTK(" ttySA%d %s%s%s\n",port->line,
141 result & TIOCM_CD ? "CD " : "",
142 result & TIOCM_CTS ? "CTS " : "",
143 result & TIOCM_DSR ? "DSR " : "");
148 static struct sa1100_port_fns trizeps_port_fns __initdata = {
149 .set_mctrl = trizeps_set_mctrl,
150 .get_mctrl = trizeps_get_mctrl,
153 static void trizeps_power_off(void)
155 printk("trizeps power off\n");
158 /* disable internal oscillator, float CS lines */
159 PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
160 /* enable wake-up on GPIO0 (Assabet...) */
161 PWER = GFER = GRER = 1;
163 * set scratchpad to zero, just in case it is used as a
164 * restart address by the bootloader.
172 TRIZEPS_BCR_set(TRIZEPS_BCR0, TRIZEPS_MFT_OFF);
175 * if power supply no Akku
176 * -> enter sleep mode
181 static int __init trizeps_init(void)
183 if (!machine_is_trizeps())
187 pm_power_off = trizeps_power_off;
189 // Init UART2 for IrDA
190 // PPDR |= PPC_TXD2; // Set TXD2 as output
191 Ser2UTCR4 = UTCR4_HSE; // enable HSE
193 Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR | HSSR0_RAB | HSSR0_FRE;
198 /* Set up external serial IRQs */
199 GAFR &= ~(GPIO_GPIO16 | GPIO_GPIO17); // no alternate function
200 GPDR &= ~(GPIO_GPIO16 | GPIO_GPIO17); // Set to Input
201 set_irq_type(IRQ_GPIO16, IRQT_RISING);
202 set_irq_type(IRQ_GPIO17, IRQT_RISING);
207 __initcall(trizeps_init);
209 static struct map_desc trizeps_io_desc[] __initdata = {
210 /* virtual physical length type */
211 { 0xF0000000l, 0x30000000l, 0x00800000l, MT_DEVICE },
212 { 0xF2000000l, 0x38000000l, 0x00800000l, MT_DEVICE },
215 static void __init trizeps_map_io(void)
218 iotable_init(trizeps_io_desc, ARRAY_SIZE(trizeps_io_desc));
220 sa1100_register_uart_fns(&trizeps_port_fns);
221 sa1100_register_uart(0, 3);
222 sa1100_register_uart(1, 1);
223 sa1100_register_uart(2, 2);
226 MACHINE_START(TRIZEPS, "TRIZEPS")
228 BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
229 MAPIO(trizeps_map_io)
230 INITIRQ(sa1100_init_irq)
231 INITTIME(sa1100_init_time)