f807c8ba26e4828298ec53d50a9a38dbac198b2c
[linux-3.10.git] / drivers / media / dvb / mantis / mantis_uart.c
1 /*
2         Mantis PCI bridge driver
3
4         Copyright (C) Manu Abraham (abraham.manu@gmail.com)
5
6         This program is free software; you can redistribute it and/or modify
7         it under the terms of the GNU General Public License as published by
8         the Free Software Foundation; either version 2 of the License, or
9         (at your option) any later version.
10
11         This program is distributed in the hope that it will be useful,
12         but WITHOUT ANY WARRANTY; without even the implied warranty of
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14         GNU General Public License for more details.
15
16         You should have received a copy of the GNU General Public License
17         along with this program; if not, write to the Free Software
18         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <linux/kernel.h>
22 #include <linux/spinlock.h>
23
24 #include <linux/signal.h>
25 #include <linux/sched.h>
26 #include <linux/interrupt.h>
27
28 #include "dmxdev.h"
29 #include "dvbdev.h"
30 #include "dvb_demux.h"
31 #include "dvb_frontend.h"
32 #include "dvb_net.h"
33
34 #include "mantis_common.h"
35 #include "mantis_reg.h"
36 #include "mantis_uart.h"
37
38 struct mantis_uart_params {
39         enum mantis_baud        baud_rate;
40         enum mantis_parity      parity;
41 };
42
43 static struct {
44         char string[7];
45 } rates[5] = {
46         { "9600" },
47         { "19200" },
48         { "38400" },
49         { "57600" },
50         { "115200" }
51 };
52
53 static struct {
54         char string[5];
55 } parity[3] = {
56         { "NONE" },
57         { "ODD" },
58         { "EVEN" }
59 };
60
61 #define UART_MAX_BUF                    16
62
63 int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
64 {
65         struct mantis_hwconfig *config = mantis->hwconfig;
66         u32 stat = 0, i;
67
68         /* get data */
69         for (i = 0; i < (config->bytes + 1); i++) {
70
71                 stat = mmread(MANTIS_UART_STAT);
72
73                 if (stat & MANTIS_UART_RXFIFO_FULL) {
74                         dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
75                 }
76                 data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
77
78                 dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
79
80                 if (data[i] & (1 << 7)) {
81                         dprintk(MANTIS_ERROR, 1, "UART framing error");
82                         return -EINVAL;
83                 }
84                 if (data[i] & (1 << 6)) {
85                         dprintk(MANTIS_ERROR, 1, "UART parity error");
86                         return -EINVAL;
87                 }
88         }
89
90         return 0;
91 }
92
93 static void mantis_uart_work(struct work_struct *work)
94 {
95         struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
96         struct mantis_hwconfig *config = mantis->hwconfig;
97         u8 buf[16];
98         int i;
99
100         mantis_uart_read(mantis, buf);
101
102         for (i = 0; i < (config->bytes + 1); i++)
103                 dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]);
104
105         dprintk(MANTIS_DEBUG, 0, "\n");
106 }
107
108 static int mantis_uart_setup(struct mantis_pci *mantis,
109                              struct mantis_uart_params *params)
110 {
111         u32 reg;
112
113         mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
114
115         reg = mmread(MANTIS_UART_BAUD);
116
117         switch (params->baud_rate) {
118         case MANTIS_BAUD_9600:
119                 reg |= 0xd8;
120                 break;
121         case MANTIS_BAUD_19200:
122                 reg |= 0x6c;
123                 break;
124         case MANTIS_BAUD_38400:
125                 reg |= 0x36;
126                 break;
127         case MANTIS_BAUD_57600:
128                 reg |= 0x23;
129                 break;
130         case MANTIS_BAUD_115200:
131                 reg |= 0x11;
132                 break;
133         default:
134                 return -EINVAL;
135         }
136
137         mmwrite(reg, MANTIS_UART_BAUD);
138
139         return 0;
140 }
141
142 int mantis_uart_init(struct mantis_pci *mantis)
143 {
144         struct mantis_hwconfig *config = mantis->hwconfig;
145         struct mantis_uart_params params;
146
147         /* default parity: */
148         params.baud_rate = config->baud_rate;
149         params.parity = config->parity;
150         dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
151                 rates[params.baud_rate].string,
152                 parity[params.parity].string);
153
154         init_waitqueue_head(&mantis->uart_wq);
155         spin_lock_init(&mantis->uart_lock);
156
157         INIT_WORK(&mantis->uart_work, mantis_uart_work);
158
159         /* disable interrupt */
160         mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
161
162         mantis_uart_setup(mantis, &params);
163
164         /* default 1 byte */
165         mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
166
167         /* flush buffer */
168         mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
169
170         /* enable interrupt */
171         mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
172         mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
173
174         schedule_work(&mantis->uart_work);
175         dprintk(MANTIS_DEBUG, 1, "UART successfully initialized");
176
177         return 0;
178 }
179 EXPORT_SYMBOL_GPL(mantis_uart_init);
180
181 void mantis_uart_exit(struct mantis_pci *mantis)
182 {
183         /* disable interrupt */
184         mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
185         flush_work_sync(&mantis->uart_work);
186 }
187 EXPORT_SYMBOL_GPL(mantis_uart_exit);