786fcc3391178ca93fedcbb3ac0410d1d8130e40
[safe/jmp/linux-2.6] / drivers / media / dvb / mantis / mantis_uart.c
1 #include <linux/spinlock.h>
2 #include "mantis_common.h"
3
4 struct mantis_uart_params {
5         enum mantis_baud        baud_rate;
6         enum mantis_parity      parity;
7 };
8
9 #define UART_MAX_BUF                    16
10
11 int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
12 {
13         struct mantis_hwconfig *config = mantis->hwconfig;
14         u32 stat, i;
15         unsigned long flags;
16
17         /* get data */
18         for (i = 0; i < (config->bytes + 1); i++) {
19
20                 if (stat & MANTIS_UART_RXFIFO_FULL) {
21                         dprintk(verbose, MANTIS_ERROR, 1, "RX Fifo FULL");
22                 }
23                 data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
24
25                 stat = mmread(MANTIS_UART_STAT);
26
27                 dprintk(verbose, MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
28
29                 if (data[i] & (1 << 7)) {
30                         dprintk(verbose, MANTIS_ERROR, 1, "UART framing error");
31                         return -EINVAL;
32                 }
33                 if (data[i] & (1 << 6)) {
34                         dprintk(verbose, MANTIS_ERROR, 1, "UART parity error");
35                         return -EINVAL;
36                 }
37         }
38
39         return 0;
40 }
41
42 static void mantis_uart_work(struct work_struct *work)
43 {
44         struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
45         struct mantis_hwconfig *config = mantis->hwconfig;
46         u8 buf[16];
47         int i;
48
49         dprintk(verbose, MANTIS_DEBUG, 1, "UART read");
50         mantis_uart_read(mantis, buf);
51
52         dprintk(verbose, MANTIS_DEBUG, 1, "UART: ");
53         for (i = 0; i < (config->bytes + 1); i++)
54                 dprintk(verbose, MANTIS_DEBUG, 0, "<%02x> ", buf[i]);
55
56         dprintk(verbose, MANTIS_DEBUG, 0, "\n");
57 }
58
59 static int mantis_uart_setup(struct mantis_pci *mantis,
60                              struct mantis_uart_params *params)
61 {
62         char* rates[] = { "B_9600", "B_19200", "B_38400", "B_57600", "B_115200" };
63         char* parity[] = { "NONE", "ODD", "EVEN" };
64
65         u32 reg;
66
67         dprintk(verbose, MANTIS_DEBUG, 1, "Set Parity <%s> Baud Rate <%s>",
68                 parity[params->parity],
69                 rates[params->baud_rate]);
70
71         mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
72
73         reg = mmread(MANTIS_UART_BAUD);
74
75         switch (params->baud_rate) {
76         case MANTIS_BAUD_9600:
77                 reg |= 0xd8;
78                 break;
79         case MANTIS_BAUD_19200:
80                 reg |= 0x6c;
81                 break;
82         case MANTIS_BAUD_38400:
83                 reg |= 0x36;
84                 break;
85         case MANTIS_BAUD_57600:
86                 reg |= 0x23;
87                 break;
88         case MANTIS_BAUD_115200:
89                 reg |= 0x11;
90                 break;
91         default:
92                 return -EINVAL;
93         }
94
95         mmwrite(reg, MANTIS_UART_BAUD);
96
97         return 0;
98 }
99
100 int mantis_uart_init(struct mantis_pci *mantis)
101 {
102         struct mantis_hwconfig *config = mantis->hwconfig;
103         struct mantis_uart_params params;
104
105         dprintk(verbose, MANTIS_DEBUG, 1, "Initializing UART ..");
106         /* default parity: */
107         params.baud_rate = config->baud_rate;
108         params.parity = config->parity;
109
110         init_waitqueue_head(&mantis->uart_wq);
111         spin_lock_init(&mantis->uart_lock);
112
113         INIT_WORK(&mantis->uart_work, mantis_uart_work);
114
115         /* disable interrupt */
116         mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
117
118         mantis_uart_setup(mantis, &params);
119
120         /* default 1 byte */
121         mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
122
123         /* flush buffer */
124         mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
125
126         /* enable interrupt */
127         mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
128         mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
129
130         schedule_work(&mantis->uart_work);
131
132         return 0;
133 }
134
135 void mantis_uart_exit(struct mantis_pci *mantis)
136 {
137         /* disable interrupt */
138         mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
139 }