Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  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;
 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);
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
243void 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:
341		netdev_err(sc->dev, "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}