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
)
45 /* reset LIU and Framer */
46 val
= cpld_val_map
[SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET
][sc
->h
.slot
];
47 cpld_write(sc
, SBE_2T3E3_CPLD_REG_STATIC_RESET
, val
);
48 udelay(10000); /* TODO - how long? */
50 cpld_write(sc
, SBE_2T3E3_CPLD_REG_STATIC_RESET
, val
);
54 val
= SBE_2T3E3_CPLD_VAL_CRC32
|
55 cpld_val_map
[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE
][sc
->h
.slot
];
56 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRA
, val
);
60 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRB
, val
);
64 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
, val
);
68 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWF
, val
);
72 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWL
, val
);
75 val
= SBE_2T3E3_CPLD_VAL_LCV_COUNTER
;
76 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PLTR
, val
);
81 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PLCR
, val
);
86 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PPFR
, val
);
87 /* TODO: this doesn't work!!! */
89 /* SERIAL_CHIP_SELECT */
91 cpld_write(sc
, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT
, val
);
94 val
= SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED
|
95 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED
|
96 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED
;
97 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PICSR
, val
);
104 void cpld_start_intr(struct channel
*sc
)
109 val
= SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE
|
110 SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE
;
111 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PIER
, val
);
114 do you want to hang up your computer?
115 ENABLE REST OF INTERRUPTS !!!
116 you have been warned :).
121 void cpld_stop_intr(struct channel
*sc
)
127 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PIER
, val
);
130 void cpld_set_frame_mode(struct channel
*sc
, u32 mode
)
132 if (sc
->p
.frame_mode
== mode
)
136 case SBE_2T3E3_FRAME_MODE_HDLC
:
137 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
138 SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE
|
139 SBE_2T3E3_CPLD_VAL_RAW_MODE
);
140 exar7250_unipolar_onoff(sc
, SBE_2T3E3_OFF
);
141 exar7300_unipolar_onoff(sc
, SBE_2T3E3_OFF
);
143 case SBE_2T3E3_FRAME_MODE_TRANSPARENT
:
144 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
145 SBE_2T3E3_CPLD_VAL_RAW_MODE
);
146 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
147 SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE
);
148 exar7250_unipolar_onoff(sc
, SBE_2T3E3_OFF
);
149 exar7300_unipolar_onoff(sc
, SBE_2T3E3_OFF
);
151 case SBE_2T3E3_FRAME_MODE_RAW
:
152 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
153 SBE_2T3E3_CPLD_VAL_RAW_MODE
);
154 exar7250_unipolar_onoff(sc
, SBE_2T3E3_ON
);
155 exar7300_unipolar_onoff(sc
, SBE_2T3E3_ON
);
161 sc
->p
.frame_mode
= mode
;
164 /* set rate of the local clock */
165 void cpld_set_frame_type(struct channel
*sc
, u32 type
)
168 case SBE_2T3E3_FRAME_TYPE_E3_G751
:
169 case SBE_2T3E3_FRAME_TYPE_E3_G832
:
170 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
171 SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3
);
173 case SBE_2T3E3_FRAME_TYPE_T3_CBIT
:
174 case SBE_2T3E3_FRAME_TYPE_T3_M13
:
175 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
176 SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3
);
183 void cpld_set_scrambler(struct channel
*sc
, u32 mode
)
185 if (sc
->p
.scrambler
== mode
)
189 case SBE_2T3E3_SCRAMBLER_OFF
:
190 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
191 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE
);
193 case SBE_2T3E3_SCRAMBLER_LARSCOM
:
194 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
195 SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE
);
196 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
197 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE
);
199 case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL
:
200 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
201 SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE
);
202 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
203 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE
);
209 sc
->p
.scrambler
= mode
;
213 void cpld_set_crc(struct channel
*sc
, u32 crc
)
215 if (sc
->p
.crc
== crc
)
219 case SBE_2T3E3_CRC_16
:
220 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
221 SBE_2T3E3_CPLD_VAL_CRC32
);
223 case SBE_2T3E3_CRC_32
:
224 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
225 SBE_2T3E3_CPLD_VAL_CRC32
);
235 void cpld_select_panel(struct channel
*sc
, u32 panel
)
237 if (sc
->p
.panel
== panel
)
240 case SBE_2T3E3_PANEL_FRONT
:
241 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
242 SBE_2T3E3_CPLD_VAL_REAR_PANEL
);
244 case SBE_2T3E3_PANEL_REAR
:
245 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
246 SBE_2T3E3_CPLD_VAL_REAR_PANEL
);
258 extern void cpld_set_clock(struct channel
*sc
, u32 mode
)
260 if (sc
->p
.clock_source
== mode
)
264 case SBE_2T3E3_TIMING_LOCAL
:
265 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
266 SBE_2T3E3_CPLD_VAL_ALT
);
268 case SBE_2T3E3_TIMING_LOOP
:
269 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRA
,
270 SBE_2T3E3_CPLD_VAL_ALT
);
276 sc
->p
.clock_source
= mode
;
279 void cpld_set_pad_count(struct channel
*sc
, u32 count
)
283 if (sc
->p
.pad_count
== count
)
287 case SBE_2T3E3_PAD_COUNT_1
:
288 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_1
;
290 case SBE_2T3E3_PAD_COUNT_2
:
291 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_2
;
293 case SBE_2T3E3_PAD_COUNT_3
:
294 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_3
;
296 case SBE_2T3E3_PAD_COUNT_4
:
297 val
= SBE_2T3E3_CPLD_VAL_PAD_COUNT_4
;
303 cpld_clear_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
,
304 SBE_2T3E3_CPLD_VAL_PAD_COUNT
);
305 cpld_set_bit(sc
, SBE_2T3E3_CPLD_REG_PCRB
, val
);
306 sc
->p
.pad_count
= count
;
309 void cpld_LOS_update(struct channel
*sc
)
313 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PICSR
,
314 SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED
|
315 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED
|
316 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED
);
317 los
= cpld_read(sc
, SBE_2T3E3_CPLD_REG_PICSR
) &
318 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED
;
320 if (los
!= sc
->s
.LOS
)
321 dev_info(&sc
->pdev
->dev
, "SBE 2T3E3: LOS status: %s\n",
322 los
? "Loss of signal" : "Signal OK");
326 void cpld_set_fractional_mode(struct channel
*sc
, u32 mode
,
329 if (mode
== SBE_2T3E3_FRACTIONAL_MODE_NONE
) {
334 if (sc
->p
.fractional_mode
== mode
&& sc
->p
.bandwidth_start
== start
&&
335 sc
->p
.bandwidth_stop
== stop
)
339 case SBE_2T3E3_FRACTIONAL_MODE_NONE
:
340 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
341 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE
);
343 case SBE_2T3E3_FRACTIONAL_MODE_0
:
344 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
345 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0
);
347 case SBE_2T3E3_FRACTIONAL_MODE_1
:
348 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
349 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1
);
351 case SBE_2T3E3_FRACTIONAL_MODE_2
:
352 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PCRC
,
353 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2
);
356 printk(KERN_ERR
"wrong mode in set_fractional_mode\n");
360 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWF
, start
);
361 cpld_write(sc
, SBE_2T3E3_CPLD_REG_PBWL
, stop
);
363 sc
->p
.fractional_mode
= mode
;
364 sc
->p
.bandwidth_start
= start
;
365 sc
->p
.bandwidth_stop
= stop
;