Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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/types.h>
 14#include "2t3e3.h"
 15#include "ctrl.h"
 16
 17void t3e3_set_frame_type(struct channel *sc, u32 mode)
 18{
 19	if (sc->p.frame_type == mode)
 20		return;
 21
 22	if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
 23		dev_err(&sc->pdev->dev, "SBE 2T3E3: changing frame type during active connection\n");
 24		return;
 25	}
 26
 27	exar7300_set_frame_type(sc, mode);
 28	exar7250_set_frame_type(sc, mode);
 29	cpld_set_frame_type(sc, mode);
 30
 31	sc->p.frame_type = mode;
 32}
 33
 34void t3e3_set_loopback(struct channel *sc, u32 mode)
 35{
 36	u32 tx, rx;
 37
 38	if (sc->p.loopback == mode)
 39		return;
 40
 41	tx = sc->p.transmitter_on;
 42	rx = sc->p.receiver_on;
 43	if (tx == SBE_2T3E3_ON)
 44		dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
 45	if (rx == SBE_2T3E3_ON)
 46		dc_receiver_onoff(sc, SBE_2T3E3_OFF);
 47
 48	/* stop current loopback if any exists */
 49	switch (sc->p.loopback) {
 50	case SBE_2T3E3_LOOPBACK_NONE:
 51		break;
 52	case SBE_2T3E3_LOOPBACK_ETHERNET:
 53		dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_OFF);
 54		break;
 55	case SBE_2T3E3_LOOPBACK_FRAMER:
 56		exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF);
 57		break;
 58	case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
 59	case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
 60	case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
 61		exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
 62		break;
 63	default:
 64		return;
 65	}
 66
 67	switch (mode) {
 68	case SBE_2T3E3_LOOPBACK_NONE:
 69		break;
 70	case SBE_2T3E3_LOOPBACK_ETHERNET:
 71		dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL);
 72		break;
 73	case SBE_2T3E3_LOOPBACK_FRAMER:
 74		exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON);
 75		break;
 76	case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
 77		exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL);
 78		break;
 79	case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
 80		exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG);
 81		break;
 82	case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
 83		exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE);
 84		break;
 85	default:
 86		return;
 87	}
 88
 89	sc->p.loopback = mode;
 90
 91	if (tx == SBE_2T3E3_ON)
 92		dc_transmitter_onoff(sc, SBE_2T3E3_ON);
 93	if (rx == SBE_2T3E3_ON)
 94		dc_receiver_onoff(sc, SBE_2T3E3_ON);
 95}
 96
 97
 98void t3e3_reg_read(struct channel *sc, u32 *reg, u32 *val)
 99{
100	u32 i;
101
102	*val = 0;
103
104	switch (reg[0]) {
105	case SBE_2T3E3_CHIP_21143:
106		if (!(reg[1] & 7))
107			*val = dc_read(sc->addr, reg[1] / 8);
108		break;
109	case SBE_2T3E3_CHIP_CPLD:
110		for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
111			if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
112				*val = cpld_read(sc, i);
113				break;
114			}
115		break;
116	case SBE_2T3E3_CHIP_FRAMER:
117		for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
118			if (t3e3_framer_reg_map[i] == reg[1]) {
119				*val = exar7250_read(sc, i);
120				break;
121			}
122		break;
123	case SBE_2T3E3_CHIP_LIU:
124		for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
125			if (t3e3_liu_reg_map[i] == reg[1]) {
126				*val = exar7300_read(sc, i);
127				break;
128			}
129		break;
130	default:
131		break;
132	}
133}
134
135void t3e3_reg_write(struct channel *sc, u32 *reg)
136{
137	u32 i;
138
139	switch (reg[0]) {
140	case SBE_2T3E3_CHIP_21143:
141		dc_write(sc->addr, reg[1], reg[2]);
142		break;
143	case SBE_2T3E3_CHIP_CPLD:
144		for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
145			if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
146				cpld_write(sc, i, reg[2]);
147				break;
148			}
149		break;
150	case SBE_2T3E3_CHIP_FRAMER:
151		for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
152			if (t3e3_framer_reg_map[i] == reg[1]) {
153				exar7250_write(sc, i, reg[2]);
154				break;
155			}
156		break;
157	case SBE_2T3E3_CHIP_LIU:
158		for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
159			if (t3e3_liu_reg_map[i] == reg[1]) {
160				exar7300_write(sc, i, reg[2]);
161				break;
162			}
163		break;
164	}
165}
166
167void t3e3_port_get(struct channel *sc, t3e3_param_t *param)
168{
169	memcpy(param, &(sc->p), sizeof(t3e3_param_t));
170}
171
172void t3e3_port_set(struct channel *sc, t3e3_param_t *param)
173{
174	if (param->frame_mode != 0xff)
175		cpld_set_frame_mode(sc, param->frame_mode);
176
177	if (param->fractional_mode != 0xff)
178		cpld_set_fractional_mode(sc, param->fractional_mode,
179					 param->bandwidth_start,
180					 param->bandwidth_stop);
181
182	if (param->pad_count != 0xff)
183		cpld_set_pad_count(sc, param->pad_count);
184
185	if (param->crc != 0xff)
186		cpld_set_crc(sc, param->crc);
187
188	if (param->receiver_on != 0xff)
189		dc_receiver_onoff(sc, param->receiver_on);
190
191	if (param->transmitter_on != 0xff)
192		dc_transmitter_onoff(sc, param->transmitter_on);
193
194	if (param->frame_type != 0xff)
195		t3e3_set_frame_type(sc, param->frame_type);
196
197	if (param->panel != 0xff)
198		cpld_select_panel(sc, param->panel);
199
200	if (param->line_build_out != 0xff)
201		exar7300_line_build_out_onoff(sc, param->line_build_out);
202
203	if (param->receive_equalization != 0xff)
204		exar7300_receive_equalization_onoff(sc, param->receive_equalization);
205
206	if (param->transmit_all_ones != 0xff)
207		exar7300_transmit_all_ones_onoff(sc, param->transmit_all_ones);
208
209	if (param->loopback != 0xff)
210		t3e3_set_loopback(sc, param->loopback);
211
212	if (param->clock_source != 0xff)
213		cpld_set_clock(sc, param->clock_source);
214
215	if (param->scrambler != 0xff)
216		cpld_set_scrambler(sc, param->scrambler);
217}
218
219void t3e3_port_get_stats(struct channel *sc,
220			 t3e3_stats_t *stats)
221{
222	u32 result;
223
224	sc->s.LOC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL)
225		& SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS ? 1 : 0;
226
227	switch (sc->p.frame_type) {
228	case SBE_2T3E3_FRAME_TYPE_E3_G751:
229	case SBE_2T3E3_FRAME_TYPE_E3_G832:
230		result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
231		sc->s.LOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOF ? 1 : 0;
232		sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
233#if 0
234		sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
235#else
236		cpld_LOS_update(sc);
237#endif
238		sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_AIS ? 1 : 0;
239		sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_FERF ? 1 : 0;
240		break;
241
242	case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
243	case SBE_2T3E3_FRAME_TYPE_T3_M13:
244		result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
245		sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIS ? 1 : 0;
246#if 0
247		sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
248#else
249		cpld_LOS_update(sc);
250#endif
251		sc->s.IDLE = result & SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE ? 1 : 0;
252		sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
253
254		result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_STATUS);
255		sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FERF ? 1 : 0;
256		sc->s.AIC = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIC ? 1 : 0;
257		sc->s.FEBE_code = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE;
258
259		sc->s.FEAC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC);
260		break;
261
262	default:
263		break;
264	}
265
266	result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB) << 8;
267	result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
268	sc->s.LCV += result;
269
270	result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB) << 8;
271	result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
272	sc->s.FRAMING_BIT += result;
273
274	result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB) << 8;
275	result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
276	sc->s.PARITY_ERROR += result;
277
278	result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB) << 8;
279	result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
280	sc->s.FEBE_count += result;
281
282	result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB) << 8;
283	result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
284	sc->s.CP_BIT += result;
285
286	memcpy(stats, &(sc->s), sizeof(t3e3_stats_t));
287}
288
289void t3e3_port_del_stats(struct channel *sc)
290{
291	memset(&(sc->s), 0, sizeof(t3e3_stats_t));
292}
293
294void t3e3_if_config(struct channel *sc, u32 cmd, char *set,
295		    t3e3_resp_t *ret, int *rlen)
296{
297	t3e3_param_t *param = (t3e3_param_t *)set;
298	u32 *data = (u32 *)set;
299
300	/* turn off all interrupt */
301	/* cpld_stop_intr(sc); */
302
303	switch (cmd) {
304	case SBE_2T3E3_PORT_GET:
305		t3e3_port_get(sc, &(ret->u.param));
306		*rlen = sizeof(ret->u.param);
307		break;
308	case SBE_2T3E3_PORT_SET:
309		t3e3_port_set(sc, param);
310		*rlen = 0;
311		break;
312	case SBE_2T3E3_PORT_GET_STATS:
313		t3e3_port_get_stats(sc, &(ret->u.stats));
314		*rlen = sizeof(ret->u.stats);
315		break;
316	case SBE_2T3E3_PORT_DEL_STATS:
317		t3e3_port_del_stats(sc);
318		*rlen = 0;
319		break;
320	case SBE_2T3E3_PORT_READ_REGS:
321		t3e3_reg_read(sc, data, &(ret->u.data));
322		*rlen = sizeof(ret->u.data);
323		break;
324	case SBE_2T3E3_PORT_WRITE_REGS:
325#if 0
326		printk(KERN_DEBUG "SBE_2T3E3_PORT_WRITE_REGS, 0x%x, 0x%x, 0x%x\n",
327		       ((int*)data)[0], ((int*)data)[1], ((int*)data)[2]);
328#endif
329		t3e3_reg_write(sc, data);
330		*rlen = 0;
331		break;
332	case SBE_2T3E3_LOG_LEVEL:
333		*rlen = 0;
334		break;
335	default:
336		*rlen = 0;
337		break;
338	}
339
340	/* turn on interrupt */
341	/* cpld_start_intr(sc); */
342}
343
344void t3e3_sc_init(struct channel *sc)
345{
346	memset(sc, 0, sizeof(*sc));
347
348	sc->p.frame_mode = SBE_2T3E3_FRAME_MODE_HDLC;
349	sc->p.fractional_mode = SBE_2T3E3_FRACTIONAL_MODE_NONE;
350	sc->p.crc = SBE_2T3E3_CRC_32;
351	sc->p.receiver_on = SBE_2T3E3_OFF;
352	sc->p.transmitter_on = SBE_2T3E3_OFF;
353	sc->p.frame_type = SBE_2T3E3_FRAME_TYPE_T3_CBIT;
354	sc->p.panel = SBE_2T3E3_PANEL_FRONT;
355	sc->p.line_build_out = SBE_2T3E3_OFF;
356	sc->p.receive_equalization = SBE_2T3E3_OFF;
357	sc->p.transmit_all_ones = SBE_2T3E3_OFF;
358	sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
359	sc->p.clock_source = SBE_2T3E3_TIMING_LOCAL;
360	sc->p.scrambler = SBE_2T3E3_SCRAMBLER_OFF;
361	sc->p.pad_count = SBE_2T3E3_PAD_COUNT_1;
362}