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