Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
staging
sbe-2t3e3
cpld.c
Go to the documentation of this file.
1
/*
2
* SBE 2T3E3 synchronous serial card driver for Linux
3
*
4
* Copyright (C) 2009-2010 Krzysztof Halasa <
[email protected]
>
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
25
static
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
33
static
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
41
void
cpld_init
(
struct
channel *
sc
)
42
{
43
u32
val
;
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
96
void
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);
104
}
105
106
void
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
115
void
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 */
150
void
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
168
void
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
198
void
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
220
void
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
243
extern
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
264
void
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
294
void
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
311
void
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
:
341
printk
(
KERN_ERR
"wrong mode in set_fractional_mode\n"
);
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
}
Generated on Thu Jan 10 2013 14:31:26 for Linux Kernel by
1.8.2