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,
34 unsigned reg, u32 bit)
37 spin_lock_irqsave(&channel->card->bootrom_lock, flags);
38 bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
39 spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
42 void cpld_init(struct channel *sc)
47 val = SBE_2T3E3_CPLD_VAL_CRC32 |
48 cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot];
49 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
53 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
57 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
61 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
65 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
68 val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER;
69 cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
74 cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
79 cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
80 /* TODO: this doesn't work!!! */
82 /* SERIAL_CHIP_SELECT */
84 cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
87 val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
88 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
89 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
90 cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
97 void cpld_start_intr(struct channel *sc)
102 val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE |
103 SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE;
104 cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
107 void cpld_stop_intr(struct channel *sc)
113 cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
116 void cpld_set_frame_mode(struct channel *sc, u32 mode)
118 if (sc->p.frame_mode == mode)
122 case SBE_2T3E3_FRAME_MODE_HDLC:
123 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
124 SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE |
125 SBE_2T3E3_CPLD_VAL_RAW_MODE);
126 exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
127 exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
129 case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
130 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
131 SBE_2T3E3_CPLD_VAL_RAW_MODE);
132 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
133 SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE);
134 exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
135 exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
137 case SBE_2T3E3_FRAME_MODE_RAW:
138 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
139 SBE_2T3E3_CPLD_VAL_RAW_MODE);
140 exar7250_unipolar_onoff(sc, SBE_2T3E3_ON);
141 exar7300_unipolar_onoff(sc, SBE_2T3E3_ON);
147 sc->p.frame_mode = mode;
150 /* set rate of the local clock */
151 void cpld_set_frame_type(struct channel *sc, u32 type)
154 case SBE_2T3E3_FRAME_TYPE_E3_G751:
155 case SBE_2T3E3_FRAME_TYPE_E3_G832:
156 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
157 SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
159 case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
160 case SBE_2T3E3_FRAME_TYPE_T3_M13:
161 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
162 SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
169 void cpld_set_scrambler(struct channel *sc, u32 mode)
171 if (sc->p.scrambler == mode)
175 case SBE_2T3E3_SCRAMBLER_OFF:
176 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
177 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
179 case SBE_2T3E3_SCRAMBLER_LARSCOM:
180 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
181 SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
182 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
183 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
185 case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL:
186 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
187 SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
188 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
189 SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
195 sc->p.scrambler = mode;
199 void cpld_set_crc(struct channel *sc, u32 crc)
201 if (sc->p.crc == crc)
205 case SBE_2T3E3_CRC_16:
206 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
207 SBE_2T3E3_CPLD_VAL_CRC32);
209 case SBE_2T3E3_CRC_32:
210 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
211 SBE_2T3E3_CPLD_VAL_CRC32);
221 void cpld_select_panel(struct channel *sc, u32 panel)
223 if (sc->p.panel == panel)
226 case SBE_2T3E3_PANEL_FRONT:
227 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
228 SBE_2T3E3_CPLD_VAL_REAR_PANEL);
230 case SBE_2T3E3_PANEL_REAR:
231 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
232 SBE_2T3E3_CPLD_VAL_REAR_PANEL);
244 void cpld_set_clock(struct channel *sc, u32 mode)
246 if (sc->p.clock_source == mode)
250 case SBE_2T3E3_TIMING_LOCAL:
251 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
252 SBE_2T3E3_CPLD_VAL_ALT);
254 case SBE_2T3E3_TIMING_LOOP:
255 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
256 SBE_2T3E3_CPLD_VAL_ALT);
262 sc->p.clock_source = mode;
265 void cpld_set_pad_count(struct channel *sc, u32 count)
269 if (sc->p.pad_count == count)
273 case SBE_2T3E3_PAD_COUNT_1:
274 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1;
276 case SBE_2T3E3_PAD_COUNT_2:
277 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2;
279 case SBE_2T3E3_PAD_COUNT_3:
280 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3;
282 case SBE_2T3E3_PAD_COUNT_4:
283 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4;
289 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
290 SBE_2T3E3_CPLD_VAL_PAD_COUNT);
291 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
292 sc->p.pad_count = count;
295 void cpld_LOS_update(struct channel *sc)
299 cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
300 SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
301 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
302 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED);
303 los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) &
304 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
306 if (los != sc->s.LOS)
307 dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
308 los ? "Loss of signal" : "Signal OK");
312 void cpld_set_fractional_mode(struct channel *sc, u32 mode,
315 if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
320 if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
321 sc->p.bandwidth_stop == stop)
325 case SBE_2T3E3_FRACTIONAL_MODE_NONE:
326 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
327 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE);
329 case SBE_2T3E3_FRACTIONAL_MODE_0:
330 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
331 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0);
333 case SBE_2T3E3_FRACTIONAL_MODE_1:
334 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
335 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1);
337 case SBE_2T3E3_FRACTIONAL_MODE_2:
338 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
339 SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
342 netdev_err(sc->dev, "wrong mode in set_fractional_mode\n");
346 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
347 cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
349 sc->p.fractional_mode = mode;
350 sc->p.bandwidth_start = start;
351 sc->p.bandwidth_stop = stop;