2 * SBE 2T3E3 synchronous serial card driver for Linux
4 * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
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.
10 * This code is based on a driver written by SBE Inc.
13 #include <linux/delay.h>
17 #define bootrom_set_bit(sc, reg, bit) \
18 bootrom_write((sc), (reg), \
19 bootrom_read((sc), (reg)) | (bit))
21 #define bootrom_clear_bit(sc, reg, bit) \
22 bootrom_write((sc), (reg), \
23 bootrom_read((sc), (reg)) & ~(bit))
25 static inline void cpld_set_bit(struct channel
*channel
, unsigned reg
, u32 bit
)
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
);
33 static inline void cpld_clear_bit(struct channel
*channel
, unsigned reg
, u32 bit
)
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
);
41 void cpld_init(struct channel
*sc
)
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
);
52 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRB
, val
);
56 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
, val
);
60 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWF
, val
);
64 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWL
, val
);
67 val
= SBE_2T3E3_CPLD_VAL_LCV_COUNTER
;
68 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PLTR
, val
);
73 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PLCR
, val
);
78 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PPFR
, val
);
79 /* TODO: this doesn't work!!! */
81 /* SERIAL_CHIP_SELECT */
83 cpld_write(sc
, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT
, val
);
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
);
96 void cpld_start_intr(struct channel
*sc
)
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
);
106 void cpld_stop_intr(struct channel
*sc
)
112 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PIER
, val
);
115 void cpld_set_frame_mode(struct channel
*sc
, u32 mode
)
117 if (sc
->p
.frame_mode
== 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
);
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
);
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
);
146 sc
->p
.frame_mode
= mode
;
149 /* set rate of the local clock */
150 void cpld_set_frame_type(struct channel
*sc
, u32 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
);
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
);
168 void cpld_set_scrambler(struct channel
*sc
, u32 mode
)
170 if (sc
->p
.scrambler
== mode
)
174 case SBE_2T3E3_SCRAMBLER_OFF
:
175 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
176 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE
);
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
);
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
);
194 sc
->p
.scrambler
= mode
;
198 void cpld_set_crc(struct channel
*sc
, u32 crc
)
200 if (sc
->p
.crc
== crc
)
204 case SBE_2T3E3_CRC_16
:
205 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
206 SBE_2T3E3_CPLD_VAL_CRC32
);
208 case SBE_2T3E3_CRC_32
:
209 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
210 SBE_2T3E3_CPLD_VAL_CRC32
);
220 void cpld_select_panel(struct channel
*sc
, u32 panel
)
222 if (sc
->p
.panel
== panel
)
225 case SBE_2T3E3_PANEL_FRONT
:
226 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
227 SBE_2T3E3_CPLD_VAL_REAR_PANEL
);
229 case SBE_2T3E3_PANEL_REAR
:
230 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
231 SBE_2T3E3_CPLD_VAL_REAR_PANEL
);
243 extern void cpld_set_clock(struct channel
*sc
, u32 mode
)
245 if (sc
->p
.clock_source
== mode
)
249 case SBE_2T3E3_TIMING_LOCAL
:
250 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
251 SBE_2T3E3_CPLD_VAL_ALT
);
253 case SBE_2T3E3_TIMING_LOOP
:
254 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
255 SBE_2T3E3_CPLD_VAL_ALT
);
261 sc
->p
.clock_source
= mode
;
264 void cpld_set_pad_count(struct channel
*sc
, u32 count
)
268 if (sc
->p
.pad_count
== count
)
272 case SBE_2T3E3_PAD_COUNT_1
:
273 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_1
;
275 case SBE_2T3E3_PAD_COUNT_2
:
276 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_2
;
278 case SBE_2T3E3_PAD_COUNT_3
:
279 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_3
;
281 case SBE_2T3E3_PAD_COUNT_4
:
282 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_4
;
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
;
294 void cpld_LOS_update(struct channel
*sc
)
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
;
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");
311 void cpld_set_fractional_mode(struct channel
*sc
, u32 mode
,
314 if (mode
== SBE_2T3E3_FRACTIONAL_MODE_NONE
) {
319 if (sc
->p
.fractional_mode
== mode
&& sc
->p
.bandwidth_start
== start
&&
320 sc
->p
.bandwidth_stop
== stop
)
324 case SBE_2T3E3_FRACTIONAL_MODE_NONE
:
325 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
326 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE
);
328 case SBE_2T3E3_FRACTIONAL_MODE_0
:
329 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
330 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0
);
332 case SBE_2T3E3_FRACTIONAL_MODE_1
:
333 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
334 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1
);
336 case SBE_2T3E3_FRACTIONAL_MODE_2
:
337 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
338 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2
);
341 netdev_err(sc
->dev
, "wrong mode in set_fractional_mode\n");
345 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWF
, start
);
346 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWL
, stop
);
348 sc
->p
.fractional_mode
= mode
;
349 sc
->p
.bandwidth_start
= start
;
350 sc
->p
.bandwidth_stop
= stop
;