Merge tag 'v3.10.107' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / sbe-2t3e3 / cpld.c
CommitLineData
921a86e0
KH
1/*
2 * SBE 2T3E3 synchronous serial card driver for Linux
3 *
4 * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License
8 * as published by the Free Software Foundation.
9 *
10 * This code is based on a driver written by SBE Inc.
11 */
12
13#include <linux/delay.h>
14#include "2t3e3.h"
15#include "ctrl.h"
16
17#define bootrom_set_bit(sc, reg, bit) \
18 bootrom_write((sc), (reg), \
19 bootrom_read((sc), (reg)) | (bit))
20
21#define bootrom_clear_bit(sc, reg, bit) \
22 bootrom_write((sc), (reg), \
23 bootrom_read((sc), (reg)) & ~(bit))
24
25static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit)
26{
27 unsigned long flags;
28 spin_lock_irqsave(&channel->card->bootrom_lock, flags);
29 bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit);
30 spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
31}
32
33static inline void cpld_clear_bit(struct channel *channel, unsigned reg, u32 bit)
34{
35 unsigned long flags;
36 spin_lock_irqsave(&channel->card->bootrom_lock, flags);
37 bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
38 spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
39}
40
41void cpld_init(struct channel *sc)
42{
43 u32 val;
921a86e0
KH
44
45 /* PCRA */
46 val = SBE_2T3E3_CPLD_VAL_CRC32 |
47 cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot];
48 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
49
50 /* PCRB */
51 val = 0;
52 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
53
54 /* PCRC */
55 val = 0;
56 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
57
58 /* PBWF */
59 val = 0;
60 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
61
62 /* PBWL */
63 val = 0;
64 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
65
66 /* PLTR */
67 val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER;
68 cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
69 udelay(1000);
70
71 /* PLCR */
72 val = 0;
73 cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
74 udelay(1000);
75
76 /* PPFR */
77 val = 0x55;
78 cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
79 /* TODO: this doesn't work!!! */
80
81 /* SERIAL_CHIP_SELECT */
82 val = 0;
83 cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
84
85 /* PICSR */
86 val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
87 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
88 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
89 cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
90
91 cpld_start_intr(sc);
92
93 udelay(1000);
94}
95
96void cpld_start_intr(struct channel *sc)
97{
98 u32 val;
99
100 /* PIER */
101 val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE |
102 SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE;
103 cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
921a86e0
KH
104}
105
106void cpld_stop_intr(struct channel *sc)
107{
108 u32 val;
109
110 /* PIER */
111 val = 0;
112 cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
113}
114
115void cpld_set_frame_mode(struct channel *sc, u32 mode)
116{
117 if (sc->p.frame_mode == mode)
118 return;
119
120 switch (mode) {
121 case SBE_2T3E3_FRAME_MODE_HDLC:
122 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
123 SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE |
124 SBE_2T3E3_CPLD_VAL_RAW_MODE);
125 exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
126 exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
127 break;
128 case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
129 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
130 SBE_2T3E3_CPLD_VAL_RAW_MODE);
131 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
132 SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE);
133 exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
134 exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
135 break;
136 case SBE_2T3E3_FRAME_MODE_RAW:
137 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
138 SBE_2T3E3_CPLD_VAL_RAW_MODE);
139 exar7250_unipolar_onoff(sc, SBE_2T3E3_ON);
140 exar7300_unipolar_onoff(sc, SBE_2T3E3_ON);
141 break;
142 default:
143 return;
144 }
145
146 sc->p.frame_mode = mode;
147}
148
149/* set rate of the local clock */
150void cpld_set_frame_type(struct channel *sc, u32 type)
151{
152 switch (type) {
153 case SBE_2T3E3_FRAME_TYPE_E3_G751:
154 case SBE_2T3E3_FRAME_TYPE_E3_G832:
155 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
156 SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
157 break;
158 case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
159 case SBE_2T3E3_FRAME_TYPE_T3_M13:
160 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
161 SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
162 break;
163 default:
164 return;
165 }
166}
167
168void cpld_set_scrambler(struct channel *sc, u32 mode)
169{
170 if (sc->p.scrambler == mode)
171 return;
172
173 switch (mode) {
174 case SBE_2T3E3_SCRAMBLER_OFF:
175 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
176 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
177 break;
178 case SBE_2T3E3_SCRAMBLER_LARSCOM:
179 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
180 SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
181 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
182 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
183 break;
184 case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL:
185 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
186 SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
187 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
188 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
189 break;
190 default:
191 return;
192 }
193
194 sc->p.scrambler = mode;
195}
196
197
198void cpld_set_crc(struct channel *sc, u32 crc)
199{
200 if (sc->p.crc == crc)
201 return;
202
203 switch (crc) {
204 case SBE_2T3E3_CRC_16:
205 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
206 SBE_2T3E3_CPLD_VAL_CRC32);
207 break;
208 case SBE_2T3E3_CRC_32:
209 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
210 SBE_2T3E3_CPLD_VAL_CRC32);
211 break;
212 default:
213 return;
214 }
215
216 sc->p.crc = crc;
217}
218
219
220void cpld_select_panel(struct channel *sc, u32 panel)
221{
222 if (sc->p.panel == panel)
223 return;
224 switch (panel) {
225 case SBE_2T3E3_PANEL_FRONT:
226 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
227 SBE_2T3E3_CPLD_VAL_REAR_PANEL);
228 break;
229 case SBE_2T3E3_PANEL_REAR:
230 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
231 SBE_2T3E3_CPLD_VAL_REAR_PANEL);
232 break;
233 default:
234 return;
235 }
236
237 udelay(100);
238
239 sc->p.panel = panel;
240}
241
242
243extern void cpld_set_clock(struct channel *sc, u32 mode)
244{
245 if (sc->p.clock_source == mode)
246 return;
247
248 switch (mode) {
249 case SBE_2T3E3_TIMING_LOCAL:
250 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
251 SBE_2T3E3_CPLD_VAL_ALT);
252 break;
253 case SBE_2T3E3_TIMING_LOOP:
254 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
255 SBE_2T3E3_CPLD_VAL_ALT);
256 break;
257 default:
258 return;
259 }
260
261 sc->p.clock_source = mode;
262}
263
264void cpld_set_pad_count(struct channel *sc, u32 count)
265{
266 u32 val;
267
268 if (sc->p.pad_count == count)
269 return;
270
271 switch (count) {
272 case SBE_2T3E3_PAD_COUNT_1:
273 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1;
274 break;
275 case SBE_2T3E3_PAD_COUNT_2:
276 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2;
277 break;
278 case SBE_2T3E3_PAD_COUNT_3:
279 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3;
280 break;
281 case SBE_2T3E3_PAD_COUNT_4:
282 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4;
283 break;
284 default:
285 return;
286 }
287
288 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
289 SBE_2T3E3_CPLD_VAL_PAD_COUNT);
290 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
291 sc->p.pad_count = count;
292}
293
294void cpld_LOS_update(struct channel *sc)
295{
296 u_int8_t los;
297
298 cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
299 SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
300 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
301 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED);
302 los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) &
303 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
304
305 if (los != sc->s.LOS)
306 dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
307 los ? "Loss of signal" : "Signal OK");
308 sc->s.LOS = los;
309}
310
311void cpld_set_fractional_mode(struct channel *sc, u32 mode,
312 u32 start, u32 stop)
313{
314 if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
315 start = 0;
316 stop = 0;
317 }
318
319 if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
320 sc->p.bandwidth_stop == stop)
321 return;
322
323 switch (mode) {
324 case SBE_2T3E3_FRACTIONAL_MODE_NONE:
325 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
326 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE);
327 break;
328 case SBE_2T3E3_FRACTIONAL_MODE_0:
329 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
330 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0);
331 break;
332 case SBE_2T3E3_FRACTIONAL_MODE_1:
333 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
334 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1);
335 break;
336 case SBE_2T3E3_FRACTIONAL_MODE_2:
337 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
338 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
339 break;
340 default:
ce833d36 341 netdev_err(sc->dev, "wrong mode in set_fractional_mode\n");
921a86e0
KH
342 return;
343 }
344
345 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
346 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
347
348 sc->p.fractional_mode = mode;
349 sc->p.bandwidth_start = start;
350 sc->p.bandwidth_stop = stop;
351}