Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 705860 | Differences between
and this patch

Collapse All | Expand All

(-)dahdi-linux-3.1.0.original/drivers/dahdi/Kbuild (+8 lines)
Lines 49-54 Link Here
49
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
49
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
50
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
50
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
51
51
52
ifdef CONFIG_PCI
53
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_AP400)		+= ap400/
54
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200)		+= opvxa1200/
55
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115)		+= opvxd115/
56
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCOPENPCI)		+= wcopenpci.o
57
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ZAPHFC)		+= zaphfc/
58
endif
59
52
obj-m += $(DAHDI_MODULES_EXTRA)
60
obj-m += $(DAHDI_MODULES_EXTRA)
53
61
54
# If you want to build OSLEC, include the code in the standard location:
62
# If you want to build OSLEC, include the code in the standard location:
(-)dahdi-linux-3.1.0.original/drivers/dahdi/Kconfig (+86 lines)
Lines 224-226 Link Here
224
224
225
225
226
source "drivers/dahdi/xpp/Kconfig"
226
source "drivers/dahdi/xpp/Kconfig"
227
228
config DAHDI_AP4XX
229
	tristate "Aligera AP4XX PCI Card Driver"
230
	depends on DAHDI && PCI
231
	default DAHDI
232
	---help---
233
	  This driver provides support for the Aligera AP400 quad-span
234
	  E1/T1 DAHDI cards:
235
236
	  To compile this driver as a module, choose M here: the
237
	  module will be called ap4xx.
238
239
	  If unsure, say Y.
240
241
config DAHDI_OPVXA1200
242
	tristate "OpenVox 8/12 ports analog card Support"
243
	depends on DAHDI && PCI
244
	default DAHDI
245
	---help---
246
	  This driver provides support for the following OpenVox
247
	  Wildcard products:
248
249
	  * A1200P (PCI)
250
	  * A1200E (PCI-E)
251
	  * A800P (PCI)
252
	  * A800E (PCI-E)
253
254
	  To compile this driver as a module, choose M here: the
255
	  module will be called opvxa1200.
256
257
	  If unsure, say Y.
258
259
config DAHDI_OPVXD115
260
	tristate "OpenVox Single-T1/E1/J1 Support"
261
	depends on DAHDI && PCI
262
	default DAHDI
263
	---help---
264
	  This driver provides support for the following OpenVox
265
	  Wildcard products:
266
267
	  * D115P/DE115P/D130P/DE130P (PCI)
268
	  * D115E/DE115E/D130E/DE130E (PCI-E)
269
270
	  To compile this driver as a module, choose M here: the
271
	  module will be called opvxd115.
272
273
	  If unsure, say Y.
274
275
276
config DAHDI_WCOPENPCI
277
	tristate "Voicetronix OpenPCI Interface DAHDI driver"
278
	depends on DAHDI && PCI
279
	default DAHDI
280
	---help---
281
	  This driver provides support for the Voicetronix OpenPCI Interface.
282
283
	  To compile this driver as a module, choose M here: the
284
	  module will be called wcopenpci.
285
286
	  If unsure, say Y.
287
288
config DAHDI_ZAPHFC
289
	tristate "HFC-S DAHDI Driver"
290
	depends on DAHDI && PCI
291
	default DAHDI
292
	---help---
293
	  This driver provides DAHDI support for various HFC-S single-port
294
          ISDN (BRI) cards.
295
296
	  To compile this driver as a module, choose M here: the
297
	  module will be called zaphfc.
298
299
	  If unsure, say Y.
300
301
config ECHO
302
	tristate "Line Echo Canceller support"
303
	default DAHDI
304
	--help--
305
	  This driver provides line echo cancelling support for mISDN and
306
	  DAHDI drivers.
307
308
	  To compile this driver as a module, choose M here: the
309
	  module will be called echo.
310
311
	  If unsure, say Y.
312
(-)dahdi-linux-3.1.0.original/drivers/dahdi/ap400/Kbuild (+26 lines)
Line 0 Link Here
1
obj-m += ap400.o
2
3
EXTRA_CFLAGS := -I$(src)/.. 
4
5
ap400-objs := ap400_drv.o
6
7
# APEC_SUPPORT
8
ECHO_FIRMWARE := $(wildcard $(src)/OCT61*.ima)
9
ifneq ($(strip $(ECHO_FIRMWARE)),)
10
	EXTRA_CFLAGS+=-DAPEC_SUPPORT $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
11
	ap400-objs += apec.o $(shell $(src)/../oct612x/octasic-helper objects ../oct612x) firmware_oct6104e-64d.o firmware_oct6104e-128d.o
12
endif
13
14
$(obj)/apec.o: $(src)/apec.h $(src)/../oct612x/include/oct6100api/oct6100_api.h
15
16
$(obj)/firmware_oct6104e-64d.o: $(src)/OCT6104E-64D.ima $(obj)/ap400_drv.o $(src)/../firmware/make_firmware_object
17
	@echo Making firmware object file for $(notdir $<)
18
	@cd $(src) && ../firmware/make_firmware_object $(notdir $<) $@ $(obj)/ap400_drv.o
19
20
$(obj)/firmware_oct6104e-128d.o: $(src)/OCT6104E-128D.ima $(obj)/ap400_drv.o $(src)/../firmware/make_firmware_object
21
	@echo Making firmware object file for $(notdir $<)
22
	@cd $(src) && ../firmware/make_firmware_object $(notdir $<) $@ $(obj)/ap400_drv.o
23
24
$(src)/../firmware/make_firmware_object:
25
	make -C $(src)/../firmware make_firmware_object
26
(-)dahdi-linux-3.1.0.original/drivers/dahdi/ap400/ap400.h (+107 lines)
Line 0 Link Here
1
/*
2
 * AP4XX  T1/E1 PCI Driver
3
 *
4
 * Written by Ronaldo Valiati <aligera@aligera.com.br>
5
 *
6
 * Based on previous works, designs, and archetectures conceived and
7
 * written by Jim Dixon <jim@lambdatel.com> and Mark Spencer <markster@digium.com>.
8
 *
9
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
10
 * Copyright (C) 2001-2005, Digium, Inc.
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#include <linux/ioctl.h>
31
32
33
#define AP4_GET_ALARMS  _IOW (DAHDI_CODE, 60, int)
34
#define AP4_GET_SLIPS	_IOW (DAHDI_CODE, 61, int)
35
36
#define AP4XX_CARD_ID		0x41434532		// "ACE2"
37
#define APE4XX_CARD_ID		0x41504534		// "APE4"
38
39
#define AP_CAS_BASE		0x0080
40
#define AP_DATA_BASE		0x0100
41
42
#define AP_CARD_TYPE_REG	0x0001
43
#define AP_T1E1_CONFIG_REG	0x0003
44
#define AP_E1_CONFIG_REG	0x0004
45
#define AP_E1_STATUS_REG	0x0005
46
#define AP_LEDS_REG		0x0006
47
#define AP_CLKSRC_REG		0x0007
48
#define AP_HWCONFIG_REG		0x0008
49
#define AP_INT_CONTROL_REG	0x0009
50
#define AP_CNT_IRQ_REG		0x000B
51
#define AP_CNT_CV_REG		0x000C
52
#define AP_CNT_CRC_REG		0x000D
53
#define AP_CLEAR_IRQ_REG	0x000E
54
#define AP_CNT_SLIP_REG		0x000F
55
56
#define AP_HWID_MASK		0x00F0
57
58
#define AP_CLKSRC_MASK		0x07
59
60
#define AP_LIU1_LINECODE	0x0080
61
#define AP_LIU2_LINECODE	0x0100
62
#define AP_LIU_RESET_BIT	0x0200
63
64
#define AP_E1_AIS_STATUS	0x01
65
#define AP_E1_BFAE_STATUS	0x02
66
#define AP_E1_MFAE_STATUS	0x04
67
#define AP_E1_SYNC_STATUS	0x08
68
#define AP_E1_CAS_STATUS	0x10
69
#define AP_E1_LOS_STATUS	0x20
70
#define AP_E1_RAI_STATUS	0x40
71
72
#define AP_E1_RAI_CONFIG	0x01
73
#define AP_E1_LOOP_CONFIG	0x10
74
#define AP_E1_CASEN_CONFIG	0x20
75
#define AP_E1_PCM30_CONFIG	0x40
76
#define AP_E1_CRCEN_CONFIG	0x80
77
78
#define AP_INT_CTL_ENABLE	0x01
79
#define AP_INT_CTL_ACTIVE	0x02
80
81
#define AP_HWID_1E1_RJ		0x01
82
#define AP_HWID_2E1_RJ		0x00
83
#define AP_HWID_4E1_RJ		0x02
84
#define AP_HWID_T1		0x04
85
86
#define AP4_T1_NE1_SEL		0x04
87
#define AP4_T1_ESF_NSF		0x02
88
#define AP4_T1_CAS_ENABLE	0x01
89
90
#define AP4_T1_FRAME_SYNC	0x01
91
92
93
typedef enum {
94
	AP_PULS_E1_75 = 0,
95
	AP_PULS_E1_120,
96
	AP_PULS_DSX1_0FT,
97
	AP_PULS_DSX1_133FT,
98
	AP_PULS_DSX1_266FT,
99
	AP_PULS_DSX1_399FT,
100
	AP_PULS_DSX1_533FT,
101
	AP_PULS_J1_110,
102
	AP_PULS_DS1_0DB,
103
	AP_PULS_DS1_M075DB,
104
	AP_PULS_DS1_M150DB,
105
	AP_PULS_DS1_M225DB
106
} liu_mode;
107
(-)dahdi-linux-3.1.0.original/drivers/dahdi/ap400/ap400_drv.c (+2343 lines)
Line 0 Link Here
1
/*
2
 * AP4XX PCI Card Driver
3
 *
4
 * Written by Ronaldo Valiati <aligera@aligera.com.br>
5
 *
6
 * Based on previous works, designs, and architectures conceived and
7
 * written by Jim Dixon <jim@lambdatel.com> and Mark Spencer <markster@digium.com>.
8
 *
9
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
10
 * Copyright (C) 2001-2005, Digium, Inc.
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#include <linux/kernel.h>
31
#include <linux/errno.h>
32
#include <linux/module.h>
33
#include <linux/pci.h>
34
#include <linux/init.h>
35
#include <linux/sched.h>
36
#include <linux/interrupt.h>
37
#include <linux/time.h>
38
#include <linux/delay.h>
39
#include <linux/proc_fs.h>
40
#include <dahdi/kernel.h>
41
#include <linux/moduleparam.h>
42
43
#include "ap400.h"
44
45
//#define AP400_DEBUG
46
#ifdef AP400_DEBUG
47
#define PDEBUG(fmt, args...) { \
48
	printk(KERN_DEBUG "AP400 (%d): ",__LINE__); \
49
	printk(fmt "\n", ## args); \
50
}
51
#else
52
#define PDEBUG(fmt, args...)
53
#endif
54
55
/*
56
 * Tasklets provide better system interactive response at the cost of the
57
 * possibility of losing a frame of data at very infrequent intervals.  If
58
 * you are more concerned with the performance of your machine, enable the
59
 * tasklets.  If you are strict about absolutely no drops, then do not enable
60
 * tasklets.
61
 */
62
63
/* #define ENABLE_TASKLETS */
64
65
66
/* Work queues are a way to better distribute load on SMP systems */
67
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
68
/*
69
 * Work queues can significantly improve performance and scalability
70
 * on multi-processor machines, but requires bypassing some kernel
71
 * API's, so it's not guaranteed to be compatible with all kernels.
72
 */
73
/* #define ENABLE_WORKQUEUES */
74
#endif
75
76
/* Enable HDLC support by hardware */
77
#ifdef AP400_HDLC
78
#include "ap400_hdlc/ap400_hdlc.c"
79
#endif
80
81
//#define APEC_SUPPORT
82
#ifdef APEC_SUPPORT
83
#include "apec.h"
84
#endif
85
86
/* Workarounds */
87
#ifndef IRQF_SHARED
88
#define IRQF_SHARED		SA_SHIRQ
89
#endif
90
91
#ifndef IRQF_DISABLED
92
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
93
#define IRQF_DISABLED		SA_INTERRUPT
94
#else
95
/* Support for disabling interrupts was completely removed from the Kernel */
96
#define IRQF_DISABLED		0x0
97
#endif
98
#endif
99
#ifndef __iomem
100
#define __iomem
101
#endif
102
103
/* Enable prefetching may help performance */
104
#define ENABLE_PREFETCH
105
106
/* Define to get more attention-grabbing but slightly more I/O using
107
   alarm status */
108
#define FANCY_ALARM
109
110
#define DEBUG_MAIN 		(1 << 0)
111
#define DEBUG_DTMF 		(1 << 1)
112
#define DEBUG_REGS 		(1 << 2)
113
#define DEBUG_TSI  		(1 << 3)
114
#define DEBUG_ECHOCAN 		(1 << 4)
115
#define DEBUG_RBS 		(1 << 5)
116
#define DEBUG_FRAMER		(1 << 6)
117
118
static int clock_source = -1;
119
static int tdm_loop = 0;
120
static int apec_enable = 1;
121
module_param(tdm_loop, int, 0600);
122
module_param(apec_enable, int, 0600);
123
124
#ifdef ENABLE_WORKQUEUES
125
#include <linux/cpumask.h>
126
127
/* XXX UGLY!!!! XXX  We have to access the direct structures of the workqueue which
128
  are only defined within workqueue.c because they don't give us a routine to allow us
129
  to nail a work to a particular thread of the CPU.  Nailing to threads gives us substantially
130
  higher scalability in multi-CPU environments though! */
131
132
/*
133
 * The per-CPU workqueue (if single thread, we always use cpu 0's).
134
 *
135
 * The sequence counters are for flush_scheduled_work().  It wants to wait
136
 * until until all currently-scheduled works are completed, but it doesn't
137
 * want to be livelocked by new, incoming ones.  So it waits until
138
 * remove_sequence is >= the insert_sequence which pertained when
139
 * flush_scheduled_work() was called.
140
 */
141
142
struct cpu_workqueue_struct {
143
144
	spinlock_t lock;
145
146
	long remove_sequence;	/* Least-recently added (next to run) */
147
	long insert_sequence;	/* Next to add */
148
149
	struct list_head worklist;
150
	wait_queue_head_t more_work;
151
	wait_queue_head_t work_done;
152
153
	struct workqueue_struct *wq;
154
	task_t *thread;
155
156
	int run_depth;		/* Detect run_workqueue() recursion depth */
157
} ____cacheline_aligned;
158
159
/*
160
 * The externally visible workqueue abstraction is an array of
161
 * per-CPU workqueues:
162
 */
163
struct workqueue_struct {
164
	struct cpu_workqueue_struct cpu_wq[NR_CPUS];
165
	const char *name;
166
	struct list_head list; 	/* Empty if single thread */
167
};
168
169
/* Preempt must be disabled. */
170
static void __ap4_queue_work(struct cpu_workqueue_struct *cwq,
171
			 struct work_struct *work)
172
{
173
	unsigned long flags;
174
175
	spin_lock_irqsave(&cwq->lock, flags);
176
	work->wq_data = cwq;
177
	list_add_tail(&work->entry, &cwq->worklist);
178
	cwq->insert_sequence++;
179
	wake_up(&cwq->more_work);
180
	spin_unlock_irqrestore(&cwq->lock, flags);
181
}
182
183
/*
184
 * Queue work on a workqueue. Return non-zero if it was successfully
185
 * added.
186
 *
187
 * We queue the work to the CPU it was submitted, but there is no
188
 * guarantee that it will be processed by that CPU.
189
 */
190
static inline int ap4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu)
191
{
192
	int ret = 0;
193
194
	if (!test_and_set_bit(0, &work->pending)) {
195
		BUG_ON(!list_empty(&work->entry));
196
		__ap4_queue_work(wq->cpu_wq + cpu, work);
197
		ret = 1;
198
	}
199
	return ret;
200
}
201
202
#endif
203
204
static int debug=0;
205
static int timingcable;
206
static int highestorder;
207
static int t1e1override = -1;
208
static int j1mode = 0;
209
static int loopback = 0;
210
static int alarmdebounce = 0;
211
212
/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
213
   can also cause PCI bus starvation, especially in combination with other
214
   aggressive cards.  Please note that burst mode has no effect on CPU
215
   utilization / max number of calls / etc. */
216
static int noburst = 1;
217
static int debugslips = 0;
218
static int polling = 0;
219
220
#ifdef FANCY_ALARM
221
static int altab[] = {
222
0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0,
223
};
224
#endif
225
226
#define FLAG_STARTED (1 << 0)
227
#define FLAG_NMF (1 << 1)
228
#define FLAG_SENDINGYELLOW (1 << 2)
229
230
#define	TYPE_T1	1		/* is a T1 card */
231
#define	TYPE_E1	2		/* is an E1 card */
232
#define TYPE_J1 3		/* is a running J1 */
233
234
struct devtype {
235
	char *desc;
236
	unsigned int flags;
237
};
238
239
static struct devtype ap401  = { "Aligera AP401", 0 };
240
static struct devtype ap402  = { "Aligera AP402", 0 };
241
static struct devtype ap404  = { "Aligera AP404", 0 };
242
static struct devtype ape401  = { "Aligera APE401", 0 };
243
static struct devtype ape402  = { "Aligera APE402", 0 };
244
static struct devtype ape404  = { "Aligera APE404", 0 };
245
246
struct ap4;
247
248
struct ap4_span {
249
	struct ap4 *owner;
250
	unsigned int *writechunk;					/* Double-word aligned write memory */
251
	unsigned int *readchunk;					/* Double-word aligned read memory */
252
	int spantype;		/* card type, T1 or E1 or J1 */
253
	int sync;
254
	int psync;
255
	int alarmtimer;
256
	int redalarms;
257
	int notclear;
258
	int alarmcount;
259
	int spanflags;
260
	int syncpos;
261
	int e1check;			/* E1 check */
262
	int reload_cas;
263
	unsigned char casbuf[15];
264
	unsigned int slipcount;
265
	struct dahdi_span span;
266
	unsigned char txsigs[16];	/* Transmit sigs */
267
	int loopupcnt;
268
	int loopdowncnt;
269
	unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
270
	unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
271
	int irqmisses;
272
#ifdef ENABLE_WORKQUEUES
273
	struct work_struct swork;
274
#endif
275
	struct dahdi_chan *chans[32];		/* Individual channels */
276
};
277
278
struct ap4_regs {
279
	volatile u32 card_id;		// 00h R0
280
	volatile u16 fpga_ver;		// 04h R1
281
	volatile u16 span_num;		// 06h R1
282
	u32 __unused;			// 08h R2
283
	volatile u32 liu_config;	// 0Ch R3
284
	volatile u32 e1_config;		// 10h R4
285
	volatile u32 e1_status;		// 14h R5
286
	volatile u32 leds;		// 18h R6
287
	volatile u32 clock_source;	// 1Ch R7
288
	u32 __unused3[8];		// 20h - 3Ch R8 - R15
289
	volatile u32 echo_ctrl;		// 40h R16
290
	volatile u32 echo_data;		// 44h R17
291
	volatile u32 t1_status;		// 48h R18
292
	volatile u32 t1_config;		// 4Ch R19
293
};
294
295
struct ap4 {
296
	/* This structure exists one per card */
297
	struct pci_dev *dev;		/* Pointer to PCI device */
298
	struct dahdi_device *ddev;
299
	struct ap4_regs *hw_regs;
300
	unsigned int intcount;
301
	int flag_1st_irq;
302
	int num;			/* Which card we are */
303
	int fpgaver;		/* version of FPGA */
304
	int hwid;			/* hardware ID */
305
	int globalconfig;	/* Whether global setup has been done */
306
	int syncsrc;			/* active sync source */
307
	struct ap4_span *tspans[4];	/* Individual spans */
308
	int numspans;			/* Number of spans on the card */
309
	int blinktimer[4];
310
#ifdef FANCY_ALARM
311
	int alarmpos[4];
312
#endif
313
	int irq;			/* IRQ used by device */
314
	int order;			/* Order */
315
	int flags;			/* Device flags */
316
	int ledreg;				/* LED Register */
317
	int e1recover;			/* E1 recovery timer */
318
	unsigned long memaddr;		/* Base address of card */
319
	unsigned long memlen;
320
	volatile unsigned int *membase;	/* Base address of card */
321
	int spansstarted;		/* number of spans started */
322
	/* spinlock_t lock; */		/* lock context */
323
	spinlock_t reglock;		/* lock register access */
324
	volatile unsigned int *writechunk;	/* Double-word aligned write memory */
325
	volatile unsigned int *readchunk;	/* Double-word aligned read memory */
326
#ifdef ENABLE_WORKQUEUES
327
	atomic_t worklist;
328
	struct workqueue_struct *workq;
329
#else
330
#ifdef ENABLE_TASKLETS
331
	int taskletrun;
332
	int taskletsched;
333
	int taskletpending;
334
	int taskletexec;
335
	int txerrors;
336
	struct tasklet_struct ap4_tlet;
337
#endif
338
#endif
339
	unsigned int passno;	/* number of interrupt passes */
340
	struct devtype *dt;
341
	char *variety;
342
	int last0;		/* for detecting double-missed IRQ */
343
	int checktiming;	/* Set >0 to cause the timing source to be checked */
344
#ifdef AP400_HDLC
345
	struct card_s *hdlc_card;
346
#endif
347
#ifdef APEC_SUPPORT
348
	int apec_enable;
349
	struct apec_s *apec;
350
#endif
351
};
352
353
354
static void __set_clear(struct ap4 *wc, int span);
355
static int ap4_startup(struct file *file, struct dahdi_span *span);
356
static int ap4_shutdown(struct dahdi_span *span);
357
static int ap4_rbsbits(struct dahdi_chan *chan, int bits);
358
static int ap4_maint(struct dahdi_span *span, int cmd);
359
static int ap4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
360
static void __ap4_set_timing_source(struct ap4 *wc, int unit);
361
static void __ap4_check_alarms(struct ap4 *wc, int span);
362
static void __ap4_check_sigbits(struct ap4 *wc, int span);
363
364
365
#define AP_ACTIVATE	(1 << 12)
366
367
#define AP_OFF	(0)
368
#define AP_ON	(1)
369
370
#define MAX_AP4_CARDS 64
371
372
#ifdef ENABLE_TASKLETS
373
static void ap4_tasklet(unsigned long data);
374
#endif
375
376
static struct ap4 *cards[MAX_AP4_CARDS];
377
378
//#define ap_debugk(fmt,args...) printk("ap400 -> %s: "fmt, __PRETTY_FUNCTION__, ##args)
379
#define ap_debugk(fmt,args...)
380
381
//#define TIMER_DEBUG	1
382
383
#ifdef TIMER_DEBUG
384
struct timer_list ap4xx_opt_timer;
385
unsigned int delay = 1000;
386
module_param(delay, uint, S_IRUGO);
387
#endif
388
389
#define PCI_DEVICE_ID_AP4XX		0x1004
390
391
static inline void __ap4_set_led(struct ap4 *wc, int span, int color)
392
{
393
	wc->ledreg &= ~(AP_ON << span);
394
	wc->ledreg |= (color << span);
395
	*(wc->membase+AP_LEDS_REG) &= ~0x0000000F;
396
	*(wc->membase+AP_LEDS_REG) |= ((wc->ledreg)&0x0F);
397
}
398
399
static inline void ap4_activate(struct ap4 *wc)
400
{
401
	wc->ledreg |= AP_ACTIVATE;
402
}
403
404
static void __set_clear(struct ap4 *wc, int span)
405
{
406
	int i,j;
407
	int oldnotclear;
408
	unsigned short val=0;
409
	struct ap4_span *ts = wc->tspans[span];
410
411
	oldnotclear = ts->notclear;
412
	if (ts->spantype == TYPE_T1) {
413
		for (i=0;i<24;i++) {
414
			j = (i/8);
415
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
416
				val |= 1 << (7 - (i % 8));
417
				ts->notclear &= ~(1 << i);
418
			} else
419
				ts->notclear |= (1 << i);
420
			if ((i % 8)==7) {
421
				val = 0;
422
			}
423
		}
424
	} else {
425
		for (i=0;i<31;i++) {
426
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
427
				ts->notclear &= ~(1 << i);
428
			else
429
				ts->notclear |= (1 << i);
430
		}
431
	}
432
}
433
434
#ifdef APEC_SUPPORT
435
436
#define APEC_CTRL_RESET		0x80000000
437
#define APEC_CTRL_DDR_NCKE	0x40000000
438
#define APEC_CTRL_EC_DISABLE	0x20000000
439
#define APEC_CTRL_DAS		0x00080000
440
#define APEC_CTRL_RD		0x00040000
441
#define APEC_CTRL_REQ		0x00020000
442
#define APEC_CTRL_READY		0x00010000
443
444
#define APEC_ACCESS_TIMEOUT	1000
445
446
static inline u16 oct_raw_read (struct ap4_regs *regs, unsigned short addr)
447
{
448
	unsigned short data;
449
	// Poll ready bit
450
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
451
	// Write control bits and address
452
	regs->echo_ctrl = APEC_CTRL_RD | APEC_CTRL_REQ | (addr & 0xFFFF);
453
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
454
	data = regs->echo_data & 0xFFFF;
455
	//PDEBUG("Raw Read 0x%04hX @ 0x%08X", data, addr);
456
	return data;
457
}
458
459
static inline void oct_raw_write (struct ap4_regs *regs, unsigned short addr,
460
							unsigned short data)
461
{
462
	// Poll ready bit
463
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
464
	// Write data, then control bits and address
465
	regs->echo_data = data & 0xFFFF;
466
	regs->echo_ctrl = APEC_CTRL_REQ | (addr & 0xFFFF);
467
	// Poll ready bit
468
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
469
	//PDEBUG("Raw Write 0x%04hX @ 0x%08X", data, addr);
470
	//oct_raw_read(regs, addr);
471
}
472
473
static inline int oct_ext_wait (struct ap4_regs *regs)
474
{
475
	int i = APEC_ACCESS_TIMEOUT;
476
	while ((oct_raw_read(regs, 0x0) & 0x100) && (i-- > 0));
477
	if (i == -1) {
478
		printk(KERN_WARNING "Wait access_req timeout\n");
479
		return -1;
480
	}
481
	return 0;
482
}
483
484
static inline u16 oct_ind_read (struct ap4_regs *regs, unsigned int addr)
485
{
486
	// Poll access_req bit
487
	if (oct_ext_wait(regs))
488
		return 0;
489
	// Write extended indirect registers
490
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
491
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
492
	oct_raw_write(regs, 0x0, ((addr & 0xE) << 8) | 0x101);
493
	// Poll access_req bit
494
	if (oct_ext_wait(regs))
495
		return 0;
496
	// Return data
497
	return oct_raw_read(regs, 0x4);
498
}
499
500
static inline void oct_ind_write (struct ap4_regs *regs, unsigned int addr,
501
							unsigned short data)
502
{
503
	// Poll access_req bit
504
	if (oct_ext_wait(regs))
505
		return;
506
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
507
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
508
	oct_raw_write(regs, 0x4, data);
509
	oct_raw_write(regs, 0x0, ((addr & 0xE) << 8) | 0x3101);
510
	// Poll access_req bit
511
	if (oct_ext_wait(regs))
512
		return;
513
}
514
515
static inline u16 oct_dir_read (struct ap4_regs *regs, unsigned int addr)
516
{
517
	// Poll access_req bit
518
	if (oct_ext_wait(regs))
519
		return 0;
520
	// Write extended direct registers
521
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
522
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
523
	oct_raw_write(regs, 0x0, 0x1);
524
	regs->echo_ctrl = APEC_CTRL_DAS | APEC_CTRL_RD | APEC_CTRL_REQ | (addr & 0xFFFF);
525
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
526
	// Return data
527
	return regs->echo_data;
528
}
529
530
static inline void oct_dir_write (struct ap4_regs *regs, unsigned int addr,
531
							unsigned short data)
532
{
533
	// Poll access_req bit
534
	if (oct_ext_wait(regs))
535
		return;
536
	// Write extended direct registers
537
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
538
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
539
	oct_raw_write(regs, 0x0, 0x3001);
540
	regs->echo_data = data & 0xFFFF;
541
	regs->echo_ctrl = APEC_CTRL_DAS | APEC_CTRL_REQ | (addr & 0xFFFF);
542
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
543
}
544
545
546
unsigned int oct_read (void *card, unsigned int addr)
547
{
548
	struct ap4 *wc = card;
549
	int flags;
550
	unsigned short data;
551
	spin_lock_irqsave(&wc->reglock, flags);
552
	data = oct_ind_read(wc->hw_regs, addr);
553
	spin_unlock_irqrestore(&wc->reglock, flags);
554
	PDEBUG("Read 0x%04hX @ 0x%08X", data, addr);
555
	return data;
556
}
557
558
void oct_write (void *card, unsigned int addr, unsigned int data)
559
{
560
	struct ap4 *wc = card;
561
	int flags;
562
	spin_lock_irqsave(&wc->reglock, flags);
563
	oct_ind_write(wc->hw_regs, addr, data);
564
	spin_unlock_irqrestore(&wc->reglock, flags);
565
	PDEBUG("Write 0x%04hX @ 0x%08X", data, addr);
566
}
567
568
static int ap4_apec_init(struct ap4 *wc)
569
{
570
	int laws[4];
571
	int i;
572
	unsigned int apec_capacity;
573
	struct firmware embedded_firmware;
574
	const struct firmware *firmware = &embedded_firmware;
575
#if !defined(HOTPLUG_FIRMWARE)
576
	extern void _binary_OCT6104E_64D_ima_size;
577
	extern u8 _binary_OCT6104E_64D_ima_start[];
578
	extern void _binary_OCT6104E_128D_ima_size;
579
	extern u8 _binary_OCT6104E_128D_ima_start[];
580
#else
581
	static const char oct64_firmware[] = "OCT6104E-64D.ima";
582
	static const char oct128_firmware[] = "OCT6104E-128D.ima";
583
#endif
584
585
	// Enable DDR and Reset Octasic
586
	wc->hw_regs->echo_ctrl |= APEC_CTRL_RESET;
587
	wc->hw_regs->echo_ctrl |= APEC_CTRL_DDR_NCKE;
588
	udelay(500);
589
	wc->hw_regs->echo_ctrl &= APEC_CTRL_RESET;
590
	wc->hw_regs->echo_ctrl &= APEC_CTRL_DDR_NCKE;
591
	wc->hw_regs->echo_ctrl &= APEC_CTRL_EC_DISABLE;
592
593
	/* Setup alaw vs ulaw rules */
594
	for (i = 0; i < wc->numspans; i++) {
595
		if (wc->tspans[i]->span.channels > 24)
596
			laws[i] = 1;	// E1: alaw
597
		else
598
			laws[i] = 0;	// T1: ulaw
599
	}
600
601
	switch ((apec_capacity = apec_capacity_get(wc))) {
602
	case 64:
603
#if defined(HOTPLUG_FIRMWARE)
604
		if ((request_firmware(&firmware, oct64_firmware, &wc->dev->dev) != 0) ||
605
		    !firmware) {
606
			printk("%s: firmware %s not available from userspace\n",
607
					wc->variety, oct64_firmware);
608
			return -1;
609
		}
610
#else
611
		embedded_firmware.data = _binary_OCT6104E_64D_ima_start;
612
		/* Yes... this is weird. objcopy gives us a symbol containing
613
		   the size of the firmware, not a pointer to a variable containing
614
		   the size. The only way we can get the value of the symbol
615
		   is to take its address, so we define it as a pointer and
616
		   then cast that value to the proper type.
617
		*/
618
		embedded_firmware.size = (size_t) &_binary_OCT6104E_64D_ima_size;
619
#endif
620
		break;
621
	case 128:
622
#if defined(HOTPLUG_FIRMWARE)
623
		if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
624
		    !firmware) {
625
			printk("%s: firmware %s not available from userspace\n",
626
					wc->variety, oct128_firmware);
627
			return -1;
628
		}
629
#else
630
		embedded_firmware.data = _binary_OCT6104E_128D_ima_start;
631
		/* Yes... this is weird. objcopy gives us a symbol containing
632
		   the size of the firmware, not a pointer to a variable containing
633
		   the size. The only way we can get the value of the symbol
634
		   is to take its address, so we define it as a pointer and
635
		   then cast that value to the proper type.
636
		*/
637
		embedded_firmware.size = (size_t) &_binary_OCT6104E_128D_ima_size;
638
#endif
639
		break;
640
	default:
641
		printk(KERN_INFO "Unsupported channel capacity found on"
642
				"echo cancellation module (%d).\n", apec_capacity);
643
		return -1;
644
	}
645
646
	if (!(wc->apec = apec_init(wc, laws, wc->numspans, firmware))) {
647
		printk(KERN_WARNING "APEC: Failed to initialize\n");
648
		if (firmware != &embedded_firmware)
649
			release_firmware(firmware);
650
		return -1;
651
	}
652
653
	if (firmware != &embedded_firmware)
654
		release_firmware(firmware);
655
656
	printk(KERN_INFO "APEC: Present and operational servicing %d span(s)\n", wc->numspans);
657
	return 0;
658
}
659
660
void ap4_apec_release(struct ap4 *wc)
661
{
662
	// Disabel DDR and reset Octasic
663
	wc->hw_regs->echo_ctrl |= APEC_CTRL_RESET;
664
	wc->hw_regs->echo_ctrl |= APEC_CTRL_DDR_NCKE;
665
	wc->hw_regs->echo_ctrl |= APEC_CTRL_EC_DISABLE;
666
	if (wc->apec)
667
		apec_release(wc->apec);
668
}
669
670
671
static int ap4_echocan(struct dahdi_chan *chan, int eclen)
672
{
673
	struct ap4 *wc = chan->pvt;
674
	int channel;
675
676
	if (!wc->apec)
677
		return -ENODEV;
678
	if (debug)
679
		printk(KERN_DEBUG "AP400: ap4_echocan @ Span %d Channel %d Length: %d\n",
680
				chan->span->offset, chan->chanpos, eclen);
681
	channel = (chan->chanpos << 2) | chan->span->offset;
682
	apec_setec(wc->apec, channel, eclen);
683
	return 0;
684
}
685
686
#endif // APEC_SUPPORT
687
688
689
static int ap4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
690
{
691
	struct ap4 *wc = chan->pvt;
692
	int span = 0;
693
	int alarms = 0;
694
	unsigned char c, e1_cfg;
695
696
	switch(cmd) {
697
		case AP4_GET_ALARMS:
698
			if (copy_from_user(&span, (int *)data, sizeof(int)))
699
				return -EFAULT;
700
			// span starts in zero
701
			span--;
702
		if (wc->tspans[span]->spantype == TYPE_E1) {
703
		        /* le status e configuracao do E1 */
704
		        c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
705
		        e1_cfg = ((*(wc->membase+AP_E1_CONFIG_REG))>>(8*span));
706
			if( c & AP_E1_LOS_STATUS) {
707
				alarms = 0x01;
708
			} else if( c & AP_E1_AIS_STATUS) {
709
				alarms = 0x02;
710
			} else if(!(c & AP_E1_BFAE_STATUS)) {
711
				alarms = 0x04;
712
				if (c & AP_E1_RAI_STATUS)
713
					alarms |= 0x08;
714
				// Erro de MFA: 00 - MFA desabilitado, 01 - erro de MFA, 10 - MFA OK
715
				if ( (c & AP_E1_MFAE_STATUS) && (e1_cfg & AP_E1_CRCEN_CONFIG) )
716
					alarms |= 0x10;
717
				else if ( (!(c & AP_E1_MFAE_STATUS)) && (e1_cfg & AP_E1_CRCEN_CONFIG) )
718
					alarms |= 0x20;
719
				// Erro de CAS: 00 - desabilitado, 01 - erro de CAS, 10 - CAS OK
720
				if ( (!(c & AP_E1_CAS_STATUS)) && (e1_cfg & AP_E1_PCM30_CONFIG))
721
					alarms |= 0x40;
722
				else if ( (c & AP_E1_CAS_STATUS) && (e1_cfg & AP_E1_PCM30_CONFIG))
723
					alarms |= 0x80;
724
			}
725
		} else {
726
			/* le status e configuracao do E1 */
727
		        c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
728
		        if( c & AP_E1_LOS_STATUS)
729
				alarms = 0x01;
730
			else {
731
			        c = wc->hw_regs->t1_status >> (8*span);
732
			        if (!(c & AP4_T1_FRAME_SYNC))
733
			        	alarms = 0x04;
734
		        }
735
		}
736
			if(debug) printk("AP4_GET_ALARMS: span = %d, alarms = 0x%02x\n", span+1, alarms);
737
			if (copy_to_user((int *)data, &alarms, sizeof(int)))
738
				return -EFAULT;
739
			break;
740
741
		case AP4_GET_SLIPS:
742
			if (copy_from_user(&span, (int *)data, sizeof(int)))
743
				return -EFAULT;
744
			// span starts in zero
745
			span--;
746
			if((span < wc->numspans) && (span >=0))
747
				alarms = wc->tspans[span]->slipcount;
748
			if(debug) printk("AP4_GET_SLIPS: span = %d, slips = 0x%02x\n", span+1, alarms);
749
			if (copy_to_user((int *)data, &alarms, sizeof(int)))
750
				return -EFAULT;
751
			break;
752
753
		default:
754
			PDEBUG("%s: Unknown IOCTL CODE!", wc->variety);
755
			return -ENOTTY;
756
	}
757
	return 0;
758
}
759
760
static inline struct ap4_span* ap4_span_from_span(struct dahdi_span *span) {
761
	return container_of(span, struct ap4_span, span);
762
}
763
764
static int ap4_maint(struct dahdi_span *span, int cmd)
765
{
766
	struct ap4_span *ts = ap4_span_from_span(span);
767
	struct ap4 *wc = ts->owner;
768
769
770
	if (ts->spantype == TYPE_E1) {
771
		switch(cmd) {
772
		case DAHDI_MAINT_NONE:
773
			printk("XXX Turn off local and remote loops E1 XXX\n");
774
			*(wc->membase+AP_E1_CONFIG_REG) &= ~(AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
775
			break;
776
		case DAHDI_MAINT_LOCALLOOP:
777
			printk("XXX Turn on local loopback E1 XXX\n");
778
			break;
779
		case DAHDI_MAINT_REMOTELOOP:
780
			printk("XXX Turn on remote loopback E1 XXX\n");
781
			break;
782
		case DAHDI_MAINT_LOOPUP:
783
			printk("XXX Turn on local loopback on E1 #%d instead of send loopup code XXX\n", span->spanno);
784
			*(wc->membase+AP_E1_CONFIG_REG) |= (AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
785
			break;
786
		case DAHDI_MAINT_LOOPDOWN:
787
			printk("XXX Turn on local loopback on E1 #%d instead of send loopdown code XXX\n", span->spanno);
788
			*(wc->membase+AP_E1_CONFIG_REG) |= (AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
789
			break;
790
		default:
791
			printk("%s: Unknown E1 maint command: %d\n", wc->variety, cmd);
792
			break;
793
		}
794
	} else {
795
		switch(cmd) {
796
	    case DAHDI_MAINT_NONE:
797
			printk("XXX Turn off local and remote loops T1 XXX\n");
798
			break;
799
	    case DAHDI_MAINT_LOCALLOOP:
800
			printk("XXX Turn on local loop and no remote loop XXX\n");
801
			break;
802
	    case DAHDI_MAINT_REMOTELOOP:
803
			printk("XXX Turn on remote loopup XXX\n");
804
			break;
805
	    case DAHDI_MAINT_LOOPUP:
806
			break;
807
	    case DAHDI_MAINT_LOOPDOWN:
808
			break;
809
	    default:
810
			printk("%s: Unknown T1 maint command: %d\n", wc->variety, cmd);
811
			break;
812
	   }
813
    }
814
	return 0;
815
}
816
817
static int ap4_rbsbits(struct dahdi_chan *chan, int bits)
818
{
819
	u_char m,c;
820
	int k,n,b;
821
	struct ap4 *wc = chan->pvt;
822
	struct ap4_span *ts = wc->tspans[chan->span->offset];
823
	unsigned long flags;
824
	volatile unsigned int *writecas = (wc->membase+AP_CAS_BASE);
825
	unsigned int allspansbits;
826
827
	//ap_debugk("chan->channo = %d, int bits = 0x%08x\n", chan->channo, bits);
828
	if(debug & DEBUG_RBS) printk("Setting bits to %d on channel %s\n", bits, chan->name);
829
	spin_lock_irqsave(&wc->reglock, flags);
830
	k = chan->span->offset;
831
	if (ts->spantype == TYPE_E1) { /* do it E1 way */
832
		if (chan->chanpos == 16) {
833
			spin_unlock_irqrestore(&wc->reglock, flags);
834
			return 0;
835
		}
836
		n = chan->chanpos - 1;
837
		if (chan->chanpos > 15) n--;
838
		b = (n % 15);
839
		c = ts->txsigs[b];
840
		m = (n / 15) << 2; /* nibble selector */
841
		c &= (0xf << m); /* keep the other nibble */
842
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
843
		ts->txsigs[b] = c;
844
		/* monta a word de 32 bits com informacao de todos os spans */
845
		allspansbits =  wc->tspans[0]->txsigs[b];
846
		if (wc->numspans > 1) {
847
			allspansbits |=	(wc->tspans[1]->txsigs[b] << 8);
848
		}
849
		if (wc->numspans == 4) {
850
			allspansbits |=	(wc->tspans[2]->txsigs[b] << 16) |
851
							(wc->tspans[3]->txsigs[b] << 24);
852
		}
853
		/* output them to the chip */
854
		writecas[b] = allspansbits;
855
		ap_debugk("escrito 0x%08x para ser transmitido pelo CAS (b = %d)\n", allspansbits, b);
856
#if 0
857
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
858
		n = chan->chanpos - 1;
859
		b = (n/4);
860
		c = ts->txsigs[b];
861
		m = ((3 - (n % 4)) << 1); /* nibble selector */
862
		c &= ~(0x3 << m); /* keep the other nibble */
863
		c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
864
		ts->txsigs[b] = c;
865
		  /* output them to the chip */
866
		//__ap4_out( ... );
867
	} else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
868
#endif
869
	} else {
870
		n = chan->chanpos - 1;
871
		b = (n/2);
872
		c = ts->txsigs[b];
873
		m = ((n % 2) << 2); /* nibble selector */
874
		c &= (0xf << m); /* keep the other nibble */
875
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
876
		ts->txsigs[b] = c;
877
		  /* output them to the chip */
878
		/* monta a word de 32 bits com informacao de todos os spans */
879
		allspansbits =  wc->tspans[0]->txsigs[b];
880
		if (wc->numspans > 1) {
881
			allspansbits |=	(wc->tspans[1]->txsigs[b] << 8);
882
		}
883
		if (wc->numspans == 4) {
884
			allspansbits |=	(wc->tspans[2]->txsigs[b] << 16) |
885
							(wc->tspans[3]->txsigs[b] << 24);
886
		}
887
		/* output them to the chip */
888
		writecas[b] = allspansbits;
889
		ap_debugk("escrito 0x%08x para ser transmitido pelo CAS (b = %d)\n", allspansbits, b);
890
	}
891
	spin_unlock_irqrestore(&wc->reglock, flags);
892
	if (debug & DEBUG_RBS)
893
		printk("Finished setting RBS bits\n");
894
	return 0;
895
}
896
897
static int ap4_shutdown(struct dahdi_span *span)
898
{
899
	int tspan;
900
	int wasrunning;
901
	unsigned long flags;
902
	struct ap4_span *ts = ap4_span_from_span(span);
903
	struct ap4 *wc = ts->owner;
904
905
	tspan = span->offset + 1;
906
	if (tspan < 0) {
907
		printk("%s: '%d' isn't us?\n", wc->variety, span->spanno);
908
		return -1;
909
	}
910
911
	spin_lock_irqsave(&wc->reglock, flags);
912
	wasrunning = span->flags & DAHDI_FLAG_RUNNING;
913
914
	span->flags &= ~DAHDI_FLAG_RUNNING;
915
	if (wasrunning)
916
		wc->spansstarted--;
917
	__ap4_set_led(wc, span->offset, AP_OFF);
918
	if (((wc->numspans == 4) &&
919
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)) &&
920
	    (!(wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)) &&
921
	    (!(wc->tspans[2]->span.flags & DAHDI_FLAG_RUNNING)) &&
922
	    (!(wc->tspans[3]->span.flags & DAHDI_FLAG_RUNNING)))
923
	    			||
924
	    ((wc->numspans == 2) &&
925
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)) &&
926
	    (!(wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)))
927
	    			||
928
	    ((wc->numspans == 1) &&
929
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)))) {
930
		/* No longer in use, disable interrupts */
931
		printk("%s: Disabling interrupts since there are no active spans\n",
932
				wc->variety);
933
	} else wc->checktiming = 1;
934
	spin_unlock_irqrestore(&wc->reglock, flags);
935
	if (debug & DEBUG_MAIN)
936
		printk("Span %d (%s) shutdown\n", span->spanno, span->name);
937
	return 0;
938
}
939
940
static int ap4_spanconfig(struct file *file, struct dahdi_span *span,
941
		struct dahdi_lineconfig *lc)
942
{
943
	int i;
944
	struct ap4_span *ts = ap4_span_from_span(span);
945
	struct ap4 *wc = ts->owner;
946
	unsigned int val;
947
948
	printk("About to enter spanconfig!\n");
949
	if (debug & DEBUG_MAIN)
950
		printk("%s: Configuring span %d\n", wc->variety, span->spanno);
951
	/* XXX We assume lineconfig is okay and shouldn't XXX */
952
	span->lineconfig = lc->lineconfig;
953
	span->txlevel = lc->lbo;
954
	span->rxlevel = 0;
955
	if (lc->sync < 0)
956
		lc->sync = 0;
957
	if (lc->sync > 4)
958
		lc->sync = 0;
959
960
	/* remove this span number from the current sync sources, if there */
961
	for(i = 0; i < wc->numspans; i++) {
962
		if (wc->tspans[i]->sync == span->spanno) {
963
			wc->tspans[i]->sync = 0;
964
			wc->tspans[i]->psync = 0;
965
		}
966
	}
967
	wc->tspans[span->offset]->syncpos = lc->sync;
968
	/* if a sync src, put it in proper place */
969
	if (lc->sync) {
970
		wc->tspans[lc->sync - 1]->sync = span->spanno;
971
		wc->tspans[lc->sync - 1]->psync = span->offset + 1;
972
	}
973
	wc->checktiming = 1;
974
	/* If we're already running, then go ahead and apply the changes */
975
	if (span->flags & DAHDI_FLAG_RUNNING)
976
		return ap4_startup(file, span);
977
978
	// Limpa contadores de slips, crc e bpv
979
	val = (*(wc->membase + AP_CNT_SLIP_REG));
980
	val = (*(wc->membase + AP_CNT_CRC_REG));
981
	val = (*(wc->membase + AP_CNT_CV_REG));
982
983
	ap_debugk("habilitando interrupcao!\n");
984
	// Nao considera as primeiras interrupcoes na soma das IRQs perdidas
985
	wc->flag_1st_irq = 16;
986
	// Enable interrupt
987
	*(wc->membase + AP_INT_CONTROL_REG) |= AP_INT_CTL_ENABLE;
988
	// Limpa interrupcao da FPGA para forcar borda de subida na proxima
989
	val = *(wc->membase + AP_CLEAR_IRQ_REG);
990
991
	printk("Done with spanconfig!\n");
992
	return 0;
993
}
994
995
static int ap4_chanconfig(struct file *file, struct dahdi_chan *chan,
996
		int sigtype)
997
{
998
	int alreadyrunning;
999
	unsigned long flags;
1000
	struct ap4 *wc = chan->pvt;
1001
1002
	alreadyrunning = wc->tspans[chan->span->offset]->span.flags & DAHDI_FLAG_RUNNING;
1003
	if (debug & DEBUG_MAIN) {
1004
		if (alreadyrunning)
1005
			printk("%s: Reconfigured channel %d (%s) sigtype %d\n",
1006
					wc->variety, chan->channo, chan->name, sigtype);
1007
		else
1008
			printk("%s: Configured channel %d (%s) sigtype %d\n",
1009
					wc->variety, chan->channo, chan->name, sigtype);
1010
	}
1011
	spin_lock_irqsave(&wc->reglock, flags);
1012
	if (alreadyrunning)
1013
		__set_clear(wc, chan->span->offset);
1014
	spin_unlock_irqrestore(&wc->reglock, flags);
1015
	return 0;
1016
}
1017
1018
static int ap4_open(struct dahdi_chan *chan)
1019
{
1020
	try_module_get(THIS_MODULE);
1021
	return 0;
1022
}
1023
1024
static int ap4_close(struct dahdi_chan *chan)
1025
{
1026
	module_put(THIS_MODULE);
1027
	return 0;
1028
}
1029
1030
static const struct dahdi_span_ops ap4_span_ops = {
1031
	.owner = THIS_MODULE,
1032
	.spanconfig = ap4_spanconfig,
1033
	.chanconfig = ap4_chanconfig,
1034
	.startup = ap4_startup,
1035
	.shutdown = ap4_shutdown,
1036
	.rbsbits = ap4_rbsbits,
1037
	.maint = ap4_maint,
1038
	.open = ap4_open,
1039
	.close  = ap4_close,
1040
#ifdef APEC_SUPPORT
1041
	.echocan = ap4_echocan,
1042
#endif
1043
	.ioctl = ap4_ioctl
1044
};
1045
1046
static void init_spans(struct ap4 *wc)
1047
{
1048
	int x,y;
1049
	struct ap4_span *ts;
1050
1051
	for (x=0;x<wc->numspans;x++) {
1052
		ts = wc->tspans[x];
1053
		sprintf(ts->span.name, "AP4%d%d/%d/%d", 0, wc->numspans, wc->num, x + 1);
1054
		snprintf(ts->span.desc, sizeof(ts->span.desc) - 1, "AP4%d%d Card %d Span %d", 0, wc->numspans, wc->num+1, x+1);
1055
		ts->span.ops = &ap4_span_ops;
1056
		if (ts->spantype == TYPE_E1) {
1057
			ts->span.channels = 31;
1058
			ts->span.spantype = SPANTYPE_DIGITAL_E1;
1059
			ts->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
1060
			ts->span.deflaw = DAHDI_LAW_ALAW;
1061
		} else {
1062
			ts->span.channels = 24;
1063
			ts->span.spantype = SPANTYPE_DIGITAL_T1;
1064
			ts->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
1065
			ts->span.deflaw = DAHDI_LAW_MULAW;
1066
		}
1067
		ts->span.chans = ts->chans;
1068
		ts->span.flags = DAHDI_FLAG_RBS;
1069
		ts->owner = wc;
1070
		ts->span.offset = x;
1071
		ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
1072
		ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
1073
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
1074
			struct dahdi_chan *mychans = ts->chans[y];
1075
			sprintf(mychans->name, "AP4%d%d/%d/%d/%d", 0, wc->numspans, wc->num, x + 1, y + 1);
1076
			mychans->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS |
1077
									 DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_EM_E1 | DAHDI_SIG_DACS_RBS;
1078
			mychans->pvt = wc;
1079
			mychans->chanpos = y + 1;
1080
		}
1081
	}
1082
	printk("%s: Spans initialized\n", wc->variety);
1083
}
1084
1085
1086
1087
static void __ap4_set_timing_source(struct ap4 *wc, int unit)
1088
{
1089
	unsigned int timing;
1090
	int x;
1091
1092
	if (unit != wc->syncsrc) {
1093
		if ((unit > -1) && (unit < 4)) {
1094
			/* define fonte de clock para interface escolhida */
1095
			timing = *(wc->membase+AP_CLKSRC_REG);
1096
			timing &= ~AP_CLKSRC_MASK;
1097
			timing |= unit+1;
1098
			*(wc->membase+AP_CLKSRC_REG) = timing;
1099
		} else {
1100
			/* define clock para interno */
1101
			timing = *(wc->membase+AP_CLKSRC_REG);
1102
			timing &= ~AP_CLKSRC_MASK;
1103
			*(wc->membase+AP_CLKSRC_REG) = timing;
1104
		}
1105
		wc->syncsrc = unit;
1106
		if ((unit < 0) || (unit > 3))
1107
			unit = 0;
1108
		else
1109
			unit++;
1110
		for (x=0;x<wc->numspans;x++)
1111
			wc->tspans[x]->span.syncsrc = unit;
1112
	} else {
1113
		if (debug & DEBUG_MAIN)
1114
			printk("%s: Timing source already set to %d\n",
1115
					wc->variety, unit);
1116
	}
1117
	printk("%s: Timing source set to %d (clksrc_reg = 0x%08x)\n",
1118
			wc->variety, unit, *(wc->membase+AP_CLKSRC_REG));
1119
}
1120
1121
static void __ap4_set_timing_source_auto(struct ap4 *wc)
1122
{
1123
	int x;
1124
1125
	wc->checktiming = 0;
1126
	for (x=0;x<wc->numspans;x++) {
1127
		if (wc->tspans[x]->sync) {
1128
			if ((wc->tspans[wc->tspans[x]->psync - 1]->span.flags & DAHDI_FLAG_RUNNING) &&
1129
				!(wc->tspans[wc->tspans[x]->psync - 1]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE) )) {
1130
					/* Valid timing source */
1131
					__ap4_set_timing_source(wc, wc->tspans[x]->psync - 1);
1132
					return;
1133
			}
1134
		}
1135
	}
1136
	__ap4_set_timing_source(wc, 4);
1137
}
1138
1139
static void __ap4_configure_t1(struct ap4 *wc, int unit, int lineconfig, int txlevel)
1140
{
1141
	char *framing, *line;
1142
	unsigned int config = 0;
1143
	unsigned int param = 0;
1144
	unsigned int linecode = 0;
1145
1146
	wc->tspans[unit]->spantype = TYPE_T1;
1147
	wc->tspans[unit]->span.channels = 24;
1148
	wc->tspans[unit]->span.deflaw = DAHDI_LAW_MULAW;
1149
1150
	/* Configure line code */
1151
	if (unit < 2)
1152
		linecode = AP_LIU1_LINECODE;
1153
	else
1154
		linecode = AP_LIU2_LINECODE;
1155
	if (lineconfig & DAHDI_CONFIG_AMI) {
1156
		*(wc->membase+AP_LEDS_REG) |= linecode;
1157
		line = "AMI";
1158
	} else {
1159
		*(wc->membase+AP_LEDS_REG) &= ~linecode;
1160
		line = "B8ZS";
1161
	}
1162
1163
	/* loopback test*/
1164
	//wc->hw_regs->e1_config |= (AP_E1_LOOP_CONFIG  << (8 * unit));
1165
	//printk("E1 config = 0x%08x\n", wc->hw_regs->e1_config);
1166
1167
	/* Configure T1 */
1168
	config = wc->hw_regs->liu_config;
1169
	config &= ~(0x000000ff << (8 * unit));
1170
	config |= (AP_PULS_DSX1_0FT << (8 * unit));
1171
	wc->hw_regs->liu_config = config;
1172
1173
	param = AP4_T1_NE1_SEL | AP4_T1_CAS_ENABLE;
1174
	if (lineconfig & DAHDI_CONFIG_D4) {
1175
		framing = "D4";
1176
	} else {
1177
		framing = "ESF";
1178
		param |= AP4_T1_ESF_NSF;
1179
	}
1180
	config = wc->hw_regs->t1_config;
1181
	config &= ~(0x000000ff << (8 * unit));
1182
	config |= (param << (8 * unit));
1183
	wc->hw_regs->t1_config = config;
1184
1185
	printk("T1 Status: 0x%08x\tT1 Config: 0x%08x\tPARAM: 0x%08x\n",
1186
			wc->hw_regs->t1_status, wc->hw_regs->t1_config, param);
1187
1188
	if (!polling) {
1189
		__ap4_check_alarms(wc, unit);
1190
		__ap4_check_sigbits(wc, unit);
1191
	}
1192
	printk("%s: Span %d configured for %s/%s\n", wc->variety, unit + 1, framing, line);
1193
}
1194
1195
static void __ap4_configure_e1(struct ap4 *wc, int unit, int lineconfig)
1196
{
1197
	char *crc4 = "";
1198
	char *framing, *line;
1199
	unsigned int e1s_cfg, config = 0;
1200
	unsigned int linecode = 0;
1201
1202
	wc->tspans[unit]->spantype = TYPE_E1;
1203
	wc->tspans[unit]->span.channels = 31;
1204
	wc->tspans[unit]->span.deflaw = DAHDI_LAW_ALAW;
1205
1206
	if (loopback) {
1207
	}
1208
1209
	if (lineconfig & DAHDI_CONFIG_CRC4) {
1210
		crc4 = "/CRC4";
1211
		config |= AP_E1_CRCEN_CONFIG;
1212
	}
1213
1214
	if(unit < 2)
1215
		linecode = AP_LIU1_LINECODE;
1216
	else
1217
		linecode = AP_LIU2_LINECODE;
1218
	/* Configure line interface */
1219
	if (lineconfig & DAHDI_CONFIG_AMI) {
1220
		*(wc->membase+AP_LEDS_REG) |= linecode;
1221
		line = "AMI";
1222
	} else {
1223
		*(wc->membase+AP_LEDS_REG) &= ~linecode;
1224
		line = "HDB3";
1225
	}
1226
1227
	if (lineconfig & DAHDI_CONFIG_CCS) {
1228
		framing = "CCS";
1229
	} else {
1230
		framing = "CAS";
1231
		config |= (AP_E1_CASEN_CONFIG | AP_E1_PCM30_CONFIG);
1232
	}
1233
1234
	e1s_cfg = *(wc->membase+AP_E1_CONFIG_REG);
1235
	e1s_cfg &= ~(0x000000ff<<(8*unit));
1236
	e1s_cfg |= (config<<(8*unit));
1237
	*(wc->membase+AP_E1_CONFIG_REG) = e1s_cfg;
1238
1239
	/* Disable T1 framer */
1240
	config = wc->hw_regs->t1_config;
1241
	config &= ~(0x000000ff << (8 * unit));
1242
	wc->hw_regs->t1_config = config;
1243
1244
	/* Configure LIU Signalling */
1245
	e1s_cfg = *(wc->membase+AP_T1E1_CONFIG_REG);
1246
	e1s_cfg &= ~(0x000000ff<<(8*unit));
1247
	e1s_cfg |= (AP_PULS_E1_120<<(8*unit));
1248
	*(wc->membase+AP_T1E1_CONFIG_REG) = e1s_cfg;
1249
1250
	if (!polling) {
1251
		__ap4_check_alarms(wc, unit);
1252
		__ap4_check_sigbits(wc, unit);
1253
	}
1254
	printk("%s: Span %d configured for %s/%s%s\n",
1255
 			wc->variety, unit + 1, framing, line, crc4);
1256
}
1257
1258
static int ap4_startup(struct file *file, struct dahdi_span *span)
1259
{
1260
	int i;
1261
	int tspan;
1262
	unsigned long flags;
1263
	int alreadyrunning;
1264
	struct ap4_span *ts = ap4_span_from_span(span);
1265
	struct ap4 *wc = ts->owner;
1266
1267
	printk("About to enter startup!\n");
1268
	tspan = span->offset + 1;
1269
	if (tspan < 0) {
1270
		printk("%s: Span '%d' isn't us?\n", wc->variety, span->spanno);
1271
		return -1;
1272
	}
1273
1274
	spin_lock_irqsave(&wc->reglock, flags);
1275
1276
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
1277
1278
	/* initialize the start value for the entire chunk of last ec buffer */
1279
	for(i = 0; i < span->channels; i++)
1280
	{
1281
		memset(ts->ec_chunk1[i],
1282
			DAHDI_LIN2X(0, span->chans[i]),DAHDI_CHUNKSIZE);
1283
		memset(ts->ec_chunk2[i],
1284
			DAHDI_LIN2X(0, span->chans[i]),DAHDI_CHUNKSIZE);
1285
	}
1286
1287
	/* Force re-evaluation fo timing source */
1288
//	if (timingcable)
1289
		wc->syncsrc = -1;
1290
1291
	if ((span->lineconfig & DAHDI_CONFIG_D4) || (span->lineconfig & DAHDI_CONFIG_ESF)) {
1292
		/* is a T1 card */
1293
		__ap4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
1294
	} else { /* is a E1 card */
1295
		__ap4_configure_e1(wc, span->offset, span->lineconfig);
1296
	}
1297
1298
	/* Note clear channel status */
1299
	wc->tspans[span->offset]->notclear = 0;
1300
	__set_clear(wc, span->offset);
1301
1302
	if (!alreadyrunning) {
1303
		span->flags |= DAHDI_FLAG_RUNNING;
1304
		wc->spansstarted++;
1305
		/* enable interrupts */
1306
1307
		if (!polling) {
1308
			__ap4_check_alarms(wc, span->offset);
1309
			__ap4_check_sigbits(wc, span->offset);
1310
		}
1311
	}
1312
	spin_unlock_irqrestore(&wc->reglock, flags);
1313
1314
	if (wc->tspans[0]->sync == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno);
1315
	if (wc->numspans > 1) {
1316
		if (wc->tspans[1]->sync == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
1317
	}
1318
	if (wc->numspans == 4) {
1319
		if (wc->tspans[2]->sync == span->spanno) printk("SPAN %d: Tertiary Sync Source\n",span->spanno);
1320
		if (wc->tspans[3]->sync == span->spanno) printk("SPAN %d: Quaternary Sync Source\n",span->spanno);
1321
	}
1322
1323
#ifdef APEC_SUPPORT
1324
	if (!apec_enable || !wc->apec_enable)
1325
		wc->hw_regs->echo_ctrl = 0xe0000000;
1326
	else if (!alreadyrunning && !wc->apec)
1327
			if (ap4_apec_init(wc))
1328
				ap4_apec_release(wc);
1329
#else
1330
	wc->hw_regs->echo_ctrl = 0xe0000000;
1331
#endif
1332
1333
	printk("Completed startup!\n");
1334
	return 0;
1335
}
1336
1337
1338
static void ap4_receiveprep(struct ap4 *wc)
1339
{
1340
	volatile unsigned int *readchunk;
1341
	unsigned int buffer[32];
1342
	unsigned char *byte = (unsigned char *) buffer;
1343
	int i, j, k;
1344
1345
	readchunk = (wc->membase + (AP_DATA_BASE));
1346
	for (i = 0; i < DAHDI_CHUNKSIZE; i++) {
1347
		/* Prefetch Card data */
1348
		for (j = 0; j < 32; ++j) {
1349
			buffer[j] = readchunk[j];
1350
		}
1351
		for (j = 0; j < wc->numspans; j++) {
1352
			/* Set first timeslot for first channel */
1353
			if (wc->tspans[j]->spantype == TYPE_E1) {
1354
				for (k = 0; k < 31; ++k) {
1355
					/* Skip first timeslot from E1 */
1356
					wc->tspans[j]->span.chans[k]->readchunk[i] =
1357
							byte[4*(k+1)+j];
1358
				}
1359
			}
1360
			else {
1361
				for (k = 0; k < 24; ++k) {
1362
					wc->tspans[j]->span.chans[k]->readchunk[i] =
1363
							byte[4*k+j];
1364
				}
1365
			}
1366
		}
1367
		readchunk += 32;
1368
	}
1369
1370
	for (i = 0; i < wc->numspans; i++) {
1371
		if (wc->tspans[i]->span.flags & DAHDI_FLAG_RUNNING) {
1372
			for (j = 0; j < wc->tspans[i]->span.channels; j++) {
1373
				/* Echo cancel double buffered data */
1374
				dahdi_ec_chunk(wc->tspans[i]->span.chans[j],
1375
				    wc->tspans[i]->span.chans[j]->readchunk,
1376
					wc->tspans[i]->ec_chunk2[j]);
1377
				memcpy(wc->tspans[i]->ec_chunk2[j],wc->tspans[i]->ec_chunk1[j],
1378
					DAHDI_CHUNKSIZE);
1379
				memcpy(wc->tspans[i]->ec_chunk1[j],
1380
					wc->tspans[i]->span.chans[j]->writechunk,
1381
						DAHDI_CHUNKSIZE);
1382
			}
1383
			dahdi_receive(&wc->tspans[i]->span);
1384
		}
1385
	}
1386
}
1387
1388
#if (DAHDI_CHUNKSIZE != 8)
1389
#error Sorry, AP400 driver does not support chunksize != 8
1390
#endif
1391
1392
#ifdef ENABLE_WORKQUEUES
1393
static void workq_handlespan(void *data)
1394
{
1395
	struct ap4_span *ts = data;
1396
	struct ap4 *wc = ts->owner;
1397
1398
//	__receive_span(ts);
1399
//	__transmit_span(ts);
1400
	atomic_dec(&wc->worklist);
1401
	atomic_read(&wc->worklist);
1402
1403
}
1404
#endif
1405
1406
static void ap4_transmitprep(struct ap4 *wc)
1407
{
1408
	volatile unsigned int *writechunk;
1409
	int x,y,z;
1410
	unsigned int tmp;
1411
1412
	for (y=0;y<wc->numspans;y++) {
1413
		if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING)
1414
			dahdi_transmit(&wc->tspans[y]->span);
1415
	}
1416
1417
	writechunk = (wc->membase+(AP_DATA_BASE));
1418
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
1419
		// Once per chunk
1420
		for (z=0;z<32;z++) {
1421
			// All channels
1422
			tmp = 0;
1423
			for (y = 0; y < wc->numspans; ++y) {
1424
				if (wc->tspans[y]->spantype == TYPE_T1 && z < 24)
1425
					tmp |= (wc->tspans[y]->span.chans[z]->writechunk[x]
1426
					                           << (8*y));
1427
				else /* Span Type is E1 */
1428
					if (z > 0) /* Skip first timeslot */
1429
						tmp |= (wc->tspans[y]->span.chans[z-1]->writechunk[x]
1430
									<< (8*y));
1431
			}
1432
			writechunk[z] = tmp;
1433
		}
1434
		// Advance pointer by 4 TDM frame lengths
1435
		writechunk += 32;
1436
	}
1437
1438
}
1439
1440
static void ap4_tdm_loop(struct ap4 *wc)
1441
{
1442
	volatile unsigned int *buf_ptr;
1443
	int x,z;
1444
	unsigned int tmp;
1445
1446
	buf_ptr = (wc->membase+AP_DATA_BASE);
1447
1448
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
1449
		// Once per chunk
1450
		for (z=0;z<32;z++) {
1451
			tmp = buf_ptr[z];
1452
			buf_ptr[z] = tmp;
1453
		}
1454
		buf_ptr += 32;
1455
	}
1456
}
1457
1458
static void __ap4_check_sigbits(struct ap4 *wc, int span)
1459
{
1460
	int a,i,rxs;
1461
	struct ap4_span *ts = wc->tspans[span];
1462
	volatile unsigned int *readcas = (wc->membase+AP_CAS_BASE);
1463
1464
//	if (debug & DEBUG_RBS)
1465
//		printk("Checking sigbits on span %d\n", span + 1);
1466
1467
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
1468
		return;
1469
	// se span estiver com alarme RED ou BLUE...
1470
	if( (ts->span.alarms & DAHDI_ALARM_RED) || (ts->span.alarms & DAHDI_ALARM_BLUE) ) {
1471
		ts->reload_cas = 4;
1472
	} else if(ts->reload_cas > 0) {
1473
		// da mais um tempo para framer recuperar e enviar bits de CAS validos
1474
		ts->reload_cas--;
1475
	}
1476
1477
	if (ts->spantype == TYPE_E1) {
1478
		for (i = 0; i < 15; i++) {
1479
1480
			// Se estamos em alarme ou recuperando de um entao mascara os bits para "1101" (bloqueado)
1481
			if(ts->reload_cas) {
1482
				a = 0xdd;
1483
			} else {
1484
				a = (int) ts->casbuf[i];
1485
			}
1486
			ts->casbuf[i] = (unsigned char) (readcas[i] >> (8*span))&0xff;
1487
1488
			/* Get high channel in low bits */
1489
			rxs = (a & 0xf);
1490
			if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
1491
				if (ts->span.chans[i+16]->rxsig != rxs) {
1492
					ap_debugk("CAS no canal %d mudou de 0x%02x para 0x%02x\n", i+16, ts->span.chans[i+16]->rxsig, rxs);
1493
					dahdi_rbsbits(ts->span.chans[i+16], rxs);
1494
				}
1495
			}
1496
			rxs = (a >> 4) & 0xf;
1497
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
1498
				if (ts->span.chans[i]->rxsig != rxs) {
1499
					ap_debugk("CAS no canal %d mudou de 0x%02x para 0x%02x\n", i, ts->span.chans[i]->rxsig, rxs);
1500
					dahdi_rbsbits(ts->span.chans[i], rxs);
1501
				}
1502
			}
1503
		}
1504
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
1505
		for (i = 0; i < 12; i++) {
1506
			a = (unsigned char) (readcas[i] >> (8*span)) & 0xcc;
1507
			rxs = a & 0xc;
1508
			//rxs = (a & 0xc) >> 2;
1509
			if (!(ts->span.chans[2*i]->sig & DAHDI_SIG_CLEAR)) {
1510
				if (ts->span.chans[2*i]->rxsig != rxs)
1511
					dahdi_rbsbits(ts->span.chans[2*i], rxs);
1512
			}
1513
			rxs = (a >> 4) & 0xc;
1514
			//rxs = ((a >> 4) & 0xc) >> 2;
1515
			if (!(ts->span.chans[2*i+1]->sig & DAHDI_SIG_CLEAR)) {
1516
				if (ts->span.chans[2*i+1]->rxsig != rxs)
1517
					dahdi_rbsbits(ts->span.chans[2*i+1], rxs);
1518
			}
1519
		}
1520
	} else { // ESF
1521
		for (i = 0; i < 12; i++) {
1522
			a = (unsigned char) (readcas[i] >> (8*span)) & 0xff;
1523
			rxs = (a & 0xf);
1524
			if (!(ts->span.chans[2*i+1]->sig & DAHDI_SIG_CLEAR)) {
1525
				/* XXX Not really reset on every trans! XXX */
1526
				if (ts->span.chans[2*i+1]->rxsig != rxs) {
1527
					dahdi_rbsbits(ts->span.chans[2*i+1], rxs);
1528
				}
1529
			}
1530
			rxs = (a >> 4) & 0xf;
1531
			if (!(ts->span.chans[2*i]->sig & DAHDI_SIG_CLEAR)) {
1532
				/* XXX Not really reset on every trans! XXX */
1533
				if (ts->span.chans[2*i]->rxsig != rxs) {
1534
					dahdi_rbsbits(ts->span.chans[2*i], rxs);
1535
				}
1536
			}
1537
		}
1538
	}
1539
}
1540
1541
static void __ap4_check_alarms(struct ap4 *wc, int span)
1542
{
1543
	unsigned char c;
1544
	int alarms;
1545
	int x,j;
1546
	struct ap4_span *ts = wc->tspans[span];
1547
	unsigned int e1_cfg;
1548
1549
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
1550
		return;
1551
1552
	/* Assume no alarms */
1553
	alarms = DAHDI_ALARM_NONE;
1554
1555
	/* And consider only carrier alarms */
1556
	ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
1557
1558
	if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
1559
		for (x=0,j=0;x < ts->span.channels;x++)
1560
			if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
1561
#ifdef CONFIG_DAHDI_NET
1562
					||
1563
			    (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
1564
#endif
1565
			    )
1566
				j++;
1567
		if (!j)
1568
			alarms |= DAHDI_ALARM_NOTOPEN;
1569
	}
1570
1571
/* le status e configuracao do E1 */
1572
	if (wc->tspans[span]->spantype == TYPE_E1) {
1573
		c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
1574
		e1_cfg = ((*(wc->membase+AP_E1_CONFIG_REG))>>(8*span));
1575
1576
		if ((c & AP_E1_LOS_STATUS)||(c & AP_E1_BFAE_STATUS)||(c & AP_E1_AIS_STATUS)) {
1577
			if (ts->alarmcount >= alarmdebounce)
1578
				alarms |= DAHDI_ALARM_RED;
1579
			else
1580
				ts->alarmcount++;
1581
		} else
1582
			ts->alarmcount = 0;
1583
1584
		if ( c & AP_E1_MFAE_STATUS )
1585
			alarms |= DAHDI_ALARM_BLUE;
1586
1587
		if ( (!(c & AP_E1_CAS_STATUS)) && (e1_cfg & AP_E1_PCM30_CONFIG))
1588
			alarms |= DAHDI_ALARM_BLUE;
1589
	} else {
1590
		c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
1591
		if (c & AP_E1_LOS_STATUS) {
1592
			if (ts->alarmcount >= alarmdebounce)
1593
				alarms |= DAHDI_ALARM_RED;
1594
			else
1595
				ts->alarmcount++;
1596
		} else
1597
			ts->alarmcount = 0;
1598
		c = wc->hw_regs->t1_status >> (8 * span);
1599
		if (!(c & AP4_T1_FRAME_SYNC))
1600
			alarms |= DAHDI_ALARM_RED;
1601
	}
1602
1603
	if (((!ts->span.alarms) && alarms) ||
1604
	    (ts->span.alarms && (!alarms)))
1605
		wc->checktiming = 1;
1606
1607
	/* Keep track of recovering */
1608
	if ((!alarms) && ts->span.alarms)
1609
		ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
1610
	if (ts->alarmtimer)
1611
		alarms |= DAHDI_ALARM_RECOVER;
1612
1613
1614
	// If receiving alarms, go into Yellow alarm state
1615
	if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
1616
		printk("Setting yellow alarm on span %d\n", span + 1);
1617
		e1_cfg = *(wc->membase+AP_E1_CONFIG_REG);
1618
		e1_cfg |= (AP_E1_RAI_CONFIG<<(8*span));
1619
		*(wc->membase+AP_E1_CONFIG_REG) = e1_cfg;
1620
		ts->spanflags |= FLAG_SENDINGYELLOW;
1621
	} else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
1622
		printk("Clearing yellow alarm on span %d\n", span + 1);
1623
		e1_cfg = *(wc->membase+AP_E1_CONFIG_REG);
1624
		e1_cfg &= ~(AP_E1_RAI_CONFIG<<(8*span));
1625
		*(wc->membase+AP_E1_CONFIG_REG) = e1_cfg;
1626
		ts->spanflags &= ~FLAG_SENDINGYELLOW;
1627
	}
1628
1629
	// Re-check the timing source when we enter/leave alarm, not withstanding yellow alarm
1630
	if (c & AP_E1_RAI_STATUS)
1631
		alarms |= DAHDI_ALARM_YELLOW;
1632
1633
	if (ts->span.mainttimer || ts->span.maintstat)
1634
		alarms |= DAHDI_ALARM_LOOPBACK;
1635
1636
	ts->span.alarms = alarms;
1637
	dahdi_alarm_notify(&ts->span);
1638
}
1639
1640
static void __ap4_do_counters(struct ap4 *wc)
1641
{
1642
	int span;
1643
1644
	for (span=0;span<wc->numspans;span++) {
1645
		struct ap4_span *ts = wc->tspans[span];
1646
		int docheck=0;
1647
		if (ts->loopupcnt || ts->loopdowncnt)
1648
			docheck++;
1649
		if (ts->alarmtimer) {
1650
			if (!--ts->alarmtimer) {
1651
				docheck++;
1652
				ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
1653
			}
1654
		}
1655
		if (docheck) {
1656
			if (!polling)
1657
				__ap4_check_alarms(wc, span);
1658
			dahdi_alarm_notify(&ts->span);
1659
		}
1660
	}
1661
}
1662
1663
static inline void __handle_leds(struct ap4 *wc)
1664
{
1665
	int x, span_status;
1666
	#define MAX_BLINKTIMER	0x14
1667
1668
	for (x=0;x<wc->numspans;x++) {
1669
		struct ap4_span *ts = wc->tspans[x];
1670
		/* le status do E1 (para avaliar LOS) */
1671
		span_status = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*x));
1672
		if (ts->span.flags & DAHDI_FLAG_RUNNING) {
1673
			if(span_status&AP_E1_LOS_STATUS) {
1674
				if (wc->blinktimer[x] >= (altab[wc->alarmpos[x]] /*>> 1*/)) {
1675
					__ap4_set_led(wc, x, AP_ON);
1676
				}
1677
				if (wc->blinktimer[x] >= (MAX_BLINKTIMER-1)) {
1678
					__ap4_set_led(wc, x, AP_OFF);
1679
				}
1680
				wc->blinktimer[x] += 1;
1681
			} else if (ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) {
1682
				if (wc->blinktimer[x] >= (altab[wc->alarmpos[x]] /*>> 1*/)) {
1683
					__ap4_set_led(wc, x, AP_ON);
1684
				}
1685
				if (wc->blinktimer[x] >= (MAX_BLINKTIMER-2)) {
1686
					__ap4_set_led(wc, x, AP_OFF);
1687
				}
1688
				wc->blinktimer[x] += 3;
1689
			} /*else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
1690
				// Yellow Alarm
1691
				__ap4_set_led(wc, x, AP_ON);
1692
			} else if (ts->span.mainttimer || ts->span.maintstat) {
1693
1694
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
1695
					__ap4_set_led(wc, x, AP_GREEN);
1696
				}
1697
				if (wc->blinktimer == 0xf) {
1698
					__ap4_set_led(wc, x, AP_OFF);
1699
				}
1700
1701
			} */else {
1702
				/* No Alarm */
1703
				__ap4_set_led(wc, x, AP_ON);
1704
			}
1705
		}	else
1706
				__ap4_set_led(wc, x, AP_OFF);
1707
1708
		if (wc->blinktimer[x] > MAX_BLINKTIMER) {
1709
			wc->blinktimer[x] = 0;
1710
			wc->alarmpos[x]++;
1711
			if (wc->alarmpos[x] >= (sizeof(altab) / sizeof(altab[0])))
1712
				wc->alarmpos[x] = 0;
1713
		}
1714
1715
	}
1716
}
1717
1718
1719
static irqreturn_t ap4_interrupt(int irq, void *dev_id)
1720
{
1721
	struct ap4 *wc = dev_id;
1722
	unsigned long flags;
1723
	int x;
1724
	static unsigned int val, cfg;
1725
	unsigned int cnt_irq_misses;
1726
	static unsigned int cnt_tmp;
1727
	int ret = 0;
1728
1729
	/* retorna se interrupcao nao foi habilitada ou nao esta ativa */
1730
	cfg = *(wc->membase + AP_INT_CONTROL_REG);
1731
	if((cfg & AP_INT_CTL_ENABLE) == 0 || (cfg & AP_INT_CTL_ACTIVE) == 0) {
1732
		ret = 0;
1733
		goto out;
1734
	}
1735
	/* se chegamos aqui eh porque a interrupcao esta habilitada
1736
	 * e esta ativa, ou seja, foi gerada pelo nosso cartao.
1737
	 * Agora damos o ack da interrupcao */
1738
	val = *(wc->membase + AP_CLEAR_IRQ_REG);
1739
1740
	/* conta interrupcoes perdidas */
1741
	if (wc->flag_1st_irq > 0) {
1742
		// nao considera as primeiras passagens pela rotina
1743
		cnt_irq_misses = (*(wc->membase+AP_CNT_IRQ_REG));
1744
		// so considera int. para o cartao
1745
		if(cnt_irq_misses) {
1746
			wc->flag_1st_irq--;
1747
			*(wc->membase+AP_CNT_IRQ_REG)=0;
1748
		}
1749
		// zera erro de CRC
1750
		cnt_tmp = (*(wc->membase + AP_CNT_CRC_REG));
1751
	} else {
1752
		// neste registro da FPGA temos o numero de interrupcoes que aconteceram
1753
		// desde o ultimo reset do contador de interrupcoes. O normal eh ler 1.
1754
		cnt_irq_misses = (*(wc->membase+AP_CNT_IRQ_REG));
1755
		// Se for zero significa que a interrupcao nao foi gerada pelo nosso cartao
1756
		if(cnt_irq_misses == 0) {
1757
			if(debug) printk("Interrupcao gerada mas nao pela FPGA?!\n");
1758
			ret = 0;
1759
			goto out;
1760
		}
1761
		// reseta o contador
1762
		*(wc->membase+AP_CNT_IRQ_REG)=0;
1763
		for(x=0;x<(wc->numspans);x++)
1764
			wc->ddev->irqmisses += (cnt_irq_misses-1);
1765
	}
1766
1767
	if (!wc->spansstarted) {
1768
		/* Not prepped yet! */
1769
		ret = 0;
1770
		goto out;
1771
	}
1772
1773
	wc->intcount++;
1774
1775
#ifdef ENABLE_WORKQUEUES
1776
	int cpus = num_online_cpus();
1777
	atomic_set(&wc->worklist, wc->numspans);
1778
	if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
1779
		ap4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
1780
	else
1781
		atomic_dec(&wc->worklist);
1782
	if (wc->numspans > 1) {
1783
		if (wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)
1784
			ap4_queue_work(wc->workq, &wc->tspans[1]->swork, 1 % cpus);
1785
		else
1786
			atomic_dec(&wc->worklist);
1787
	}
1788
	if (wc->numspans == 4) {
1789
		if (wc->tspans[2]->span.flags & DAHDI_FLAG_RUNNING)
1790
			ap4_queue_work(wc->workq, &wc->tspans[2]->swork, 2 % cpus);
1791
		else
1792
			atomic_dec(&wc->worklist);
1793
		if (wc->tspans[3]->span.flags & DAHDI_FLAG_RUNNING)
1794
			ap4_queue_work(wc->workq, &wc->tspans[3]->swork, 3 % cpus);
1795
		else
1796
			atomic_dec(&wc->worklist);
1797
	}
1798
#else
1799
	if (tdm_loop == 1)
1800
		ap4_tdm_loop(wc);
1801
	else {
1802
		ap4_receiveprep(wc);
1803
		ap4_transmitprep(wc);
1804
	}
1805
#endif
1806
1807
	// Estatisticas a cada 128ms
1808
	if(!(wc->intcount&0x7f)){
1809
		clock_source = wc->hw_regs->clock_source;
1810
		cnt_tmp = (*(wc->membase + AP_CNT_CV_REG));
1811
		for(x=0;x<(wc->numspans);x++)
1812
			wc->tspans[x]->span.count.bpv += (cnt_tmp>>(8*x))&0xff;
1813
		cnt_tmp = (*(wc->membase + AP_CNT_CRC_REG));
1814
		for(x=0;x<(wc->numspans);x++)
1815
			wc->tspans[x]->span.count.crc4 += (cnt_tmp>>(8*x))&0xff;
1816
		cnt_tmp = (*(wc->membase + AP_CNT_SLIP_REG));
1817
		for(x=0;x<(wc->numspans);x++) {
1818
			if (((cnt_tmp>>(8*x))&0xff) && (!(wc->tspans[x]->span.alarms & DAHDI_ALARM_RED)) ){
1819
				wc->tspans[x]->slipcount++;
1820
				if(debug) printk("Slip detected on span %d: slipcount = %d\n", x+1, wc->tspans[x]->slipcount);
1821
			}
1822
		}
1823
	}
1824
1825
	spin_lock_irqsave(&wc->reglock, flags);
1826
1827
	__handle_leds(wc);
1828
1829
	__ap4_do_counters(wc);
1830
1831
	//x = wc->intcount & 15;
1832
	x = wc->intcount & 7;
1833
	switch(x) {
1834
	case 0:
1835
	case 1:
1836
	case 2:
1837
	case 3:
1838
		__ap4_check_alarms(wc, x);
1839
		break;
1840
	case 4:
1841
	case 5:
1842
	case 6:
1843
	case 7:
1844
		__ap4_check_sigbits(wc, x - 4);
1845
		break;
1846
	}
1847
1848
	if (wc->checktiming > 0)
1849
		__ap4_set_timing_source_auto(wc);
1850
	spin_unlock_irqrestore(&wc->reglock, flags);
1851
	/* IRQ was treated */
1852
	ret = 1;
1853
out:
1854
#ifdef AP400_HDLC
1855
	/* Call AP400_HDLC_CARD IRQ handler before leave */
1856
	ret |= ap400_intr_handler(irq, wc->hdlc_card);
1857
#endif
1858
1859
	return IRQ_RETVAL(ret);
1860
}
1861
1862
1863
static int __devinit ap4_launch(struct ap4 *wc)
1864
{
1865
	int x;
1866
	unsigned long flags;
1867
1868
	if (wc->tspans[0]->span.flags & DAHDI_FLAG_REGISTERED)
1869
		return 0;
1870
	printk("%s: Launching card: %d\n", wc->variety, wc->order);
1871
1872
	/* Setup serial parameters and system interface */
1873
	for (x=0;x<4;x++) {
1874
		//ap4_serial_setup(wc, x);
1875
		wc->globalconfig = 1;
1876
	}
1877
1878
	for (x=0; x<wc->numspans; x++)
1879
		list_add_tail(&wc->tspans[x]->span.device_node,
1880
				&wc->ddev->spans);
1881
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
1882
		printk(KERN_ERR "Unable to register span %s\n", wc->tspans[0]->span.name);
1883
		return -1; /* FIXME: proper error handling */
1884
	}
1885
	wc->checktiming = 1;
1886
	spin_lock_irqsave(&wc->reglock, flags);
1887
//	__ap4_set_timing_source(wc,4);
1888
	spin_unlock_irqrestore(&wc->reglock, flags);
1889
#ifdef ENABLE_TASKLETS
1890
	tasklet_init(&wc->ap4_tlet, ap4_tasklet, (unsigned long)wc);
1891
#endif
1892
	return 0;
1893
}
1894
1895
1896
static int ap4xx_liu_reset(struct ap4 *wc)
1897
{
1898
 	unsigned int jiffies_hold = jiffies;
1899
	*(wc->membase+AP_LEDS_REG) |= AP_LIU_RESET_BIT;
1900
	while(jiffies<=(jiffies_hold+2));
1901
	*(wc->membase+AP_LEDS_REG) &= ~AP_LIU_RESET_BIT;
1902
	return 0;
1903
}
1904
1905
1906
static int ap4xx_bus_test(struct ap4 *wc)
1907
{
1908
	int tst_result = 0;
1909
	unsigned int val;
1910
1911
	*(wc->membase+AP_E1_CONFIG_REG) = 0xAAAAAAAA;
1912
	*wc->membase = 0; // flush
1913
	val = *(wc->membase+AP_E1_CONFIG_REG);
1914
	if(val != 0xAAAAAAAA) {
1915
		printk("Escrito 0xAAAAAAAA, lido 0x%08X!\n", val);
1916
		tst_result++;
1917
	}
1918
	*(wc->membase+AP_E1_CONFIG_REG) = 0x55555555;
1919
	*wc->membase = 0; // flush
1920
	val = *(wc->membase+AP_E1_CONFIG_REG);
1921
	if(val != 0x55555555) {
1922
		printk("Escrito 0x55555555, lido 0x%08X!\n", val);
1923
		tst_result++;
1924
	}
1925
	*(wc->membase+AP_E1_CONFIG_REG) = 0xFFFFFFFF;
1926
	*wc->membase = 0; // flush
1927
	val = *(wc->membase+AP_E1_CONFIG_REG);
1928
	if(val != 0xFFFFFFFF) {
1929
		printk("Escrito 0xFFFFFFFF, lido 0x%08X!\n", val);
1930
		tst_result++;
1931
	}
1932
	*(wc->membase+AP_E1_CONFIG_REG) = 0x00000000;
1933
	*wc->membase = 0xFFFFFFFF; // flush
1934
	val = *(wc->membase+AP_E1_CONFIG_REG);
1935
	if(val != 0x00000000) {
1936
		printk("Escrito 0x00000000, lido 0x%08X!\n", val);
1937
		tst_result++;
1938
	}
1939
	return tst_result;
1940
}
1941
1942
#ifdef TIMER_DEBUG
1943
void ap4xx_opt_timeout(unsigned long arg)
1944
{
1945
	struct pci_dev *dev = (struct pci_dev *)arg;
1946
	struct ap4 *wc = pci_get_drvdata(dev);
1947
1948
//	ap_debugk("wc->tspans[0]->span.chans[1].readchunk[1] = 0x%02x\n", wc->tspans[0]->span.chans[0].readchunk[1]);
1949
//	ap_debugk("e1s_cfg = 0x%08x\n", *(wc->membase+AP_E1_CONFIG_REG));
1950
//	ap_debugk("e1_status = 0x%08x\n", *(wc->membase + AP_E1_STATUS_REG));
1951
//	ap_debugk("clk_cfg = 0x%08x\n", *(wc->membase+0x07));
1952
//	ap_debugk("e1_data = 0x%08x\n", *(wc->membase + (AP_DATA_BASE + 1)));
1953
//	ap_debugk("cas_data = 0x%08x\n", *(wc->membase + AP_CAS_BASE));
1954
1955
	// dispara timer novamente
1956
	init_timer(&ap4xx_opt_timer);
1957
	ap4xx_opt_timer.function = ap4xx_opt_timeout;
1958
	ap4xx_opt_timer.data = arg;
1959
	ap4xx_opt_timer.expires = jiffies + (delay/4);
1960
	add_timer(&ap4xx_opt_timer);
1961
1962
}
1963
#endif
1964
1965
static inline int ap4_card_detect (struct ap4 *wc) {
1966
	int i;
1967
	if ((wc->hw_regs->card_id != AP4XX_CARD_ID) &&
1968
			(wc->hw_regs->card_id != APE4XX_CARD_ID)) {
1969
		printk("AP400: Unknown card ID(0x%08X)! Aborting...\n", wc->hw_regs->card_id);
1970
		return -EPERM;
1971
	}
1972
	// Test bus integrity
1973
	for (i=0; i < 1000; i++) {
1974
		if (ap4xx_bus_test(wc)) {
1975
			printk("AP400: Bus integrity test failed! Aborting...\n");
1976
			return -EIO;
1977
		}
1978
	}
1979
	printk("AP400: Bus integrity OK!\n");
1980
1981
	wc->fpgaver = wc->hw_regs->fpga_ver;
1982
	wc->numspans = wc->hw_regs->span_num;
1983
	wc->hwid = ((*(wc->membase+AP_HWCONFIG_REG))&AP_HWID_MASK)>>4;
1984
1985
	if ((wc->hwid == AP_HWID_1E1_RJ && wc->numspans != 1) ||
1986
			(wc->hwid == AP_HWID_2E1_RJ && wc->numspans != 2) ||
1987
			(wc->hwid == AP_HWID_4E1_RJ && wc->numspans != 4)) {
1988
		printk("AP400: Incompatible Hardware ID(0x%02x)! Aborting...\n", wc->hwid);
1989
		return -EIO;
1990
	}
1991
1992
	if (wc->hw_regs->card_id == AP4XX_CARD_ID)
1993
		switch (wc->numspans) {
1994
		case 1:
1995
			wc->dt = (struct devtype *) &ap401;
1996
			break;
1997
		case 2:
1998
			wc->dt = (struct devtype *) &ap402;
1999
			break;
2000
		case 4:
2001
			wc->dt = (struct devtype *) &ap404;
2002
			break;
2003
		default:
2004
			printk("AP400: Unsupported spans number(%d)! Aborting...\n",
2005
					wc->numspans);
2006
			return -EPERM;
2007
		}
2008
	else
2009
		switch (wc->numspans) {
2010
		case 1:
2011
			wc->dt = (struct devtype *) &ape401;
2012
			break;
2013
		case 2:
2014
			wc->dt = (struct devtype *) &ape402;
2015
			break;
2016
		case 4:
2017
			wc->dt = (struct devtype *) &ape404;
2018
			break;
2019
		default:
2020
			printk("APE400: Unsupported spans number(%d)! Aborting...\n",
2021
					wc->numspans);
2022
			return -EPERM;
2023
	}
2024
2025
	wc->variety = wc->dt->desc;
2026
	printk("Found a %s (firmware version %d.%d) at base address %08lx, remapped to %p\n",
2027
			wc->variety, wc->fpgaver >> 8, wc->fpgaver & 0xFF,
2028
			wc->memaddr, wc->membase);
2029
2030
	return 0;
2031
}
2032
2033
static void __devexit ap4_remove_one(struct pci_dev *pdev);
2034
2035
static int __devinit ap4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2036
{
2037
	int res;
2038
	struct ap4 *wc;
2039
	int x,f;
2040
	int basesize;
2041
	static int initd_ifaces=0;
2042
	// Initialize pointer struct
2043
	if(!initd_ifaces){
2044
		memset((void *)cards,0,(sizeof(struct ap4 *))*MAX_AP4_CARDS);
2045
		initd_ifaces=1;
2046
	}
2047
2048
	if ((res = pci_enable_device(pdev)) != 0) {
2049
		goto out;
2050
	}
2051
	// Allocate card struct
2052
	wc = kmalloc(sizeof(struct ap4), GFP_KERNEL);
2053
	if (wc == NULL) {
2054
		res = -ENOMEM;
2055
		goto out;
2056
	}
2057
2058
	memset(wc, 0x0, sizeof(struct ap4));
2059
	spin_lock_init(&wc->reglock);
2060
2061
	basesize = DAHDI_MAX_CHUNKSIZE * 32 * 2 * 4;
2062
2063
	// Request PCI regions
2064
	if ((res = pci_request_regions(pdev, "ap400")) != 0) {
2065
		printk("AP400: Unable to request regions!\n");
2066
		goto out;
2067
	}
2068
2069
	// Remap PCI address
2070
	wc->memaddr = pci_resource_start(pdev, 2);
2071
	wc->memlen = pci_resource_len(pdev, 2);
2072
	wc->membase = ioremap_nocache(wc->memaddr, wc->memlen);
2073
	if(wc->membase == NULL) {
2074
		printk("AP400: ioremap failed!\n");
2075
		res = -EIO;
2076
		goto out;
2077
	}
2078
	wc->hw_regs = (struct ap4_regs *) wc->membase;
2079
2080
	// Detect Card model
2081
	if ((res = ap4_card_detect(wc)) != 0)
2082
		goto out;
2083
2084
	ap4xx_liu_reset(wc);
2085
2086
	// This rids of the Double missed interrupt message after loading
2087
	wc->last0 = 1;
2088
2089
	wc->dev = pdev;
2090
2091
	// 32 channels, Double-buffer, Read/Write, 4 spans
2092
	wc->writechunk = kmalloc(basesize * 2, GFP_KERNEL);
2093
	if (!wc->writechunk) {
2094
		printk("%s: Unable to allocate memory!\n", wc->variety);
2095
		res = -ENOMEM;
2096
		goto out;
2097
	}
2098
2099
	// Read is after the whole write piece (in words)
2100
	wc->readchunk = wc->writechunk + basesize / 4;
2101
2102
2103
	// Initialize Write/Buffers to all blank data
2104
	memset((void *) wc->writechunk, 0x00, basesize);
2105
	memset((void *) wc->readchunk, 0xff, basesize);
2106
2107
	/* Keep track of which device we are */
2108
	pci_set_drvdata(pdev, wc);
2109
2110
	/* inicializa contador de interrupcao */
2111
	wc->intcount = 0;
2112
2113
	for(x = 0; x < MAX_AP4_CARDS; x++) {
2114
		if (!cards[x]) break;
2115
	}
2116
2117
	if (x >= MAX_AP4_CARDS) {
2118
		printk("No cards[] slot available!!\n");
2119
		res = -ENOMEM;
2120
		goto out;
2121
	}
2122
2123
	wc->num = x;
2124
	cards[x] = wc;
2125
2126
	/* Allocate pieces we need here, consider 31 channels for E1*/
2127
	for (x=0;x<4;x++) {
2128
		wc->tspans[x] = kmalloc(sizeof(struct ap4_span), GFP_KERNEL);
2129
		if (wc->tspans[x]) {
2130
			memset(wc->tspans[x], 0, sizeof(struct ap4_span));
2131
			wc->tspans[x]->spantype = TYPE_E1;
2132
		} else {
2133
			res = -ENOMEM;
2134
			goto out;
2135
		}
2136
		for (f = 0; f < 31; f++) {
2137
			if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
2138
				res = -ENOMEM;
2139
				goto out;
2140
			}
2141
			memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
2142
		}
2143
#ifdef ENABLE_WORKQUEUES
2144
		INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
2145
#endif
2146
		wc->tspans[x]->spanflags |= wc->dt->flags;
2147
	}
2148
2149
	if (request_irq(pdev->irq, ap4_interrupt, IRQF_DISABLED | IRQF_SHARED, "ap400", wc))
2150
	{
2151
		printk("%s: Unable to request IRQ %d\n", wc->variety, pdev->irq);
2152
		res = -EIO;
2153
		goto out;
2154
	}
2155
2156
	wc->ddev = dahdi_create_device();
2157
	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
2158
			wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
2159
	if (!wc->ddev->location)
2160
		return -ENOMEM; /* FIXME: proper error handling */
2161
	wc->ddev->manufacturer = "Aligera";
2162
	wc->ddev->devicetype = wc->variety;
2163
	wc->ddev->irqmisses = 0;
2164
	init_spans(wc);
2165
2166
	/* Launch cards as appropriate */
2167
	x = 0;
2168
	for(;;) {
2169
		/* Find a card to activate */
2170
		f = 0;
2171
		for (x=0;cards[x];x++) {
2172
			if (cards[x]->order <= highestorder) {
2173
				ap4_launch(cards[x]);
2174
				if (cards[x]->order == highestorder)
2175
					f = 1;
2176
			}
2177
		}
2178
		/* If we found at least one, increment the highest order and search again, otherwise stop */
2179
		if (f)
2180
			highestorder++;
2181
		else
2182
			break;
2183
	}
2184
2185
#ifdef APEC_SUPPORT
2186
	if (wc->fpgaver >= 0x0400)
2187
		wc->apec_enable = 1;
2188
#endif
2189
2190
#ifdef TIMER_DEBUG
2191
	// dispara timer de debug
2192
	init_timer(&ap4xx_opt_timer);
2193
	ap4xx_opt_timer.function = ap4xx_opt_timeout;
2194
	ap4xx_opt_timer.data = (unsigned long) pdev;
2195
	ap4xx_opt_timer.expires = jiffies + 100;
2196
	add_timer(&ap4xx_opt_timer);
2197
#endif
2198
2199
	/* Initialize HDLC_CARD */
2200
#ifdef AP400_HDLC
2201
	u8 __iomem *base_addr[3];
2202
	unsigned int bar_size[3];
2203
	int i;
2204
	base_addr[2] = (void *) wc->membase;
2205
	bar_size[2] = wc->memlen;
2206
	for (i = 0; i < 2; i++) {
2207
		bar_size[i] = (u32) pci_resource_len(pdev, i);
2208
		base_addr[i] = ioremap_nocache(pci_resource_start(pdev, i),
2209
								bar_size[i]);
2210
		if (base_addr[i] == NULL) {
2211
			printk(KERN_ERR "Memory map failed\n");
2212
			res = -ENODEV;
2213
			goto out;
2214
		}
2215
	}
2216
	ap400_card_init(&wc->hdlc_card, base_addr, bar_size);
2217
	ap400_intr_enable(wc->hdlc_card);
2218
#endif
2219
2220
	res = 0;
2221
out:
2222
	if (res != 0) {
2223
		ap4_remove_one(pdev);
2224
	}
2225
	return res;
2226
}
2227
2228
static void __devexit ap4_remove_one(struct pci_dev *pdev)
2229
{
2230
	struct ap4 *wc = pci_get_drvdata(pdev);
2231
	int x;
2232
2233
	if (wc) {
2234
		ap_debugk("desabilita interrupcao!\n");
2235
		// desabilita interrupcao
2236
		*(wc->membase + AP_INT_CONTROL_REG) &= ~AP_INT_CTL_ENABLE;
2237
2238
#ifdef APEC_SUPPORT
2239
		// Stop echo cancellation module
2240
		ap4_apec_release(wc);
2241
#endif
2242
		/* Unregister spans */
2243
		dahdi_unregister_device(wc->ddev);
2244
		kfree(wc->ddev->location);
2245
		dahdi_free_device(wc->ddev);
2246
#ifdef ENABLE_WORKQUEUES
2247
		if (wc->workq) {
2248
			flush_workqueue(wc->workq);
2249
			destroy_workqueue(wc->workq);
2250
		}
2251
#endif
2252
2253
#ifdef TIMER_DEBUG
2254
		del_timer(&ap4xx_opt_timer);
2255
#endif
2256
2257
		wc->hw_regs = NULL;
2258
		if(wc->membase)
2259
			iounmap((void *)wc->membase);
2260
2261
		/* Immediately free resources */
2262
		kfree((void *) wc->writechunk);
2263
2264
#ifdef AP400_HDLC
2265
		/* Remove HDLC Card */
2266
		ap400_card_remove(wc->hdlc_card);
2267
		if (wc->hdlc_card->cfg_base_addr)
2268
			iounmap(wc->hdlc_card->cfg_base_addr);
2269
		if (wc->hdlc_card->buf_base_addr)
2270
			iounmap(wc->hdlc_card->buf_base_addr);
2271
		kfree(wc->hdlc_card);
2272
#endif
2273
		free_irq(pdev->irq, wc);
2274
2275
		cards[wc->num] = NULL;
2276
		for (x=0;x<wc->numspans;x++) {
2277
			if (wc->tspans[x])
2278
				kfree(wc->tspans[x]);
2279
		}
2280
		kfree(wc);
2281
	}
2282
	pci_release_regions(pdev);
2283
	pci_disable_device(pdev);
2284
	pci_set_drvdata(pdev, NULL);
2285
	printk(KERN_INFO "AP400 driver removed\n");
2286
}
2287
2288
2289
static struct pci_device_id ap4_pci_tbl[] __devinitdata =
2290
{
2291
	{ PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_AP4XX), },
2292
	{ 0, }
2293
};
2294
2295
2296
static struct pci_driver ap4_driver = {
2297
	.name = 	"Unified ap4xx driver",
2298
	.probe = 	ap4_init_one,
2299
#ifdef LINUX26
2300
	.remove =	__devexit_p(ap4_remove_one),
2301
#else
2302
	.remove =	ap4_remove_one,
2303
#endif
2304
	.id_table = ap4_pci_tbl,
2305
};
2306
2307
static int __init ap4_init(void)
2308
{
2309
	int res;
2310
	printk("Unified AP4XX PCI Card Driver\n");
2311
	res = pci_register_driver(&ap4_driver);
2312
	if (res) {
2313
		return -ENODEV;
2314
	}
2315
	return 0;
2316
}
2317
2318
static void __exit ap4_cleanup(void)
2319
{
2320
	printk("Unified AP4XX PCI Card Driver Cleanup\n");
2321
	pci_unregister_driver(&ap4_driver);
2322
}
2323
2324
2325
MODULE_AUTHOR("Aligera (aligera@aligera.com.br)");
2326
MODULE_DESCRIPTION("Unified AP4XX PCI Card Driver");
2327
#ifdef MODULE_LICENSE
2328
MODULE_LICENSE("GPL");
2329
#endif
2330
module_param(debug, int, 0600);
2331
module_param(loopback, int, 0600);
2332
module_param(noburst, int, 0600);
2333
module_param(debugslips, int, 0600);
2334
module_param(polling, int, 0600);
2335
module_param(timingcable, int, 0600);
2336
module_param(t1e1override, int, 0600);
2337
module_param(alarmdebounce, int, 0600);
2338
module_param(j1mode, int, 0600);
2339
2340
MODULE_DEVICE_TABLE(pci, ap4_pci_tbl);
2341
2342
module_init(ap4_init);
2343
module_exit(ap4_cleanup);
(-)dahdi-linux-3.1.0.original/drivers/dahdi/ap400/apec.c (+390 lines)
Line 0 Link Here
1
/*
2
 * AP400 Echo Cancelation Hardware support
3
 *
4
 * Written by Wagner Gegler <aligera@aligera.com.br>
5
 *
6
 * Based on previous work written by Mark Spencer <markster@digium.com>
7
 *
8
 * Copyright (C) 2005-2006 Digium, Inc.
9
 *
10
 * Mark Spencer <markster@digium.com>
11
 *
12
 * All Rights Reserved
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#include <linux/slab.h>
31
#include <linux/vmalloc.h>
32
#include <linux/string.h>
33
#include <linux/time.h>
34
#include <linux/version.h>
35
#include <linux/delay.h>
36
37
#include "apec.h"
38
#include "oct6100api/oct6100_api.h"
39
40
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
41
#include <linux/config.h>
42
#else
43
#include <linux/autoconf.h>
44
#endif
45
46
/* API for Octasic access */
47
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
48
{
49
	/* Why couldn't they just take a timeval like everyone else? */
50
	struct timeval tv;
51
	unsigned long long total_usecs;
52
	unsigned int mask = ~0;
53
54
	do_gettimeofday(&tv);
55
	total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
56
				  (((unsigned long long)(tv.tv_usec)));
57
	f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
58
	f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
59
	return cOCT6100_ERR_OK;
60
}
61
62
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
63
{
64
	memset(f_pAddress, f_ulPattern, f_ulLength);
65
	return cOCT6100_ERR_OK;
66
}
67
68
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
69
{
70
	memcpy(f_pDestination, f_pSource, f_ulLength);
71
	return cOCT6100_ERR_OK;
72
}
73
74
UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
75
{
76
	return cOCT6100_ERR_OK;
77
}
78
79
UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
80
{
81
#ifdef OCTASIC_DEBUG
82
	printk("I should never be called! (destroy serialize object)\n");
83
#endif
84
	return cOCT6100_ERR_OK;
85
}
86
87
UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
88
{
89
	/* Not needed */
90
	return cOCT6100_ERR_OK;
91
}
92
93
UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
94
{
95
	/* Not needed */
96
	return cOCT6100_ERR_OK;
97
}
98
99
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
100
{
101
	oct_write(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
102
	return cOCT6100_ERR_OK;
103
}
104
105
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
106
{
107
	unsigned int x;
108
	for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
109
		oct_write(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
110
	}
111
	return cOCT6100_ERR_OK;
112
}
113
114
UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
115
{
116
	unsigned int x;
117
	for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
118
		oct_write(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
119
	}
120
	return cOCT6100_ERR_OK;
121
}
122
123
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
124
{
125
	*(f_pReadParams->pusReadData) = oct_read(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
126
	return cOCT6100_ERR_OK;
127
}
128
129
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
130
{
131
	unsigned int x;
132
	for (x=0;x<f_pBurstParams->ulReadLength;x++) {
133
		f_pBurstParams->pusReadData[x] = oct_read(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
134
	}
135
	return cOCT6100_ERR_OK;
136
}
137
138
#if 0
139
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
140
#else
141
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
142
#endif
143
144
struct apec_s {
145
	tPOCT6100_INSTANCE_API pApiInstance;
146
	UINT32 aulEchoChanHndl[128];
147
	int chanflags[128];
148
	int ecmode[128];
149
	int numchans;
150
};
151
152
#define FLAG_DTMF	 (1 << 0)
153
#define FLAG_MUTE	 (1 << 1)
154
#define FLAG_ECHO	 (1 << 2)
155
156
static void apec_setecmode(struct apec_s *apec, int channel, int mode)
157
{
158
	tOCT6100_CHANNEL_MODIFY *modify;
159
	UINT32 ulResult;
160
161
	if (apec->ecmode[channel] == mode)
162
		return;
163
	modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
164
	if (!modify) {
165
		printk("APEC: Unable to allocate memory for setec!\n");
166
		return;
167
	}
168
	Oct6100ChannelModifyDef(modify);
169
	modify->ulEchoOperationMode = mode;
170
	modify->ulChannelHndl = apec->aulEchoChanHndl[channel];
171
	ulResult = Oct6100ChannelModify(apec->pApiInstance, modify);
172
	if (ulResult != GENERIC_OK) {
173
		printk("Failed to apply echo can changes on channel %d!\n", channel);
174
	} else {
175
#ifdef OCTASIC_DEBUG
176
		printk("Echo can on channel %d set to %d\n", channel, mode);
177
#endif
178
		apec->ecmode[channel] = mode;
179
	}
180
	kfree(modify);
181
}
182
183
void apec_setec(struct apec_s *apec, int channel, int eclen)
184
{
185
	if (eclen) {
186
		apec->chanflags[channel] |= FLAG_ECHO;
187
		apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
188
		apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
189
	} else {
190
		apec->chanflags[channel] &= ~FLAG_ECHO;
191
		if (apec->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
192
			apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
193
			apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
194
		} else
195
			apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
196
	}
197
	printk("APEC: Setting EC on channel %d to %d\n", channel, eclen);
198
}
199
200
int apec_checkirq(struct apec_s *apec)
201
{
202
	tOCT6100_INTERRUPT_FLAGS InterruptFlags;
203
204
	Oct6100InterruptServiceRoutineDef(&InterruptFlags);
205
	Oct6100InterruptServiceRoutine(apec->pApiInstance, &InterruptFlags);
206
207
	return InterruptFlags.fToneEventsPending ? 1 : 0;
208
}
209
210
unsigned int apec_capacity_get(void *wc)
211
{
212
	UINT32 ulResult;
213
214
	tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
215
216
	Oct6100ApiGetCapacityPinsDef(&CapacityPins);
217
	CapacityPins.pProcessContext = wc;
218
	CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
219
	CapacityPins.fEnableMemClkOut = TRUE;
220
	CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
221
222
	ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
223
	if (ulResult != cOCT6100_ERR_OK) {
224
		printk("Failed to get chip capacity, code %08x!\n", ulResult);
225
		return 0;
226
	}
227
	return CapacityPins.ulCapacityValue;
228
}
229
230
struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
231
{
232
	tOCT6100_CHIP_OPEN *ChipOpen;
233
	tOCT6100_GET_INSTANCE_SIZE InstanceSize;
234
	tOCT6100_CHANNEL_OPEN *ChannelOpen;
235
	UINT32 ulResult;
236
	struct apec_s *apec;
237
	int x, law;
238
#ifdef CONFIG_4KSTACKS
239
	unsigned long flags;
240
#endif
241
242
	if (!(apec = kmalloc(sizeof(struct apec_s), GFP_KERNEL)))
243
		return NULL;
244
245
	memset(apec, 0, sizeof(struct apec_s));
246
247
	if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
248
		kfree(apec);
249
		return NULL;
250
	}
251
252
	memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
253
254
	if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
255
		kfree(apec);
256
		kfree(ChipOpen);
257
		return NULL;
258
	}
259
260
	memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
261
262
	for (x=0;x<128;x++)
263
		apec->ecmode[x] = -1;
264
265
	apec->numchans = numspans * 32;
266
	printk("APEC: echo cancellation for %d channels\n", apec->numchans);
267
268
	Oct6100ChipOpenDef(ChipOpen);
269
270
	/* Setup Chip Open Parameters */
271
	ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
272
	Oct6100GetInstanceSizeDef(&InstanceSize);
273
274
	ChipOpen->pProcessContext = wc;
275
276
	ChipOpen->pbyImageFile = firmware->data;
277
	ChipOpen->ulImageSize = firmware->size;
278
279
	ChipOpen->fEnableMemClkOut = TRUE;
280
	ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
281
	ChipOpen->ulMaxChannels = apec->numchans;
282
	ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
283
	ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
284
	ChipOpen->ulNumMemoryChips = 1;
285
	ChipOpen->ulMaxTdmStreams = 4;
286
	ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
287
	ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
288
#if 0
289
	ChipOpen->fEnableAcousticEcho = TRUE;
290
#endif
291
292
	ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
293
	if (ulResult != cOCT6100_ERR_OK) {
294
		printk("Failed to get instance size, code %08x!\n", ulResult);
295
		kfree(apec);
296
		return NULL;
297
	}
298
299
300
	apec->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
301
	if (!apec->pApiInstance) {
302
		printk("Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
303
		kfree(apec);
304
		kfree(ChipOpen);
305
		kfree(ChannelOpen);
306
		return NULL;
307
	}
308
309
	/* I don't know what to curse more in this comment, the problems caused by
310
	 * the 4K kernel stack limit change or the octasic API for being so darn
311
	 * stack unfriendly.  Stupid, stupid, stupid.  So we disable IRQs so we
312
	 * don't run the risk of overflowing the stack while we initialize the
313
	 * octasic. */
314
#ifdef CONFIG_4KSTACKS
315
	local_irq_save(flags);
316
#endif
317
	ulResult = Oct6100ChipOpen(apec->pApiInstance, ChipOpen);
318
	if (ulResult != cOCT6100_ERR_OK) {
319
		printk("Failed to open chip, code %08x!\n", ulResult);
320
#ifdef CONFIG_4KSTACKS
321
		local_irq_restore(flags);
322
#endif
323
		kfree(apec);
324
		kfree(ChipOpen);
325
		kfree(ChannelOpen);
326
		return NULL;
327
	}
328
	for (x=0; x < 128; x++) {
329
		/* execute this loop always on 4 span cards but
330
		*  on 2 span cards only execute for the channels related to our spans */
331
		if ((x & 0x3) < numspans) {
332
			/* span timeslots are interleaved 12341234...
333
		 	*  therefore, the lower 2 bits tell us which span this
334
			*  timeslot/channel
335
		 	*/
336
			if (isalaw[x & 0x03])
337
				law = cOCT6100_PCM_A_LAW;
338
			else
339
				law = cOCT6100_PCM_U_LAW;
340
			Oct6100ChannelOpenDef(ChannelOpen);
341
			ChannelOpen->pulChannelHndl = &apec->aulEchoChanHndl[x];
342
			ChannelOpen->ulUserChanId = x;
343
			ChannelOpen->TdmConfig.ulRinPcmLaw = law;
344
			ChannelOpen->TdmConfig.ulRinStream = 0;
345
			ChannelOpen->TdmConfig.ulRinTimeslot = x;
346
			ChannelOpen->TdmConfig.ulSinPcmLaw = law;
347
			ChannelOpen->TdmConfig.ulSinStream = 1;
348
			ChannelOpen->TdmConfig.ulSinTimeslot = x;
349
			ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
350
			ChannelOpen->TdmConfig.ulSoutStream = 2;
351
			ChannelOpen->TdmConfig.ulSoutTimeslot = x;
352
			ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
353
			ChannelOpen->TdmConfig.ulRoutStream = 3;
354
			ChannelOpen->TdmConfig.ulRoutTimeslot = x;
355
			ChannelOpen->VqeConfig.fEnableNlp = TRUE;
356
			ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
357
			ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
358
359
			ChannelOpen->fEnableToneDisabler = TRUE;
360
			ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
361
362
			ulResult = Oct6100ChannelOpen(apec->pApiInstance, ChannelOpen);
363
			if (ulResult != GENERIC_OK) {
364
				printk("Failed to open channel %d!\n", x);
365
			}
366
		}
367
	}
368
369
#ifdef CONFIG_4KSTACKS
370
	local_irq_restore(flags);
371
#endif
372
	kfree(ChipOpen);
373
	kfree(ChannelOpen);
374
	return apec;
375
}
376
377
void apec_release(struct apec_s *apec)
378
{
379
	UINT32 ulResult;
380
	tOCT6100_CHIP_CLOSE ChipClose;
381
382
	Oct6100ChipCloseDef(&ChipClose);
383
	ulResult = Oct6100ChipClose(apec->pApiInstance, &ChipClose);
384
	if (ulResult != cOCT6100_ERR_OK) {
385
		printk("Failed to close chip, code %08x!\n", ulResult);
386
	}
387
	vfree(apec->pApiInstance);
388
	kfree(apec);
389
	printk(KERN_INFO "APEC: Releasing...\n");
390
}
(-)dahdi-linux-3.1.0.original/drivers/dahdi/ap400/apec.h (+48 lines)
Line 0 Link Here
1
/*
2
 * AP400 Echo Cancelation Hardware support
3
 *
4
 * Written by Wagner Gegler <aligera@aligera.com.br>
5
 * 
6
 * Based on previous work written by Mark Spencer <markster@digium.com>
7
 * 
8
 * Copyright (C) 2005-2006 Digium, Inc.
9
 *
10
 * Mark Spencer <markster@digium.com>
11
 *
12
 * All Rights Reserved
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#ifndef _APEC_H_
31
#define _APEC_H_
32
33
#include <linux/firmware.h>
34
35
struct apec_s;
36
37
/* From AP400 */
38
unsigned int oct_read(void *card, unsigned int addr);
39
void oct_write(void *card, unsigned int addr, unsigned int data);
40
41
/* From APEC */
42
struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
43
unsigned int apec_capacity_get(void *wc);
44
void apec_setec(struct apec_s *instance, int channel, int eclen);
45
int apec_checkirq(struct apec_s *apec);
46
void apec_release(struct apec_s *instance);
47
48
#endif /*_APEC_H_*/
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxa1200/Kbuild (+19 lines)
Line 0 Link Here
1
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200) += opvxa1200.o
2
3
EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
4
5
opvxa1200-objs := base.o
6
7
DAHDI_KERNEL_H_NAME:=kernel.h
8
DAHDI_KERNEL_H_PATH:=$(DAHDI_INCLUDE)/dahdi/$(DAHDI_KERNEL_H_NAME)
9
ifneq ($(DAHDI_KERNEL_H_PATH),)
10
        DAHDI_SPAN_MODULE:=$(shell if grep -C 5 "struct dahdi_span {" $(DAHDI_KERNEL_H_PATH) | grep -q "struct module \*owner"; then echo "yes"; else echo "no"; fi)
11
        DAHDI_SPAN_OPS:=$(shell if grep -q "struct dahdi_span_ops {" $(DAHDI_KERNEL_H_PATH); then echo "yes"; else echo "no"; fi)
12
        ifeq ($(DAHDI_SPAN_MODULE),yes)
13
                EXTRA_CFLAGS+=-DDAHDI_SPAN_MODULE
14
        else
15
                ifeq ($(DAHDI_SPAN_OPS),yes)
16
                        EXTRA_CFLAGS+=-DDAHDI_SPAN_OPS
17
                endif
18
        endif
19
endif
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxa1200/Makefile (+8 lines)
Line 0 Link Here
1
ifdef KBUILD_EXTMOD
2
# We only get here on kernels 2.6.0-2.6.9 .
3
# For newer kernels, Kbuild will be included directly by the kernel
4
# build system.
5
include $(src)/Kbuild
6
7
else
8
endif
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxa1200/base.c (+3070 lines)
Line 0 Link Here
1
/*
2
 * OpenVox A1200P FXS/FXO Interface Driver for DAHDI Telephony interface
3
 *
4
 * Written by MiaoLin<miaolin@openvox.cn>
5
 *
6
 * Copyright (C) 2005-2010 OpenVox Communication Co. Ltd,
7
 *
8
 * All rights reserved.
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 * 
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 * 
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
23
 *
24
 */
25
26
/* Rev histroy
27
 *
28
 * Rev 0.10 initial version	
29
 * Rev 0.11 
30
 * 	fixed the led light on/off bug.
31
 * 	modify some wctdm print to opvxa1200
32
 * 	support firmware version 1.2, faster i/o operation, and better LED control.
33
 * 
34
 * Rev 0.12 patched to support new pci id 0x8519
35
 * Rev 0.13 patched to remove the warning during compile under kernel 2.6.22 
36
 * Rev 0.14 patched to remove the bug for ZAP_IRQ_SHARED , 3/9/2007 
37
 * Rev 0.15 patched to support new pci ID 0X9532 by james.zhu, 23/10/2007
38
 * Rev 0.16 support new pci id 0x9559 by Miao Lin 21/3/2008
39
 * Rev 0.17 
40
 *	patched a few bugs, 
41
 *	add hwgain support.
42
 *	fixed A800P version check
43
 * Rev 1.4.9.2 
44
 *		Only generate 8 channels for A800P
45
 * 		Version number synced to zaptel distribution.
46
 * Rev 1.4.9.2.a
47
 *		Fixed freeregion.
48
 * 		
49
 * Rev 1.4.9.2.b
50
 *    Add cid before first ring support.
51
 *    New Paremeters:
52
 *          	cidbeforering : set to 1 will cause the card enable cidbeforering function. default 0
53
 * 		cidbuflen : length of cid buffer, in msec, default 3000 msec.
54
 *              cidtimeout : time out of a ring, default 6000msec
55
 *   	User must set cidstart=polarity in zapata.conf to use with this feature
56
 * 		cidsignalling = signalling format send before 1st ring. most likely dtmf.
57
 * 
58
 * Rev 1.4.9.2.c
59
 * 	add driver parameter cidtimeout.
60
 * 
61
 * Rev 1.4.9.2.d 
62
 *  	add debug stuff to test fxs power alarm
63
 *  
64
 * Rev 1.4.11
65
 *  	Support enhanced full scale tx/rx for FXO required by europe standard (Register 30, acim) (module parm fxofullscale)
66
 *  
67
 * Rev 1.4.12 2008/10/17
68
 *      Fixed bug cause FXS module report fake power alarm.
69
 *      Power alarm debug stuff removed.
70
 * 
71
 * Rev 2.0 DAHDI 2008/10/17
72
 *
73
 * Rev 2.0.1 add new pci id 0x9599
74
 * Re 2.0.2 12/01/2009  
75
       add fixedtimepolarity: set time(ms) when send polarity after 1st ring happen. 
76
 *				Sometimes the dtmf cid is sent just after first ring off, and the system do not have 
77
 *				enough time to start detect 1st dtmf.
78
 *				0 means send polarity at the end of 1st ring.
79
 *				x means send ploarity after x ms of 1st ring begin.
80
 * 
81
 * Rev 2.0.3 12/01/2009 
82
 *        Add touch_softlockup_watchdog() in wctdm_hardware_init, to avoid cpu softlockup system message for FXS.
83
 *
84
 *
85
 * Rev 1.4.12.4  17/04/2009 James.zhu
86
 *       Changed wctdm_voicedaa_check_hook() to detect FXO battery and solved the problem with dial(dahdi/go/XXXXXXXXXX)
87
 *       add alarm detection for FXO
88
 *
89
 * Rev 1.4.12.5 01/10/2009 james.zhu
90
 *       Add jiffies for 5 second in wctdm_hardware_init
91
 *
92
 *
93
 */ 
94
95
#include <linux/kernel.h>
96
#include <linux/errno.h>
97
#include <linux/module.h>
98
#include <linux/init.h>
99
#include <linux/errno.h>
100
#include <linux/pci.h>
101
#include <linux/interrupt.h>
102
#include <linux/moduleparam.h>
103
#include <linux/version.h>
104
#include <asm/io.h>
105
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
106
#include <linux/nmi.h>
107
#else
108
#include <linux/sched.h>
109
#endif
110
#include "proslic.h"
111
   
112
/* MiaoLin debug start */
113
#include <linux/string.h>
114
#include <asm/uaccess.h> 	/* get_fs(), set_fs(), KERNEL_DS */
115
#include <linux/file.h> 	/* fput() */
116
/* MiaoLin debug end */
117
  
118
119
/*
120
 *  Define for audio vs. register based ring detection
121
 *  
122
 */
123
/* #define AUDIO_RINGCHECK  */
124
125
/*
126
  Experimental max loop current limit for the proslic
127
  Loop current limit is from 20 mA to 41 mA in steps of 3
128
  (according to datasheet)
129
  So set the value below to:
130
  0x00 : 20mA (default)
131
  0x01 : 23mA
132
  0x02 : 26mA
133
  0x03 : 29mA
134
  0x04 : 32mA
135
  0x05 : 35mA
136
  0x06 : 37mA
137
  0x07 : 41mA
138
*/
139
static int loopcurrent = 20;
140
141
static int reversepolarity = 0;
142
143
static alpha  indirect_regs[] =
144
{
145
{0,255,"DTMF_ROW_0_PEAK",0x55C2},
146
{1,255,"DTMF_ROW_1_PEAK",0x51E6},
147
{2,255,"DTMF_ROW2_PEAK",0x4B85},
148
{3,255,"DTMF_ROW3_PEAK",0x4937},
149
{4,255,"DTMF_COL1_PEAK",0x3333},
150
{5,255,"DTMF_FWD_TWIST",0x0202},
151
{6,255,"DTMF_RVS_TWIST",0x0202},
152
{7,255,"DTMF_ROW_RATIO_TRES",0x0198},
153
{8,255,"DTMF_COL_RATIO_TRES",0x0198},
154
{9,255,"DTMF_ROW_2ND_ARM",0x0611},
155
{10,255,"DTMF_COL_2ND_ARM",0x0202},
156
{11,255,"DTMF_PWR_MIN_TRES",0x00E5},
157
{12,255,"DTMF_OT_LIM_TRES",0x0A1C},
158
{13,0,"OSC1_COEF",0x7B30},
159
{14,1,"OSC1X",0x0063},
160
{15,2,"OSC1Y",0x0000},
161
{16,3,"OSC2_COEF",0x7870},
162
{17,4,"OSC2X",0x007D},
163
{18,5,"OSC2Y",0x0000},
164
{19,6,"RING_V_OFF",0x0000},
165
{20,7,"RING_OSC",0x7EF0},
166
{21,8,"RING_X",0x0160},
167
{22,9,"RING_Y",0x0000},
168
{23,255,"PULSE_ENVEL",0x2000},
169
{24,255,"PULSE_X",0x2000},
170
{25,255,"PULSE_Y",0x0000},
171
//{26,13,"RECV_DIGITAL_GAIN",0x4000},	// playback volume set lower
172
{26,13,"RECV_DIGITAL_GAIN",0x2000},	// playback volume set lower
173
{27,14,"XMIT_DIGITAL_GAIN",0x4000},
174
//{27,14,"XMIT_DIGITAL_GAIN",0x2000},
175
{28,15,"LOOP_CLOSE_TRES",0x1000},
176
{29,16,"RING_TRIP_TRES",0x3600},
177
{30,17,"COMMON_MIN_TRES",0x1000},
178
{31,18,"COMMON_MAX_TRES",0x0200},
179
{32,19,"PWR_ALARM_Q1Q2",0x07C0},
180
{33,20,"PWR_ALARM_Q3Q4",0x2600},
181
{34,21,"PWR_ALARM_Q5Q6",0x1B80},
182
{35,22,"LOOP_CLOSURE_FILTER",0x8000},
183
{36,23,"RING_TRIP_FILTER",0x0320},
184
{37,24,"TERM_LP_POLE_Q1Q2",0x008C},
185
{38,25,"TERM_LP_POLE_Q3Q4",0x0100},
186
{39,26,"TERM_LP_POLE_Q5Q6",0x0010},
187
{40,27,"CM_BIAS_RINGING",0x0C00},
188
{41,64,"DCDC_MIN_V",0x0C00},
189
{42,255,"DCDC_XTRA",0x1000},
190
{43,66,"LOOP_CLOSE_TRES_LOW",0x1000},
191
};
192
193
194
#include <dahdi/kernel.h>
195
#include <dahdi/wctdm_user.h>
196
197
#include "fxo_modes.h"
198
199
#define NUM_FXO_REGS 60
200
201
#define WC_MAX_IFACES 128
202
203
#define WC_OFFSET	4	/* Offset between transmit and receive, in bytes. */
204
#define WC_SYNCFLAG	0xca1ef1ac
205
206
#define WC_CNTL    	0x00
207
#define WC_OPER		0x01
208
#define WC_AUXC    	0x02
209
#define WC_AUXD    	0x03
210
#define WC_MASK0   	0x04
211
#define WC_MASK1   	0x05
212
#define WC_INTSTAT 	0x06
213
#define WC_AUXR		0x07
214
215
#define WC_DMAWS	0x08
216
#define WC_DMAWI	0x0c
217
#define WC_DMAWE	0x10
218
#define WC_DMARS	0x18
219
#define WC_DMARI	0x1c
220
#define WC_DMARE	0x20
221
222
#define WC_AUXFUNC	0x2b
223
#define WC_SERCTL	0x2d
224
#define WC_FSCDELAY	0x2f
225
226
#define WC_REGBASE	0xc0
227
228
#define WC_VER		0x0
229
#define WC_CS		0x1
230
#define WC_SPICTRL	0x2
231
#define WC_SPIDATA	0x3
232
233
#define BIT_SPI_BYHW 	(1 << 0)
234
#define BIT_SPI_BUSY    (1 << 1)	// 0=can read/write spi, 1=spi working.
235
#define BIT_SPI_START	(1 << 2)
236
237
238
#define BIT_LED_CLK     (1 << 0)	// MiaoLin add to control the led. 
239
#define BIT_LED_DATA    (1 << 1)	// MiaoLin add to control the led.
240
241
#define BIT_CS		(1 << 2)
242
#define BIT_SCLK	(1 << 3)
243
#define BIT_SDI		(1 << 4)
244
#define BIT_SDO		(1 << 5)
245
246
#define FLAG_EMPTY	0
247
#define FLAG_WRITE	1
248
#define FLAG_READ	2
249
#define DEFAULT_RING_DEBOUNCE		64		/* Ringer Debounce (64 ms) */
250
#define POLARITY_DEBOUNCE 	64  	/* Polarity debounce (64 ms) */
251
#define OHT_TIMER		6000	/* How long after RING to retain OHT */
252
253
#define FLAG_3215	(1 << 0)
254
#define FLAG_A800	(1 << 7)
255
256
#define MAX_NUM_CARDS 12
257
#define NUM_CARDS 12
258
#define NUM_FLAG  4	/* number of flag channels. */
259
260
261
enum cid_hook_state {
262
	CID_STATE_IDLE = 0,
263
	CID_STATE_RING_ON,
264
	CID_STATE_RING_OFF,
265
	CID_STATE_WAIT_RING_FINISH
266
};
267
268
/* if you want to record the last 8 sec voice before the driver unload, uncomment it and rebuild. */
269
/* #define TEST_LOG_INCOME_VOICE */
270
#define voc_buffer_size (8000*8)
271
272
273
#define MAX_ALARMS 10
274
275
#define MOD_TYPE_FXS	0
276
#define MOD_TYPE_FXO	1
277
278
#define MINPEGTIME	10 * 8		/* 30 ms peak to peak gets us no more than 100 Hz */
279
#define PEGTIME		50 * 8		/* 50ms peak to peak gets us rings of 10 Hz or more */
280
#define PEGCOUNT	5		/* 5 cycles of pegging means RING */
281
282
#define NUM_CAL_REGS 12
283
284
struct calregs {
285
	unsigned char vals[NUM_CAL_REGS];
286
};
287
288
enum proslic_power_warn {
289
	PROSLIC_POWER_UNKNOWN = 0,
290
	PROSLIC_POWER_ON,
291
	PROSLIC_POWER_WARNED,
292
};
293
294
enum battery_state {
295
	BATTERY_UNKNOWN = 0,
296
	BATTERY_PRESENT,
297
	BATTERY_LOST,
298
};
299
struct wctdm {
300
	struct pci_dev *dev;
301
	char *variety;
302
	struct dahdi_span span;
303
	struct dahdi_device *ddev;
304
	unsigned char ios;
305
	int usecount;
306
	unsigned int intcount;
307
	int dead;
308
	int pos;
309
	int flags[MAX_NUM_CARDS];
310
	int freeregion;
311
	int alt;
312
	int curcard;
313
	int cardflag;		/* Bit-map of present cards */
314
	enum proslic_power_warn proslic_power;
315
	spinlock_t lock;
316
317
	union {
318
		struct fxo {
319
#ifdef AUDIO_RINGCHECK
320
			unsigned int pegtimer;
321
			int pegcount;
322
			int peg;
323
			int ring;
324
#else			
325
			int wasringing;
326
			int lastrdtx;
327
#endif			
328
			int ringdebounce;
329
			int offhook;
330
		    unsigned int battdebounce;
331
			unsigned int battalarm;
332
			enum battery_state battery;
333
		        int lastpol;
334
		        int polarity;
335
		        int polaritydebounce;
336
		} fxo;
337
		struct fxs {
338
			int oldrxhook;
339
			int debouncehook;
340
			int lastrxhook;
341
			int debounce;
342
			int ohttimer;
343
			int idletxhookstate;		/* IDLE changing hook state */
344
			int lasttxhook;
345
			int palarms;
346
			struct calregs calregs;
347
		} fxs;
348
	} mod[MAX_NUM_CARDS];
349
350
	/* Receive hook state and debouncing */
351
	int modtype[MAX_NUM_CARDS];
352
	unsigned char reg0shadow[MAX_NUM_CARDS];
353
	unsigned char reg1shadow[MAX_NUM_CARDS];
354
355
	unsigned long ioaddr;
356
	unsigned long mem_region;	/* 32 bit Region allocated to tiger320 */
357
	unsigned long mem_len;		/* Length of 32 bit region */
358
	volatile unsigned long mem32;	/* Virtual representation of 32 bit memory area */
359
	
360
	dma_addr_t 	readdma;
361
	dma_addr_t	writedma;
362
	volatile unsigned char *writechunk;					/* Double-word aligned write memory */
363
	volatile unsigned char *readchunk;					/* Double-word aligned read memory */
364
	/*struct dahdi_chan chans[MAX_NUM_CARDS];*/
365
	struct dahdi_chan _chans[NUM_CARDS];
366
	struct dahdi_chan *chans[NUM_CARDS];
367
368
369
#ifdef TEST_LOG_INCOME_VOICE	
370
	char * voc_buf[MAX_NUM_CARDS + NUM_FLAG];
371
	int voc_ptr[MAX_NUM_CARDS + NUM_FLAG];
372
#endif
373
	int lastchan;
374
	unsigned short ledstate;
375
	unsigned char fwversion;
376
	int max_cards;
377
	char *card_name;
378
	
379
	char *cid_history_buf[MAX_NUM_CARDS];
380
	int	 cid_history_ptr[MAX_NUM_CARDS];
381
	int  cid_history_clone_cnt[MAX_NUM_CARDS];
382
	enum cid_hook_state cid_state[MAX_NUM_CARDS];
383
   int 	cid_ring_on_time[MAX_NUM_CARDS];
384
};
385
386
static char* A1200P_Name = "A1200P";
387
static char* A800P_Name  = "A800P";
388
389
struct wctdm_desc {
390
	char *name;
391
	int flags;
392
};
393
394
static struct wctdm_desc wctdme = { "OpenVox A1200P/A800P", 0 };
395
static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 };
396
397
static struct wctdm *ifaces[WC_MAX_IFACES];
398
399
static void wctdm_release(struct wctdm *wc);
400
401
static unsigned int battdebounce;
402
static unsigned int battalarm;
403
static unsigned int battthresh;
404
static int ringdebounce = DEFAULT_RING_DEBOUNCE;
405
/* times 4, because must be a multiple of 4ms: */
406
static int dialdebounce = 8 * 8;
407
static int fwringdetect = 0;
408
static int debug = 0;
409
static int robust = 0;
410
static int timingonly = 0;
411
static int lowpower = 0;
412
static int boostringer = 0;
413
static int fastringer = 0;
414
static int _opermode = 0;
415
static char *opermode = "FCC";
416
static int fxshonormode = 0;
417
static int alawoverride = 0;
418
static int fastpickup = 0;
419
static int fxotxgain = 0;
420
static int fxorxgain = 0;
421
static int fxstxgain = 0;
422
static int fxsrxgain = 0;
423
/* special h/w control command */
424
static int spibyhw = 1;
425
static int usememio = 1;
426
static int cidbeforering = 0;
427
static int cidbuflen = 3000;	/* in msec, default 3000 */
428
static int cidtimeout = 6*1000;	/* in msec, default 6000 */
429
static int fxofullscale = 0;	/* fxo full scale tx/rx, register 30, acim */
430
static int fixedtimepolarity=0;	/* time delay in ms when send polarity after rise edge of 1st ring.*/
431
432
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
433
434
static void wctdm_set_led(struct wctdm* wc, int card, int onoff)
435
{
436
	int i;
437
	unsigned char c;
438
	
439
	wc->ledstate &= ~(0x01<<card);
440
	wc->ledstate |= (onoff<<card);
441
	c = (inb(wc->ioaddr + WC_AUXD)&~BIT_LED_CLK)|BIT_LED_DATA;
442
	outb( c,  wc->ioaddr + WC_AUXD);
443
	for(i=MAX_NUM_CARDS-1; i>=0; i--)
444
	{
445
		if(wc->ledstate & (0x0001<<i))
446
			if(wc->fwversion == 0x11)
447
				c &= ~BIT_LED_DATA;
448
			else
449
				c |= BIT_LED_DATA;
450
		else
451
			if(wc->fwversion == 0x11)
452
				c |= BIT_LED_DATA;
453
			else
454
				c &= ~BIT_LED_DATA;
455
			
456
		outb( c,  wc->ioaddr + WC_AUXD);
457
		outb( c|BIT_LED_CLK,  wc->ioaddr + WC_AUXD);
458
		outb( (c&~BIT_LED_CLK)|BIT_LED_DATA,  wc->ioaddr + WC_AUXD);
459
	}	
460
}
461
 
462
463
static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char ints)
464
{
465
	int x, y, chan_offset, pos;
466
	volatile unsigned char *txbuf;
467
	
468
	if (ints & /*0x01*/ 0x04) 
469
		/* Write is at interrupt address.  Start writing from normal offset */
470
		txbuf = wc->writechunk;
471
	else 
472
		txbuf = wc->writechunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
473
		
474
	/* Calculate Transmission */
475
	dahdi_transmit(&wc->span);
476
	
477
	if(wc->lastchan == -1)	// not in sync.
478
		return;
479
	
480
	chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
481
482
	for (y=0;y<DAHDI_CHUNKSIZE;y++) {
483
#ifdef __BIG_ENDIAN
484
	// operation pending...
485
#else
486
		for (x=0;x<(MAX_NUM_CARDS+NUM_FLAG);x++) {
487
			pos = y * (MAX_NUM_CARDS+NUM_FLAG) + ((x + chan_offset + MAX_NUM_CARDS+NUM_FLAG - WC_OFFSET)&0x0f);
488
			if(x<wc->max_cards/*MAX_NUM_CARDS*/)
489
				txbuf[pos] = wc->chans[x]->writechunk[y]; 
490
			else
491
				txbuf[pos] = 0; 
492
		}
493
#endif
494
	}
495
}
496
497
498
#ifdef AUDIO_RINGCHECK
499
static inline void ring_check(struct wctdm *wc, int card)
500
{
501
	int x;
502
	short sample;
503
	if (wc->modtype[card] != MOD_TYPE_FXO)
504
		return;
505
	wc->mod[card].fxo.pegtimer += DAHDI_CHUNKSIZE;
506
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
507
		/* Look for pegging to indicate ringing */
508
		sample = DAHDI_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card])));
509
		if ((sample > 10000) && (wc->mod[card].fxo.peg != 1)) {
510
			if (debug > 1) printk(KERN_DEBUG "High peg!\n");
511
			if ((wc->mod[card].fxo.pegtimer < PEGTIME) && (wc->mod[card].fxo.pegtimer > MINPEGTIME))
512
				wc->mod[card].fxo.pegcount++;
513
			wc->mod[card].fxo.pegtimer = 0;
514
			wc->mod[card].fxo.peg = 1;
515
		} else if ((sample < -10000) && (wc->mod[card].fxo.peg != -1)) {
516
			if (debug > 1) printk(KERN_DEBUG "Low peg!\n");
517
			if ((wc->mod[card].fxo.pegtimer < (PEGTIME >> 2)) && (wc->mod[card].fxo.pegtimer > (MINPEGTIME >> 2)))
518
				wc->mod[card].fxo.pegcount++;
519
			wc->mod[card].fxo.pegtimer = 0;
520
			wc->mod[card].fxo.peg = -1;
521
		}
522
	}
523
	if (wc->mod[card].fxo.pegtimer > PEGTIME) {
524
		/* Reset pegcount if our timer expires */
525
		wc->mod[card].fxo.pegcount = 0;
526
	}
527
	/* Decrement debouncer if appropriate */
528
	if (wc->mod[card].fxo.ringdebounce)
529
		wc->mod[card].fxo.ringdebounce--;
530
	if (!wc->mod[card].fxo.offhook && !wc->mod[card].fxo.ringdebounce) {
531
		if (!wc->mod[card].fxo.ring && (wc->mod[card].fxo.pegcount > PEGCOUNT)) {
532
			/* It's ringing */
533
			if (debug)
534
				printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
535
			if (!wc->mod[card].fxo.offhook)
536
				dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_RING);
537
			wc->mod[card].fxo.ring = 1;
538
		}
539
		if (wc->mod[card].fxo.ring && !wc->mod[card].fxo.pegcount) {
540
			/* No more ring */
541
			if (debug)
542
				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
543
			dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
544
			wc->mod[card].fxo.ring = 0;
545
		}
546
	}
547
}
548
#endif
549
550
551
static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char ints)
552
{
553
	volatile unsigned char *rxbuf;
554
	int x, y, chan_offset;
555
556
557
	if (ints & 0x08/*0x04*/)
558
		/* Read is at interrupt address.  Valid data is available at normal offset */
559
		rxbuf = wc->readchunk;
560
	else
561
		rxbuf = wc->readchunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
562
563
	for(x=0; x<4; x++)
564
		if(  *(int*)(rxbuf+x*4) == WC_SYNCFLAG)
565
			break;
566
	if(x==4)
567
	{
568
		printk("buffer sync misseed!\n");
569
		wc->lastchan = -1;
570
		return;
571
	}
572
	else if(wc->lastchan != x)
573
	{
574
		printk("buffer re-sync occur from %d to %d\n", wc->lastchan, x);
575
		wc->lastchan = x;
576
	}
577
	chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
578
579
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
580
#ifdef __BIG_ENDIAN
581
	// operation pending...
582
#else
583
		for (y=0;y<wc->max_cards/*MAX_NUM_CARDS*/;y++) { 
584
			if (wc->cardflag & (1 << y))
585
				wc->chans[y]->readchunk[x] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset ) & 0x0f)];
586
#ifdef TEST_LOG_INCOME_VOICE
587
			wc->voc_buf[y][wc->voc_ptr[y]] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset) & 0x0f)];
588
			wc->voc_ptr[y]++;
589
			if(wc->voc_ptr[y] >= voc_buffer_size)
590
				wc->voc_ptr[y] = 0;
591
#endif		
592
		}
593
#endif
594
	}
595
	
596
	if(cidbeforering)
597
	{
598
		for(x=0; x<wc->max_cards; x++)
599
		{
600
			if (wc->modtype[wc->chans[x]->chanpos - 1] == MOD_TYPE_FXO)
601
				if(wc->mod[wc->chans[x]->chanpos - 1].fxo.offhook == 0)
602
				{
603
					/*unsigned int *p_readchunk, *p_cid_history;
604
					
605
					p_readchunk = (unsigned int*)wc->chans[x].readchunk;
606
					p_cid_history = (unsigned int*)(wc->cid_history_buf[x] + wc->cid_history_ptr[x]);*/
607
					
608
					if(wc->cid_state[x] == CID_STATE_IDLE)	/* we need copy data to the cid voice buffer */
609
					{
610
						memcpy(wc->cid_history_buf[x] + wc->cid_history_ptr[x], wc->chans[x]->readchunk, DAHDI_CHUNKSIZE);
611
						wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
612
					}
613
					else if (wc->cid_state[x] == CID_STATE_RING_ON)
614
						wc->cid_history_clone_cnt[x] = cidbuflen;
615
					else if (wc->cid_state[x] == CID_STATE_RING_OFF)
616
					{ 
617
						if(wc->cid_history_clone_cnt[x])
618
						{	
619
							memcpy(wc->chans[x]->readchunk, wc->cid_history_buf[x] + wc->cid_history_ptr[x], DAHDI_MAX_CHUNKSIZE);
620
							wc->cid_history_clone_cnt[x]--;
621
							wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_MAX_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
622
						}
623
						else
624
						{
625
							wc->cid_state[x] = CID_STATE_WAIT_RING_FINISH;
626
							wc->cid_history_clone_cnt[x] = cidtimeout; /* wait 6 sec, if no ring, return to idle */
627
						}
628
					}
629
					else if(wc->cid_state[x] == CID_STATE_WAIT_RING_FINISH)
630
					{
631
						if(wc->cid_history_clone_cnt[x] > 0)
632
							wc->cid_history_clone_cnt[x]--;
633
						else
634
						{
635
							wc->cid_state[x] = CID_STATE_IDLE;
636
							wc->cid_history_ptr[x] = 0;
637
							wc->cid_history_clone_cnt[x] = 0;
638
						}
639
					}
640
				}
641
		}		
642
	}
643
	
644
#ifdef AUDIO_RINGCHECK
645
	for (x=0;x<wc->max_cards;x++)
646
		ring_check(wc, x);
647
#endif		
648
	/* XXX We're wasting 8 taps.  We should get closer :( */
649
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
650
		if (wc->cardflag & (1 << x))
651
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
652
	}
653
	dahdi_receive(&wc->span);
654
}
655
656
static void wctdm_stop_dma(struct wctdm *wc);
657
static void wctdm_reset_tdm(struct wctdm *wc);
658
static void wctdm_restart_dma(struct wctdm *wc);
659
660
661
static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg);
662
static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val);
663
664
665
static inline void __write_8bits(struct wctdm *wc, unsigned char bits)
666
{
667
	if(spibyhw == 0)
668
	{
669
		int x;
670
		/* Drop chip select */
671
		wc->ios |= BIT_SCLK;
672
		outb(wc->ios, wc->ioaddr + WC_AUXD);
673
		wc->ios &= ~BIT_CS;
674
		outb(wc->ios, wc->ioaddr + WC_AUXD);
675
		for (x=0;x<8;x++) {
676
			/* Send out each bit, MSB first, drop SCLK as we do so */
677
			if (bits & 0x80)
678
				wc->ios |= BIT_SDI;
679
			else
680
				wc->ios &= ~BIT_SDI;
681
			wc->ios &= ~BIT_SCLK;
682
			outb(wc->ios, wc->ioaddr + WC_AUXD);
683
			/* Now raise SCLK high again and repeat */
684
			wc->ios |= BIT_SCLK;
685
			outb(wc->ios, wc->ioaddr + WC_AUXD);
686
			bits <<= 1;
687
		}
688
		/* Finally raise CS back high again */
689
		wc->ios |= BIT_CS;
690
		outb(wc->ios, wc->ioaddr + WC_AUXD);
691
	}
692
	else
693
	{
694
		__wctdm_setcreg(wc, WC_SPIDATA, bits);
695
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
696
		while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
697
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
698
	}
699
}
700
701
702
static inline void __reset_spi(struct wctdm *wc)
703
{
704
	__wctdm_setcreg(wc, WC_SPICTRL, 0);
705
	
706
	/* Drop chip select and clock once and raise and clock once */
707
	wc->ios |= BIT_SCLK;
708
	outb(wc->ios, wc->ioaddr + WC_AUXD);
709
	wc->ios &= ~BIT_CS;
710
	outb(wc->ios, wc->ioaddr + WC_AUXD);
711
	wc->ios |= BIT_SDI;
712
	wc->ios &= ~BIT_SCLK;
713
	outb(wc->ios, wc->ioaddr + WC_AUXD);
714
	/* Now raise SCLK high again and repeat */
715
	wc->ios |= BIT_SCLK;
716
	outb(wc->ios, wc->ioaddr + WC_AUXD);
717
	/* Finally raise CS back high again */
718
	wc->ios |= BIT_CS;
719
	outb(wc->ios, wc->ioaddr + WC_AUXD);
720
	/* Clock again */
721
	wc->ios &= ~BIT_SCLK;
722
	outb(wc->ios, wc->ioaddr + WC_AUXD);
723
	/* Now raise SCLK high again and repeat */
724
	wc->ios |= BIT_SCLK;
725
	outb(wc->ios, wc->ioaddr + WC_AUXD);
726
	
727
	__wctdm_setcreg(wc, WC_SPICTRL, spibyhw);
728
729
}
730
731
static inline unsigned char __read_8bits(struct wctdm *wc)
732
{
733
	unsigned char res=0, c;
734
	int x;
735
	if(spibyhw == 0)
736
	{
737
		wc->ios &= ~BIT_CS;
738
		outb(wc->ios, wc->ioaddr + WC_AUXD);
739
		/* Drop chip select */
740
		wc->ios &= ~BIT_CS;
741
		outb(wc->ios, wc->ioaddr + WC_AUXD);
742
		for (x=0;x<8;x++) {
743
			res <<= 1;
744
			/* Get SCLK */
745
			wc->ios &= ~BIT_SCLK;
746
			outb(wc->ios, wc->ioaddr + WC_AUXD);
747
			/* Read back the value */
748
			c = inb(wc->ioaddr + WC_AUXR);
749
			if (c & BIT_SDO)
750
				res |= 1;
751
			/* Now raise SCLK high again */
752
			wc->ios |= BIT_SCLK;
753
			outb(wc->ios, wc->ioaddr + WC_AUXD);
754
		}
755
		/* Finally raise CS back high again */
756
		wc->ios |= BIT_CS;
757
		outb(wc->ios, wc->ioaddr + WC_AUXD);
758
		wc->ios &= ~BIT_SCLK;
759
		outb(wc->ios, wc->ioaddr + WC_AUXD);
760
	}
761
	else
762
	{
763
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
764
		while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
765
		res = __wctdm_getcreg(wc, WC_SPIDATA);
766
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
767
	}
768
	
769
	/* And return our result */
770
	return res;
771
}
772
773
static void __wctdm_setcreg_mem(struct wctdm *wc, unsigned char reg, unsigned char val)
774
{
775
	unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
776
	*p = val;
777
}
778
779
static unsigned char __wctdm_getcreg_mem(struct wctdm *wc, unsigned char reg)
780
{
781
	unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
782
	return (*p)&0x00ff;
783
}
784
785
786
static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val)
787
{
788
	if(usememio)
789
		__wctdm_setcreg_mem(wc, reg, val);
790
	else
791
		outb(val, wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
792
}
793
794
static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg)
795
{
796
	if(usememio)
797
		return __wctdm_getcreg_mem(wc, reg);
798
	else
799
		return inb(wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
800
}
801
802
static inline void __wctdm_setcard(struct wctdm *wc, int card)
803
{
804
	if (wc->curcard != card) {
805
		__wctdm_setcreg(wc, WC_CS, card);
806
		wc->curcard = card;
807
		//printk("Select card %d\n", card);
808
	}
809
}
810
811
static void __wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
812
{
813
	__wctdm_setcard(wc, card);
814
	if (wc->modtype[card] == MOD_TYPE_FXO) {
815
		__write_8bits(wc, 0x20);
816
		__write_8bits(wc, reg & 0x7f);
817
	} else {
818
		__write_8bits(wc, reg & 0x7f);
819
	}
820
	__write_8bits(wc, value);
821
}
822
823
static void wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
824
{
825
	unsigned long flags;
826
	spin_lock_irqsave(&wc->lock, flags);
827
	__wctdm_setreg(wc, card, reg, value);
828
	spin_unlock_irqrestore(&wc->lock, flags);
829
}
830
831
static unsigned char __wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
832
{
833
	__wctdm_setcard(wc, card);
834
	if (wc->modtype[card] == MOD_TYPE_FXO) {
835
		__write_8bits(wc, 0x60);
836
		__write_8bits(wc, reg & 0x7f);
837
	} else {
838
		__write_8bits(wc, reg | 0x80);
839
	}
840
	return __read_8bits(wc);
841
}
842
843
static inline void reset_spi(struct wctdm *wc, int card)
844
{
845
	unsigned long flags;
846
	spin_lock_irqsave(&wc->lock, flags);
847
	__wctdm_setcard(wc, card);
848
	__reset_spi(wc);
849
	__reset_spi(wc);
850
	spin_unlock_irqrestore(&wc->lock, flags);
851
}
852
853
static unsigned char wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
854
{
855
	unsigned long flags;
856
	unsigned char res;
857
	spin_lock_irqsave(&wc->lock, flags);
858
	res = __wctdm_getreg(wc, card, reg);
859
	spin_unlock_irqrestore(&wc->lock, flags);
860
	return res;
861
}
862
863
static int __wait_access(struct wctdm *wc, int card)
864
{
865
    unsigned char data = 0;
866
    long origjiffies;
867
    int count = 0;
868
869
    #define MAX 6000 /* attempts */
870
871
872
    origjiffies = jiffies;
873
    /* Wait for indirect access */
874
    while (count++ < MAX)
875
	 {
876
		data = __wctdm_getreg(wc, card, I_STATUS);
877
878
		if (!data)
879
			return 0;
880
881
	 }
882
883
    if(count > (MAX-1)) printk(KERN_NOTICE " ##### Loop error (%02x) #####\n", data);
884
885
	return 0;
886
}
887
888
static unsigned char translate_3215(unsigned char address)
889
{
890
	int x;
891
	for (x=0;x<sizeof(indirect_regs)/sizeof(indirect_regs[0]);x++) {
892
		if (indirect_regs[x].address == address) {
893
			address = indirect_regs[x].altaddr;
894
			break;
895
		}
896
	}
897
	return address;
898
}
899
900
static int wctdm_proslic_setreg_indirect(struct wctdm *wc, int card, unsigned char address, unsigned short data)
901
{
902
	unsigned long flags;
903
	int res = -1;
904
	/* Translate 3215 addresses */
905
	if (wc->flags[card] & FLAG_3215) {
906
		address = translate_3215(address);
907
		if (address == 255)
908
			return 0;
909
	}
910
	spin_lock_irqsave(&wc->lock, flags);
911
	if(!__wait_access(wc, card)) {
912
		__wctdm_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF));
913
		__wctdm_setreg(wc, card, IDA_HI,(unsigned char)((data & 0xFF00)>>8));
914
		__wctdm_setreg(wc, card, IAA,address);
915
		res = 0;
916
	};
917
	spin_unlock_irqrestore(&wc->lock, flags);
918
	return res;
919
}
920
921
static int wctdm_proslic_getreg_indirect(struct wctdm *wc, int card, unsigned char address)
922
{ 
923
	unsigned long flags;
924
	int res = -1;
925
	char *p=NULL;
926
	/* Translate 3215 addresses */
927
	if (wc->flags[card] & FLAG_3215) {
928
		address = translate_3215(address);
929
		if (address == 255)
930
			return 0;
931
	}
932
	spin_lock_irqsave(&wc->lock, flags);
933
	if (!__wait_access(wc, card)) {
934
		__wctdm_setreg(wc, card, IAA, address);
935
		if (!__wait_access(wc, card)) {
936
			unsigned char data1, data2;
937
			data1 = __wctdm_getreg(wc, card, IDA_LO);
938
			data2 = __wctdm_getreg(wc, card, IDA_HI);
939
			res = data1 | (data2 << 8);
940
		} else
941
			p = "Failed to wait inside\n";
942
	} else
943
		p = "failed to wait\n";
944
	spin_unlock_irqrestore(&wc->lock, flags);
945
	if (p)
946
		printk(KERN_NOTICE "%s", p);
947
	return res;
948
}
949
950
static int wctdm_proslic_init_indirect_regs(struct wctdm *wc, int card)
951
{
952
	unsigned char i;
953
954
	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
955
	{
956
		if(wctdm_proslic_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))
957
			return -1;
958
	}
959
960
	return 0;
961
}
962
963
static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card)
964
{ 
965
	int passed = 1;
966
	unsigned short i, initial;
967
	int j;
968
969
	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++) 
970
	{
971
		if((j = wctdm_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
972
			printk(KERN_NOTICE "Failed to read indirect register %d\n", i);
973
			return -1;
974
		}
975
		initial= indirect_regs[i].initial;
976
977
		if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255)))
978
		{
979
			 printk(KERN_NOTICE "!!!!!!! %s  iREG %X = %X  should be %X\n",
980
				indirect_regs[i].name,indirect_regs[i].address,j,initial );
981
			 passed = 0;
982
		}	
983
	}
984
985
    if (passed) {
986
		if (debug)
987
			printk(KERN_DEBUG "Init Indirect Registers completed successfully.\n");
988
    } else {
989
		printk(KERN_NOTICE " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
990
		return -1;
991
    }
992
    return 0;
993
}
994
995
static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card)
996
{
997
	int res;
998
	/* Check loopback */
999
	res = wc->reg1shadow[card];
1000
	
1001
	if (!res && (res != wc->mod[card].fxs.lasttxhook))     // read real state from register   By wx
1002
		res=wctdm_getreg(wc, card, 64);
1003
	
1004
	if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
1005
		res = wctdm_getreg(wc, card, 8);
1006
		if (res) {
1007
			printk(KERN_NOTICE "Ouch, part reset, quickly restoring reality (%d)\n", card);
1008
			wctdm_init_proslic(wc, card, 1, 0, 1);
1009
		} else {
1010
			if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
1011
				printk(KERN_NOTICE "Power alarm on module %d, resetting!\n", card + 1);
1012
				if (wc->mod[card].fxs.lasttxhook == 4)
1013
					wc->mod[card].fxs.lasttxhook = 1;
1014
				wctdm_setreg(wc, card, 64, wc->mod[card].fxs.lasttxhook);
1015
			} else {
1016
				if (wc->mod[card].fxs.palarms == MAX_ALARMS)
1017
					printk(KERN_NOTICE "Too many power alarms on card %d, NOT resetting!\n", card + 1);
1018
			}
1019
		}
1020
	}
1021
}
1022
static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
1023
{
1024
#define MS_PER_CHECK_HOOK 16
1025
1026
#ifndef AUDIO_RINGCHECK
1027
	unsigned char res;
1028
#endif	
1029
	signed char b;
1030
	int errors = 0;
1031
	struct fxo *fxo = &wc->mod[card].fxo;
1032
1033
	/* Try to track issues that plague slot one FXO's */
1034
	b = wc->reg0shadow[card];
1035
	if ((b & 0x2) || !(b & 0x8)) {
1036
		/* Not good -- don't look at anything else */
1037
		if (debug)
1038
			printk(KERN_DEBUG "Error (%02x) on card %d!\n", b, card + 1); 
1039
		errors++;
1040
	}
1041
	b &= 0x9b;
1042
	if (fxo->offhook) {
1043
		if (b != 0x9)
1044
			wctdm_setreg(wc, card, 5, 0x9);
1045
	} else {
1046
		if (b != 0x8)
1047
			wctdm_setreg(wc, card, 5, 0x8);
1048
	}
1049
	if (errors)
1050
		return;
1051
	if (!fxo->offhook) {
1052
 if(fixedtimepolarity) {
1053
			if ( wc->cid_state[card] == CID_STATE_RING_ON && wc->cid_ring_on_time[card]>0)
1054
			{
1055
 	if(wc->cid_ring_on_time[card]>=fixedtimepolarity )
1056
			{
1057
			dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1058
			wc->cid_ring_on_time[card] = -1;	/* the polarity already sent */	
1059
			}
1060
			else
1061
		wc->cid_ring_on_time[card] += 16;
1062
    }
1063
}
1064
		if (fwringdetect) {
1065
			res = wc->reg0shadow[card] & 0x60;
1066
			if (fxo->ringdebounce) {
1067
				--fxo->ringdebounce;
1068
				if (res && (res != fxo->lastrdtx) &&
1069
				    (fxo->battery == BATTERY_PRESENT)) {
1070
					if (!fxo->wasringing) {
1071
						fxo->wasringing = 1;
1072
						if (debug)
1073
          printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
1074
	if(cidbeforering)
1075
						{
1076
							if(wc->cid_state[card] == CID_STATE_IDLE)
1077
							{
1078
								wc->cid_state[card] = CID_STATE_RING_ON;
1079
								wc->cid_ring_on_time[card] = 16;	/* check every 16ms */
1080
							}
1081
							else
1082
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1083
						}
1084
						else 							
1085
        dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1086
					}
1087
					fxo->lastrdtx = res;
1088
					fxo->ringdebounce = 10;
1089
				} else if (!res) {
1090
					if ((fxo->ringdebounce == 0) && fxo->wasringing) {
1091
				fxo->wasringing = 0;
1092
				if (debug)
1093
				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
1094
	if(cidbeforering)
1095
						{
1096
							if(wc->cid_state[card] == CID_STATE_RING_ON)
1097
							{
1098
								if(fixedtimepolarity==0)
1099
									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1100
								wc->cid_state[card] = CID_STATE_RING_OFF;
1101
							}
1102
							else 
1103
							{
1104
								if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
1105
									wc->cid_history_clone_cnt[card] = cidtimeout;
1106
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1107
							}
1108
						}
1109
						else
1110
1111
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1112
				}
1113
				}
1114
			} else if (res && (fxo->battery == BATTERY_PRESENT)) {
1115
				fxo->lastrdtx = res;
1116
				fxo->ringdebounce = 10;
1117
			}
1118
		} else {
1119
			res = wc->reg0shadow[card];
1120
			if ((res & 0x60) && (fxo->battery == BATTERY_PRESENT)) {
1121
				fxo->ringdebounce += (DAHDI_CHUNKSIZE * 16);
1122
				if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
1123
					if (!fxo->wasringing) {
1124
						fxo->wasringing = 1;
1125
 if(cidbeforering)
1126
						{
1127
							if(wc->cid_state[card] == CID_STATE_IDLE)
1128
							{	
1129
								wc->cid_state[card] = CID_STATE_RING_ON;
1130
								wc->cid_ring_on_time[card] = 16;		/* check every 16ms */
1131
							}
1132
							else
1133
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1134
						}
1135
						else      
1136
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1137
						if (debug)
1138
							printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
1139
					}
1140
					fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
1141
				}
1142
			} else {
1143
				fxo->ringdebounce -= DAHDI_CHUNKSIZE * 4;
1144
				if (fxo->ringdebounce <= 0) {
1145
					if (fxo->wasringing) {
1146
						fxo->wasringing = 0;
1147
	if(cidbeforering)
1148
						{
1149
							if(wc->cid_state[card] == CID_STATE_RING_ON)
1150
							{
1151
								if(fixedtimepolarity==0)
1152
									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1153
								wc->cid_state[card] = CID_STATE_RING_OFF;
1154
							}
1155
							else 
1156
							{
1157
								if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
1158
									wc->cid_history_clone_cnt[card] = cidtimeout;
1159
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1160
							}
1161
						}
1162
						else
1163
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1164
						if (debug)
1165
							printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
1166
					}
1167
					fxo->ringdebounce = 0;
1168
				}
1169
			}
1170
		}
1171
	}
1172
1173
	b = wc->reg1shadow[card];
1174
	if (abs(b) < battthresh) {
1175
		/* possible existing states:
1176
		   battery lost, no debounce timer
1177
		   battery lost, debounce timer (going to battery present)
1178
		   battery present or unknown, no debounce timer
1179
		   battery present or unknown, debounce timer (going to battery lost)
1180
		*/
1181
1182
		if (fxo->battery == BATTERY_LOST) {
1183
			if (fxo->battdebounce) {
1184
				/* we were going to BATTERY_PRESENT, but battery was lost again,
1185
				   so clear the debounce timer */
1186
				fxo->battdebounce = 0;
1187
			}
1188
		} else {
1189
			if (fxo->battdebounce) {
1190
				/* going to BATTERY_LOST, see if we are there yet */
1191
				if (--fxo->battdebounce == 0) {
1192
					fxo->battery = BATTERY_LOST;
1193
					if (debug)
1194
						printk(KERN_DEBUG "NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);
1195
#ifdef	JAPAN
1196
					if (!wc->ohdebounce && wc->offhook) {
1197
						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_ONHOOK);
1198
						if (debug)
1199
							printk(KERN_DEBUG "Signalled On Hook\n");
1200
#ifdef	ZERO_BATT_RING
1201
						wc->onhook++;
1202
#endif
1203
					}
1204
#else
1205
					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
1206
					/* set the alarm timer, taking into account that part of its time
1207
					   period has already passed while debouncing occurred */
1208
					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
1209
#endif
1210
				}
1211
			} else {
1212
				/* start the debounce timer to verify that battery has been lost */
1213
				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
1214
			}
1215
		}
1216
	} else {
1217
		/* possible existing states:
1218
		   battery lost or unknown, no debounce timer
1219
		   battery lost or unknown, debounce timer (going to battery present)
1220
		   battery present, no debounce timer
1221
		   battery present, debounce timer (going to battery lost)
1222
		*/
1223
1224
		if (fxo->battery == BATTERY_PRESENT) {
1225
			if (fxo->battdebounce) {
1226
				/* we were going to BATTERY_LOST, but battery appeared again,
1227
				   so clear the debounce timer */
1228
				fxo->battdebounce = 0;
1229
			}
1230
		} else {
1231
			if (fxo->battdebounce) {
1232
				/* going to BATTERY_PRESENT, see if we are there yet */
1233
				if (--fxo->battdebounce == 0) {
1234
					fxo->battery = BATTERY_PRESENT;
1235
					if (debug)
1236
						printk(KERN_DEBUG "BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1, 
1237
						       (b < 0) ? "-" : "+");			    
1238
#ifdef	ZERO_BATT_RING
1239
					if (wc->onhook) {
1240
						wc->onhook = 0;
1241
						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1242
						if (debug)
1243
							printk(KERN_DEBUG "Signalled Off Hook\n");
1244
					}
1245
#else
1246
					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1247
#endif
1248
					/* set the alarm timer, taking into account that part of its time
1249
					   period has already passed while debouncing occurred */
1250
					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
1251
				}
1252
			} else {
1253
				/* start the debounce timer to verify that battery has appeared */
1254
				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
1255
			}
1256
		}
1257
	}
1258
1259
	if (fxo->lastpol >= 0) {
1260
		if (b < 0) {
1261
			fxo->lastpol = -1;
1262
			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
1263
		}
1264
	} 
1265
	if (fxo->lastpol <= 0) {
1266
		if (b > 0) {
1267
			fxo->lastpol = 1;
1268
			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
1269
		}
1270
	}
1271
1272
	if (fxo->battalarm) {
1273
		if (--fxo->battalarm == 0) {
1274
			/* the alarm timer has expired, so update the battery alarm state
1275
			   for this channel */
1276
			dahdi_alarm_channel(wc->chans[card], fxo->battery == BATTERY_LOST ? DAHDI_ALARM_RED : DAHDI_ALARM_NONE);
1277
		}
1278
	}
1279
1280
	if (fxo->polaritydebounce) {
1281
		if (--fxo->polaritydebounce == 0) {
1282
		    if (fxo->lastpol != fxo->polarity) {
1283
				if (debug)
1284
					printk(KERN_DEBUG "%lu Polarity reversed (%d -> %d)\n", jiffies, 
1285
				       fxo->polarity, 
1286
				       fxo->lastpol);
1287
				if (fxo->polarity)
1288
					dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1289
				fxo->polarity = fxo->lastpol;
1290
		    }
1291
		}
1292
	}
1293
#undef MS_PER_CHECK_HOOK
1294
}
1295
1296
static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
1297
{
1298
	char res;
1299
	int hook;
1300
1301
	/* For some reason we have to debounce the
1302
	   hook detector.  */
1303
1304
	res = wc->reg0shadow[card];
1305
	hook = (res & 1);
1306
	if (hook != wc->mod[card].fxs.lastrxhook) {
1307
		/* Reset the debounce (must be multiple of 4ms) */
1308
		wc->mod[card].fxs.debounce = dialdebounce * 4;
1309
1310
#if 0
1311
		printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
1312
#endif
1313
	} else {
1314
		if (wc->mod[card].fxs.debounce > 0) {
1315
			wc->mod[card].fxs.debounce-= 16 * DAHDI_CHUNKSIZE;
1316
#if 0
1317
			printk(KERN_DEBUG "Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
1318
#endif
1319
			if (!wc->mod[card].fxs.debounce) {
1320
#if 0
1321
				printk(KERN_DEBUG "Counted down debounce, newhook: %d...\n", hook);
1322
#endif
1323
				wc->mod[card].fxs.debouncehook = hook;
1324
			}
1325
			if (!wc->mod[card].fxs.oldrxhook && wc->mod[card].fxs.debouncehook) {
1326
				/* Off hook */
1327
#if 1
1328
				if (debug)
1329
#endif				
1330
					printk(KERN_DEBUG "opvxa1200: Card %d Going off hook\n", card);
1331
				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1332
				if (robust)
1333
					wctdm_init_proslic(wc, card, 1, 0, 1);
1334
				wc->mod[card].fxs.oldrxhook = 1;
1335
			
1336
			} else if (wc->mod[card].fxs.oldrxhook && !wc->mod[card].fxs.debouncehook) {
1337
				/* On hook */
1338
#if 1
1339
				if (debug)
1340
#endif				
1341
					printk(KERN_DEBUG "opvxa1200: Card %d Going on hook\n", card);
1342
				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
1343
				wc->mod[card].fxs.oldrxhook = 0;
1344
			}
1345
		}
1346
	}
1347
	wc->mod[card].fxs.lastrxhook = hook;
1348
}
1349
1350
static irqreturn_t wctdm_interrupt(int irq, void *dev_id)
1351
{
1352
	struct wctdm *wc = dev_id;
1353
	unsigned char ints;
1354
	int x, y, z;
1355
	int mode;
1356
1357
	ints = inb(wc->ioaddr + WC_INTSTAT);
1358
1359
	if (!ints)
1360
		return IRQ_NONE;
1361
1362
	outb(ints, wc->ioaddr + WC_INTSTAT);
1363
	
1364
	if (ints & 0x10) {
1365
		/* Stop DMA, wait for watchdog */
1366
		printk(KERN_INFO "TDM PCI Master abort\n");
1367
		wctdm_stop_dma(wc);
1368
		return IRQ_RETVAL(1);
1369
	}
1370
	
1371
	if (ints & 0x20) {
1372
		printk(KERN_INFO "PCI Target abort\n");
1373
		return IRQ_RETVAL(1);
1374
	}
1375
1376
	for (x=0;x<wc->max_cards/*4*3*/;x++) {
1377
		if (wc->cardflag & (1 << x) &&
1378
		    (wc->modtype[x] == MOD_TYPE_FXS)) {
1379
			if (wc->mod[x].fxs.lasttxhook == 0x4) {
1380
				/* RINGing, prepare for OHT */
1381
				wc->mod[x].fxs.ohttimer = OHT_TIMER << 3;
1382
				if (reversepolarity)
1383
					wc->mod[x].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
1384
				else
1385
					wc->mod[x].fxs.idletxhookstate = 0x2; 
1386
			} else {
1387
				if (wc->mod[x].fxs.ohttimer) {
1388
					wc->mod[x].fxs.ohttimer-= DAHDI_CHUNKSIZE;
1389
					if (!wc->mod[x].fxs.ohttimer) {
1390
						if (reversepolarity)
1391
							wc->mod[x].fxs.idletxhookstate = 0x5;	/* Switch to active */
1392
						else
1393
							wc->mod[x].fxs.idletxhookstate = 0x1;
1394
						if ((wc->mod[x].fxs.lasttxhook == 0x2) || (wc->mod[x].fxs.lasttxhook == 0x6)) {
1395
							/* Apply the change if appropriate */
1396
							if (reversepolarity) 
1397
								wc->mod[x].fxs.lasttxhook = 0x5;
1398
							else
1399
								wc->mod[x].fxs.lasttxhook = 0x1;
1400
							wctdm_setreg(wc, x, 64, wc->mod[x].fxs.lasttxhook);
1401
						}
1402
					}
1403
				}
1404
			}
1405
		}
1406
	}
1407
1408
	if (ints & 0x0f) {
1409
		wc->intcount++;
1410
		z = wc->intcount & 0x3;
1411
		mode = wc->intcount & 0xc;
1412
		for(y=0; y<wc->max_cards/4/*3*/; y++)
1413
		{
1414
			x = z + y*4;
1415
			if (wc->cardflag & (1 << x ) ) 
1416
			{
1417
				switch(mode) 
1418
				{
1419
				case 0:
1420
					/* Rest */
1421
					break;
1422
				case 4:
1423
					/* Read first shadow reg */
1424
					if (wc->modtype[x] == MOD_TYPE_FXS)
1425
						wc->reg0shadow[x] = wctdm_getreg(wc, x, 68);
1426
					else if (wc->modtype[x] == MOD_TYPE_FXO)
1427
						wc->reg0shadow[x] = wctdm_getreg(wc, x, 5);
1428
					break;
1429
				case 8:
1430
					/* Read second shadow reg */
1431
					if (wc->modtype[x] == MOD_TYPE_FXS)
1432
						wc->reg1shadow[x] = wctdm_getreg(wc, x, 64);
1433
					else if (wc->modtype[x] == MOD_TYPE_FXO)
1434
						wc->reg1shadow[x] = wctdm_getreg(wc, x, 29);
1435
					break;
1436
				case 12:
1437
					/* Perform processing */
1438
					if (wc->modtype[x] == MOD_TYPE_FXS) {
1439
						wctdm_proslic_check_hook(wc, x);
1440
						if (!(wc->intcount & 0xf0))
1441
							wctdm_proslic_recheck_sanity(wc, x);
1442
					} else if (wc->modtype[x] == MOD_TYPE_FXO) {
1443
						wctdm_voicedaa_check_hook(wc, x);
1444
					}
1445
					break;
1446
				}
1447
			}
1448
		}
1449
		if (!(wc->intcount % 10000)) {
1450
			/* Accept an alarm once per 10 seconds */
1451
			for (x=0;x<wc->max_cards/*4*3*/;x++) 
1452
				if (wc->modtype[x] == MOD_TYPE_FXS) {
1453
					if (wc->mod[x].fxs.palarms)
1454
						wc->mod[x].fxs.palarms--;
1455
				}
1456
		}
1457
		wctdm_receiveprep(wc, ints);
1458
		wctdm_transmitprep(wc, ints);
1459
	}
1460
1461
	return IRQ_RETVAL(1);
1462
1463
}
1464
1465
static int wctdm_voicedaa_insane(struct wctdm *wc, int card)
1466
{
1467
	int blah;
1468
	blah = wctdm_getreg(wc, card, 2);
1469
	if (blah != 0x3)
1470
		return -2;
1471
	blah = wctdm_getreg(wc, card, 11);
1472
	if (debug)
1473
		printk(KERN_DEBUG "VoiceDAA System: %02x\n", blah & 0xf);
1474
	return 0;
1475
}
1476
1477
static int wctdm_proslic_insane(struct wctdm *wc, int card)
1478
{
1479
	int blah,insane_report;
1480
	insane_report=0;
1481
1482
	blah = wctdm_getreg(wc, card, 0);
1483
	if (debug) 
1484
		printk(KERN_DEBUG "ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));
1485
1486
#if 0
1487
	if ((blah & 0x30) >> 4) {
1488
		printk(KERN_DEBUG "ProSLIC on module %d is not a 3210.\n", card);
1489
		return -1;
1490
	}
1491
#endif
1492
	if (((blah & 0xf) == 0) || ((blah & 0xf) == 0xf)) {
1493
		/* SLIC not loaded */
1494
		return -1;
1495
	}
1496
	if ((blah & 0xf) < 2) {
1497
		printk(KERN_NOTICE "ProSLIC 3210 version %d is too old\n", blah & 0xf);
1498
		return -1;
1499
	}
1500
	if (wctdm_getreg(wc, card, 1) & 0x80)
1501
	/* ProSLIC 3215, not a 3210 */
1502
		wc->flags[card] |= FLAG_3215;
1503
	
1504
	blah = wctdm_getreg(wc, card, 8);
1505
	if (blah != 0x2) {
1506
		printk(KERN_NOTICE  "ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
1507
		return -1;
1508
	} else if ( insane_report)
1509
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);
1510
1511
	blah = wctdm_getreg(wc, card, 64);
1512
	if (blah != 0x0) {
1513
		printk(KERN_NOTICE  "ProSLIC on module %d insane (2)\n", card);
1514
		return -1;
1515
	} else if ( insane_report)
1516
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);
1517
1518
	blah = wctdm_getreg(wc, card, 11);
1519
	if (blah != 0x33) {
1520
		printk(KERN_NOTICE  "ProSLIC on module %d insane (3)\n", card);
1521
		return -1;
1522
	} else if ( insane_report)
1523
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);
1524
1525
	/* Just be sure it's setup right. */
1526
	wctdm_setreg(wc, card, 30, 0);
1527
1528
	if (debug) 
1529
		printk(KERN_DEBUG "ProSLIC on module %d seems sane.\n", card);
1530
	return 0;
1531
}
1532
1533
static int wctdm_proslic_powerleak_test(struct wctdm *wc, int card)
1534
{
1535
	unsigned long origjiffies;
1536
	unsigned char vbat;
1537
1538
	/* Turn off linefeed */
1539
	wctdm_setreg(wc, card, 64, 0);
1540
1541
	/* Power down */
1542
	wctdm_setreg(wc, card, 14, 0x10);
1543
1544
	/* Wait for one second */
1545
	origjiffies = jiffies;
1546
1547
	while((vbat = wctdm_getreg(wc, card, 82)) > 0x6) {
1548
		if ((jiffies - origjiffies) >= (HZ/2))
1549
			break;
1550
	}
1551
1552
	if (vbat < 0x06) {
1553
		printk(KERN_NOTICE "Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,
1554
		       376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ));
1555
		return -1;
1556
	} else if (debug) {
1557
		printk(KERN_NOTICE "Post-leakage voltage: %d volts\n", 376 * vbat / 1000);
1558
	}
1559
	return 0;
1560
}
1561
1562
static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast)
1563
{
1564
	unsigned char vbat;
1565
	unsigned long origjiffies;
1566
	int lim;
1567
1568
	/* Set period of DC-DC converter to 1/64 khz */
1569
	wctdm_setreg(wc, card, 92, 0xff /* was 0xff */);
1570
1571
	/* Wait for VBat to powerup */
1572
	origjiffies = jiffies;
1573
1574
	/* Disable powerdown */
1575
	wctdm_setreg(wc, card, 14, 0);
1576
1577
	/* If fast, don't bother checking anymore */
1578
	if (fast)
1579
		return 0;
1580
1581
	while((vbat = wctdm_getreg(wc, card, 82)) < 0xc0) {
1582
		/* Wait no more than 500ms */
1583
		if ((jiffies - origjiffies) > HZ/2) {
1584
			break;
1585
		}
1586
	}
1587
1588
	if (vbat < 0xc0) {
1589
		if (wc->proslic_power == PROSLIC_POWER_UNKNOWN)
1590
				 printk(KERN_NOTICE "ProSLIC on module %d failed to powerup within %d ms (%d mV only)\n\n -- DID YOU REMEMBER TO PLUG IN THE HD POWER CABLE TO THE A1200P??\n",
1591
					card, (int)(((jiffies - origjiffies) * 1000 / HZ)),
1592
					vbat * 375);
1593
		wc->proslic_power = PROSLIC_POWER_WARNED;
1594
		return -1;
1595
	} else if (debug) {
1596
		printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
1597
		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
1598
	}
1599
	wc->proslic_power = PROSLIC_POWER_ON;
1600
1601
        /* Proslic max allowed loop current, reg 71 LOOP_I_LIMIT */
1602
        /* If out of range, just set it to the default value     */
1603
        lim = (loopcurrent - 20) / 3;
1604
        if ( loopcurrent > 41 ) {
1605
                lim = 0;
1606
                if (debug)
1607
                        printk(KERN_DEBUG "Loop current out of range! Setting to default 20mA!\n");
1608
        }
1609
        else if (debug)
1610
                        printk(KERN_DEBUG "Loop current set to %dmA!\n",(lim*3)+20);
1611
        wctdm_setreg(wc,card,LOOP_I_LIMIT,lim);
1612
1613
	/* Engage DC-DC converter */
1614
	wctdm_setreg(wc, card, 93, 0x19 /* was 0x19 */);
1615
#if 0
1616
	origjiffies = jiffies;
1617
	while(0x80 & wctdm_getreg(wc, card, 93)) {
1618
		if ((jiffies - origjiffies) > 2 * HZ) {
1619
			printk(KERN_DEBUG "Timeout waiting for DC-DC calibration on module %d\n", card);
1620
			return -1;
1621
		}
1622
	}
1623
1624
#if 0
1625
	/* Wait a full two seconds */
1626
	while((jiffies - origjiffies) < 2 * HZ);
1627
1628
	/* Just check to be sure */
1629
	vbat = wctdm_getreg(wc, card, 82);
1630
	printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
1631
		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
1632
#endif
1633
#endif
1634
	return 0;
1635
1636
}
1637
1638
static int wctdm_proslic_manual_calibrate(struct wctdm *wc, int card){
1639
	unsigned long origjiffies;
1640
	unsigned char i;
1641
1642
	wctdm_setreg(wc, card, 21, 0);//(0)  Disable all interupts in DR21
1643
	wctdm_setreg(wc, card, 22, 0);//(0)Disable all interupts in DR21
1644
	wctdm_setreg(wc, card, 23, 0);//(0)Disable all interupts in DR21
1645
	wctdm_setreg(wc, card, 64, 0);//(0)
1646
1647
	wctdm_setreg(wc, card, 97, 0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration.
1648
	wctdm_setreg(wc, card, 96, 0x47); //(0x47)	Calibrate common mode and differential DAC mode DAC + ILIM
1649
1650
	origjiffies=jiffies;
1651
	while( wctdm_getreg(wc,card,96)!=0 ){
1652
		if((jiffies-origjiffies)>80)
1653
			return -1;
1654
	}
1655
//Initialized DR 98 and 99 to get consistant results.
1656
// 98 and 99 are the results registers and the search should have same intial conditions.
1657
1658
/*******************************The following is the manual gain mismatch calibration****************************/
1659
/*******************************This is also available as a function *******************************************/
1660
	// Delay 10ms
1661
	origjiffies=jiffies; 
1662
	while((jiffies-origjiffies)<1);
1663
	wctdm_proslic_setreg_indirect(wc, card, 88,0);
1664
	wctdm_proslic_setreg_indirect(wc,card,89,0);
1665
	wctdm_proslic_setreg_indirect(wc,card,90,0);
1666
	wctdm_proslic_setreg_indirect(wc,card,91,0);
1667
	wctdm_proslic_setreg_indirect(wc,card,92,0);
1668
	wctdm_proslic_setreg_indirect(wc,card,93,0);
1669
1670
	wctdm_setreg(wc, card, 98,0x10); // This is necessary if the calibration occurs other than at reset time
1671
	wctdm_setreg(wc, card, 99,0x10);
1672
1673
	for ( i=0x1f; i>0; i--)
1674
	{
1675
		wctdm_setreg(wc, card, 98,i);
1676
		origjiffies=jiffies; 
1677
		while((jiffies-origjiffies)<4);
1678
		if((wctdm_getreg(wc,card,88)) == 0)
1679
			break;
1680
	} // for
1681
1682
	for ( i=0x1f; i>0; i--)
1683
	{
1684
		wctdm_setreg(wc, card, 99,i);
1685
		origjiffies=jiffies; 
1686
		while((jiffies-origjiffies)<4);
1687
		if((wctdm_getreg(wc,card,89)) == 0)
1688
			break;
1689
	}//for
1690
1691
/*******************************The preceding is the manual gain mismatch calibration****************************/
1692
/**********************************The following is the longitudinal Balance Cal***********************************/
1693
	wctdm_setreg(wc,card,64,1);
1694
	while((jiffies-origjiffies)<10); // Sleep 100?
1695
1696
	wctdm_setreg(wc, card, 64, 0);
1697
	wctdm_setreg(wc, card, 23, 0x4);  // enable interrupt for the balance Cal
1698
	wctdm_setreg(wc, card, 97, 0x1); // this is a singular calibration bit for longitudinal calibration
1699
	wctdm_setreg(wc, card, 96,0x40);
1700
1701
	wctdm_getreg(wc,card,96); /* Read Reg 96 just cause */
1702
1703
	wctdm_setreg(wc, card, 21, 0xFF);
1704
	wctdm_setreg(wc, card, 22, 0xFF);
1705
	wctdm_setreg(wc, card, 23, 0xFF);
1706
1707
	/**The preceding is the longitudinal Balance Cal***/
1708
	return(0);
1709
1710
}
1711
#if 1
1712
static int wctdm_proslic_calibrate(struct wctdm *wc, int card)
1713
{
1714
	unsigned long origjiffies;
1715
	int x;
1716
	/* Perform all calibrations */
1717
	wctdm_setreg(wc, card, 97, 0x1f);
1718
	
1719
	/* Begin, no speedup */
1720
	wctdm_setreg(wc, card, 96, 0x5f);
1721
1722
	/* Wait for it to finish */
1723
	origjiffies = jiffies;
1724
	while(wctdm_getreg(wc, card, 96)) {
1725
		if ((jiffies - origjiffies) > 2 * HZ) {
1726
			printk(KERN_NOTICE "Timeout waiting for calibration of module %d\n", card);
1727
			return -1;
1728
		}
1729
	}
1730
	
1731
	if (debug) {
1732
		/* Print calibration parameters */
1733
		printk(KERN_DEBUG "Calibration Vector Regs 98 - 107: \n");
1734
		for (x=98;x<108;x++) {
1735
			printk(KERN_DEBUG "%d: %02x\n", x, wctdm_getreg(wc, card, x));
1736
		}
1737
	}
1738
	return 0;
1739
}
1740
#endif
1741
1742
static void wait_just_a_bit(int foo)
1743
{
1744
	long newjiffies;
1745
	newjiffies = jiffies + foo;
1746
	while(jiffies < newjiffies);
1747
}
1748
1749
/*********************************************************************
1750
 * Set the hwgain on the analog modules
1751
 *
1752
 * card = the card position for this module (0-23)
1753
 * gain = gain in dB x10 (e.g. -3.5dB  would be gain=-35)
1754
 * tx = (0 for rx; 1 for tx)
1755
 *
1756
 *******************************************************************/
1757
static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
1758
{
1759
	if (!(wc->modtype[card] == MOD_TYPE_FXO)) {
1760
		printk(KERN_NOTICE "Cannot adjust gain.  Unsupported module type!\n");
1761
		return -1;
1762
	}
1763
	if (tx) {
1764
		if (debug)
1765
			printk(KERN_DEBUG "setting FXO tx gain for card=%d to %d\n", card, gain);
1766
		if (gain >=  -150 && gain <= 0) {
1767
			wctdm_setreg(wc, card, 38, 16 + (gain/-10));
1768
			wctdm_setreg(wc, card, 40, 16 + (-gain%10));
1769
		} else if (gain <= 120 && gain > 0) {
1770
			wctdm_setreg(wc, card, 38, gain/10);
1771
			wctdm_setreg(wc, card, 40, (gain%10));
1772
		} else {
1773
			printk(KERN_INFO "FXO tx gain is out of range (%d)\n", gain);
1774
			return -1;
1775
		}
1776
	} else { /* rx */
1777
		if (debug)
1778
			printk(KERN_DEBUG "setting FXO rx gain for card=%d to %d\n", card, gain);
1779
		if (gain >=  -150 && gain <= 0) {
1780
			wctdm_setreg(wc, card, 39, 16+ (gain/-10));
1781
			wctdm_setreg(wc, card, 41, 16 + (-gain%10));
1782
		} else if (gain <= 120 && gain > 0) {
1783
			wctdm_setreg(wc, card, 39, gain/10);
1784
			wctdm_setreg(wc, card, 41, (gain%10));
1785
		} else {
1786
			printk(KERN_INFO "FXO rx gain is out of range (%d)\n", gain);
1787
			return -1;
1788
		}
1789
	}
1790
1791
	return 0;
1792
}
1793
1794
static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane)
1795
{
1796
	unsigned char reg16=0, reg26=0, reg30=0, reg31=0;
1797
	long newjiffies;
1798
	wc->modtype[card] = MOD_TYPE_FXO;
1799
	/* Sanity check the ProSLIC */
1800
	reset_spi(wc, card);
1801
	if (!sane && wctdm_voicedaa_insane(wc, card))
1802
		return -2;
1803
1804
	/* Software reset */
1805
	wctdm_setreg(wc, card, 1, 0x80);
1806
1807
	/* Wait just a bit */
1808
	wait_just_a_bit(HZ/10);
1809
1810
	/* Enable PCM, ulaw */
1811
	if (alawoverride)
1812
		wctdm_setreg(wc, card, 33, 0x20);
1813
	else
1814
		wctdm_setreg(wc, card, 33, 0x28);
1815
1816
	/* Set On-hook speed, Ringer impedence, and ringer threshold */
1817
	reg16 |= (fxo_modes[_opermode].ohs << 6);
1818
	reg16 |= (fxo_modes[_opermode].rz << 1);
1819
	reg16 |= (fxo_modes[_opermode].rt);
1820
	wctdm_setreg(wc, card, 16, reg16);
1821
1822
	if(fwringdetect) {
1823
		/* Enable ring detector full-wave rectifier mode */
1824
		wctdm_setreg(wc, card, 18, 2);
1825
		wctdm_setreg(wc, card, 24, 0);
1826
	} else { 
1827
		/* Set to the device defaults */
1828
		wctdm_setreg(wc, card, 18, 0);
1829
		wctdm_setreg(wc, card, 24, 0x19);
1830
	}
1831
	
1832
	/* Set DC Termination:
1833
	   Tip/Ring voltage adjust, minimum operational current, current limitation */
1834
	reg26 |= (fxo_modes[_opermode].dcv << 6);
1835
	reg26 |= (fxo_modes[_opermode].mini << 4);
1836
	reg26 |= (fxo_modes[_opermode].ilim << 1);
1837
	wctdm_setreg(wc, card, 26, reg26);
1838
1839
	/* Set AC Impedence */ 
1840
	reg30 = (fxofullscale==1) ? (fxo_modes[_opermode].acim|0x10) :  (fxo_modes[_opermode].acim);
1841
	wctdm_setreg(wc, card, 30, reg30);
1842
1843
	/* Misc. DAA parameters */
1844
	if (fastpickup)
1845
		reg31 = 0xb3;
1846
	else
1847
		reg31 = 0xa3;
1848
1849
	reg31 |= (fxo_modes[_opermode].ohs2 << 3);
1850
	wctdm_setreg(wc, card, 31, reg31);
1851
1852
	/* Set Transmit/Receive timeslot */
1853
	//printk("set card %d to %d\n", card, (3-(card%4)) * 8 + (card/4) * 64);
1854
	wctdm_setreg(wc, card, 34, (3-(card%4)) * 8 + (card/4) * 64);
1855
	wctdm_setreg(wc, card, 35, 0x00);
1856
	wctdm_setreg(wc, card, 36, (3-(card%4)) * 8 + (card/4) * 64);
1857
	wctdm_setreg(wc, card, 37, 0x00);
1858
1859
	/* Enable ISO-Cap */
1860
	wctdm_setreg(wc, card, 6, 0x00);
1861
1862
	if (fastpickup)
1863
		wctdm_setreg(wc, card, 17, wctdm_getreg(wc, card, 17) | 0x20);
1864
1865
	/* Wait 1000ms for ISO-cap to come up */
1866
	newjiffies = jiffies;
1867
	newjiffies += 2 * HZ;
1868
	while((jiffies < newjiffies) && !(wctdm_getreg(wc, card, 11) & 0xf0))
1869
		wait_just_a_bit(HZ/10);
1870
1871
	if (!(wctdm_getreg(wc, card, 11) & 0xf0)) {
1872
		printk(KERN_NOTICE "VoiceDAA did not bring up ISO link properly!\n");
1873
		return -1;
1874
	}
1875
	if (debug)
1876
		printk(KERN_DEBUG "ISO-Cap is now up, line side: %02x rev %02x\n", 
1877
		       wctdm_getreg(wc, card, 11) >> 4,
1878
		       (wctdm_getreg(wc, card, 13) >> 2) & 0xf);
1879
	/* Enable on-hook line monitor */
1880
	wctdm_setreg(wc, card, 5, 0x08);
1881
1882
	/* Take values for fxotxgain and fxorxgain and apply them to module */
1883
	wctdm_set_hwgain(wc, card, fxotxgain, 1);
1884
	wctdm_set_hwgain(wc, card, fxorxgain, 0);
1885
1886
	/* NZ -- crank the tx gain up by 7 dB */
1887
	if (!strcmp(fxo_modes[_opermode].name, "NEWZEALAND")) {
1888
		printk(KERN_INFO "Adjusting gain\n");
1889
		wctdm_set_hwgain(wc, card, 7, 1);
1890
	}
1891
1892
	if(debug)
1893
		printk(KERN_DEBUG "DEBUG fxotxgain:%i.%i fxorxgain:%i.%i\n", (wctdm_getreg(wc, card, 38)/16)?-(wctdm_getreg(wc, card, 38) - 16) : wctdm_getreg(wc, card, 38), (wctdm_getreg(wc, card, 40)/16)? -(wctdm_getreg(wc, card, 40) - 16):wctdm_getreg(wc, card, 40), (wctdm_getreg(wc, card, 39)/16)? -(wctdm_getreg(wc, card, 39) - 16) : wctdm_getreg(wc, card, 39),(wctdm_getreg(wc, card, 41)/16)?-(wctdm_getreg(wc, card, 41) - 16):wctdm_getreg(wc, card, 41));
1894
1895
    return 0;
1896
		
1897
}
1898
1899
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, int sane)
1900
{
1901
1902
	unsigned short tmp[5];
1903
	unsigned char r19, r9;
1904
	int x;
1905
	int fxsmode=0;
1906
1907
	/* Sanity check the ProSLIC */
1908
	if (!sane && wctdm_proslic_insane(wc, card))
1909
		return -2;
1910
1911
	/* By default, don't send on hook */
1912
	if (reversepolarity)
1913
		wc->mod[card].fxs.idletxhookstate = 5;
1914
	else
1915
		wc->mod[card].fxs.idletxhookstate = 1;
1916
		
1917
	if (sane) {
1918
		/* Make sure we turn off the DC->DC converter to prevent anything from blowing up */
1919
		wctdm_setreg(wc, card, 14, 0x10);
1920
	}
1921
1922
	if (wctdm_proslic_init_indirect_regs(wc, card)) {
1923
		printk(KERN_INFO "Indirect Registers failed to initialize on module %d.\n", card);
1924
		return -1;
1925
	}
1926
1927
	/* Clear scratch pad area */
1928
	wctdm_proslic_setreg_indirect(wc, card, 97,0);
1929
1930
	/* Clear digital loopback */
1931
	wctdm_setreg(wc, card, 8, 0);
1932
1933
	/* Revision C optimization */
1934
	wctdm_setreg(wc, card, 108, 0xeb);
1935
1936
	/* Disable automatic VBat switching for safety to prevent
1937
	   Q7 from accidently turning on and burning out. */
1938
	wctdm_setreg(wc, card, 67, 0x07);  /* Note, if pulse dialing has problems at high REN loads
1939
					      change this to 0x17 */
1940
1941
	/* Turn off Q7 */
1942
	wctdm_setreg(wc, card, 66, 1);
1943
1944
	/* Flush ProSLIC digital filters by setting to clear, while
1945
	   saving old values */
1946
	for (x=0;x<5;x++) {
1947
		tmp[x] = wctdm_proslic_getreg_indirect(wc, card, x + 35);
1948
		wctdm_proslic_setreg_indirect(wc, card, x + 35, 0x8000);
1949
	}
1950
1951
	/* Power up the DC-DC converter */
1952
	if (wctdm_powerup_proslic(wc, card, fast)) {
1953
		printk(KERN_NOTICE "Unable to do INITIAL ProSLIC powerup on module %d\n", card);
1954
		return -1;
1955
	}
1956
1957
	if (!fast) {
1958
1959
		/* Check for power leaks */
1960
		if (wctdm_proslic_powerleak_test(wc, card)) {
1961
			printk(KERN_NOTICE "ProSLIC module %d failed leakage test.  Check for short circuit\n", card);
1962
		}
1963
		/* Power up again */
1964
		if (wctdm_powerup_proslic(wc, card, fast)) {
1965
			printk(KERN_NOTICE "Unable to do FINAL ProSLIC powerup on module %d\n", card);
1966
			return -1;
1967
		}
1968
#ifndef NO_CALIBRATION
1969
		/* Perform calibration */
1970
		if(manual) {
1971
			if (wctdm_proslic_manual_calibrate(wc, card)) {
1972
				//printk(KERN_NOTICE "Proslic failed on Manual Calibration\n");
1973
				if (wctdm_proslic_manual_calibrate(wc, card)) {
1974
					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n");
1975
					return -1;
1976
				}
1977
				printk(KERN_NOTICE "Proslic Passed Manual Calibration on Second Attempt\n");
1978
			}
1979
		}
1980
		else {
1981
			if(wctdm_proslic_calibrate(wc, card))  {
1982
				//printk(KERN_NOTICE "ProSlic died on Auto Calibration.\n");
1983
				if (wctdm_proslic_calibrate(wc, card)) {
1984
					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Auto Calibrate\n");
1985
					return -1;
1986
				}
1987
				printk(KERN_NOTICE "Proslic Passed Auto Calibration on Second Attempt\n");
1988
			}
1989
		}
1990
		/* Perform DC-DC calibration */
1991
		wctdm_setreg(wc, card, 93, 0x99);
1992
		r19 = wctdm_getreg(wc, card, 107);
1993
		if ((r19 < 0x2) || (r19 > 0xd)) {
1994
			printk(KERN_NOTICE "DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19);
1995
			wctdm_setreg(wc, card, 107, 0x8);
1996
		}
1997
1998
		/* Save calibration vectors */
1999
		for (x=0;x<NUM_CAL_REGS;x++)
2000
			wc->mod[card].fxs.calregs.vals[x] = wctdm_getreg(wc, card, 96 + x);
2001
#endif
2002
2003
	} else {
2004
		/* Restore calibration registers */
2005
		for (x=0;x<NUM_CAL_REGS;x++)
2006
			wctdm_setreg(wc, card, 96 + x, wc->mod[card].fxs.calregs.vals[x]);
2007
	}
2008
	/* Calibration complete, restore original values */
2009
	for (x=0;x<5;x++) {
2010
		wctdm_proslic_setreg_indirect(wc, card, x + 35, tmp[x]);
2011
	}
2012
2013
	if (wctdm_proslic_verify_indirect_regs(wc, card)) {
2014
		printk(KERN_INFO "Indirect Registers failed verification.\n");
2015
		return -1;
2016
	}
2017
2018
2019
#if 0
2020
    /* Disable Auto Power Alarm Detect and other "features" */
2021
    wctdm_setreg(wc, card, 67, 0x0e);
2022
    blah = wctdm_getreg(wc, card, 67);
2023
#endif
2024
2025
#if 0
2026
    if (wctdm_proslic_setreg_indirect(wc, card, 97, 0x0)) { // Stanley: for the bad recording fix
2027
		 printk(KERN_INFO "ProSlic IndirectReg Died.\n");
2028
		 return -1;
2029
	}
2030
#endif
2031
2032
    if (alawoverride)
2033
    	wctdm_setreg(wc, card, 1, 0x20);
2034
    else
2035
    	wctdm_setreg(wc, card, 1, 0x28);
2036
  // U-Law 8-bit interface
2037
    wctdm_setreg(wc, card, 2, (3-(card%4)) * 8 + (card/4) * 64);    // Tx Start count low byte  0
2038
    wctdm_setreg(wc, card, 3, 0);    // Tx Start count high byte 0
2039
    wctdm_setreg(wc, card, 4, (3-(card%4)) * 8 + (card/4) * 64);    // Rx Start count low byte  0
2040
    wctdm_setreg(wc, card, 5, 0);    // Rx Start count high byte 0
2041
    wctdm_setreg(wc, card, 18, 0xff);     // clear all interrupt
2042
    wctdm_setreg(wc, card, 19, 0xff);
2043
    wctdm_setreg(wc, card, 20, 0xff);
2044
    wctdm_setreg(wc, card, 73, 0x04);
2045
	if (fxshonormode) {
2046
		fxsmode = acim2tiss[fxo_modes[_opermode].acim];
2047
		wctdm_setreg(wc, card, 10, 0x08 | fxsmode);
2048
		if (fxo_modes[_opermode].ring_osc)
2049
			wctdm_proslic_setreg_indirect(wc, card, 20, fxo_modes[_opermode].ring_osc);
2050
		if (fxo_modes[_opermode].ring_x)
2051
			wctdm_proslic_setreg_indirect(wc, card, 21, fxo_modes[_opermode].ring_x);
2052
	}
2053
    if (lowpower)
2054
    	wctdm_setreg(wc, card, 72, 0x10);
2055
2056
#if 0
2057
    wctdm_setreg(wc, card, 21, 0x00); 	// enable interrupt
2058
    wctdm_setreg(wc, card, 22, 0x02); 	// Loop detection interrupt
2059
    wctdm_setreg(wc, card, 23, 0x01); 	// DTMF detection interrupt
2060
#endif
2061
2062
#if 0
2063
    /* Enable loopback */
2064
    wctdm_setreg(wc, card, 8, 0x2);
2065
    wctdm_setreg(wc, card, 14, 0x0);
2066
    wctdm_setreg(wc, card, 64, 0x0);
2067
    wctdm_setreg(wc, card, 1, 0x08);
2068
#endif
2069
2070
	if (fastringer) {
2071
		/* Speed up Ringer */
2072
		wctdm_proslic_setreg_indirect(wc, card, 20, 0x7e6d);
2073
		wctdm_proslic_setreg_indirect(wc, card, 21, 0x01b9);
2074
		/* Beef up Ringing voltage to 89V */
2075
		if (boostringer) {
2076
			wctdm_setreg(wc, card, 74, 0x3f);
2077
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x247)) 
2078
				return -1;
2079
			printk(KERN_INFO  "Boosting fast ringer on slot %d (89V peak)\n", card + 1);
2080
		} else if (lowpower) {
2081
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x14b)) 
2082
				return -1;
2083
			printk(KERN_INFO  "Reducing fast ring power on slot %d (50V peak)\n", card + 1);
2084
		} else
2085
			printk(KERN_INFO  "Speeding up ringer on slot %d (25Hz)\n", card + 1);
2086
	} else {
2087
		/* Beef up Ringing voltage to 89V */
2088
		if (boostringer) {
2089
			wctdm_setreg(wc, card, 74, 0x3f);
2090
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x1d1)) 
2091
				return -1;
2092
			printk(KERN_INFO  "Boosting ringer on slot %d (89V peak)\n", card + 1);
2093
		} else if (lowpower) {
2094
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x108)) 
2095
				return -1;
2096
			printk(KERN_INFO  "Reducing ring power on slot %d (50V peak)\n", card + 1);
2097
		}
2098
	}
2099
2100
	if(fxstxgain || fxsrxgain) {
2101
		r9 = wctdm_getreg(wc, card, 9);
2102
		switch (fxstxgain) {
2103
		
2104
			case 35:
2105
				r9+=8;
2106
				break;
2107
			case -35:
2108
				r9+=4;
2109
				break;
2110
			case 0: 
2111
				break;
2112
		}
2113
	
2114
		switch (fxsrxgain) {
2115
			
2116
			case 35:
2117
				r9+=2;
2118
				break;
2119
			case -35:
2120
				r9+=1;
2121
				break;
2122
			case 0:
2123
				break;
2124
		}
2125
		wctdm_setreg(wc,card,9,r9);
2126
	}
2127
2128
	if(debug)
2129
		printk(KERN_DEBUG "DEBUG: fxstxgain:%s fxsrxgain:%s\n",((wctdm_getreg(wc, card, 9)/8) == 1)?"3.5":(((wctdm_getreg(wc,card,9)/4) == 1)?"-3.5":"0.0"),((wctdm_getreg(wc, card, 9)/2) == 1)?"3.5":((wctdm_getreg(wc,card,9)%2)?"-3.5":"0.0"));
2130
2131
	wctdm_setreg(wc, card, 64, 0x01);
2132
	return 0;
2133
}
2134
2135
2136
static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
2137
{
2138
	struct wctdm_stats stats;
2139
	struct wctdm_regs regs;
2140
	struct wctdm_regop regop;
2141
	struct wctdm_echo_coefs echoregs;
2142
	struct dahdi_hwgain hwgain;
2143
	struct wctdm *wc = chan->pvt;
2144
	int x;
2145
	switch (cmd) {
2146
	case DAHDI_ONHOOKTRANSFER:
2147
		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2148
			return -EINVAL;
2149
		if (get_user(x, (__user  int *)data))
2150
			return -EFAULT;
2151
		wc->mod[chan->chanpos - 1].fxs.ohttimer = x << 3;
2152
		if (reversepolarity)
2153
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
2154
		else
2155
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x2;
2156
		if (wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x1 || wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x5) {
2157
				/* Apply the change if appropriate */
2158
				if (reversepolarity)
2159
					wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x6;
2160
				else
2161
					wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x2;
2162
				wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
2163
		}
2164
		break;
2165
	case DAHDI_SETPOLARITY:
2166
		if (get_user(x, (__user int *)data))
2167
			return -EFAULT;
2168
		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2169
			return -EINVAL;
2170
		/* Can't change polarity while ringing or when open */
2171
		if ((wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x04) ||
2172
		    (wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x00))
2173
			return -EINVAL;
2174
2175
		if ((x && !reversepolarity) || (!x && reversepolarity))
2176
			wc->mod[chan->chanpos - 1].fxs.lasttxhook |= 0x04;
2177
		else
2178
			wc->mod[chan->chanpos - 1].fxs.lasttxhook &= ~0x04;
2179
		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
2180
		break;
2181
	case WCTDM_GET_STATS:
2182
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2183
			stats.tipvolt = wctdm_getreg(wc, chan->chanpos - 1, 80) * -376;
2184
			stats.ringvolt = wctdm_getreg(wc, chan->chanpos - 1, 81) * -376;
2185
			stats.batvolt = wctdm_getreg(wc, chan->chanpos - 1, 82) * -376;
2186
		} else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2187
			stats.tipvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2188
			stats.ringvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2189
			stats.batvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2190
		} else 
2191
			return -EINVAL;
2192
		if (copy_to_user((__user void *)data, &stats, sizeof(stats)))
2193
			return -EFAULT;
2194
		break;
2195
	case WCTDM_GET_REGS:
2196
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2197
			for (x=0;x<NUM_INDIRECT_REGS;x++)
2198
				regs.indirect[x] = wctdm_proslic_getreg_indirect(wc, chan->chanpos -1, x);
2199
			for (x=0;x<NUM_REGS;x++)
2200
				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
2201
		} else {
2202
			memset(&regs, 0, sizeof(regs));
2203
			for (x=0;x<NUM_FXO_REGS;x++)
2204
				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
2205
		}
2206
		if (copy_to_user((__user void *)data, &regs, sizeof(regs)))
2207
			return -EFAULT;
2208
		break;
2209
	case WCTDM_SET_REG:
2210
		if (copy_from_user(&regop, (__user void *)data, sizeof(regop)))
2211
			return -EFAULT;
2212
		if (regop.indirect) {
2213
			if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2214
				return -EINVAL;
2215
			printk(KERN_INFO  "Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos);
2216
			wctdm_proslic_setreg_indirect(wc, chan->chanpos - 1, regop.reg, regop.val);
2217
		} else {
2218
			regop.val &= 0xff;
2219
			printk(KERN_INFO  "Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos);
2220
			wctdm_setreg(wc, chan->chanpos - 1, regop.reg, regop.val);
2221
		}
2222
		break;
2223
	case WCTDM_SET_ECHOTUNE:
2224
		printk(KERN_INFO  "-- Setting echo registers: \n");
2225
		if (copy_from_user(&echoregs, (__user void *)data, sizeof(echoregs)))
2226
			return -EFAULT;
2227
2228
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2229
			/* Set the ACIM register */
2230
			wctdm_setreg(wc, chan->chanpos - 1, 30, (fxofullscale==1) ? (echoregs.acim|0x10) : echoregs.acim);
2231
2232
			/* Set the digital echo canceller registers */
2233
			wctdm_setreg(wc, chan->chanpos - 1, 45, echoregs.coef1);
2234
			wctdm_setreg(wc, chan->chanpos - 1, 46, echoregs.coef2);
2235
			wctdm_setreg(wc, chan->chanpos - 1, 47, echoregs.coef3);
2236
			wctdm_setreg(wc, chan->chanpos - 1, 48, echoregs.coef4);
2237
			wctdm_setreg(wc, chan->chanpos - 1, 49, echoregs.coef5);
2238
			wctdm_setreg(wc, chan->chanpos - 1, 50, echoregs.coef6);
2239
			wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7);
2240
			wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8);
2241
2242
			printk(KERN_INFO  "-- Set echo registers successfully\n");
2243
2244
			break;
2245
		} else {
2246
			return -EINVAL;
2247
2248
		}
2249
		break;
2250
	case DAHDI_SET_HWGAIN:
2251
		if (copy_from_user(&hwgain, (__user void *) data, sizeof(hwgain)))
2252
			return -EFAULT;
2253
2254
		wctdm_set_hwgain(wc, chan->chanpos-1, hwgain.newgain, hwgain.tx);
2255
2256
		if (debug)
2257
			printk(KERN_DEBUG  "Setting hwgain on channel %d to %d for %s direction\n", 
2258
				chan->chanpos-1, hwgain.newgain, hwgain.tx ? "tx" : "rx");
2259
		break;
2260
	default:
2261
		return -ENOTTY;
2262
	}
2263
	return 0;
2264
2265
}
2266
2267
static int wctdm_open(struct dahdi_chan *chan)
2268
{
2269
	struct wctdm *wc = chan->pvt;
2270
	if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
2271
		return -ENODEV;
2272
	if (wc->dead)
2273
		return -ENODEV;
2274
	wc->usecount++;
2275
2276
	/*MOD_INC_USE_COUNT; */
2277
	try_module_get(THIS_MODULE);
2278
	return 0;
2279
}
2280
2281
static inline struct wctdm *wctdm_from_span(struct dahdi_span *span)
2282
{
2283
	return container_of(span, struct wctdm, span);
2284
}
2285
2286
static int wctdm_watchdog(struct dahdi_span *span, int event)
2287
{
2288
	printk(KERN_INFO "opvxa1200: Restarting DMA\n");
2289
	wctdm_restart_dma(wctdm_from_span(span));
2290
	return 0;
2291
}
2292
2293
static int wctdm_close(struct dahdi_chan *chan)
2294
{
2295
	struct wctdm *wc = chan->pvt;
2296
	wc->usecount--;
2297
2298
	/*MOD_DEC_USE_COUNT;*/
2299
	module_put(THIS_MODULE);
2300
2301
	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2302
		if (reversepolarity)
2303
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 5;
2304
		else
2305
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 1;
2306
	}
2307
	/* If we're dead, release us now */
2308
	if (!wc->usecount && wc->dead) 
2309
		wctdm_release(wc);
2310
	return 0;
2311
}
2312
2313
static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
2314
{
2315
	struct wctdm *wc = chan->pvt;
2316
	int reg=0;
2317
	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2318
		/* XXX Enable hooksig for FXO XXX */
2319
		switch(txsig) {
2320
		case DAHDI_TXSIG_START:
2321
		case DAHDI_TXSIG_OFFHOOK:
2322
			wc->mod[chan->chanpos - 1].fxo.offhook = 1;
2323
			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x9);
2324
			if(cidbeforering)
2325
			{
2326
				wc->cid_state[chan->chanpos - 1] = CID_STATE_IDLE;
2327
				wc->cid_history_clone_cnt[chan->chanpos - 1] = 0;
2328
				wc->cid_history_ptr[chan->chanpos - 1] = 0;
2329
				memset(wc->cid_history_buf[chan->chanpos - 1], DAHDI_LIN2X(0, chan), cidbuflen * DAHDI_MAX_CHUNKSIZE);
2330
			}
2331
			break;
2332
		case DAHDI_TXSIG_ONHOOK:
2333
			wc->mod[chan->chanpos - 1].fxo.offhook = 0;
2334
			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x8);
2335
			break;
2336
		default:
2337
			printk(KERN_NOTICE "wcfxo: Can't set tx state to %d\n", txsig);
2338
		}
2339
	} else {
2340
		switch(txsig) {
2341
		case DAHDI_TXSIG_ONHOOK:
2342
			switch(chan->sig) {
2343
			case DAHDI_SIG_EM:
2344
			case DAHDI_SIG_FXOKS:
2345
			case DAHDI_SIG_FXOLS:
2346
				wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
2347
				break;
2348
			case DAHDI_SIG_FXOGS:
2349
				wc->mod[chan->chanpos-1].fxs.lasttxhook = 3;
2350
				break;
2351
			}
2352
			break;
2353
		case DAHDI_TXSIG_OFFHOOK:
2354
			switch(chan->sig) {
2355
			case DAHDI_SIG_EM:
2356
				wc->mod[chan->chanpos-1].fxs.lasttxhook = 5;
2357
				break;
2358
			default:
2359
				wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
2360
				break;
2361
			}
2362
			break;
2363
		case DAHDI_TXSIG_START:
2364
			wc->mod[chan->chanpos-1].fxs.lasttxhook = 4;
2365
			break;
2366
		case DAHDI_TXSIG_KEWL:
2367
			wc->mod[chan->chanpos-1].fxs.lasttxhook = 0;
2368
			break;
2369
		default:
2370
			printk(KERN_NOTICE "opvxa1200: Can't set tx state to %d\n", txsig);
2371
		}
2372
		if (debug)
2373
			printk(KERN_DEBUG "Setting FXS hook state to %d (%02x)\n", txsig, reg);
2374
2375
#if 1
2376
		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos-1].fxs.lasttxhook);
2377
#endif
2378
	}
2379
	return 0;
2380
}
2381
2382
#ifdef DAHDI_SPAN_OPS
2383
static const struct dahdi_span_ops wctdm_span_ops = {
2384
	.owner = THIS_MODULE,
2385
	.hooksig = wctdm_hooksig,
2386
	.open = wctdm_open,
2387
	.close = wctdm_close,
2388
	.ioctl = wctdm_ioctl,
2389
	.watchdog = wctdm_watchdog,
2390
};
2391
#endif
2392
2393
static int wctdm_initialize(struct wctdm *wc)
2394
{
2395
	int x;
2396
2397
	/* Dahdi stuff */
2398
	sprintf(wc->span.name, "OPVXA1200/%d", wc->pos);
2399
	snprintf(wc->span.desc, sizeof(wc->span.desc)-1, "%s Board %d", wc->variety, wc->pos + 1);
2400
	wc->ddev->location = kasprintf(GFP_KERNEL,
2401
				      "PCI Bus %02d Slot %02d",
2402
				      wc->dev->bus->number,
2403
				      PCI_SLOT(wc->dev->devfn) + 1);
2404
	if (!wc->ddev->location) {
2405
		dahdi_free_device(wc->ddev);
2406
		wc->ddev = NULL;
2407
		return -ENOMEM;
2408
	}
2409
	wc->ddev->manufacturer = "OpenVox";
2410
	wc->ddev->devicetype = wc->variety;
2411
	if (alawoverride) {
2412
		printk(KERN_INFO "ALAW override parameter detected.  Device will be operating in ALAW\n");
2413
		wc->span.deflaw = DAHDI_LAW_ALAW;
2414
	} else
2415
		wc->span.deflaw = DAHDI_LAW_MULAW;
2416
		
2417
	x = __wctdm_getcreg(wc, WC_VER);
2418
	wc->fwversion = x;
2419
	if( x & FLAG_A800)
2420
	{
2421
		wc->card_name = A800P_Name;
2422
		wc->max_cards = 8;
2423
	}
2424
	else
2425
	{
2426
		wc->card_name = A1200P_Name;
2427
		wc->max_cards = 12;
2428
	}
2429
		
2430
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2431
		sprintf(wc->chans[x]->name, "OPVXA1200/%d/%d", wc->pos, x);
2432
		wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
2433
		wc->chans[x]->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
2434
		wc->chans[x]->chanpos = x+1;
2435
		wc->chans[x]->pvt = wc;
2436
	}
2437
2438
#ifdef DAHDI_SPAN_MODULE	
2439
		wc->span.owner = THIS_MODULE;
2440
#endif
2441
2442
#ifdef DAHDI_SPAN_OPS
2443
	wc->span.ops = &wctdm_span_ops;
2444
#else
2445
		wc->span.hooksig = wctdm_hooksig,
2446
		wc->span.watchdog = wctdm_watchdog,
2447
		wc->span.open = wctdm_open;
2448
		wc->span.close  = wctdm_close;
2449
		wc->span.ioctl = wctdm_ioctl;
2450
		wc->span.pvt = wc;
2451
#endif
2452
	wc->span.chans = wc->chans;
2453
	wc->span.channels = wc->max_cards;	/*MAX_NUM_CARDS;*/
2454
	wc->span.flags = DAHDI_FLAG_RBS;
2455
	wc->span.ops = &wctdm_span_ops;
2456
2457
	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
2458
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
2459
		printk(KERN_NOTICE "Unable to register device %s with DAHDI\n",
2460
				wc->span.name);
2461
		kfree(wc->ddev->location);
2462
		dahdi_free_device(wc->ddev);
2463
		wc->ddev = NULL;
2464
		return -1;
2465
	}
2466
	return 0;
2467
}
2468
2469
static void wctdm_post_initialize(struct wctdm *wc)
2470
{
2471
	int x;
2472
2473
	/* Finalize signalling  */
2474
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2475
		if (wc->cardflag & (1 << x)) {
2476
			if (wc->modtype[x] == MOD_TYPE_FXO)
2477
				wc->chans[x]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
2478
			else
2479
				wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
2480
		} else if (!(wc->chans[x]->sigcap & DAHDI_SIG_BROKEN)) {
2481
			wc->chans[x]->sigcap = 0;
2482
		}
2483
	}
2484
}
2485
2486
static int wctdm_hardware_init(struct wctdm *wc)
2487
{
2488
	/* Hardware stuff */
2489
	unsigned char ver;
2490
	unsigned char x,y;
2491
	int failed;
2492
	long origjiffies; //ml.
2493
	
2494
	/* Signal Reset */
2495
	printk("before raise reset\n");
2496
	outb(0x01, wc->ioaddr + WC_CNTL);
2497
2498
	/* Wait for 5 second */
2499
	
2500
	origjiffies = jiffies;
2501
2502
	while(1) 
2503
	{
2504
		if ((jiffies - origjiffies) >= (HZ*5))
2505
			break;;
2506
	}
2507
2508
	/* printk(KERN_INFO "after raise reset\n");*/
2509
2510
	/* Check OpenVox chip */
2511
	x=inb(wc->ioaddr + WC_CNTL);
2512
	ver = __wctdm_getcreg(wc, WC_VER);
2513
	wc->fwversion = ver;
2514
	/*if( ver & FLAG_A800)
2515
	{
2516
		wc->card_name = A800P_Name;
2517
		wc->max_cards = 8;
2518
	}
2519
	else
2520
	{
2521
		wc->card_name = A1200P_Name;
2522
		wc->max_cards = 12;
2523
	}*/
2524
	printk(KERN_NOTICE "OpenVox %s version: %01x.%01x\n", wc->card_name, (ver&(~FLAG_A800))>>4, ver&0x0f);
2525
	
2526
	failed = 0;
2527
	if (ver != 0x00) {
2528
		for (x=0;x<16;x++) {
2529
			/* Test registers */
2530
			__wctdm_setcreg(wc, WC_CS, x);
2531
			y = __wctdm_getcreg(wc, WC_CS) & 0x0f;
2532
			if (x != y) {
2533
				printk(KERN_INFO "%02x != %02x\n", x, y);
2534
				failed++;
2535
			}
2536
		}
2537
2538
		if (!failed) {
2539
			printk(KERN_INFO "OpenVox %s passed register test\n", wc->card_name);
2540
		} else {
2541
			printk(KERN_NOTICE "OpenVox %s failed register test\n", wc->card_name);
2542
			return -1;
2543
		}
2544
	} else {
2545
		printk(KERN_INFO "No OpenVox chip %02x\n", ver);
2546
	}
2547
2548
	if (spibyhw)
2549
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);	// spi controled by hw MiaoLin;
2550
	else
2551
		__wctdm_setcreg(wc, WC_SPICTRL, 0);	
2552
		
2553
	/* Reset PCI Interface chip and registers (and serial) */
2554
	outb(0x06, wc->ioaddr + WC_CNTL);
2555
	/* Setup our proper outputs for when we switch for our "serial" port */
2556
	wc->ios = BIT_CS | BIT_SCLK | BIT_SDI;
2557
2558
	outb(wc->ios, wc->ioaddr + WC_AUXD);
2559
2560
	/* Set all to outputs except AUX 5, which is an input */
2561
	outb(0xdf, wc->ioaddr + WC_AUXC);
2562
2563
	/* Select alternate function for AUX0 */  /* Useless in OpenVox by MiaoLin. */
2564
	/* outb(0x4, wc->ioaddr + WC_AUXFUNC); */
2565
	
2566
	/* Wait 1/4 of a sec */
2567
	wait_just_a_bit(HZ/4);
2568
2569
	/* Back to normal, with automatic DMA wrap around */
2570
	outb(0x30 | 0x01, wc->ioaddr + WC_CNTL);
2571
	wc->ledstate = 0;
2572
	wctdm_set_led(wc, 0, 0);
2573
	
2574
	/* Make sure serial port and DMA are out of reset */
2575
	outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, wc->ioaddr + WC_CNTL);
2576
	
2577
	/* Configure serial port for MSB->LSB operation */
2578
	outb(0xc1, wc->ioaddr + WC_SERCTL);
2579
2580
	/* Delay FSC by 0 so it's properly aligned */
2581
	outb(0x01, wc->ioaddr + WC_FSCDELAY);  /* Modify to 1 by MiaoLin */
2582
2583
	/* Setup DMA Addresses */
2584
	outl(wc->writedma,                    wc->ioaddr + WC_DMAWS);		/* Write start */
2585
	outl(wc->writedma + DAHDI_CHUNKSIZE * 4 * 4 - 4, wc->ioaddr + WC_DMAWI);		/* Middle (interrupt) */
2586
	outl(wc->writedma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMAWE);			/* End */
2587
	
2588
	outl(wc->readdma,                    	 wc->ioaddr + WC_DMARS);	/* Read start */
2589
	outl(wc->readdma + DAHDI_CHUNKSIZE * 4 * 4 - 4, 	 wc->ioaddr + WC_DMARI);	/* Middle (interrupt) */
2590
	outl(wc->readdma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMARE);	/* End */
2591
	
2592
	/* Clear interrupts */
2593
	outb(0xff, wc->ioaddr + WC_INTSTAT);
2594
2595
	/* Wait 1/4 of a second more */
2596
	wait_just_a_bit(HZ/4);
2597
2598
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2599
		int sane=0,ret=0,readi=0;
2600
#if 1
2601
		touch_softlockup_watchdog();  // avoid showing CPU softlock message
2602
		/* Init with Auto Calibration */
2603
		if (!(ret=wctdm_init_proslic(wc, x, 0, 0, sane))) {
2604
			wc->cardflag |= (1 << x);
2605
                        if (debug) {
2606
                                readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
2607
                                printk("Proslic module %d loop current is %dmA\n",x,
2608
                                ((readi*3)+20));
2609
                        }
2610
			printk(KERN_INFO "Module %d: Installed -- AUTO FXS/DPO\n",x);
2611
			wctdm_set_led(wc, (unsigned int)x, 1);
2612
		} else {
2613
			if(ret!=-2) {
2614
				sane=1;
2615
				
2616
				printk(KERN_INFO "Init ProSlic with Manual Calibration \n");
2617
				/* Init with Manual Calibration */
2618
				if (!wctdm_init_proslic(wc, x, 0, 1, sane)) {
2619
					wc->cardflag |= (1 << x);
2620
                                if (debug) {
2621
                                        readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
2622
                                        printk("Proslic module %d loop current is %dmA\n",x,
2623
                                        ((readi*3)+20));
2624
                                }
2625
					printk(KERN_INFO "Module %d: Installed -- MANUAL FXS\n",x);
2626
				} else {
2627
					printk(KERN_NOTICE "Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");
2628
					wc->chans[x]->sigcap = __DAHDI_SIG_FXO | DAHDI_SIG_BROKEN;
2629
				} 
2630
			} else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) {
2631
				wc->cardflag |= (1 << x);
2632
				printk(KERN_INFO "Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);
2633
				wctdm_set_led(wc, (unsigned int)x, 1);
2634
			} else
2635
				printk(KERN_NOTICE "Module %d: Not installed\n", x);
2636
		}
2637
#endif
2638
	}
2639
2640
	/* Return error if nothing initialized okay. */
2641
	if (!wc->cardflag && !timingonly)
2642
		return -1;
2643
	/*__wctdm_setcreg(wc, WC_SYNC, (wc->cardflag << 1) | 0x1); */  /* removed by MiaoLin */
2644
	return 0;
2645
}
2646
2647
static void wctdm_enable_interrupts(struct wctdm *wc)
2648
{
2649
	/* Clear interrupts */
2650
	outb(0xff, wc->ioaddr + WC_INTSTAT);
2651
2652
	/* Enable interrupts (we care about all of them) */
2653
	outb(0x3c, wc->ioaddr + WC_MASK0);
2654
	/* No external interrupts */
2655
	outb(0x00, wc->ioaddr + WC_MASK1);
2656
}
2657
2658
static void wctdm_restart_dma(struct wctdm *wc)
2659
{
2660
	/* Reset Master and TDM */
2661
	outb(0x01, wc->ioaddr + WC_CNTL);
2662
	outb(0x01, wc->ioaddr + WC_OPER);
2663
}
2664
2665
static void wctdm_start_dma(struct wctdm *wc)
2666
{
2667
	/* Reset Master and TDM */
2668
	outb(0x0f, wc->ioaddr + WC_CNTL);
2669
	set_current_state(TASK_INTERRUPTIBLE);
2670
	schedule_timeout(1);
2671
	outb(0x01, wc->ioaddr + WC_CNTL);
2672
	outb(0x01, wc->ioaddr + WC_OPER);
2673
}
2674
2675
static void wctdm_stop_dma(struct wctdm *wc)
2676
{
2677
	outb(0x00, wc->ioaddr + WC_OPER);
2678
}
2679
2680
static void wctdm_reset_tdm(struct wctdm *wc)
2681
{
2682
	/* Reset TDM */
2683
	outb(0x0f, wc->ioaddr + WC_CNTL);
2684
}
2685
2686
static void wctdm_disable_interrupts(struct wctdm *wc)	
2687
{
2688
	outb(0x00, wc->ioaddr + WC_MASK0);
2689
	outb(0x00, wc->ioaddr + WC_MASK1);
2690
}
2691
2692
static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2693
{
2694
	int res;
2695
	struct wctdm *wc;
2696
	struct wctdm_desc *d = (struct wctdm_desc *)ent->driver_data;
2697
	int x;
2698
	int y;
2699
2700
	static int initd_ifaces=0;
2701
	
2702
	if(initd_ifaces){
2703
		memset((void *)ifaces,0,(sizeof(struct wctdm *))*WC_MAX_IFACES);
2704
		initd_ifaces=1;
2705
	}
2706
	for (x=0;x<WC_MAX_IFACES;x++)
2707
		if (!ifaces[x]) break;
2708
	if (x >= WC_MAX_IFACES) {
2709
		printk(KERN_NOTICE "Too many interfaces\n");
2710
		return -EIO;
2711
	}
2712
	
2713
	if (pci_enable_device(pdev)) {
2714
		res = -EIO;
2715
	} else {
2716
		wc = kmalloc(sizeof(struct wctdm), GFP_KERNEL);
2717
		if (wc) {
2718
			int cardcount = 0;
2719
			
2720
			wc->lastchan = -1;	/* first channel offset = -1; */
2721
			wc->ledstate = 0;
2722
			
2723
			ifaces[x] = wc;
2724
			memset(wc, 0, sizeof(struct wctdm));
2725
			for (x=0; x < sizeof(wc->chans)/sizeof(wc->chans[0]); ++x) {
2726
				wc->chans[x] = &wc->_chans[x];
2727
			}
2728
2729
			spin_lock_init(&wc->lock);
2730
			wc->curcard = -1;
2731
			wc->ioaddr = pci_resource_start(pdev, 0);
2732
			wc->mem_region = pci_resource_start(pdev, 1);
2733
			wc->mem_len = pci_resource_len(pdev, 1);
2734
			wc->mem32 = (unsigned long)ioremap(wc->mem_region, wc->mem_len);
2735
			wc->dev = pdev;
2736
			wc->pos = x;
2737
			wc->variety = d->name;
2738
			for (y=0;y<MAX_NUM_CARDS;y++)
2739
				wc->flags[y] = d->flags;
2740
			/* Keep track of whether we need to free the region */
2741
			if (request_region(wc->ioaddr, 0xff, "opvxa1200")) 
2742
				wc->freeregion = 1;
2743
			else
2744
				wc->freeregion = 0;
2745
			
2746
			if (request_mem_region(wc->mem_region, wc->mem_len, "opvxa1200"))
2747
				wc->freeregion |= 0x02;
2748
2749
			/* Allocate enough memory for two zt chunks, receive and transmit.  Each sample uses
2750
			   8 bits.  */
2751
			wc->writechunk = pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, &wc->writedma);
2752
			if (!wc->writechunk) {
2753
				printk(KERN_NOTICE "opvxa1200: Unable to allocate DMA-able memory\n");
2754
				if (wc->freeregion & 0x01)
2755
					release_region(wc->ioaddr, 0xff);
2756
				if (wc->freeregion & 0x02)
2757
				{
2758
					release_mem_region(wc->mem_region, wc->mem_len);
2759
					iounmap((void *)wc->mem32);
2760
				}
2761
				return -ENOMEM;
2762
			}
2763
2764
			wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
2765
			wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
2766
			
2767
			if (wctdm_initialize(wc)) {
2768
				printk(KERN_NOTICE "opvxa1200: Unable to intialize FXS\n");
2769
				/* Set Reset Low */
2770
				x=inb(wc->ioaddr + WC_CNTL);
2771
				outb((~0x1)&x, wc->ioaddr + WC_CNTL);
2772
				/* Free Resources */
2773
				free_irq(pdev->irq, wc);
2774
				if (wc->freeregion & 0x01)
2775
					release_region(wc->ioaddr, 0xff);
2776
				if (wc->freeregion & 0x02)
2777
				{
2778
					release_mem_region(wc->mem_region, wc->mem_len);
2779
					iounmap((void *)wc->mem32);
2780
				}
2781
			}
2782
2783
			/* Enable bus mastering */
2784
			pci_set_master(pdev);
2785
2786
			/* Keep track of which device we are */
2787
			pci_set_drvdata(pdev, wc);
2788
2789
2790
			if (request_irq(pdev->irq, wctdm_interrupt, IRQF_SHARED, "opvxa1200", wc)) {
2791
				printk(KERN_NOTICE "opvxa1200: Unable to request IRQ %d\n", pdev->irq);
2792
				if (wc->freeregion & 0x01)
2793
					release_region(wc->ioaddr, 0xff);
2794
				if (wc->freeregion & 0x02)
2795
				{
2796
					release_mem_region(wc->mem_region, wc->mem_len);
2797
					iounmap((void *)wc->mem32);
2798
				}
2799
				pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2800
				pci_set_drvdata(pdev, NULL);
2801
				kfree(wc);
2802
				return -EIO;
2803
			}
2804
2805
			if (wctdm_hardware_init(wc)) {
2806
				unsigned char w;
2807
2808
				/* Set Reset Low */
2809
				w=inb(wc->ioaddr + WC_CNTL);
2810
				outb((~0x1)&w, wc->ioaddr + WC_CNTL);
2811
				/* Free Resources */
2812
				free_irq(pdev->irq, wc);
2813
				if (wc->freeregion & 0x01)
2814
					release_region(wc->ioaddr, 0xff);
2815
				if (wc->freeregion & 0x02)
2816
				{
2817
					release_mem_region(wc->mem_region, wc->mem_len);
2818
					iounmap((void *)wc->mem32);
2819
				}
2820
				pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2821
				pci_set_drvdata(pdev, NULL);
2822
				dahdi_unregister_device(wc->ddev);
2823
				kfree(wc->ddev->location);
2824
				dahdi_free_device(wc->ddev);
2825
				kfree(wc);
2826
				return -EIO;
2827
2828
			}
2829
2830
#ifdef TEST_LOG_INCOME_VOICE
2831
			for(x=0; x<MAX_NUM_CARDS+NUM_FLAG; x++)
2832
			{
2833
				wc->voc_buf[x] = kmalloc(voc_buffer_size, GFP_KERNEL);
2834
				wc->voc_ptr[x] = 0;
2835
			}
2836
#endif
2837
2838
			if(cidbeforering) 
2839
			{		
2840
				int len = cidbuflen * DAHDI_MAX_CHUNKSIZE;
2841
				if(debug)
2842
					printk("cidbeforering support enabled, length is %d msec\n", cidbuflen);
2843
				for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) 
2844
				{
2845
					wc->cid_history_buf[x] = kmalloc(len, GFP_KERNEL);
2846
					wc->cid_history_ptr[x] = 0;
2847
					wc->cid_history_clone_cnt[x] = 0;
2848
					wc->cid_state[x] = CID_STATE_IDLE;
2849
				}
2850
			}
2851
			
2852
			wctdm_post_initialize(wc);
2853
2854
			/* Enable interrupts */
2855
			wctdm_enable_interrupts(wc);
2856
			/* Initialize Write/Buffers to all blank data */
2857
			memset((void *)wc->writechunk,0, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2);
2858
2859
			/* Start DMA */
2860
			wctdm_start_dma(wc);
2861
2862
			for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2863
				if (wc->cardflag & (1 << x))
2864
					cardcount++;
2865
			}
2866
2867
			printk(KERN_INFO "Found an OpenVox %s: Version %x.%x (%d modules)\n", wc->card_name, (wc->fwversion&(~FLAG_A800))>>4, wc->fwversion&0x0f, cardcount);
2868
			if(debug)
2869
				printk(KERN_DEBUG "OpenVox %s debug On\n", wc->card_name);
2870
			
2871
			res = 0;
2872
		} else
2873
			res = -ENOMEM;
2874
	}
2875
	return res;
2876
}
2877
2878
static void wctdm_release(struct wctdm *wc)
2879
{
2880
#ifdef TEST_LOG_INCOME_VOICE
2881
	struct file * f = NULL;
2882
	mm_segment_t orig_fs;
2883
	int i;
2884
	char fname[20];
2885
#endif
2886
	
2887
	dahdi_unregister_device(wc->ddev);
2888
	kfree(wc->ddev->location);
2889
	dahdi_free_device(wc->ddev);
2890
	if (wc->freeregion & 0x01)
2891
		release_region(wc->ioaddr, 0xff);
2892
	if (wc->freeregion & 0x02)
2893
	{
2894
		release_mem_region(wc->mem_region, wc->mem_len);
2895
		iounmap((void *)wc->mem32);
2896
	}
2897
	
2898
#ifdef TEST_LOG_INCOME_VOICE
2899
	for(i=0; i<MAX_NUM_CARDS + NUM_FLAG; i++)
2900
	{
2901
		sprintf(fname, "//usr//%d.pcm", i); 
2902
		f = filp_open(fname, O_RDWR|O_CREAT, 00);
2903
	
2904
		if (!f || !f->f_op || !f->f_op->read)
2905
		{
2906
			printk("WARNING: File (read) object is a null pointer!!!\n");
2907
			continue;
2908
		}
2909
	
2910
		f->f_pos = 0;
2911
		
2912
		orig_fs = get_fs();
2913
		set_fs(KERNEL_DS); 
2914
		
2915
		if(wc->voc_buf[i])
2916
		{
2917
			f->f_op->write(f, wc->voc_buf[i], voc_buffer_size, &f->f_pos);
2918
			kfree(wc->voc_buf[i]);
2919
		}
2920
		
2921
		set_fs(orig_fs); 
2922
		fput(f);
2923
	}
2924
#endif
2925
 
2926
	if(cidbeforering) 
2927
	{
2928
		int x;
2929
		for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) 
2930
			kfree(wc->cid_history_buf[x]);
2931
	}
2932
 
2933
	kfree(wc);
2934
	printk(KERN_INFO "Free an OpenVox A1200 card\n");
2935
}
2936
2937
static void __devexit wctdm_remove_one(struct pci_dev *pdev)
2938
{
2939
	struct wctdm *wc = pci_get_drvdata(pdev);
2940
	if (wc) {
2941
2942
		/* Stop any DMA */
2943
		wctdm_stop_dma(wc);
2944
		wctdm_reset_tdm(wc);
2945
2946
		/* In case hardware is still there */
2947
		wctdm_disable_interrupts(wc);
2948
		
2949
		/* Immediately free resources */
2950
		pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2951
		free_irq(pdev->irq, wc);
2952
2953
		/* Reset PCI chip and registers */
2954
		if(wc->fwversion > 0x11)
2955
			outb(0x0e, wc->ioaddr + WC_CNTL);
2956
		else
2957
		{
2958
			wc->ledstate = 0;
2959
			wctdm_set_led(wc,0,0);	// power off all leds.
2960
		}
2961
2962
		/* Release span, possibly delayed */
2963
		if (!wc->usecount)
2964
			wctdm_release(wc);
2965
		else
2966
			wc->dead = 1;
2967
	}
2968
}
2969
2970
static struct pci_device_id wctdm_pci_tbl[] = {
2971
	{ 0xe159, 0x0001, 0x9100, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2972
	{ 0xe159, 0x0001, 0x9519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2973
	{ 0xe159, 0x0001, 0x95D9, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2974
	{ 0xe159, 0x0001, 0x9500, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2975
	{ 0xe159, 0x0001, 0x9532, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme }, 
2976
	{ 0xe159, 0x0001, 0x8519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2977
	{ 0xe159, 0x0001, 0x9559, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2978
	{ 0xe159, 0x0001, 0x9599, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2979
	{ 0 }
2980
};
2981
2982
MODULE_DEVICE_TABLE(pci, wctdm_pci_tbl);
2983
2984
static struct pci_driver wctdm_driver = {
2985
	.name = "opvxa1200",
2986
	.probe =	wctdm_init_one,
2987
	.remove =	__devexit_p(wctdm_remove_one),
2988
	.suspend = NULL,
2989
	.resume =	NULL,
2990
	.id_table = wctdm_pci_tbl,
2991
};
2992
2993
static int __init wctdm_init(void)
2994
{
2995
	int res;
2996
	int x;
2997
	for (x=0;x<(sizeof(fxo_modes) / sizeof(fxo_modes[0])); x++) {
2998
		if (!strcmp(fxo_modes[x].name, opermode))
2999
			break;
3000
	}
3001
	if (x < sizeof(fxo_modes) / sizeof(fxo_modes[0])) {
3002
		_opermode = x;
3003
	} else {
3004
		printk(KERN_NOTICE "Invalid/unknown operating mode '%s' specified.  Please choose one of:\n", opermode);
3005
		for (x=0;x<sizeof(fxo_modes) / sizeof(fxo_modes[0]); x++)
3006
			printk(KERN_INFO "  %s\n", fxo_modes[x].name);
3007
		printk(KERN_INFO "Note this option is CASE SENSITIVE!\n");
3008
		return -ENODEV;
3009
	}
3010
	if (!strcmp(fxo_modes[_opermode].name, "AUSTRALIA")) {
3011
		boostringer=1;
3012
		fxshonormode=1;
3013
}
3014
	if (battdebounce == 0) {
3015
		battdebounce = fxo_modes[_opermode].battdebounce;
3016
	}
3017
	if (battalarm == 0) {
3018
		battalarm = fxo_modes[_opermode].battalarm;
3019
	}
3020
	if (battthresh == 0) {
3021
		battthresh = fxo_modes[_opermode].battthresh;
3022
	}
3023
3024
	res = pci_register_driver(&wctdm_driver);
3025
	if (res)
3026
		return -ENODEV;
3027
	return 0;
3028
}
3029
3030
static void __exit wctdm_cleanup(void)
3031
{
3032
	pci_unregister_driver(&wctdm_driver);
3033
}
3034
3035
module_param(debug, int, 0600);
3036
module_param(loopcurrent, int, 0600);
3037
module_param(reversepolarity, int, 0600);
3038
module_param(robust, int, 0600);
3039
module_param(opermode, charp, 0600);
3040
module_param(timingonly, int, 0600);
3041
module_param(lowpower, int, 0600);
3042
module_param(boostringer, int, 0600);
3043
module_param(fastringer, int, 0600);
3044
module_param(fxshonormode, int, 0600);
3045
module_param(battdebounce, uint, 0600);
3046
module_param(battthresh, uint, 0600);
3047
module_param(battalarm, uint, 0600);
3048
module_param(ringdebounce, int, 0600);
3049
module_param(dialdebounce, int, 0600);
3050
module_param(fwringdetect, int, 0600);
3051
module_param(alawoverride, int, 0600);
3052
module_param(fastpickup, int, 0600);
3053
module_param(fxotxgain, int, 0600);
3054
module_param(fxorxgain, int, 0600);
3055
module_param(fxstxgain, int, 0600);
3056
module_param(fxsrxgain, int, 0600);
3057
module_param(spibyhw, int, 0600);
3058
module_param(usememio, int, 0600);
3059
module_param(cidbeforering, int, 0600);
3060
module_param(cidbuflen, int, 0600);
3061
module_param(cidtimeout, int, 0600);
3062
module_param(fxofullscale, int, 0600);
3063
module_param(fixedtimepolarity, int, 0600);
3064
3065
MODULE_DESCRIPTION("OpenVox A1200 Driver");
3066
MODULE_AUTHOR("MiaoLin <miaolin@openvox.com.cn>");
3067
MODULE_LICENSE("GPL v2");
3068
3069
module_init(wctdm_init);
3070
module_exit(wctdm_cleanup);
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/Kbuild (+32 lines)
Line 0 Link Here
1
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115) += opvxd115.o
2
3
FIRM_DIR	:= ../firmware
4
5
EXTRA_CFLAGS += -I$(src)/.. $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
6
7
ifeq ($(HOTPLUG_FIRMWARE),yes)
8
  EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
9
endif
10
11
opvxd115-objs := base.o vpm450m.o
12
13
DAHDI_KERNEL_H_NAME:=kernel.h
14
DAHDI_KERNEL_H_PATH:=$(DAHDI_INCLUDE)/dahdi/$(DAHDI_KERNEL_H_NAME)
15
ifneq ($(DAHDI_KERNEL_H_PATH),)
16
        DAHDI_SPAN_MODULE:=$(shell if grep -C 5 "struct dahdi_span {" $(DAHDI_KERNEL_H_PATH) | grep -q "struct module \*owner"; then echo "yes"; else echo "no"; fi)
17
        DAHDI_SPAN_OPS:=$(shell if grep -q "struct dahdi_span_ops {" $(DAHDI_KERNEL_H_PATH); then echo "yes"; else echo "no"; fi)
18
        ifeq ($(DAHDI_SPAN_MODULE),yes)
19
                EXTRA_CFLAGS+=-DDAHDI_SPAN_MODULE
20
        else
21
                ifeq ($(DAHDI_SPAN_OPS),yes)
22
                        EXTRA_CFLAGS+=-DDAHDI_SPAN_OPS
23
                endif
24
        endif
25
endif
26
27
ifneq ($(HOTPLUG_FIRMWARE),yes)
28
opvxd115-objs += $(FIRM_DIR)/dahdi-fw-oct6114-032.o
29
endif
30
31
$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-032.o: $(obj)/base.o
32
	$(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-oct6114-032.o
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/Makefile (+8 lines)
Line 0 Link Here
1
ifdef KBUILD_EXTMOD
2
# We only get here on kernels 2.6.0-2.6.9 .
3
# For newer kernels, Kbuild will be included directly by the kernel
4
# build system.
5
include $(src)/Kbuild
6
7
else
8
endif
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/base.c (+4908 lines)
Line 0 Link Here
1
/*
2
 * OpenVox D115P/D115E PCI/PCI-E Driver version 0.1 01/07/2011
3
 *
4
 * Written by Mark Spencer <markster@digium.com>
5
 * Modify from wct4xxp module by mark.liu@openvox.cn
6
7
 * Based on previous works, designs, and archetectures conceived and
8
 * written by Jim Dixon <jim@lambdatel.com>.
9
 *
10
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
11
 * Copyright (C) 2001-2010, Digium, Inc.
12
 *
13
 * All rights reserved.
14
 *
15
 */
16
17
/*
18
 * See http://www.asterisk.org for more information about
19
 * the Asterisk project. Please do not directly contact
20
 * any of the maintainers of this project for assistance;
21
 * the project provides a web site, mailing lists and IRC
22
 * channels for your use.
23
 *
24
 * This program is free software, distributed under the terms of
25
 * the GNU General Public License Version 2 as published by the
26
 * Free Software Foundation. See the LICENSE file included with
27
 * this program for more details.
28
 */
29
30
#include <linux/kernel.h>
31
#include <linux/errno.h>
32
#include <linux/module.h>
33
#include <linux/pci.h>
34
#include <linux/init.h>
35
#include <linux/sched.h>
36
#include <linux/interrupt.h>
37
#include <linux/spinlock.h>
38
#include <asm/io.h>
39
#include <linux/version.h>
40
#include <linux/delay.h>
41
#include <linux/moduleparam.h>
42
43
#include <dahdi/kernel.h>
44
45
#include "opvxd115.h"
46
#include "vpm450m.h"
47
48
/* Work queues are a way to better distribute load on SMP systems */
49
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
50
/*
51
 * Work queues can significantly improve performance and scalability
52
 * on multi-processor machines, but requires bypassing some kernel
53
 * API's, so it's not guaranteed to be compatible with all kernels.
54
 */
55
/* #define ENABLE_WORKQUEUES */
56
#endif
57
58
/* Enable prefetching may help performance */
59
#define ENABLE_PREFETCH
60
61
/* Support first generation cards? */
62
#define SUPPORT_GEN1 
63
64
/* Define to get more attention-grabbing but slightly more I/O using
65
   alarm status */
66
#define FANCY_ALARM
67
68
/* Define to support Digium Voice Processing Module expansion card */
69
#define VPM_SUPPORT
70
71
#define DEBUG_MAIN 		(1 << 0)
72
#define DEBUG_DTMF 		(1 << 1)
73
#define DEBUG_REGS 		(1 << 2)
74
#define DEBUG_TSI  		(1 << 3)
75
#define DEBUG_ECHOCAN 	(1 << 4)
76
#define DEBUG_RBS 		(1 << 5)
77
#define DEBUG_FRAMER		(1 << 6)
78
79
/* Maximum latency to be used with Gen 5 */
80
#define GEN5_MAX_LATENCY	127
81
82
#define T4_BASE_SIZE (DAHDI_MAX_CHUNKSIZE * 32 * 4) 
83
84
#ifdef ENABLE_WORKQUEUES
85
#include <linux/cpu.h>
86
87
/* XXX UGLY!!!! XXX  We have to access the direct structures of the workqueue which
88
  are only defined within workqueue.c because they don't give us a routine to allow us
89
  to nail a work to a particular thread of the CPU.  Nailing to threads gives us substantially
90
  higher scalability in multi-CPU environments though! */
91
92
/*
93
 * The per-CPU workqueue (if single thread, we always use cpu 0's).
94
 *
95
 * The sequence counters are for flush_scheduled_work().  It wants to wait
96
 * until until all currently-scheduled works are completed, but it doesn't
97
 * want to be livelocked by new, incoming ones.  So it waits until
98
 * remove_sequence is >= the insert_sequence which pertained when
99
 * flush_scheduled_work() was called.
100
 */
101
 
102
struct cpu_workqueue_struct {
103
104
	spinlock_t lock;
105
106
	long remove_sequence;	/* Least-recently added (next to run) */
107
	long insert_sequence;	/* Next to add */
108
109
	struct list_head worklist;
110
	wait_queue_head_t more_work;
111
	wait_queue_head_t work_done;
112
113
	struct workqueue_struct *wq;
114
	task_t *thread;
115
116
	int run_depth;		/* Detect run_workqueue() recursion depth */
117
} ____cacheline_aligned;
118
119
/*
120
 * The externally visible workqueue abstraction is an array of
121
 * per-CPU workqueues:
122
 */
123
struct workqueue_struct {
124
	/* TODO: Find out exactly where the API changed */
125
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
126
	struct cpu_workqueue_struct *cpu_wq;
127
#else
128
	struct cpu_workqueue_struct cpu_wq[NR_CPUS];
129
#endif
130
	const char *name;
131
	struct list_head list; 	/* Empty if single thread */
132
};
133
134
/* Preempt must be disabled. */
135
static void __t4_queue_work(struct cpu_workqueue_struct *cwq,
136
			 struct work_struct *work)
137
{
138
	unsigned long flags;
139
140
	spin_lock_irqsave(&cwq->lock, flags);
141
	work->wq_data = cwq;
142
	list_add_tail(&work->entry, &cwq->worklist);
143
	cwq->insert_sequence++;
144
	wake_up(&cwq->more_work);
145
	spin_unlock_irqrestore(&cwq->lock, flags);
146
}
147
148
/*
149
 * Queue work on a workqueue. Return non-zero if it was successfully
150
 * added.
151
 *
152
 * We queue the work to the CPU it was submitted, but there is no
153
 * guarantee that it will be processed by that CPU.
154
 */
155
static inline int t4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu)
156
{
157
	int ret = 0;
158
	get_cpu();
159
	if (!test_and_set_bit(0, &work->pending)) {
160
		BUG_ON(!list_empty(&work->entry));
161
		__t4_queue_work(wq->cpu_wq + cpu, work);
162
		ret = 1;
163
	}
164
	put_cpu();
165
	return ret;
166
}
167
168
#endif
169
170
/*
171
 * Define CONFIG_EXTENDED_RESET to allow the qfalc framer extra time
172
 * to reset itself upon hardware initialization. This exits for rare
173
 * cases for customers who are seeing the qfalc returning unexpected
174
 * information at initialization
175
 */
176
#undef CONFIG_EXTENDED_RESET
177
178
static int pedanticpci = 1;
179
static int debug=0;
180
static int timingcable = 0;
181
static int t1e1override = -1;  /* 0xff for E1, 0x00 for T1 */
182
static int j1mode = 0;
183
static int sigmode = FRMR_MODE_NO_ADDR_CMP;
184
static int alarmdebounce = 2500; /* LOF/LFA def to 2.5s AT&T TR54016*/
185
static int losalarmdebounce = 2500;/* LOS def to 2.5s AT&T TR54016*/
186
static int aisalarmdebounce = 2500;/* AIS(blue) def to 2.5s AT&T TR54016*/
187
static int yelalarmdebounce = 500;/* RAI(yellow) def to 0.5s AT&T devguide */
188
static int max_latency = GEN5_MAX_LATENCY;  /* Used to set a maximum latency (if you don't wish it to hard cap it at a certain value) in milliseconds */
189
#ifdef VPM_SUPPORT
190
static int vpmsupport = 1;
191
/* If set to auto, vpmdtmfsupport is enabled for VPM400M and disabled for VPM450M */
192
static int vpmdtmfsupport = -1; /* -1=auto, 0=disabled, 1=enabled*/
193
static int vpmspans = 1;
194
#define VPM_DEFAULT_DTMFTHRESHOLD 1000
195
static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
196
static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
197
#endif
198
/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
199
   can also cause PCI bus starvation, especially in combination with other
200
   aggressive cards.  Please note that burst mode has no effect on CPU
201
   utilization / max number of calls / etc. */
202
static int noburst;
203
/* For 56kbps links, set this module parameter to 0x7f */
204
static int hardhdlcmode = 0xff;
205
206
static int latency = 1;
207
208
static int ms_per_irq = 1;
209
210
#ifdef FANCY_ALARM
211
static int altab[] = {
212
0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0, 
213
};
214
#endif
215
216
#define MAX_SPANS 16
217
218
#define FLAG_STARTED (1 << 0)
219
#define FLAG_NMF (1 << 1)
220
#define FLAG_SENDINGYELLOW (1 << 2)
221
222
223
#define	TYPE_T1	1		/* is a T1 card */
224
#define	TYPE_E1	2		/* is an E1 card */
225
#define TYPE_J1 3		/* is a running J1 */
226
227
#define FLAG_2NDGEN  (1 << 3)
228
#define FLAG_2PORT   (1 << 4)
229
#define FLAG_VPM2GEN (1 << 5)
230
#define FLAG_OCTOPT  (1 << 6)
231
#define FLAG_3RDGEN  (1 << 7)
232
#define FLAG_BURST   (1 << 8)
233
#define FLAG_5THGEN  (1 << 10)
234
235
#define CANARY 0xc0de
236
237
238
#define PORTS_PER_FRAMER 4
239
240
struct devtype {
241
	char *desc;
242
	unsigned int flags;
243
};
244
245
static struct devtype opvxd115 = { "OpenVox D115P/D115E ", FLAG_2NDGEN};
246
static struct devtype opvxd130 = { "OpenVox D130P/D130E", FLAG_5THGEN | FLAG_BURST | FLAG_2NDGEN | FLAG_3RDGEN};
247
	
248
249
struct t4;
250
251
struct t4_span {
252
	struct t4 *owner;
253
	unsigned int *writechunk;					/* Double-word aligned write memory */
254
	unsigned int *readchunk;					/* Double-word aligned read memory */
255
	int spantype;		/* card type, T1 or E1 or J1 */
256
	int sync;
257
	int psync;
258
	int alarmtimer;
259
	int redalarms;
260
	int notclear;
261
	int alarmcount;
262
	int losalarmcount;
263
	int aisalarmcount;
264
	int yelalarmcount;
265
	int spanflags;
266
	int syncpos;
267
#ifdef SUPPORT_GEN1
268
	int e1check;			/* E1 check */
269
#endif
270
	struct dahdi_span span;
271
	unsigned char txsigs[16];	/* Transmit sigs */
272
	int loopupcnt;
273
	int loopdowncnt;
274
#ifdef SUPPORT_GEN1
275
	unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
276
	unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
277
#endif
278
	int irqmisses;
279
	
280
	/* HDLC controller fields */
281
	struct dahdi_chan *sigchan;
282
	unsigned char sigmode;
283
	int sigactive;
284
	int frames_out;
285
	int frames_in;
286
287
#ifdef VPM_SUPPORT
288
	unsigned long dtmfactive;
289
	unsigned long dtmfmask;
290
	unsigned long dtmfmutemask;
291
	short dtmfenergy[31];
292
	short dtmfdigit[31];
293
#endif
294
#ifdef ENABLE_WORKQUEUES
295
	struct work_struct swork;
296
#endif	
297
	struct dahdi_chan *chans[32];		/* Individual channels */
298
	struct dahdi_echocan_state *ec[32];	/* Echocan state for each channel */
299
};
300
301
struct t4 {
302
	/* This structure exists one per card */
303
	struct pci_dev *dev;		/* Pointer to PCI device */
304
	struct dahdi_device *ddev;	/* Pointer to DAHDI device */
305
	unsigned int intcount;
306
	int num;			/* Which card we are */
307
	int t1e1;			/* T1/E1 select pins */
308
	int globalconfig;	/* Whether global setup has been done */
309
	int syncsrc;			/* active sync source */
310
	struct t4_span *tspans[4];	/* Individual spans */
311
	int numspans;			/* Number of spans on the card */
312
	int blinktimer;
313
#ifdef FANCY_ALARM
314
	int alarmpos;
315
#endif
316
	int irq;			/* IRQ used by device */
317
	int order;			/* Order */
318
	int flags;                      /* Device flags */
319
	unsigned int falc31 : 1;	/* are we falc v3.1 (atomic not necessary) */
320
	int master;				/* Are we master */
321
	int ledreg;				/* LED Register */
322
	unsigned int gpio;
323
	unsigned int gpioctl;
324
	int e1recover;			/* E1 recovery timer */
325
	spinlock_t reglock;		/* lock register access */
326
	int spansstarted;		/* number of spans started */
327
	volatile unsigned int *writechunk;					/* Double-word aligned write memory */
328
	volatile unsigned int *readchunk;					/* Double-word aligned read memory */
329
	unsigned short canary;
330
#ifdef ENABLE_WORKQUEUES
331
	atomic_t worklist;
332
	struct workqueue_struct *workq;
333
#endif
334
	unsigned int passno;	/* number of interrupt passes */
335
	char *variety;
336
	int last0;		/* for detecting double-missed IRQ */
337
338
	/* DMA related fields */
339
	unsigned int dmactrl;
340
	dma_addr_t 	readdma;
341
	dma_addr_t	writedma;
342
	unsigned long memaddr;		/* Base address of card */
343
	unsigned long memlen;
344
	__iomem volatile unsigned int *membase;	/* Base address of card */
345
346
	/* Add this for our softlockup protector */
347
	unsigned int oct_rw_count;
348
349
	/* Flags for our bottom half */
350
	unsigned long checkflag;
351
	struct tasklet_struct t4_tlet;
352
	unsigned int vpm400checkstatus;
353
	/* Latency related additions */
354
	unsigned char rxident;
355
	unsigned char lastindex;
356
	int numbufs;
357
	int needed_latency;
358
	
359
#ifdef VPM_SUPPORT
360
	struct vpm450m *vpm450m;
361
	int vpm;
362
#endif	
363
364
};
365
366
#define T4_VPM_PRESENT (1 << 28)
367
368
#ifdef VPM_SUPPORT
369
static void t4_vpm400_init(struct t4 *wc);
370
static void t4_vpm450_init(struct t4 *wc);
371
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
372
373
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
374
375
static const struct dahdi_echocan_features vpm400m_ec_features = {
376
	.NLP_automatic = 1,
377
	.CED_tx_detect = 1,
378
	.CED_rx_detect = 1,
379
};
380
381
static const struct dahdi_echocan_features vpm450m_ec_features = {
382
	.NLP_automatic = 1,
383
	.CED_tx_detect = 1,
384
	.CED_rx_detect = 1,
385
};
386
387
static const struct dahdi_echocan_ops vpm400m_ec_ops = {
388
	.echocan_free = echocan_free,
389
};
390
391
static const struct dahdi_echocan_ops vpm450m_ec_ops = {
392
	.echocan_free = echocan_free,
393
};
394
#endif
395
396
static void __set_clear(struct t4 *wc, int span);
397
static int t4_startup(struct file *file, struct dahdi_span *span);
398
static int t4_shutdown(struct dahdi_span *span);
399
static int t4_rbsbits(struct dahdi_chan *chan, int bits);
400
static int t4_maint(struct dahdi_span *span, int cmd);
401
static int t4_clear_maint(struct dahdi_span *span);
402
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
403
static int t4_reset_counters(struct dahdi_span *span);
404
#endif
405
#ifdef SUPPORT_GEN1
406
static int t4_reset_dma(struct t4 *wc);
407
#endif
408
static void t4_hdlc_hard_xmit(struct dahdi_chan *chan);
409
static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
410
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan);
411
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan);
412
static void __t4_set_rclk_src(struct t4 *wc, int span);
413
static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave);
414
static void t4_check_alarms(struct t4 *wc, int span);
415
static void t4_check_sigbits(struct t4 *wc, int span);
416
417
#define WC_RDADDR	0
418
#define WC_WRADDR	1
419
#define WC_COUNT	2
420
#define WC_DMACTRL	3	
421
#define WC_INTR		4
422
/* #define WC_GPIO		5 */
423
#define WC_VERSION	6
424
#define WC_LEDS		7
425
#define WC_GPIOCTL	8
426
#define WC_GPIO		9
427
#define WC_LADDR	10
428
#define WC_LDATA		11
429
#define WC_LCS		(1 << 11)
430
#define WC_LCS2		(1 << 12)
431
#define WC_LALE			(1 << 13)
432
#define WC_LFRMR_CS	(1 << 10)	/* Framer's ChipSelect signal */
433
#define WC_ACTIVATE	(1 << 12)
434
#define WC_LREAD			(1 << 15)
435
#define WC_LWRITE		(1 << 16)
436
437
#define WC_OFF    (0)
438
#define WC_RED    (1)
439
#define WC_GREEN  (2)
440
#define WC_YELLOW (3)
441
442
#define WC_RECOVER 	0
443
#define WC_SELF 	1
444
445
#define LIM0_T 0x36 		/* Line interface mode 0 register */
446
#define LIM0_LL (1 << 1)	/* Local Loop */
447
#define LIM1_T 0x37		/* Line interface mode 1 register */
448
#define LIM1_RL (1 << 1)	/* Remote Loop */
449
450
#define FMR0 0x1C		/* Framer Mode Register 0 */
451
#define FMR0_SIM (1 << 0)	/* Alarm Simulation */
452
#define FMR1_T 0x1D		/* Framer Mode Register 1 */
453
#define FMR1_ECM (1 << 2)	/* Error Counter 1sec Interrupt Enable */
454
#define DEC_T 0x60		/* Diable Error Counter */
455
#define IERR_T 0x1B		/* Single Bit Defect Insertion Register */
456
#define IBV	0	 /* Bipolar violation */
457
#define IPE	(1 << 1) /* PRBS defect */
458
#define ICASE	(1 << 2) /* CAS defect */
459
#define ICRCE	(1 << 3) /* CRC defect */
460
#define IMFE	(1 << 4) /* Multiframe defect */
461
#define IFASE	(1 << 5) /* FAS defect */
462
#define ISR3_SEC (1 << 6)	/* Internal one-second interrupt bit mask */
463
#define ISR3_ES (1 << 7)	/* Errored Second interrupt bit mask */
464
#define ESM 0x47		/* Errored Second mask register */
465
466
#define FMR2_T 0x1E		/* Framer Mode Register 2 */
467
#define FMR2_PLB (1 << 2)	/* Framer Mode Register 2 */
468
469
#define FECL_T 0x50		/* Framing Error Counter Lower Byte */
470
#define FECH_T 0x51		/* Framing Error Counter Higher Byte */
471
#define CVCL_T 0x52		/* Code Violation Counter Lower Byte */
472
#define CVCH_T 0x53		/* Code Violation Counter Higher Byte */
473
#define CEC1L_T 0x54		/* CRC Error Counter 1 Lower Byte */
474
#define CEC1H_T 0x55		/* CRC Error Counter 1 Higher Byte */
475
#define EBCL_T 0x56		/* E-Bit Error Counter Lower Byte */
476
#define EBCH_T 0x57		/* E-Bit Error Counter Higher Byte */
477
#define BECL_T 0x58		/* Bit Error Counter Lower Byte */
478
#define BECH_T 0x59		/* Bit Error Counter Higher Byte */
479
#define COEC_T 0x5A		/* COFA Event Counter */
480
#define PRBSSTA_T 0xDA		/* PRBS Status Register */
481
482
#define LCR1_T 0x3B		/* Loop Code Register 1 */
483
#define EPRM (1 << 7)		/* Enable PRBS rx */
484
#define XPRBS (1 << 6)		/* Enable PRBS tx */
485
#define FLLB (1 << 1)		/* Framed line loop/Invert */
486
#define LLBP (1 << 0)		/* Line Loopback Pattern */
487
#define TPC0_T 0xA8		/* Test Pattern Control Register */
488
#define FRA (1 << 6)		/* Framed/Unframed Selection */
489
#define PRBS23 (3 << 4)		/* Pattern selection (23 poly) */
490
#define PRM (1 << 2)		/* Non framed mode */
491
#define FRS1_T 0x4D		/* Framer Receive Status Reg 1 */
492
#define LLBDD (1 << 4)
493
#define LLBAD (1 << 3)
494
495
#define MAX_T4_CARDS 64
496
497
static void t4_isr_bh(unsigned long data);
498
499
static struct t4 *cards[MAX_T4_CARDS];
500
501
502
#define MAX_TDM_CHAN 32
503
#define MAX_DTMF_DET 16
504
505
#define HDLC_IMR0_MASK (FRMR_IMR0_RME | FRMR_IMR0_RPF)
506
#if 0
507
#define HDLC_IMR1_MASK (FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR)
508
#else
509
#define HDLC_IMR1_MASK	(FRMR_IMR1_XDU | FRMR_IMR1_XPR)
510
#endif
511
512
static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
513
{
514
	unsigned int res = readl(&wc->membase[addr]);
515
	return res;
516
}
517
518
static inline void __t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
519
{
520
	unsigned int tmp;
521
	writel(value, &wc->membase[addr]);
522
	if (pedanticpci) {
523
		tmp = __t4_pci_in(wc, WC_VERSION);
524
		if ((tmp & 0xffff0000) != 0xc01a0000)
525
			dev_notice(&wc->dev->dev,
526
					"Version Synchronization Error!\n");
527
	}
528
#if 0
529
	tmp = __t4_pci_in(wc, addr);
530
	if ((value != tmp) && (addr != WC_LEDS) && (addr != WC_LDATA) &&
531
		(addr != WC_GPIO) && (addr != WC_INTR))
532
		dev_info(&wc->dev->dev, "Tried to load %08x into %08x, "
533
				"but got %08x instead\n", value, addr, tmp);
534
#endif		
535
}
536
537
static inline void __t4_gpio_set(struct t4 *wc, unsigned bits, unsigned int val)
538
{
539
	unsigned int newgpio;
540
	newgpio = wc->gpio & (~bits);
541
	newgpio |= val;
542
	if (newgpio != wc->gpio) {
543
		wc->gpio = newgpio;
544
		__t4_pci_out(wc, WC_GPIO, wc->gpio);
545
	}	
546
}
547
548
static inline void __t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
549
{
550
	unsigned int newgpioctl;
551
	newgpioctl = wc->gpioctl & (~bits);
552
	newgpioctl |= val;
553
	if (newgpioctl != wc->gpioctl) {
554
		wc->gpioctl = newgpioctl;
555
		__t4_pci_out(wc, WC_GPIOCTL, wc->gpioctl);
556
	}
557
}
558
559
static inline void t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
560
{
561
	unsigned long flags;
562
	spin_lock_irqsave(&wc->reglock, flags);
563
	__t4_gpio_setdir(wc, bits, val);
564
	spin_unlock_irqrestore(&wc->reglock, flags);
565
}
566
567
static inline void t4_gpio_set(struct t4 *wc, unsigned int bits, unsigned int val)
568
{
569
	unsigned long flags;
570
	spin_lock_irqsave(&wc->reglock, flags);
571
	__t4_gpio_set(wc, bits, val);
572
	spin_unlock_irqrestore(&wc->reglock, flags);
573
}
574
575
static inline void t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
576
{
577
	unsigned long flags;
578
	spin_lock_irqsave(&wc->reglock, flags);
579
	__t4_pci_out(wc, addr, value);
580
	spin_unlock_irqrestore(&wc->reglock, flags);
581
}
582
583
static inline void __t4_set_led(struct t4 *wc, int span, int color)
584
{
585
	int oldreg = wc->ledreg;
586
	wc->ledreg &= ~(0x3 << (span << 1));
587
	wc->ledreg |= (color << (span << 1));
588
	if (oldreg != wc->ledreg)
589
		__t4_pci_out(wc, WC_LEDS, wc->ledreg);
590
}
591
592
static inline void t4_activate(struct t4 *wc)
593
{
594
	wc->ledreg |= WC_ACTIVATE;
595
	t4_pci_out(wc, WC_LEDS, wc->ledreg);
596
}
597
598
static inline unsigned int t4_pci_in(struct t4 *wc, const unsigned int addr)
599
{
600
	unsigned int ret;
601
	unsigned long flags;
602
	
603
	spin_lock_irqsave(&wc->reglock, flags);
604
	ret = __t4_pci_in(wc, addr);
605
	spin_unlock_irqrestore(&wc->reglock, flags);
606
	return ret;
607
}
608
609
static inline unsigned int __t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
610
{
611
	unsigned int ret;
612
	unit &= 0x3;
613
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
614
	if (!pedanticpci)
615
		__t4_pci_in(wc, WC_VERSION);
616
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LREAD);
617
	if (!pedanticpci) {
618
		__t4_pci_in(wc, WC_VERSION);
619
	} else {
620
		__t4_pci_out(wc, WC_VERSION, 0);
621
	}
622
	ret = __t4_pci_in(wc, WC_LDATA);
623
 	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
624
625
	if (unlikely(debug & DEBUG_REGS))
626
		dev_info(&wc->dev->dev, "Reading unit %d address %02x is "
627
				"%02x\n", unit, addr, ret & 0xff);
628
629
	if (!pedanticpci)
630
		__t4_pci_in(wc, WC_VERSION);
631
632
	return ret & 0xff;
633
}
634
635
static inline unsigned int t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
636
{
637
	unsigned long flags;
638
	unsigned int ret;
639
	spin_lock_irqsave(&wc->reglock, flags);
640
	ret = __t4_framer_in(wc, unit, addr);
641
	spin_unlock_irqrestore(&wc->reglock, flags);
642
	return ret;
643
644
}
645
646
static inline void __t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
647
{
648
	unit &= 0x3;
649
	if (unlikely(debug & DEBUG_REGS))
650
		dev_info(&wc->dev->dev, "Writing %02x to address %02x of "
651
				"unit %d\n", value, addr, unit);
652
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
653
	__t4_pci_out(wc, WC_LDATA, value);
654
	if (!pedanticpci)
655
		__t4_pci_in(wc, WC_VERSION);
656
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE);
657
	if (!pedanticpci)
658
		__t4_pci_in(wc, WC_VERSION);
659
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));	
660
	if (!pedanticpci)
661
		__t4_pci_in(wc, WC_VERSION);
662
	if (unlikely(debug & DEBUG_REGS))
663
		dev_info(&wc->dev->dev, "Write complete\n");
664
#if 0
665
	if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc))
666
	{ unsigned int tmp;
667
	tmp = __t4_framer_in(wc, unit, addr);
668
	if (tmp != value) {
669
		dev_notice(&wc->dev->dev, "Expected %d from unit %d "
670
				"register %d but got %d instead\n",
671
				value, unit, addr, tmp);
672
	} }
673
#endif	
674
}
675
676
static inline void t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
677
{
678
	unsigned long flags;
679
	spin_lock_irqsave(&wc->reglock, flags);
680
	__t4_framer_out(wc, unit, addr, value);
681
	spin_unlock_irqrestore(&wc->reglock, flags);
682
}
683
684
#ifdef VPM_SUPPORT
685
686
static inline void wait_a_little(void)
687
{
688
	unsigned long newjiffies=jiffies+2;
689
	while(jiffies < newjiffies);
690
}
691
692
static inline unsigned int __t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
693
{
694
	unsigned int ret;
695
	unit &= 0x7;
696
	__t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12));
697
	__t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12) | (1 << 11) | WC_LREAD);
698
	ret = __t4_pci_in(wc, WC_LDATA);
699
	__t4_pci_out(wc, WC_LADDR, 0);
700
	return ret & 0xff;
701
}
702
703
static inline void __t4_raw_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
704
{
705
	int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
706
	if (!octopt) 
707
		__t4_gpio_set(wc, 0xff, (addr >> 8));
708
	__t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
709
	if (!octopt)
710
		__t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
711
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
712
	if (!pedanticpci)
713
		__t4_pci_in(wc, WC_VERSION);
714
	if (!octopt)
715
		__t4_gpio_set(wc, 0xff, (value >> 8));
716
	__t4_pci_out(wc, WC_LDATA, (value & 0xffff));
717
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE | WC_LCS));
718
	if (!pedanticpci)
719
		__t4_pci_in(wc, WC_VERSION);
720
	__t4_pci_out(wc, WC_LADDR, (0));
721
	if (!pedanticpci)
722
		__t4_pci_in(wc, WC_VERSION);
723
}
724
725
static inline unsigned int __t4_raw_oct_in(struct t4 *wc, const unsigned int addr)
726
{
727
	unsigned int ret;
728
	int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
729
	if (!octopt)
730
		__t4_gpio_set(wc, 0xff, (addr >> 8));
731
	__t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
732
	if (!octopt)
733
		__t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
734
	if (!pedanticpci)
735
		__t4_pci_in(wc, WC_VERSION);
736
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
737
	if (!pedanticpci)
738
		__t4_pci_in(wc, WC_VERSION);
739
#ifdef PEDANTIC_OCTASIC_CHECKING 
740
	__t4_pci_out(wc, WC_LADDR, (WC_LALE));
741
	if (!pedanticpci)
742
		__t4_pci_in(wc, WC_VERSION);
743
#endif
744
	if (!octopt) {
745
		__t4_gpio_setdir(wc, 0xff, 0x00);
746
		__t4_gpio_set(wc, 0xff, 0x00);
747
	}
748
	__t4_pci_out(wc, WC_LADDR, (WC_LREAD | WC_LALE | WC_LCS));
749
	if (!pedanticpci)
750
		__t4_pci_in(wc, WC_VERSION);
751
	if (octopt) {
752
		ret = __t4_pci_in(wc, WC_LDATA) & 0xffff;
753
	} else {
754
		ret = __t4_pci_in(wc, WC_LDATA) & 0xff;
755
		ret |= (__t4_pci_in(wc, WC_GPIO) & 0xff) << 8;
756
	}
757
	__t4_pci_out(wc, WC_LADDR, (0));
758
	if (!pedanticpci)
759
		__t4_pci_in(wc, WC_VERSION);
760
	if (!octopt)
761
		__t4_gpio_setdir(wc, 0xff, 0xff);
762
	return ret & 0xffff;
763
}
764
765
static inline unsigned int __t4_oct_in(struct t4 *wc, unsigned int addr)
766
{
767
#ifdef PEDANTIC_OCTASIC_CHECKING
768
	int count = 1000;
769
#endif
770
	__t4_raw_oct_out(wc, 0x0008, (addr >> 20));
771
	__t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
772
	__t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (1));
773
#ifdef PEDANTIC_OCTASIC_CHECKING
774
	while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
775
	if (count != 1000)
776
		dev_notice(&wc->dev->dev, "Yah, read can be slow...\n");
777
	if (!count)
778
		dev_notice(&wc->dev->dev, "Read timed out!\n");
779
#endif
780
	return __t4_raw_oct_in(wc, 0x0004);
781
}
782
783
static inline unsigned int t4_oct_in(struct t4 *wc, const unsigned int addr)
784
{
785
	unsigned long flags;
786
	unsigned int ret;
787
788
	spin_lock_irqsave(&wc->reglock, flags);
789
	ret = __t4_oct_in(wc, addr);
790
	spin_unlock_irqrestore(&wc->reglock, flags);
791
	return ret;
792
}
793
794
static inline unsigned int t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
795
{
796
	unsigned long flags;
797
	unsigned int ret;
798
	spin_lock_irqsave(&wc->reglock, flags);
799
	ret = __t4_vpm_in(wc, unit, addr);
800
	spin_unlock_irqrestore(&wc->reglock, flags);
801
	return ret;
802
}
803
804
static inline void __t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
805
{
806
	unit &= 0x7;
807
	if (debug & DEBUG_REGS)
808
		dev_notice(&wc->dev->dev, "Writing %02x to address %02x of "
809
				"ec unit %d\n", value, addr, unit);
810
	__t4_pci_out(wc, WC_LADDR, (addr & 0xff));
811
	__t4_pci_out(wc, WC_LDATA, value);
812
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
813
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11) | WC_LWRITE);
814
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
815
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff));	
816
	__t4_pci_out(wc, WC_LADDR, 0);
817
	if (debug & DEBUG_REGS)
818
		dev_notice(&wc->dev->dev, "Write complete\n");
819
820
      
821
#if 0
822
	{ unsigned int tmp;
823
	tmp = t4_vpm_in(wc, unit, addr);
824
	if (tmp != value) {
825
		dev_notice(&wc->dev->dev, "Expected %d from unit %d echo "
826
				"register %d but got %d instead\n",
827
				value, unit, addr, tmp);
828
	} }
829
#endif
830
}
831
832
static inline void __t4_oct_out(struct t4 *wc, unsigned int addr, unsigned int value)
833
{
834
#ifdef PEDANTIC_OCTASIC_CHECKING
835
	int count = 1000;
836
#endif
837
	__t4_raw_oct_out(wc, 0x0008, (addr >> 20));
838
	__t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
839
	__t4_raw_oct_out(wc, 0x0004, value);
840
	__t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (3 << 12) | 1);
841
#ifdef PEDANTIC_OCTASIC_CHECKING
842
	while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
843
	if (count != 1000)
844
		dev_notice(&wc->dev->dev, "Yah, write can be slow\n");
845
	if (!count)
846
		dev_notice(&wc->dev->dev, "Write timed out!\n");
847
#endif
848
}
849
850
static inline void t4_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
851
{
852
	unsigned long flags;
853
854
	spin_lock_irqsave(&wc->reglock, flags);
855
	__t4_oct_out(wc, addr, value);
856
	spin_unlock_irqrestore(&wc->reglock, flags);
857
}
858
859
static inline void t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
860
{
861
	unsigned long flags;
862
	spin_lock_irqsave(&wc->reglock, flags);
863
	__t4_vpm_out(wc, unit, addr, value);
864
	spin_unlock_irqrestore(&wc->reglock, flags);
865
}
866
867
static const char vpm_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#'};
868
869
static void t4_check_vpm450(struct t4 *wc)
870
{
871
	int channel, tone, start, span;
872
873
	if (vpm450m_checkirq(wc->vpm450m)) {
874
		while(vpm450m_getdtmf(wc->vpm450m, &channel, &tone, &start)) {
875
			span = channel & 0x3;
876
			channel >>= 2;
877
			if (!wc->t1e1)
878
				channel -= 5;
879
			else
880
				channel -= 1;
881
			if (unlikely(debug))
882
				dev_info(&wc->dev->dev, "Got tone %s of '%c' "
883
					"on channel %d of span %d\n",
884
					(start ? "START" : "STOP"),
885
					tone, channel, span + 1);
886
			if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) {
887
				if (start) {
888
					/* The octasic is supposed to mute us, but...  Yah, you
889
					   guessed it.  */
890
					if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) {
891
						unsigned long flags;
892
						struct dahdi_chan *chan = wc->tspans[span]->span.chans[channel];
893
						int y;
894
						spin_lock_irqsave(&chan->lock, flags);
895
						for (y=0;y<chan->numbufs;y++) {
896
							if ((chan->inreadbuf > -1) && (chan->readidx[y]))
897
								memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
898
						}
899
						spin_unlock_irqrestore(&chan->lock, flags);
900
					}
901
					set_bit(channel, &wc->tspans[span]->dtmfactive);
902
					dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFDOWN | tone));
903
				} else {
904
					clear_bit(channel, &wc->tspans[span]->dtmfactive);
905
					dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFUP | tone));
906
				}
907
			}
908
		}
909
	}
910
}
911
912
static void t4_check_vpm400(struct t4 *wc, unsigned int newio)
913
{
914
	unsigned int digit, regval = 0;
915
	unsigned int regbyte;
916
	int x, i;
917
	short energy=0;
918
	static unsigned int lastio = 0;
919
	struct t4_span *ts;
920
921
	if (debug && (newio != lastio)) 
922
		dev_notice(&wc->dev->dev, "Last was %08x, new is %08x\n",
923
				lastio, newio);
924
925
	lastio = newio;
926
 
927
	for(x = 0; x < 8; x++) {
928
		if (newio & (1 << (7 - x)))
929
			continue;
930
		ts = wc->tspans[x%4];
931
		/* Start of DTMF detection process */	
932
		regbyte = t4_vpm_in(wc, x, 0xb8);
933
		t4_vpm_out(wc, x, 0xb8, regbyte); /* Write 1 to clear */
934
		regval = regbyte << 8;
935
		regbyte = t4_vpm_in(wc, x, 0xb9);
936
		t4_vpm_out(wc, x, 0xb9, regbyte);
937
		regval |= regbyte;
938
939
		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
940
			if(regval & 0x0001) {
941
				int channel = (i << 1) + (x >> 2);
942
				int base = channel - 1;
943
944
				if (!wc->t1e1)
945
					base -= 4;
946
				regbyte = t4_vpm_in(wc, x, 0xa8 + i);
947
				digit = vpm_digits[regbyte];
948
				if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
949
					energy = t4_vpm_in(wc, x, 0x58 + channel);
950
					energy = DAHDI_XLAW(energy, ts->chans[0]);
951
					ts->dtmfenergy[base] = energy;
952
				}
953
				set_bit(base, &ts->dtmfactive);
954
				if (ts->dtmfdigit[base]) {
955
					if (ts->dtmfmask & (1 << base))
956
						dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
957
				}
958
				ts->dtmfdigit[base] = digit;
959
				if (test_bit(base, &ts->dtmfmask))
960
					dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFDOWN | digit));
961
				if (test_bit(base, &ts->dtmfmutemask)) {
962
					/* Mute active receive buffer*/
963
					unsigned long flags;
964
					struct dahdi_chan *chan = ts->span.chans[base];
965
					int y;
966
					spin_lock_irqsave(&chan->lock, flags);
967
					for (y=0;y<chan->numbufs;y++) {
968
						if ((chan->inreadbuf > -1) && (chan->readidx[y]))
969
							memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
970
					}
971
					spin_unlock_irqrestore(&chan->lock, flags);
972
				}
973
				if (debug)
974
					dev_notice(&wc->dev->dev, "Digit "
975
						"Seen: %d, Span: %d, channel:"
976
						" %d, energy: %02x, 'channel "
977
						"%d' chip %d\n", digit, x % 4,
978
						base + 1, energy, channel, x);
979
				
980
			}
981
			regval = regval >> 1;
982
		}
983
		if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN))
984
			continue;
985
986
		/* Start of DTMF off detection process */	
987
		regbyte = t4_vpm_in(wc, x, 0xbc);
988
		t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */
989
		regval = regbyte << 8;
990
		regbyte = t4_vpm_in(wc, x, 0xbd);
991
		t4_vpm_out(wc, x, 0xbd, regbyte);
992
		regval |= regbyte;
993
994
		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
995
			if(regval & 0x0001) {
996
				int channel = (i << 1) + (x >> 2);
997
				int base = channel - 1;
998
999
				if (!wc->t1e1)
1000
					base -= 4;
1001
				clear_bit(base, &ts->dtmfactive);
1002
				if (ts->dtmfdigit[base]) {
1003
					if (test_bit(base, &ts->dtmfmask))
1004
						dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
1005
				}
1006
				digit = ts->dtmfdigit[base];
1007
				ts->dtmfdigit[base] = 0;
1008
				if (debug)
1009
					dev_notice(&wc->dev->dev, "Digit "
1010
						"Gone: %d, Span: %d, channel:"
1011
						" %d, energy: %02x, 'channel "
1012
						"%d' chip %d\n", digit, x % 4,
1013
						base + 1, energy, channel, x);
1014
				
1015
			}
1016
			regval = regval >> 1;
1017
		}
1018
1019
	}
1020
}
1021
#endif
1022
1023
static void hdlc_stop(struct t4 *wc, unsigned int span)
1024
{
1025
	struct t4_span *t = wc->tspans[span];
1026
	unsigned char imr0, imr1, mode;
1027
	int i = 0;
1028
1029
	if (debug & DEBUG_FRAMER)
1030
		dev_notice(&wc->dev->dev, "Stopping HDLC controller on span "
1031
				"%d\n", span+1);
1032
	
1033
	/* Clear receive and transmit timeslots */
1034
	for (i = 0; i < 4; i++) {
1035
		t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00);
1036
		t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00);
1037
	}
1038
1039
	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
1040
	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
1041
1042
	/* Disable HDLC interrupts */
1043
	imr0 |= HDLC_IMR0_MASK;
1044
	t4_framer_out(wc, span, FRMR_IMR0, imr0);
1045
1046
	imr1 |= HDLC_IMR1_MASK;
1047
	t4_framer_out(wc, span, FRMR_IMR1, imr1);
1048
1049
	mode = t4_framer_in(wc, span, FRMR_MODE);
1050
	mode &= ~FRMR_MODE_HRAC;
1051
	t4_framer_out(wc, span, FRMR_MODE, mode);
1052
1053
	t->sigactive = 0;
1054
}
1055
1056
static inline void __t4_framer_cmd(struct t4 *wc, unsigned int span, int cmd)
1057
{
1058
	__t4_framer_out(wc, span, FRMR_CMDR, cmd);
1059
}
1060
1061
static inline void t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd)
1062
{
1063
	int sis;
1064
	int loops = 0;
1065
1066
	/* XXX could be time consuming XXX */
1067
	for (;;) {
1068
		sis = t4_framer_in(wc, span, FRMR_SIS);
1069
		if (!(sis & 0x04))
1070
			break;
1071
		if (!loops++ && (debug & DEBUG_FRAMER)) {
1072
			dev_notice(&wc->dev->dev, "!!!SIS Waiting before cmd "
1073
					"%02x\n", cmd);
1074
		}
1075
	}
1076
	if (loops && (debug & DEBUG_FRAMER))
1077
		dev_notice(&wc->dev->dev, "!!!SIS waited %d loops\n", loops);
1078
1079
	t4_framer_out(wc, span, FRMR_CMDR, cmd);
1080
}
1081
1082
static int hdlc_start(struct t4 *wc, unsigned int span, struct dahdi_chan *chan, unsigned char mode)
1083
{
1084
	struct t4_span *t = wc->tspans[span];
1085
	unsigned char imr0, imr1;
1086
	int offset = chan->chanpos;
1087
	unsigned long flags;
1088
1089
	if (debug & DEBUG_FRAMER)
1090
		dev_info(&wc->dev->dev, "Starting HDLC controller for channel "
1091
				"%d span %d\n", offset, span+1);
1092
1093
	if (mode != FRMR_MODE_NO_ADDR_CMP)
1094
		return -1;
1095
1096
	mode |= FRMR_MODE_HRAC;
1097
1098
	/* Make sure we're in the right mode */
1099
	t4_framer_out(wc, span, FRMR_MODE, mode);
1100
	t4_framer_out(wc, span, FRMR_TSEO, 0x00);
1101
	t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode);
1102
1103
	/* Set the interframe gaps, etc */
1104
	t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
1105
1106
	t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
1107
	
1108
	/* Set up the time slot that we want to tx/rx on */
1109
	t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
1110
	t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
1111
1112
	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
1113
	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
1114
1115
	/* Enable our interrupts again */
1116
	imr0 &= ~HDLC_IMR0_MASK;
1117
	t4_framer_out(wc, span, FRMR_IMR0, imr0);
1118
1119
	imr1 &= ~HDLC_IMR1_MASK;
1120
	t4_framer_out(wc, span, FRMR_IMR1, imr1);
1121
1122
	/* Reset the signaling controller */
1123
	t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
1124
1125
	spin_lock_irqsave(&wc->reglock, flags);
1126
	t->sigchan = chan;
1127
	spin_unlock_irqrestore(&wc->reglock, flags);
1128
1129
	t->sigactive = 0;
1130
1131
	return 0;
1132
}
1133
1134
static void __set_clear(struct t4 *wc, int span)
1135
{
1136
	int i,j;
1137
	int oldnotclear;
1138
	unsigned short val=0;
1139
	struct t4_span *ts = wc->tspans[span];
1140
1141
	oldnotclear = ts->notclear;
1142
	if ((ts->spantype == TYPE_T1) || (ts->spantype == TYPE_J1)) {
1143
		for (i=0;i<24;i++) {
1144
			j = (i/8);
1145
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
1146
				val |= 1 << (7 - (i % 8));
1147
				ts->notclear &= ~(1 << i);
1148
			} else
1149
				ts->notclear |= (1 << i);
1150
			if ((i % 8)==7) {
1151
				if (debug)
1152
					dev_notice(&wc->dev->dev, "Putting %d "
1153
						"in register %02x on span %d"
1154
						"\n", val, 0x2f + j, span + 1);
1155
				__t4_framer_out(wc, span, 0x2f + j, val);
1156
				val = 0;
1157
			}
1158
		}
1159
	} else {
1160
		for (i=0;i<31;i++) {
1161
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
1162
				ts->notclear &= ~(1 << i);
1163
			else 
1164
				ts->notclear |= (1 << i);
1165
		}
1166
	}
1167
	if (ts->notclear != oldnotclear) {
1168
		unsigned char reg;
1169
		reg = __t4_framer_in(wc, span, FRMR_IMR0);
1170
		if (ts->notclear)
1171
			reg &= ~0x08;
1172
		else
1173
			reg |= 0x08;
1174
		__t4_framer_out(wc, span, FRMR_IMR0, reg);
1175
	}
1176
}
1177
1178
#if 0
1179
static void set_clear(struct t4 *wc, int span)
1180
{
1181
	unsigned long flags;
1182
	spin_lock_irqsave(&wc->reglock, flags);
1183
	__set_clear(wc, span);
1184
	spin_unlock_irqrestore(&wc->reglock, flags);
1185
}
1186
#endif
1187
1188
static int t4_dacs(struct dahdi_chan *dst, struct dahdi_chan *src)
1189
{
1190
	struct t4 *wc;
1191
	struct t4_span *ts;
1192
	wc = dst->pvt;
1193
	ts = wc->tspans[dst->span->offset];
1194
	if (src && (src->pvt != dst->pvt)) {
1195
		if (ts->spanflags & FLAG_2NDGEN)
1196
			t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
1197
		wc = src->pvt;
1198
		if (ts->spanflags & FLAG_2NDGEN)
1199
			t4_tsi_unassign(wc, src->span->offset, src->chanpos);
1200
		if (debug)
1201
			dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
1202
				"default and...\n", src->span->offset,
1203
				src->chanpos);
1204
		if (debug)
1205
			dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
1206
				"default\n", dst->span->offset, dst->chanpos);
1207
		return -1;
1208
	}
1209
	if (src) {
1210
		t4_tsi_assign(wc, src->span->offset, src->chanpos, dst->span->offset, dst->chanpos);
1211
		if (debug)
1212
			dev_notice(&wc->dev->dev, "Assigning channel %d/%d -> "
1213
				"%d/%d!\n", src->span->offset, src->chanpos,
1214
				dst->span->offset, dst->chanpos);
1215
	} else {
1216
		t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
1217
		if (debug)
1218
			dev_notice(&wc->dev->dev, "Unassigning channel %d/%d!"
1219
				"\n", dst->span->offset, dst->chanpos);
1220
	}
1221
	return 0;
1222
}
1223
1224
#ifdef VPM_SUPPORT
1225
1226
void oct_set_reg(void *data, unsigned int reg, unsigned int val)
1227
{
1228
	struct t4 *wc = data;
1229
	t4_oct_out(wc, reg, val);
1230
}
1231
1232
unsigned int oct_get_reg(void *data, unsigned int reg)
1233
{
1234
	struct t4 *wc = data;
1235
	unsigned int ret;
1236
	ret = t4_oct_in(wc, reg);
1237
	return ret;
1238
}
1239
1240
static int t4_vpm_unit(int span, int channel)
1241
{
1242
	int unit = 0;
1243
	switch(vpmspans) {
1244
	case 4:
1245
		unit = span;
1246
		unit += (channel & 1) << 2;
1247
		break;
1248
	case 2:
1249
		unit = span;
1250
		unit += (channel & 0x3) << 1;
1251
		break;
1252
	case 1:
1253
		unit = span;
1254
		unit += (channel & 0x7);
1255
	}
1256
	return unit;
1257
}
1258
1259
static inline struct t4_span *t4_from_span(struct dahdi_span *span)
1260
{
1261
	return container_of(span, struct t4_span, span);
1262
}
1263
1264
static int t4_echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
1265
			  struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
1266
{
1267
	struct t4 *wc = chan->pvt;
1268
	struct t4_span *tspan = container_of(chan->span, struct t4_span, span);
1269
	int channel;
1270
	const struct dahdi_echocan_ops *ops;
1271
	const struct dahdi_echocan_features *features;
1272
1273
	if (!vpmsupport || !wc->vpm)
1274
		return -ENODEV;
1275
1276
	if (chan->span->offset >= vpmspans)
1277
		return -ENODEV;
1278
1279
	if (wc->vpm450m) {
1280
		ops = &vpm450m_ec_ops;
1281
		features = &vpm450m_ec_features;
1282
	} else {
1283
		ops = &vpm400m_ec_ops;
1284
		features = &vpm400m_ec_features;
1285
	}
1286
1287
	if (ecp->param_count > 0) {
1288
		dev_warn(&wc->dev->dev, "echo canceller does not support "
1289
				"parameters; failing request\n");
1290
		return -EINVAL;
1291
	}
1292
1293
	*ec = tspan->ec[chan->chanpos - 1];
1294
	(*ec)->ops = ops;
1295
	(*ec)->features = *features;
1296
1297
	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
1298
1299
	if (wc->vpm450m) {
1300
		channel = channel << 2;
1301
		channel |= chan->span->offset;
1302
		if (debug & DEBUG_ECHOCAN)
1303
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1304
				"Channel is %d, Span is %d, offset is %d "
1305
				"length %d\n", wc->num, chan->chanpos,
1306
				chan->span->offset, channel, ecp->tap_length);
1307
		vpm450m_setec(wc->vpm450m, channel, ecp->tap_length);
1308
	} else {
1309
		int unit = t4_vpm_unit(chan->span->offset, channel);
1310
1311
		if (debug & DEBUG_ECHOCAN)
1312
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1313
				"Channel is %d, Span is %d, unit is %d, "
1314
				"unit offset is %d length %d\n", wc->num,
1315
				chan->chanpos, chan->span->offset, unit,
1316
				channel, ecp->tap_length);
1317
		t4_vpm_out(wc, unit, channel, 0x3e);
1318
	}
1319
1320
	return 0;
1321
}
1322
1323
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
1324
{
1325
	struct t4 *wc = chan->pvt;
1326
	int channel;
1327
1328
	memset(ec, 0, sizeof(*ec));
1329
1330
	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
1331
1332
	if (wc->vpm450m) {
1333
		channel = channel << 2;
1334
		channel |= chan->span->offset;
1335
		if (debug & DEBUG_ECHOCAN)
1336
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1337
				"Channel is %d, Span is %d, offset is %d "
1338
				"length 0\n", wc->num, chan->chanpos,
1339
				chan->span->offset, channel);
1340
		vpm450m_setec(wc->vpm450m, channel, 0);
1341
	} else {
1342
		int unit = t4_vpm_unit(chan->span->offset, channel);
1343
1344
		if (debug & DEBUG_ECHOCAN)
1345
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1346
				"Channel is %d, Span is %d, unit is %d, "
1347
				"unit offset is %d length 0\n", wc->num,
1348
				chan->chanpos, chan->span->offset, unit,
1349
				channel);
1350
		t4_vpm_out(wc, unit, channel, 0x01);
1351
	}
1352
}
1353
#endif
1354
1355
static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
1356
{
1357
	struct t4_regs regs;
1358
	int x;
1359
	struct t4 *wc = chan->pvt;
1360
#ifdef VPM_SUPPORT
1361
	int j;
1362
	int channel;
1363
	struct t4_span *ts = wc->tspans[chan->span->offset];
1364
#endif
1365
1366
#ifdef VPM_SUPPORT
1367
	if (dtmfthreshold == 0)
1368
		dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
1369
	if (lastdtmfthreshold != dtmfthreshold) {
1370
		lastdtmfthreshold = dtmfthreshold;
1371
		t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
1372
	}
1373
#endif
1374
1375
	switch(cmd) {
1376
	case WCT4_GET_REGS:
1377
		for (x=0;x<NUM_PCI;x++)
1378
			regs.pci[x] = t4_pci_in(wc, x);
1379
		for (x=0;x<NUM_REGS;x++)
1380
			regs.regs[x] = t4_framer_in(wc, chan->span->offset, x);
1381
		if (copy_to_user((__user void *) data, &regs, sizeof(regs)))
1382
			return -EFAULT;
1383
		break;
1384
#ifdef VPM_SUPPORT
1385
	case DAHDI_TONEDETECT:
1386
		if (get_user(j, (__user int *) data))
1387
			return -EFAULT;
1388
		if (!wc->vpm)
1389
			return -ENOSYS;
1390
		if (j && (vpmdtmfsupport == 0))
1391
			return -ENOSYS;
1392
		if (j & DAHDI_TONEDETECT_ON)
1393
			set_bit(chan->chanpos - 1, &ts->dtmfmask);
1394
		else
1395
			clear_bit(chan->chanpos - 1, &ts->dtmfmask);
1396
		if (j & DAHDI_TONEDETECT_MUTE)
1397
			set_bit(chan->chanpos - 1, &ts->dtmfmutemask);
1398
		else
1399
			clear_bit(chan->chanpos - 1, &ts->dtmfmutemask);
1400
		if (wc->vpm450m) {
1401
			channel = (chan->chanpos) << 2;
1402
			if (!wc->t1e1)
1403
				channel += (4 << 2);
1404
			channel |= chan->span->offset;
1405
			vpm450m_setdtmf(wc->vpm450m, channel, j & DAHDI_TONEDETECT_ON, j & DAHDI_TONEDETECT_MUTE);
1406
		}
1407
		return 0;
1408
#endif
1409
	default:
1410
		return -ENOTTY;
1411
	}
1412
	return 0;
1413
}
1414
1415
static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts)
1416
{
1417
	int res, i;
1418
	unsigned int size = 32;
1419
	unsigned char buf[32];
1420
1421
	res = dahdi_hdlc_getbuf(ts->sigchan, buf, &size);
1422
	if (debug & DEBUG_FRAMER)
1423
		dev_notice(&wc->dev->dev, "Got buffer sized %d and res %d "
1424
				"for %d\n", size, res, span);
1425
	if (size > 0) {
1426
		ts->sigactive = 1;
1427
1428
		if (debug & DEBUG_FRAMER) {
1429
			dev_notice(&wc->dev->dev, "TX(");
1430
			for (i = 0; i < size; i++)
1431
				dev_notice(&wc->dev->dev, "%s%02x",
1432
						(i ? " " : ""), buf[i]);
1433
			dev_notice(&wc->dev->dev, ")\n");
1434
		}
1435
1436
		for (i = 0; i < size; i++)
1437
			t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]);
1438
1439
		if (res) /* End of message */ {
1440
			if (debug & DEBUG_FRAMER)
1441
				dev_notice(&wc->dev->dev,
1442
					"transmiting XHF|XME\n");
1443
			t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME);
1444
#if 0
1445
			ts->sigactive = (__t4_framer_in(wc, span, FRMR_SIS) & FRMR_SIS_XFW) ? 0 : 1;
1446
#endif
1447
			++ts->frames_out;
1448
			if ((debug & DEBUG_FRAMER) && !(ts->frames_out & 0x0f))
1449
				dev_notice(&wc->dev->dev, "Transmitted %d "
1450
					"frames on span %d\n", ts->frames_out,
1451
					span);
1452
		} else { /* Still more to transmit */
1453
			if (debug & DEBUG_FRAMER)
1454
				dev_notice(&wc->dev->dev, "transmiting XHF\n");
1455
			t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF);
1456
		}
1457
	}
1458
	else if (res < 0)
1459
		ts->sigactive = 0;
1460
}
1461
1462
static void t4_hdlc_hard_xmit(struct dahdi_chan *chan)
1463
{
1464
	struct t4 *wc = chan->pvt;
1465
	int span = chan->span->offset;
1466
	struct t4_span *ts = wc->tspans[span];
1467
	unsigned long flags; 
1468
1469
	spin_lock_irqsave(&wc->reglock, flags);
1470
	if (!ts->sigchan) {
1471
		dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit: Invalid (NULL) "
1472
				"signalling channel\n");
1473
		spin_unlock_irqrestore(&wc->reglock, flags);
1474
		return;
1475
	}
1476
	spin_unlock_irqrestore(&wc->reglock, flags);
1477
1478
	if (debug & DEBUG_FRAMER)
1479
		dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit on channel %s "
1480
				"(sigchan %s), sigactive=%d\n", chan->name,
1481
				ts->sigchan->name, ts->sigactive);
1482
1483
	if ((ts->sigchan == chan) && !ts->sigactive)
1484
		t4_hdlc_xmit_fifo(wc, span, ts);
1485
}
1486
1487
static int t4_maint(struct dahdi_span *span, int cmd)
1488
{
1489
	struct t4_span *ts = t4_from_span(span);
1490
	struct t4 *wc = ts->owner;
1491
	unsigned int reg;
1492
#ifdef DAHDI_SPAN_OPS
1493
	unsigned long flags;
1494
#endif
1495
1496
	if (ts->spantype == TYPE_E1) {
1497
		switch(cmd) {
1498
		case DAHDI_MAINT_NONE:
1499
			dev_info(&wc->dev->dev, "Clearing all maint modes\n");
1500
			t4_clear_maint(span);
1501
			break;
1502
		case DAHDI_MAINT_LOCALLOOP:
1503
			dev_info(&wc->dev->dev,
1504
				 "Turning on local loopback\n");
1505
			t4_clear_maint(span);
1506
			reg = t4_framer_in(wc, span->offset, LIM0_T);
1507
			t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
1508
			break;
1509
#ifdef DAHDI_SPAN_OPS
1510
		case DAHDI_MAINT_NETWORKLINELOOP:
1511
			dev_info(&wc->dev->dev,
1512
				 "Turning on network line loopback\n");
1513
			t4_clear_maint(span);
1514
			reg = t4_framer_in(wc, span->offset, LIM1_T);
1515
			t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
1516
			break;
1517
		case DAHDI_MAINT_NETWORKPAYLOADLOOP:
1518
			dev_info(&wc->dev->dev,
1519
				 "Turning on network payload loopback\n");
1520
			t4_clear_maint(span);
1521
			reg = t4_framer_in(wc, span->offset, FMR2_T);
1522
			t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
1523
			break;
1524
#endif
1525
		case DAHDI_MAINT_LOOPUP:
1526
		case DAHDI_MAINT_LOOPDOWN:
1527
			dev_info(&wc->dev->dev,
1528
				"Loopup & loopdown supported in E1 mode\n");
1529
			return -ENOSYS;
1530
#ifdef DAHDI_SPAN_OPS
1531
		case DAHDI_MAINT_FAS_DEFECT:
1532
			t4_framer_out(wc, span->offset, IERR_T, IFASE);
1533
			break;
1534
		case DAHDI_MAINT_MULTI_DEFECT:
1535
			t4_framer_out(wc, span->offset, IERR_T, IMFE);
1536
			break;
1537
		case DAHDI_MAINT_CRC_DEFECT:
1538
			t4_framer_out(wc, span->offset, IERR_T, ICRCE);
1539
			break;
1540
		case DAHDI_MAINT_CAS_DEFECT:
1541
			t4_framer_out(wc, span->offset, IERR_T, ICASE);
1542
			break;
1543
		case DAHDI_MAINT_PRBS_DEFECT:
1544
			t4_framer_out(wc, span->offset, IERR_T, IPE);
1545
			break;
1546
		case DAHDI_MAINT_BIPOLAR_DEFECT:
1547
			t4_framer_out(wc, span->offset, IERR_T, IBV);
1548
			break;
1549
		case DAHDI_RESET_COUNTERS:
1550
			t4_reset_counters(span);
1551
			break;
1552
		case DAHDI_MAINT_ALARM_SIM:
1553
			dev_info(&wc->dev->dev, "Invoking alarm state");
1554
			reg = t4_framer_in(wc, span->offset, FMR0);
1555
			t4_framer_out(wc, span->offset, FMR0, (reg|FMR0_SIM));
1556
			break;
1557
#endif
1558
		default:
1559
			dev_info(&wc->dev->dev,
1560
					"Unknown E1 maint command: %d\n", cmd);
1561
			return -ENOSYS;
1562
		}
1563
	} else {
1564
		switch(cmd) {
1565
		case DAHDI_MAINT_NONE:
1566
			dev_info(&wc->dev->dev, "Clearing all maint modes\n");
1567
			t4_clear_maint(span);
1568
			break;
1569
		case DAHDI_MAINT_LOCALLOOP:
1570
			dev_info(&wc->dev->dev,
1571
				 "Turning on local loopback\n");
1572
			t4_clear_maint(span);
1573
			reg = t4_framer_in(wc, span->offset, LIM0_T);
1574
			t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
1575
			break;
1576
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1577
		case DAHDI_MAINT_NETWORKLINELOOP:
1578
			dev_info(&wc->dev->dev,
1579
				 "Turning on network line loopback\n");
1580
			t4_clear_maint(span);
1581
			reg = t4_framer_in(wc, span->offset, LIM1_T);
1582
			t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
1583
			break;
1584
		case DAHDI_MAINT_NETWORKPAYLOADLOOP:
1585
			dev_info(&wc->dev->dev,
1586
				 "Turning on network payload loopback\n");
1587
			t4_clear_maint(span);
1588
			reg = t4_framer_in(wc, span->offset, FMR2_T);
1589
			t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
1590
			break;
1591
#endif
1592
		case DAHDI_MAINT_LOOPUP:
1593
			dev_info(&wc->dev->dev, "Transmitting loopup code\n");
1594
			t4_clear_maint(span);
1595
			t4_framer_out(wc, span->offset, 0x21, 0x50);
1596
			break;
1597
		case DAHDI_MAINT_LOOPDOWN:
1598
			dev_info(&wc->dev->dev, "Transmitting loopdown code\n");
1599
			t4_clear_maint(span);
1600
			t4_framer_out(wc, span->offset, 0x21, 0x60);
1601
			break;
1602
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1603
		case DAHDI_MAINT_FAS_DEFECT:
1604
			t4_framer_out(wc, span->offset, IERR_T, IFASE);
1605
			break;
1606
		case DAHDI_MAINT_MULTI_DEFECT:
1607
			t4_framer_out(wc, span->offset, IERR_T, IMFE);
1608
			break;
1609
		case DAHDI_MAINT_CRC_DEFECT:
1610
			t4_framer_out(wc, span->offset, IERR_T, ICRCE);
1611
			break;
1612
		case DAHDI_MAINT_CAS_DEFECT:
1613
			t4_framer_out(wc, span->offset, IERR_T, ICASE);
1614
			break;
1615
		case DAHDI_MAINT_PRBS_DEFECT:
1616
			t4_framer_out(wc, span->offset, IERR_T, IPE);
1617
			break;
1618
		case DAHDI_MAINT_BIPOLAR_DEFECT:
1619
			t4_framer_out(wc, span->offset, IERR_T, IBV);
1620
			break;
1621
		case DAHDI_MAINT_PRBS:
1622
			dev_info(&wc->dev->dev, "PRBS not supported\n");
1623
#if 0
1624
			dev_notice(&wc->dev->dev, "Enabling PRBS!\n");
1625
			span->mainttimer = 1;
1626
			/* Enable PRBS monitor */
1627
			reg = t4_framer_in(wc, span->offset, LCR1_T);
1628
			reg |= EPRM;
1629
1630
			/* Setup PRBS xmit */
1631
			t4_framer_out(wc, span->offset, TPC0_T, 0);
1632
1633
			/* Enable PRBS transmit */
1634
			reg |= XPRBS;
1635
			reg &= ~LLBP;
1636
			reg &= ~FLLB;
1637
			t4_framer_out(wc, span->offset, LCR1_T, reg);
1638
#endif
1639
			return -ENOSYS;
1640
		case DAHDI_RESET_COUNTERS:
1641
			t4_reset_counters(span);
1642
			break;
1643
#endif
1644
#ifdef DAHDI_SPAN_OPS
1645
		case DAHDI_MAINT_ALARM_SIM:
1646
			reg = t4_framer_in(wc, span->offset, FMR0);
1647
1648
			/*
1649
			 * The alarm simulation state machine requires us to
1650
			 * bring this bit up and down for at least 1 clock cycle
1651
			 */
1652
			spin_lock_irqsave(&wc->reglock, flags);
1653
			__t4_framer_out(wc, span->offset,
1654
					FMR0, (reg | FMR0_SIM));
1655
			udelay(1);
1656
			__t4_framer_out(wc, span->offset,
1657
					FMR0, (reg & ~FMR0_SIM));
1658
			udelay(1);
1659
			spin_unlock_irqrestore(&wc->reglock, flags);
1660
1661
			reg = t4_framer_in(wc, span->offset, 0x4e);
1662
			if (debug & DEBUG_MAIN) {
1663
				dev_info(&wc->dev->dev,
1664
					"FRS2(alarm state): %d\n",
1665
					((reg & 0xe0) >> 5));
1666
			}
1667
			break;
1668
#endif
1669
		default:
1670
			dev_info(&wc->dev->dev, "Unknown T1 maint command:%d\n",
1671
									cmd);
1672
			break;
1673
	   }
1674
    }
1675
	return 0;
1676
}
1677
1678
static int t4_clear_maint(struct dahdi_span *span)
1679
{
1680
	struct t4_span *ts = t4_from_span(span);
1681
	struct t4 *wc = ts->owner;
1682
	unsigned int reg;
1683
1684
	/* Clear local loop */
1685
	reg = t4_framer_in(wc, span->offset, LIM0_T);
1686
	t4_framer_out(wc, span->offset, LIM0_T, (reg & ~LIM0_LL));
1687
1688
	/* Clear Remote Loop */
1689
	reg = t4_framer_in(wc, span->offset, LIM1_T);
1690
	t4_framer_out(wc, span->offset, LIM1_T, (reg & ~LIM1_RL));
1691
1692
	/* Clear Remote Payload Loop */
1693
	reg = t4_framer_in(wc, span->offset, FMR2_T);
1694
	t4_framer_out(wc, span->offset, FMR2_T, (reg & ~FMR2_PLB));
1695
1696
	/* Clear PRBS */
1697
	reg = t4_framer_in(wc, span->offset, LCR1_T);
1698
	t4_framer_out(wc, span->offset, LCR1_T, (reg & ~(XPRBS | EPRM)));
1699
1700
	span->mainttimer = 0;
1701
1702
	return 0;
1703
}
1704
1705
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1706
static int t4_reset_counters(struct dahdi_span *span)
1707
{
1708
	struct t4_span *ts = t4_from_span(span);
1709
	memset(&ts->span.count, 0, sizeof(ts->span.count));
1710
	return 0;
1711
}
1712
#endif
1713
1714
static int t4_rbsbits(struct dahdi_chan *chan, int bits)
1715
{
1716
	u_char m,c;
1717
	int k,n,b;
1718
	struct t4 *wc = chan->pvt;
1719
	struct t4_span *ts = wc->tspans[chan->span->offset];
1720
	unsigned long flags;
1721
	
1722
	if (debug & DEBUG_RBS)
1723
		dev_notice(&wc->dev->dev, "Setting bits to %d on channel %s\n",
1724
				bits, chan->name);
1725
	spin_lock_irqsave(&wc->reglock, flags);	
1726
	k = chan->span->offset;
1727
	if (ts->spantype == TYPE_E1) { /* do it E1 way */
1728
		if (chan->chanpos == 16) {
1729
			spin_unlock_irqrestore(&wc->reglock, flags);
1730
			return 0;
1731
		}
1732
		n = chan->chanpos - 1;
1733
		if (chan->chanpos > 15) n--;
1734
		b = (n % 15);
1735
		c = ts->txsigs[b];
1736
		m = (n / 15) << 2; /* nibble selector */
1737
		c &= (0xf << m); /* keep the other nibble */
1738
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
1739
		ts->txsigs[b] = c;
1740
		  /* output them to the chip */
1741
		__t4_framer_out(wc,k,0x71 + b,c); 
1742
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
1743
		n = chan->chanpos - 1;
1744
		b = (n/4);
1745
		c = ts->txsigs[b];
1746
		m = ((3 - (n % 4)) << 1); /* nibble selector */
1747
		c &= ~(0x3 << m); /* keep the other nibble */
1748
		c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
1749
		ts->txsigs[b] = c;
1750
		  /* output them to the chip */
1751
		__t4_framer_out(wc,k,0x70 + b,c); 
1752
		__t4_framer_out(wc,k,0x70 + b + 6,c); 
1753
	} else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
1754
		n = chan->chanpos - 1;
1755
		b = (n/2);
1756
		c = ts->txsigs[b];
1757
		m = ((n % 2) << 2); /* nibble selector */
1758
		c &= (0xf << m); /* keep the other nibble */
1759
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
1760
		ts->txsigs[b] = c;
1761
		  /* output them to the chip */
1762
		__t4_framer_out(wc,k,0x70 + b,c); 
1763
	} 
1764
	spin_unlock_irqrestore(&wc->reglock, flags);
1765
	if (debug & DEBUG_RBS)
1766
		dev_notice(&wc->dev->dev, "Finished setting RBS bits\n");
1767
	return 0;
1768
}
1769
1770
static int t4_shutdown(struct dahdi_span *span)
1771
{
1772
	int tspan;
1773
	int wasrunning;
1774
	unsigned long flags;
1775
	struct t4_span *ts = t4_from_span(span);
1776
	struct t4 *wc = ts->owner;
1777
1778
	tspan = span->offset + 1;
1779
	if (tspan < 0) {
1780
		dev_notice(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
1781
				span->spanno);
1782
		return -1;
1783
	}
1784
1785
	if (debug & DEBUG_MAIN)
1786
		dev_notice(&wc->dev->dev, "Shutting down span %d (%s)\n",
1787
				span->spanno, span->name);
1788
1789
	/* Stop HDLC controller if runned */
1790
	if (ts->sigchan)
1791
		hdlc_stop(wc, span->offset);
1792
	
1793
	spin_lock_irqsave(&wc->reglock, flags);
1794
	wasrunning = span->flags & DAHDI_FLAG_RUNNING;
1795
1796
	span->flags &= ~DAHDI_FLAG_RUNNING;
1797
	__t4_set_led(wc, span->offset, WC_OFF);
1798
	if ((wc->numspans == 1) && 
1799
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING))) {
1800
		/* No longer in use, disable interrupts */
1801
		dev_info(&wc->dev->dev, "opvxd115: Disabling interrupts since "
1802
				"there are no active spans\n");
1803
		set_bit(T4_STOP_DMA, &wc->checkflag);
1804
	} else
1805
		set_bit(T4_CHECK_TIMING, &wc->checkflag);
1806
1807
	spin_unlock_irqrestore(&wc->reglock, flags);
1808
1809
	/* Wait for interrupt routine to shut itself down */
1810
	msleep(10);
1811
	if (wasrunning)
1812
		wc->spansstarted--;
1813
1814
	if (debug & DEBUG_MAIN)
1815
		dev_notice(&wc->dev->dev, "Span %d (%s) shutdown\n",
1816
				span->spanno, span->name);
1817
	return 0;
1818
}
1819
1820
static void t4_chan_set_sigcap(struct dahdi_span *span, int x)
1821
{
1822
	struct t4_span *wc = container_of(span, struct t4_span, span);
1823
	struct dahdi_chan *chan = wc->chans[x];
1824
	chan->sigcap = DAHDI_SIG_CLEAR;
1825
	/* E&M variant supported depends on span type */
1826
	if (wc->spantype == TYPE_E1) {
1827
		/* E1 sigcap setup */
1828
		if (span->lineconfig & DAHDI_CONFIG_CCS) {
1829
			/* CCS setup */
1830
			chan->sigcap |= DAHDI_SIG_MTP2 | DAHDI_SIG_SF |
1831
				DAHDI_SIG_HARDHDLC;
1832
			return;
1833
		}
1834
		/* clear out sig and sigcap for channel 16 on E1 CAS
1835
		 * lines, otherwise, set it correctly */
1836
		if (x == 15) {
1837
			/* CAS signaling channel setup */
1838
			wc->chans[15]->sigcap = 0;
1839
			wc->chans[15]->sig = 0;
1840
			return;
1841
		}
1842
		/* normal CAS setup */
1843
		chan->sigcap |= DAHDI_SIG_EM_E1 | DAHDI_SIG_FXSLS |
1844
			DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_SF |
1845
			DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS |
1846
			DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS;
1847
	} else {
1848
		/* T1 sigcap setup */
1849
		chan->sigcap |= DAHDI_SIG_EM | DAHDI_SIG_FXSLS |
1850
			DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_MTP2 |
1851
			DAHDI_SIG_SF | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS |
1852
			DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS |
1853
			DAHDI_SIG_HARDHDLC;
1854
	}
1855
}
1856
1857
static int t4_spanconfig(struct file *file, struct dahdi_span *span,
1858
		struct dahdi_lineconfig *lc)
1859
{
1860
	int i;
1861
	struct t4_span *ts = t4_from_span(span);
1862
	struct t4 *wc = ts->owner;
1863
1864
	if (debug)
1865
		dev_info(&wc->dev->dev, "About to enter spanconfig!\n");
1866
	if (debug & DEBUG_MAIN)
1867
		dev_notice(&wc->dev->dev, "opvxd115: Configuring span %d\n",
1868
				span->spanno);
1869
1870
	if (lc->sync < 0)
1871
		lc->sync = 0;
1872
	if (lc->sync > wc->numspans)
1873
		lc->sync = 0;
1874
	
1875
	/* remove this span number from the current sync sources, if there */
1876
	for(i = 0; i < wc->numspans; i++) {
1877
		if (wc->tspans[i]->sync == span->spanno) {
1878
			wc->tspans[i]->sync = 0;
1879
			wc->tspans[i]->psync = 0;
1880
		}
1881
	}
1882
	wc->tspans[span->offset]->syncpos = lc->sync;
1883
	/* if a sync src, put it in proper place */
1884
	if (lc->sync) {
1885
		wc->tspans[lc->sync - 1]->sync = span->spanno;
1886
		wc->tspans[lc->sync - 1]->psync = span->offset + 1;
1887
	}
1888
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
1889
1890
	/* Make sure this is clear in case of multiple startup and shutdown
1891
	 * iterations */
1892
	clear_bit(T4_STOP_DMA, &wc->checkflag);
1893
	
1894
	/* make sure that sigcaps gets updated if necessary */
1895
	for (i = 0; i < span->channels; i++)
1896
		t4_chan_set_sigcap(span, i);
1897
1898
	/* If we're already running, then go ahead and apply the changes */
1899
	if (span->flags & DAHDI_FLAG_RUNNING)
1900
		return t4_startup(file, span);
1901
1902
	if (debug)
1903
		dev_info(&wc->dev->dev, "Done with spanconfig!\n");
1904
	return 0;
1905
}
1906
1907
static int t4_chanconfig(struct file *file, struct dahdi_chan *chan,
1908
		int sigtype)
1909
{
1910
	int alreadyrunning;
1911
	unsigned long flags;
1912
	struct t4 *wc = chan->pvt;
1913
	struct t4_span *ts = wc->tspans[chan->span->offset];
1914
1915
	alreadyrunning = ts->span.flags & DAHDI_FLAG_RUNNING;
1916
	if (debug & DEBUG_MAIN) {
1917
		if (alreadyrunning)
1918
			dev_notice(&wc->dev->dev, "opvxd115: Reconfigured "
1919
				"channel %d (%s) sigtype %d\n",
1920
				chan->channo, chan->name, sigtype);
1921
		else
1922
			dev_notice(&wc->dev->dev, "opvxd115: Configured channel"
1923
				" %d (%s) sigtype %d\n",
1924
				chan->channo, chan->name, sigtype);
1925
	}
1926
1927
	spin_lock_irqsave(&wc->reglock, flags);	
1928
1929
	if (alreadyrunning)
1930
		__set_clear(wc, chan->span->offset);
1931
1932
	spin_unlock_irqrestore(&wc->reglock, flags);	
1933
1934
	/* (re)configure signalling channel */
1935
	if ((sigtype == DAHDI_SIG_HARDHDLC) || (ts->sigchan == chan)) {
1936
		if (debug & DEBUG_FRAMER)
1937
			dev_notice(&wc->dev->dev, "%sonfiguring hardware HDLC "
1938
				"on %s\n",
1939
				((sigtype == DAHDI_SIG_HARDHDLC) ? "C" : "Unc"),
1940
				chan->name);
1941
		if (alreadyrunning) {
1942
			if (ts->sigchan)
1943
				hdlc_stop(wc, ts->sigchan->span->offset);
1944
			if (sigtype == DAHDI_SIG_HARDHDLC) {
1945
				if (hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
1946
					dev_notice(&wc->dev->dev, "Error "
1947
						"initializing signalling "
1948
						"controller\n");
1949
					return -1;
1950
				}
1951
			} else {
1952
				spin_lock_irqsave(&wc->reglock, flags);
1953
				ts->sigchan = NULL;
1954
				spin_unlock_irqrestore(&wc->reglock, flags);
1955
			}
1956
		
1957
		}
1958
		else {
1959
			spin_lock_irqsave(&wc->reglock, flags);
1960
			ts->sigchan = (sigtype == DAHDI_SIG_HARDHDLC) ? chan : NULL;
1961
			spin_unlock_irqrestore(&wc->reglock, flags);
1962
			ts->sigactive = 0;
1963
		}
1964
	}
1965
	return 0;
1966
}
1967
1968
static int t4_open(struct dahdi_chan *chan)
1969
{
1970
	return 0;
1971
}
1972
1973
static int t4_close(struct dahdi_chan *chan)
1974
{
1975
	return 0;
1976
}
1977
1978
static void set_span_devicetype(struct t4 *wc)
1979
{
1980
	struct dahdi_device *ddev = wc->ddev;
1981
	const char *devicetype_old = ddev->devicetype;
1982
	char *extra_str = "";
1983
1984
	if (wc->vpm == T4_VPM_PRESENT)
1985
		extra_str = (!wc->vpm450m) ? " (VPM400M)" : " (VPMOCT032)",
1986
	wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s%s",
1987
			wc->variety, extra_str);
1988
1989
	/* On the off chance that we were able to allocate it previously. */
1990
	if (!wc->ddev->devicetype)
1991
		wc->ddev->devicetype = devicetype_old;
1992
	else
1993
		kfree(devicetype_old);
1994
}
1995
1996
/* The number of cards we have seen with each
1997
   possible 'order' switch setting.
1998
*/
1999
static unsigned int order_index[16];
2000
2001
static void setup_chunks(struct t4 *wc, int which)
2002
{
2003
	struct t4_span *ts;
2004
	int offset = 1;
2005
	int x, y;
2006
	int gen2;
2007
2008
	if (!wc->t1e1)
2009
		offset += 4;
2010
2011
	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
2012
2013
	for (x = 0; x < wc->numspans; x++) {
2014
		ts = wc->tspans[x];
2015
		ts->writechunk = (void *)(wc->writechunk + (x * 32 * 2) + (which * (1024 >> 2)));
2016
		ts->readchunk = (void *)(wc->readchunk + (x * 32 * 2) + (which * (1024 >> 2)));
2017
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
2018
			struct dahdi_chan *mychans = ts->chans[y];
2019
			if (gen2) {
2020
				mychans->writechunk = (void *)(wc->writechunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
2021
				mychans->readchunk = (void *)(wc->readchunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
2022
			}
2023
		}
2024
	}
2025
}
2026
2027
#ifdef DAHDI_SPAN_OPS
2028
static const struct dahdi_span_ops t4_gen1_span_ops = {
2029
	.owner = THIS_MODULE,
2030
	.spanconfig = t4_spanconfig,
2031
	.chanconfig = t4_chanconfig,
2032
	.startup = t4_startup,
2033
	.shutdown = t4_shutdown,
2034
	.rbsbits = t4_rbsbits,
2035
	.maint = t4_maint,
2036
	.open = t4_open,
2037
	.close  = t4_close,
2038
	.ioctl = t4_ioctl,
2039
	.hdlc_hard_xmit = t4_hdlc_hard_xmit,
2040
};
2041
2042
static const struct dahdi_span_ops t4_gen2_span_ops = {
2043
	.owner = THIS_MODULE,
2044
	.spanconfig = t4_spanconfig,
2045
	.chanconfig = t4_chanconfig,
2046
	.startup = t4_startup,
2047
	.shutdown = t4_shutdown,
2048
	.rbsbits = t4_rbsbits,
2049
	.maint = t4_maint,
2050
	.open = t4_open,
2051
	.close  = t4_close,
2052
	.ioctl = t4_ioctl,
2053
	.hdlc_hard_xmit = t4_hdlc_hard_xmit,
2054
	.dacs = t4_dacs,
2055
#ifdef VPM_SUPPORT
2056
	.echocan_create = t4_echocan_create,
2057
#endif
2058
};
2059
#endif
2060
2061
static void init_spans(struct t4 *wc)
2062
{
2063
	int x,y;
2064
	int gen2;
2065
	struct t4_span *ts;
2066
	unsigned int reg;
2067
2068
	wc->ddev->manufacturer = "OpenVox";
2069
	if (order_index[wc->order] == 1)
2070
		wc->ddev->location = kasprintf(GFP_KERNEL,
2071
				"Board ID Switch %d", wc->order);
2072
	else
2073
		wc->ddev->location = kasprintf(GFP_KERNEL,
2074
				"PCI Bus %02d Slot %02d",
2075
				wc->dev->bus->number,
2076
				PCI_SLOT(wc->dev->devfn) + 1);
2077
	if (!wc->ddev->location)
2078
		return; /* FIXME: Error handling */
2079
2080
	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
2081
	for (x = 0; x < wc->numspans; x++) {
2082
		ts = wc->tspans[x];
2083
		sprintf(ts->span.name, "D115/D130/%d/%d", wc->num, x + 1);
2084
		snprintf(ts->span.desc, sizeof(ts->span.desc) - 1,
2085
			 "D115/D130 (E1|T1) Card %d Span %d", wc->num, x+1);
2086
		switch (ts->spantype) {
2087
		case TYPE_T1:
2088
			ts->span.spantype = SPANTYPE_DIGITAL_T1;
2089
			break;
2090
		case TYPE_E1:
2091
			ts->span.spantype = SPANTYPE_DIGITAL_E1;
2092
			break;
2093
		case TYPE_J1:
2094
			ts->span.spantype = SPANTYPE_DIGITAL_J1;
2095
			break;
2096
		}
2097
#ifdef DAHDI_SPAN_MODULE	
2098
		ts->span.owner = THIS_MODULE;
2099
#endif
2100
#ifdef DAHDI_SPAN_OPS
2101
		if (gen2) {
2102
			ts->span.ops = &t4_gen2_span_ops;
2103
		} else {
2104
			ts->span.ops = &t4_gen1_span_ops;
2105
		}
2106
#else
2107
		ts->span.spanconfig = t4_spanconfig;
2108
		ts->span.chanconfig = t4_chanconfig;
2109
		ts->span.startup = t4_startup;
2110
		ts->span.shutdown = t4_shutdown;
2111
		ts->span.rbsbits = t4_rbsbits;
2112
		ts->span.maint = t4_maint;
2113
		ts->span.open = t4_open;
2114
		ts->span.close  = t4_close;
2115
		ts->span.ioctl = t4_ioctl;
2116
		ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
2117
		if (gen2) {
2118
#ifdef VPM_SUPPORT
2119
		if (vpmsupport)
2120
			ts->span.echocan_create = t4_echocan_create;
2121
#endif			
2122
			ts->span.dacs = t4_dacs;
2123
		}
2124
		ts->span.pvt = ts;
2125
#endif
2126
2127
		/* HDLC Specific init */
2128
		ts->sigchan = NULL;
2129
		ts->sigmode = sigmode;
2130
		ts->sigactive = 0;
2131
		
2132
		if (ts->spantype == TYPE_T1 || ts->spantype == TYPE_J1) {
2133
			ts->span.channels = 24;
2134
			ts->span.deflaw = DAHDI_LAW_MULAW;
2135
			ts->span.linecompat = DAHDI_CONFIG_AMI |
2136
				DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 |
2137
				DAHDI_CONFIG_ESF;
2138
		} else {
2139
			ts->span.channels = 31;
2140
			ts->span.deflaw = DAHDI_LAW_ALAW;
2141
			ts->span.linecompat = DAHDI_CONFIG_AMI |
2142
				DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS |
2143
				DAHDI_CONFIG_CRC4;
2144
		}
2145
		ts->span.chans = ts->chans;
2146
		ts->span.flags = DAHDI_FLAG_RBS;
2147
2148
		ts->owner = wc;
2149
		ts->span.offset = x;
2150
		ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
2151
		ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
2152
2153
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
2154
			struct dahdi_chan *mychans = ts->chans[y];
2155
			sprintf(mychans->name, "D115/D130/%d/%d/%d", wc->num, x + 1, y + 1);
2156
			t4_chan_set_sigcap(&ts->span, x);
2157
			mychans->pvt = wc;
2158
			mychans->chanpos = y + 1;
2159
		}
2160
2161
		/* Enable 1sec timer interrupt */
2162
		reg = t4_framer_in(wc, x, FMR1_T);
2163
		t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
2164
2165
		/* Enable Errored Second interrupt */
2166
		t4_framer_out(wc, x, ESM, 0);
2167
2168
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
2169
		t4_reset_counters(&ts->span);
2170
#endif
2171
	}
2172
2173
	set_span_devicetype(wc);
2174
	setup_chunks(wc, 0);
2175
	wc->lastindex = 0;
2176
}
2177
2178
static void t4_serial_setup(struct t4 *wc, int unit)
2179
{
2180
	if (!wc->globalconfig) {
2181
		wc->globalconfig = 1;
2182
		if (debug)
2183
			dev_info(&wc->dev->dev, "opvxd115: Setting up global "
2184
					"serial parameters\n");
2185
		t4_framer_out(wc, 0, 0x85, 0xe0);	/* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
2186
		t4_framer_out(wc, 0, 0x08, 0x01);	/* IPC: Interrupt push/pull active low */
2187
	
2188
		/* Global clocks (8.192 Mhz CLK) */
2189
		t4_framer_out(wc, 0, 0x92, 0x00);	
2190
		t4_framer_out(wc, 0, 0x93, 0x18);
2191
		t4_framer_out(wc, 0, 0x94, 0xfb);
2192
		t4_framer_out(wc, 0, 0x95, 0x0b);
2193
		t4_framer_out(wc, 0, 0x96, 0x00);
2194
		t4_framer_out(wc, 0, 0x97, 0x0b);
2195
		t4_framer_out(wc, 0, 0x98, 0xdb);
2196
		t4_framer_out(wc, 0, 0x99, 0xdf);
2197
	}
2198
2199
	/* Configure interrupts */	
2200
	t4_framer_out(wc, unit, FRMR_GCR, 0x00);	/* GCR: Interrupt on Activation/Deactivation of each */
2201
2202
	/* Configure system interface */
2203
	t4_framer_out(wc, unit, FRMR_SIC1, 0xc2);	/* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */
2204
	t4_framer_out(wc, unit, FRMR_SIC2, 0x20 | (unit << 1)); /* SIC2: No FFS, no center receive eliastic buffer, phase */
2205
	t4_framer_out(wc, unit, FRMR_SIC3, 0x04);	/* SIC3: Edges for capture */
2206
	t4_framer_out(wc, unit, FRMR_CMR2, 0x00);	/* CMR2: We provide sync and clock for tx and rx. */
2207
	if (!wc->t1e1) { /* T1 mode */
2208
		t4_framer_out(wc, unit, FRMR_XC0, 0x03);	/* XC0: Normal operation of Sa-bits */
2209
		t4_framer_out(wc, unit, FRMR_XC1, 0x84);	/* XC1: 0 offset */
2210
		if (wc->tspans[unit]->spantype == TYPE_J1)
2211
			t4_framer_out(wc, unit, FRMR_RC0, 0x83);	/* RC0: Just shy of 1023 */
2212
		else
2213
			t4_framer_out(wc, unit, FRMR_RC0, 0x03);	/* RC0: Just shy of 1023 */
2214
		t4_framer_out(wc, unit, FRMR_RC1, 0x84);	/* RC1: The rest of RC0 */
2215
	} else { /* E1 mode */
2216
		t4_framer_out(wc, unit, FRMR_XC0, 0x00);	/* XC0: Normal operation of Sa-bits */
2217
		t4_framer_out(wc, unit, FRMR_XC1, 0x04);	/* XC1: 0 offset */
2218
		t4_framer_out(wc, unit, FRMR_RC0, 0x04);	/* RC0: Just shy of 1023 */
2219
		t4_framer_out(wc, unit, FRMR_RC1, 0x04);	/* RC1: The rest of RC0 */
2220
	}
2221
	
2222
	/* Configure ports */
2223
	t4_framer_out(wc, unit, 0x80, 0x00);	/* PC1: SPYR/SPYX input on RPA/XPA */
2224
	if (wc->falc31) {
2225
			  t4_framer_out(wc, unit, 0x81, 0xBB);	/* PC2: RMFB/XSIG output/input on RPB/XPB */
2226
			  t4_framer_out(wc, unit, 0x82, 0xBB);	/* PC3: Some unused stuff */
2227
			  t4_framer_out(wc, unit, 0x83, 0xBB);	/* PC4: Some more unused stuff */
2228
	} else {
2229
			  t4_framer_out(wc, unit, 0x81, 0x22);	/* PC2: RMFB/XSIG output/input on RPB/XPB */
2230
			  t4_framer_out(wc, unit, 0x82, 0x65);	/* PC3: Some unused stuff */
2231
			  t4_framer_out(wc, unit, 0x83, 0x35);	/* PC4: Some more unused stuff */
2232
	}
2233
	t4_framer_out(wc, unit, 0x84, 0x01);	/* PC5: XMFS active low, SCLKR is input, RCLK is output */
2234
	if (debug & DEBUG_MAIN)
2235
		dev_notice(&wc->dev->dev, "Successfully initialized serial "
2236
				"bus for unit %d\n", unit);
2237
}
2238
2239
static int syncsrc = 0;
2240
static int syncnum = 0 /* -1 */;
2241
static int syncspan = 0;
2242
#ifdef DEFINE_SPINLOCK
2243
static DEFINE_SPINLOCK(synclock);
2244
#else
2245
static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
2246
#endif
2247
2248
static void __t4_set_rclk_src(struct t4 *wc, int span)
2249
{
2250
	int cmr1 = 0x38;	/* Clock Mode: RCLK sourced by DCO-R1
2251
				   by default, Disable Clock-Switching */
2252
2253
	cmr1 |= (span << 6);
2254
	__t4_framer_out(wc, 0, 0x44, cmr1);
2255
2256
	dev_info(&wc->dev->dev, "RCLK source set to span %d\n", span+1);
2257
}
2258
2259
static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave)
2260
{
2261
	if (slave) {
2262
		wc->dmactrl |= (1 << 25);
2263
		dev_info(&wc->dev->dev, "SCLK is slaved to timing cable\n");
2264
	} else {
2265
		wc->dmactrl &= ~(1 << 25);
2266
	}
2267
2268
	if (master) {
2269
		wc->dmactrl |= (1 << 24);
2270
		dev_info(&wc->dev->dev, "SCLK is master to timing cable\n");
2271
	} else {
2272
		wc->dmactrl &= ~(1 << 24);
2273
	}
2274
2275
	if (mode == WC_RECOVER)
2276
		wc->dmactrl |= (1 << 29); /* Recover timing from RCLK */
2277
2278
	if (mode == WC_SELF)
2279
		wc->dmactrl &= ~(1 << 29);/* Provide timing from MCLK */
2280
2281
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2282
}
2283
2284
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
2285
static ssize_t t4_timing_master_show(struct device *dev,
2286
				     struct device_attribute *attr,
2287
				     char *buf)
2288
{
2289
	struct t4 *wc = dev_get_drvdata(dev);
2290
	if (wc->dmactrl & (1 << 29))
2291
		return sprintf(buf, "%d\n", wc->syncsrc);
2292
	else
2293
		return sprintf(buf, "%d\n", -1);
2294
}
2295
2296
static DEVICE_ATTR(timing_master, 0400, t4_timing_master_show, NULL);
2297
2298
static void create_sysfs_files(struct t4 *wc)
2299
{
2300
	int ret;
2301
	ret = device_create_file(&wc->dev->dev,
2302
				 &dev_attr_timing_master);
2303
	if (ret) {
2304
		dev_info(&wc->dev->dev,
2305
			"Failed to create device attributes.\n");
2306
	}
2307
}
2308
2309
static void remove_sysfs_files(struct t4 *wc)
2310
{
2311
	device_remove_file(&wc->dev->dev,
2312
			   &dev_attr_timing_master);
2313
}
2314
2315
#else
2316
2317
static inline void create_sysfs_files(struct t4 *wc) { return; }
2318
static inline void remove_sysfs_files(struct t4 *wc) { return; }
2319
2320
#endif /* LINUX_KERNEL > 2.6.18 */
2321
2322
static inline void __t4_update_timing(struct t4 *wc)
2323
{
2324
	int i;
2325
	/* update sync src info */
2326
	if (wc->syncsrc != syncsrc) {
2327
		dev_info(&wc->dev->dev, "Swapping card %d from %d to %d\n",
2328
				wc->num, wc->syncsrc, syncsrc);
2329
		wc->syncsrc = syncsrc;
2330
		/* Update sync sources */
2331
		for (i = 0; i < wc->numspans; i++) {
2332
			wc->tspans[i]->span.syncsrc = wc->syncsrc;
2333
		}
2334
		if (syncnum == wc->num) {
2335
			__t4_set_rclk_src(wc, syncspan-1);
2336
			__t4_set_sclk_src(wc, WC_RECOVER, 1, 0);
2337
			if (debug)
2338
				dev_notice(&wc->dev->dev, "Card %d, using sync "
2339
					"span %d, master\n", wc->num, syncspan);
2340
		} else {
2341
			__t4_set_sclk_src(wc, WC_RECOVER, 0, 1);
2342
			if (debug)
2343
				dev_notice(&wc->dev->dev, "Card %d, using "
2344
					"Timing Bus, NOT master\n", wc->num);
2345
		}
2346
	}
2347
}
2348
2349
static int __t4_findsync(struct t4 *wc)
2350
{
2351
	int i;
2352
	int x;
2353
	unsigned long flags;
2354
	int p;
2355
	int nonzero;
2356
	int newsyncsrc = 0;			/* DAHDI span number */
2357
	int newsyncnum = 0;			/* opvxd115 card number */
2358
	int newsyncspan = 0;		/* span on given opvxd115 card */
2359
	spin_lock_irqsave(&synclock, flags);
2360
#if 1
2361
	if (!wc->num) {
2362
		/* If we're the first card, go through all the motions, up to 8 levels
2363
		   of sync source */
2364
		p = 1;
2365
		while (p < 8) {
2366
			nonzero = 0;
2367
			for (x=0;cards[x];x++) {
2368
				for (i = 0; i < wc->numspans; i++) {
2369
					if (cards[x]->tspans[i]->syncpos) {
2370
						nonzero = 1;
2371
						if ((cards[x]->tspans[i]->syncpos == p) &&
2372
						    !(cards[x]->tspans[i]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_LOOPBACK)) &&
2373
							(cards[x]->tspans[i]->span.flags & DAHDI_FLAG_RUNNING)) {
2374
								/* This makes a good sync source */
2375
								newsyncsrc = cards[x]->tspans[i]->span.spanno;
2376
								newsyncnum = x;
2377
								newsyncspan = i + 1;
2378
								/* Jump out */
2379
								goto found;
2380
						}
2381
					}
2382
				}		
2383
			}
2384
			if (nonzero)
2385
				p++;
2386
			else 
2387
				break;
2388
		}
2389
found:		
2390
		if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) {
2391
			if (debug)
2392
				dev_notice(&wc->dev->dev, "New syncnum: %d "
2393
					"(was %d), syncsrc: %d (was %d), "
2394
					"syncspan: %d (was %d)\n", newsyncnum,
2395
					syncnum, newsyncsrc, syncsrc,
2396
					newsyncspan, syncspan);
2397
			syncnum = newsyncnum;
2398
			syncsrc = newsyncsrc;
2399
			syncspan = newsyncspan;
2400
			for (x=0;cards[x];x++) {
2401
				__t4_update_timing(cards[x]);
2402
			}
2403
		}
2404
	}
2405
	__t4_update_timing(wc);
2406
#endif	
2407
	spin_unlock_irqrestore(&synclock, flags);
2408
	return 0;
2409
}
2410
2411
static void __t4_set_timing_source_auto(struct t4 *wc)
2412
{
2413
	int x;
2414
	int firstprio, secondprio;
2415
	firstprio = secondprio = 4;
2416
2417
	if (debug)
2418
		dev_info(&wc->dev->dev, "timing source auto\n");
2419
	clear_bit(T4_CHECK_TIMING, &wc->checkflag);
2420
	if (timingcable) {
2421
		__t4_findsync(wc);
2422
	} else {
2423
		if (debug)
2424
			dev_info(&wc->dev->dev, "Evaluating spans for timing "
2425
					"source\n");
2426
		for (x=0;x<wc->numspans;x++) {
2427
			if ((wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) &&
2428
			   !(wc->tspans[x]->span.alarms & (DAHDI_ALARM_RED |
2429
							   DAHDI_ALARM_BLUE))) {
2430
				if (debug)
2431
					dev_info(&wc->dev->dev, "span %d is "
2432
						"green : syncpos %d\n", x+1,
2433
						wc->tspans[x]->syncpos);
2434
				if (wc->tspans[x]->syncpos) {
2435
					/* Valid rsync source in recovered
2436
					   timing mode */
2437
					if (firstprio == 4)
2438
						firstprio = x;
2439
					else if (wc->tspans[x]->syncpos <
2440
						wc->tspans[firstprio]->syncpos)
2441
						firstprio = x;
2442
				} else {
2443
					/* Valid rsync source in system timing
2444
					   mode */
2445
					if (secondprio == 4)
2446
						secondprio = x;
2447
				}
2448
			}
2449
		}
2450
		if (firstprio != 4) {
2451
			wc->syncsrc = firstprio;
2452
			__t4_set_rclk_src(wc, firstprio);
2453
			__t4_set_sclk_src(wc, WC_RECOVER, 0, 0);
2454
			dev_info(&wc->dev->dev, "Recovered timing mode, "\
2455
						"RCLK set to span %d\n",
2456
						firstprio+1);
2457
		} else if (secondprio != 4) {
2458
			wc->syncsrc = -1;
2459
			__t4_set_rclk_src(wc, secondprio);
2460
			__t4_set_sclk_src(wc, WC_SELF, 0, 0);
2461
			dev_info(&wc->dev->dev, "System timing mode, "\
2462
						"RCLK set to span %d\n",
2463
						secondprio+1);
2464
		} else {
2465
			wc->syncsrc = -1;
2466
			dev_info(&wc->dev->dev, "All spans in alarm : No valid"\
2467
						"span to source RCLK from\n");
2468
			/* Default rclk to lock with span 1 */
2469
			__t4_set_rclk_src(wc, 0);
2470
			__t4_set_sclk_src(wc, WC_SELF, 0, 0);
2471
		}
2472
	}
2473
}
2474
2475
static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel)
2476
{
2477
	unsigned int fmr4, fmr2, fmr1, fmr0, lim2;
2478
	char *framing, *line;
2479
	int mytxlevel;
2480
	if ((txlevel > 7) || (txlevel < 4))
2481
		mytxlevel = 0;
2482
	else
2483
		mytxlevel = txlevel - 4;
2484
	fmr1 = 0x9c; /* FMR1: Mode 1, T1 mode, CRC on for ESF, 8.192 Mhz system data rate, no XAIS */
2485
	fmr2 = 0x20; /* FMR2: no payload loopback, don't auto yellow */
2486
	fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */
2487
	lim2 = 0x21; /* LIM2: 50% peak is a "1", Advanced Loss recovery */
2488
	lim2 |= (mytxlevel << 6);	/* LIM2: Add line buildout */
2489
	__t4_framer_out(wc, unit, 0x1d, fmr1);
2490
	__t4_framer_out(wc, unit, 0x1e, fmr2);
2491
2492
	/* Configure line interface */
2493
	if (lineconfig & DAHDI_CONFIG_AMI) {
2494
		line = "AMI";
2495
		/* workaround for errata #2 in ES v3 09-10-16 */
2496
		fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
2497
	} else {
2498
		line = "B8ZS";
2499
		fmr0 = 0xf0;
2500
	}
2501
	if (lineconfig & DAHDI_CONFIG_D4) {
2502
		framing = "D4";
2503
	} else {
2504
		framing = "ESF";
2505
		fmr4 |= 0x2;
2506
		fmr2 |= 0xc0;
2507
	}
2508
	__t4_framer_out(wc, unit, 0x1c, fmr0);
2509
	__t4_framer_out(wc, unit, 0x20, fmr4);
2510
	__t4_framer_out(wc, unit, 0x21, 0x40);	/* FMR5: Enable RBS mode */
2511
2512
	__t4_framer_out(wc, unit, 0x37, 0xf0 );	/* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
2513
	__t4_framer_out(wc, unit, 0x36, 0x08);	/* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
2514
2515
	__t4_framer_out(wc, unit, 0x02, 0x50);	/* CMDR: Reset the receiver and transmitter line interface */
2516
	__t4_framer_out(wc, unit, 0x02, 0x00);	/* CMDR: Reset the receiver and transmitter line interface */
2517
2518
	if (wc->falc31) {
2519
		if (debug)
2520
			dev_info(&wc->dev->dev, "card %d span %d: setting Rtx "
2521
					"to 0ohm for T1\n", wc->num, unit);
2522
		__t4_framer_out(wc, unit, 0x86, 0x00);	/* PC6: set Rtx to 0ohm for T1 */
2523
2524
		// Hitting the bugfix register to fix errata #3
2525
		__t4_framer_out(wc, unit, 0xbd, 0x05);
2526
	}
2527
2528
	__t4_framer_out(wc, unit, 0x3a, lim2);	/* LIM2: 50% peak amplitude is a "1" */
2529
	__t4_framer_out(wc, unit, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
2530
	__t4_framer_out(wc, unit, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
2531
	
2532
	/* Generate pulse mask for T1 */
2533
	switch(mytxlevel) {
2534
	case 3:
2535
		__t4_framer_out(wc, unit, 0x26, 0x07);	/* XPM0 */
2536
		__t4_framer_out(wc, unit, 0x27, 0x01);	/* XPM1 */
2537
		__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2538
		break;
2539
	case 2:
2540
		__t4_framer_out(wc, unit, 0x26, 0x8c);	/* XPM0 */
2541
		__t4_framer_out(wc, unit, 0x27, 0x11);	/* XPM1 */
2542
		__t4_framer_out(wc, unit, 0x28, 0x01);	/* XPM2 */
2543
		break;
2544
	case 1:
2545
		__t4_framer_out(wc, unit, 0x26, 0x8c);	/* XPM0 */
2546
		__t4_framer_out(wc, unit, 0x27, 0x01);	/* XPM1 */
2547
		__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2548
		break;
2549
	case 0:
2550
	default:
2551
		__t4_framer_out(wc, unit, 0x26, 0xd7);	/* XPM0 */
2552
		__t4_framer_out(wc, unit, 0x27, 0x22);	/* XPM1 */
2553
		__t4_framer_out(wc, unit, 0x28, 0x01);	/* XPM2 */
2554
		break;
2555
	}
2556
2557
	/* Don't mask framer interrupts if hardware HDLC is in use */
2558
	__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0));	/* IMR0: We care about CAS changes, etc */
2559
	__t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0));	/* IMR1: We care about nothing */
2560
	__t4_framer_out(wc, unit, 0x16, 0x00);	/* IMR2: All the alarm stuff! */
2561
	__t4_framer_out(wc, unit, 0x17, 0x34);	/* IMR3: AIS and friends */
2562
	__t4_framer_out(wc, unit, 0x18, 0x3f);  /* IMR4: Slips on transmit */
2563
2564
	dev_info(&wc->dev->dev, "Span %d configured for %s/%s\n", unit + 1,
2565
			framing, line);
2566
}
2567
2568
static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
2569
{
2570
	unsigned int fmr2, fmr1, fmr0;
2571
	unsigned int cas = 0;
2572
	unsigned int imr3extra=0;
2573
	char *crc4 = "";
2574
	char *framing, *line;
2575
	fmr1 = 0x44; /* FMR1: E1 mode, Automatic force resync, PCM30 mode, 8.192 Mhz backplane, no XAIS */
2576
	fmr2 = 0x03; /* FMR2: Auto transmit remote alarm, auto loss of multiframe recovery, no payload loopback */
2577
	if (lineconfig & DAHDI_CONFIG_CRC4) {
2578
		fmr1 |= 0x08;	/* CRC4 transmit */
2579
		fmr2 |= 0xc0;	/* CRC4 receive */
2580
		crc4 = "/CRC4";
2581
	}
2582
	__t4_framer_out(wc, unit, 0x1d, fmr1);
2583
	__t4_framer_out(wc, unit, 0x1e, fmr2);
2584
2585
	/* Configure line interface */
2586
	if (lineconfig & DAHDI_CONFIG_AMI) {
2587
		line = "AMI";
2588
		/* workaround for errata #2 in ES v3 09-10-16 */
2589
		fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
2590
	} else {
2591
		line = "HDB3";
2592
		fmr0 = 0xf0;
2593
	}
2594
	if (lineconfig & DAHDI_CONFIG_CCS) {
2595
		framing = "CCS";
2596
		imr3extra = 0x28;
2597
	} else {
2598
		framing = "CAS";
2599
		cas = 0x40;
2600
	}
2601
	__t4_framer_out(wc, unit, 0x1c, fmr0);
2602
2603
	__t4_framer_out(wc, unit, 0x37, 0xf0 /*| 0x6 */ );	/* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
2604
	__t4_framer_out(wc, unit, 0x36, 0x08);	/* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
2605
2606
	__t4_framer_out(wc, unit, 0x02, 0x50);	/* CMDR: Reset the receiver and transmitter line interface */
2607
	__t4_framer_out(wc, unit, 0x02, 0x00);	/* CMDR: Reset the receiver and transmitter line interface */
2608
2609
	if (wc->falc31) {
2610
		if (debug)
2611
			dev_info(&wc->dev->dev,
2612
					"setting Rtx to 7.5ohm for E1\n");
2613
		__t4_framer_out(wc, unit, 0x86, 0x40);	/* PC6: turn on 7.5ohm Rtx for E1 */
2614
	}
2615
2616
	/* Condition receive line interface for E1 after reset */
2617
	__t4_framer_out(wc, unit, 0xbb, 0x17);
2618
	__t4_framer_out(wc, unit, 0xbc, 0x55);
2619
	__t4_framer_out(wc, unit, 0xbb, 0x97);
2620
	__t4_framer_out(wc, unit, 0xbb, 0x11);
2621
	__t4_framer_out(wc, unit, 0xbc, 0xaa);
2622
	__t4_framer_out(wc, unit, 0xbb, 0x91);
2623
	__t4_framer_out(wc, unit, 0xbb, 0x12);
2624
	__t4_framer_out(wc, unit, 0xbc, 0x55);
2625
	__t4_framer_out(wc, unit, 0xbb, 0x92);
2626
	__t4_framer_out(wc, unit, 0xbb, 0x0c);
2627
	__t4_framer_out(wc, unit, 0xbb, 0x00);
2628
	__t4_framer_out(wc, unit, 0xbb, 0x8c);
2629
	
2630
	__t4_framer_out(wc, unit, 0x3a, 0x20);	/* LIM2: 50% peak amplitude is a "1" */
2631
	__t4_framer_out(wc, unit, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
2632
	__t4_framer_out(wc, unit, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
2633
	
2634
	__t4_framer_out(wc, unit, 0x20, 0x9f);	/* XSW: Spare bits all to 1 */
2635
	__t4_framer_out(wc, unit, 0x21, 0x1c|cas);	/* XSP: E-bit set when async. AXS auto, XSIF to 1 */
2636
	
2637
	
2638
	/* Generate pulse mask for E1 */
2639
	__t4_framer_out(wc, unit, 0x26, 0x54);	/* XPM0 */
2640
	__t4_framer_out(wc, unit, 0x27, 0x02);	/* XPM1 */
2641
	__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2642
2643
	/* Don't mask framer interrupts if hardware HDLC is in use */
2644
	__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0));	/* IMR0: We care about CRC errors, CAS changes, etc */
2645
	__t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0));	/* IMR1: We care about loopup / loopdown */
2646
	__t4_framer_out(wc, unit, 0x16, 0x00);	/* IMR2: We care about all the alarm stuff! */
2647
	__t4_framer_out(wc, unit, 0x17, 0x04 | imr3extra); /* IMR3: AIS */
2648
	__t4_framer_out(wc, unit, 0x18, 0x3f);  /* IMR4: We care about slips on transmit */
2649
2650
	dev_info(&wc->dev->dev, "opvxd115: Span %d configured for %s/%s%s\n",
2651
			unit + 1, framing, line, crc4);
2652
}
2653
2654
static int t4_startup(struct file *file, struct dahdi_span *span)
2655
{
2656
#ifdef SUPPORT_GEN1
2657
	int i;
2658
#endif
2659
	int tspan;
2660
	unsigned long flags;
2661
	int alreadyrunning;
2662
	struct t4_span *ts = t4_from_span(span);
2663
	struct t4 *wc = ts->owner;
2664
2665
	set_bit(T4_IGNORE_LATENCY, &wc->checkflag);
2666
	if (debug)
2667
		dev_info(&wc->dev->dev, "About to enter startup!\n");
2668
	tspan = span->offset + 1;
2669
	if (tspan < 0) {
2670
		dev_info(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
2671
				span->spanno);
2672
		return -1;
2673
	}
2674
2675
	spin_lock_irqsave(&wc->reglock, flags);
2676
2677
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
2678
2679
#ifdef SUPPORT_GEN1
2680
	/* initialize the start value for the entire chunk of last ec buffer */
2681
	for(i = 0; i < span->channels; i++)
2682
	{
2683
		memset(ts->ec_chunk1[i],
2684
			DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
2685
		memset(ts->ec_chunk2[i],
2686
			DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
2687
	}
2688
#endif
2689
	/* Force re-evaluation of timing source */
2690
	wc->syncsrc = -1;
2691
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
2692
2693
	if (ts->spantype == TYPE_E1) { /* if this is an E1 card */
2694
		__t4_configure_e1(wc, span->offset, span->lineconfig);
2695
	} else { /* is a T1 card */
2696
		__t4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
2697
	}
2698
2699
	/* Note clear channel status */
2700
	wc->tspans[span->offset]->notclear = 0;
2701
	__set_clear(wc, span->offset);
2702
	
2703
	if (!alreadyrunning) {
2704
		span->flags |= DAHDI_FLAG_RUNNING;
2705
		wc->spansstarted++;
2706
2707
		if (wc->flags & FLAG_5THGEN)
2708
			__t4_pci_out(wc, 5, (ms_per_irq << 16) | wc->numbufs);
2709
		/* enable interrupts */
2710
		/* Start DMA, enabling DMA interrupts on read only */
2711
#if 0
2712
		/* Enable framer only interrupts */
2713
		wc->dmactrl |= 1 << 27;
2714
#endif
2715
		wc->dmactrl |= (ts->spanflags & FLAG_2NDGEN) ? 0xc0000000 : 0xc0000003;
2716
#ifdef VPM_SUPPORT
2717
		wc->dmactrl |= wc->vpm;
2718
#endif
2719
		/* Seed interrupt register */
2720
		__t4_pci_out(wc, WC_INTR, 0x0c);
2721
		if (noburst || !(ts->spanflags & FLAG_BURST))
2722
			wc->dmactrl |= (1 << 26);
2723
		__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2724
2725
		/* Startup HDLC controller too */
2726
	}
2727
2728
	if (ts->sigchan) {
2729
		struct dahdi_chan *sigchan = ts->sigchan;
2730
2731
		spin_unlock_irqrestore(&wc->reglock, flags);
2732
		if (hdlc_start(wc, span->offset, sigchan, ts->sigmode)) {
2733
			dev_notice(&wc->dev->dev, "Error initializing "
2734
					"signalling controller\n");
2735
			return -1;
2736
		}
2737
		spin_lock_irqsave(&wc->reglock, flags);
2738
	}
2739
2740
	spin_unlock_irqrestore(&wc->reglock, flags);
2741
2742
	t4_check_alarms(wc, span->offset);
2743
	t4_check_sigbits(wc, span->offset);
2744
2745
	if (wc->tspans[0]->sync == span->spanno)
2746
		dev_info(&wc->dev->dev, "SPAN %d: Primary Sync Source\n",
2747
				span->spanno);
2748
#ifdef VPM_SUPPORT
2749
	if (!alreadyrunning && !wc->vpm) {
2750
		wait_a_little();
2751
		t4_vpm400_init(wc);
2752
		if (!wc->vpm)
2753
			t4_vpm450_init(wc);
2754
		wc->dmactrl |= wc->vpm;
2755
		t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2756
		if (wc->vpm)
2757
			set_span_devicetype(wc);
2758
	}
2759
#endif
2760
	if (debug)
2761
		dev_info(&wc->dev->dev, "Completed startup!\n");
2762
	clear_bit(T4_IGNORE_LATENCY, &wc->checkflag);
2763
	return 0;
2764
}
2765
2766
#ifdef SUPPORT_GEN1
2767
static inline void e1_check(struct t4 *wc, int span, int val)
2768
{
2769
	struct t4_span *ts = wc->tspans[span];
2770
	if ((ts->span.channels > 24) &&
2771
	    (ts->span.flags & DAHDI_FLAG_RUNNING) &&
2772
	    !(ts->span.alarms) &&
2773
	    (!wc->e1recover))   {
2774
		if (val != 0x1b) {
2775
			ts->e1check++;
2776
		} else
2777
			ts->e1check = 0;
2778
		if (ts->e1check > 100) {
2779
			/* Wait 1000 ms */
2780
			wc->e1recover = 1000 * 8;
2781
			wc->tspans[0]->e1check = 0;
2782
			if (debug & DEBUG_MAIN)
2783
				dev_notice(&wc->dev->dev, "Detected loss of "
2784
					"E1 alignment on span %d!\n", span);
2785
			t4_reset_dma(wc);
2786
		}
2787
	}
2788
}
2789
2790
static void t4_receiveprep(struct t4 *wc, int irq)
2791
{
2792
	volatile unsigned int *readchunk;
2793
	int dbl = 0;
2794
	int x,y,z;
2795
	unsigned int tmp;
2796
	int offset=0;
2797
	if (!wc->t1e1)
2798
		offset = 4;
2799
	if (irq & 1) {
2800
		/* First part */
2801
		readchunk = wc->readchunk;
2802
		if (!wc->last0) 
2803
			dbl = 1;
2804
		wc->last0 = 0;
2805
	} else {
2806
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE * 32;
2807
		if (wc->last0) 
2808
			dbl = 1;
2809
		wc->last0 = 1;
2810
	}
2811
	if (dbl) {
2812
		for (x=0;x<wc->numspans;x++)
2813
			wc->ddev->irqmisses++;
2814
		if (debug & DEBUG_MAIN)
2815
			dev_notice(&wc->dev->dev, "opvxd115: Double/missed "
2816
				"interrupt detected\n");
2817
	}
2818
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
2819
		for (z=0;z<24;z++) {
2820
			/* All T1/E1 channels */
2821
			tmp = readchunk[z+1+offset];
2822
			wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
2823
		}
2824
		if (wc->t1e1) {
2825
			if (wc->e1recover > 0)
2826
				wc->e1recover--;
2827
			tmp = readchunk[0];
2828
			e1_check(wc, 0, (tmp & 0x7f000000) >> 24);
2829
			for (z=24;z<31;z++) {
2830
				/* Only E1 channels now */
2831
				tmp = readchunk[z+1];
2832
				if (wc->tspans[0]->span.channels > 24)
2833
					wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
2834
			}
2835
		}
2836
		/* Advance pointer by 4 TDM frame lengths */
2837
		readchunk += 32;
2838
	}
2839
	for (x=0;x<wc->numspans;x++) {
2840
		if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
2841
			for (y=0;y<wc->tspans[x]->span.channels;y++) {
2842
				/* Echo cancel double buffered data */
2843
				dahdi_ec_chunk(wc->tspans[x]->span.chans[y], 
2844
				    wc->tspans[x]->span.chans[y]->readchunk, 
2845
					wc->tspans[x]->ec_chunk2[y]);
2846
				memcpy(wc->tspans[x]->ec_chunk2[y],wc->tspans[x]->ec_chunk1[y],
2847
					DAHDI_CHUNKSIZE);
2848
				memcpy(wc->tspans[x]->ec_chunk1[y],
2849
					wc->tspans[x]->span.chans[y]->writechunk,
2850
						DAHDI_CHUNKSIZE);
2851
			}
2852
			dahdi_receive(&wc->tspans[x]->span);
2853
		}
2854
	}
2855
}
2856
#endif
2857
2858
#if (DAHDI_CHUNKSIZE != 8)
2859
#error Sorry, nextgen does not support chunksize != 8
2860
#endif
2861
2862
static inline void __receive_span(struct t4_span *ts)
2863
{
2864
#ifdef VPM_SUPPORT
2865
	int y;
2866
	unsigned long merged;
2867
	merged = ts->dtmfactive & ts->dtmfmutemask;
2868
	if (merged) {
2869
		for (y=0;y<ts->span.channels;y++) {
2870
			/* Mute any DTMFs which are supposed to be muted */
2871
			if (test_bit(y, &merged)) {
2872
				memset(ts->span.chans[y]->readchunk, DAHDI_XLAW(0, ts->span.chans[y]), DAHDI_CHUNKSIZE);
2873
			}
2874
		}
2875
	}
2876
#endif	
2877
2878
#ifdef ENABLE_PREFETCH
2879
	prefetch((void *)(ts->readchunk));
2880
	prefetch((void *)(ts->writechunk));
2881
	prefetch((void *)(ts->readchunk + 8));
2882
	prefetch((void *)(ts->writechunk + 8));
2883
	prefetch((void *)(ts->readchunk + 16));
2884
	prefetch((void *)(ts->writechunk + 16));
2885
	prefetch((void *)(ts->readchunk + 24));
2886
	prefetch((void *)(ts->writechunk + 24));
2887
	prefetch((void *)(ts->readchunk + 32));
2888
	prefetch((void *)(ts->writechunk + 32));
2889
	prefetch((void *)(ts->readchunk + 40));
2890
	prefetch((void *)(ts->writechunk + 40));
2891
	prefetch((void *)(ts->readchunk + 48));
2892
	prefetch((void *)(ts->writechunk + 48));
2893
	prefetch((void *)(ts->readchunk + 56));
2894
	prefetch((void *)(ts->writechunk + 56));
2895
#endif
2896
2897
	dahdi_ec_span(&ts->span);
2898
	dahdi_receive(&ts->span);
2899
}
2900
2901
static inline void __transmit_span(struct t4_span *ts)
2902
{
2903
	dahdi_transmit(&ts->span);
2904
}
2905
2906
#ifdef ENABLE_WORKQUEUES
2907
static void workq_handlespan(void *data)
2908
{
2909
	struct t4_span *ts = data;
2910
	struct t4 *wc = ts->owner;
2911
	
2912
	__receive_span(ts);
2913
	__transmit_span(ts);
2914
	atomic_dec(&wc->worklist);
2915
	if (!atomic_read(&wc->worklist))
2916
		t4_pci_out(wc, WC_INTR, 0);
2917
}
2918
#else
2919
static void t4_prep_gen2(struct t4 *wc)
2920
{
2921
	int x;
2922
	for (x=0;x<wc->numspans;x++) {
2923
		if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
2924
			__receive_span(wc->tspans[x]);
2925
			__transmit_span(wc->tspans[x]);
2926
		}
2927
	}
2928
}
2929
2930
#endif
2931
#ifdef SUPPORT_GEN1
2932
static void t4_transmitprep(struct t4 *wc, int irq)
2933
{
2934
	volatile unsigned int *writechunk;
2935
	int x,y,z;
2936
	unsigned int tmp;
2937
	int offset=0;
2938
	if (!wc->t1e1)
2939
		offset = 4;
2940
	if (irq & 1) {
2941
		/* First part */
2942
		writechunk = wc->writechunk + 1;
2943
	} else {
2944
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE * 32  + 1;
2945
	}
2946
	for (y=0;y<wc->numspans;y++) {
2947
		if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING) 
2948
			dahdi_transmit(&wc->tspans[y]->span);
2949
	}
2950
2951
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
2952
		/* Once per chunk */
2953
		for (z=0;z<24;z++) {
2954
			/* All T1/E1 channels */
2955
			tmp = (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
2956
			writechunk[z+offset] = tmp;
2957
		}
2958
		if (wc->t1e1) {
2959
			for (z=24;z<31;z++) {
2960
				/* Only E1 channels now */
2961
				tmp = 0;
2962
				if (wc->tspans[0]->span.channels > 24)
2963
					tmp |= (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
2964
				writechunk[z] = tmp;
2965
			}
2966
		}
2967
		/* Advance pointer by 4 TDM frame lengths */
2968
		writechunk += 32;
2969
	}
2970
2971
}
2972
#endif
2973
2974
static void t4_check_sigbits(struct t4 *wc, int span)
2975
{
2976
	int a,i,rxs;
2977
	struct t4_span *ts = wc->tspans[span];
2978
2979
	if (debug & DEBUG_RBS)
2980
		dev_notice(&wc->dev->dev, "Checking sigbits on span %d\n",
2981
				span + 1);
2982
2983
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
2984
		return;
2985
	if (ts->spantype == TYPE_E1) {
2986
		for (i = 0; i < 15; i++) {
2987
			a = t4_framer_in(wc, span, 0x71 + i);
2988
			/* Get high channel in low bits */
2989
			rxs = (a & 0xf);
2990
			if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
2991
				if (ts->span.chans[i+16]->rxsig != rxs)
2992
					dahdi_rbsbits(ts->span.chans[i+16], rxs);
2993
			}
2994
			rxs = (a >> 4) & 0xf;
2995
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
2996
				if (ts->span.chans[i]->rxsig != rxs)
2997
					dahdi_rbsbits(ts->span.chans[i], rxs);
2998
			}
2999
		}
3000
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
3001
		for (i = 0; i < 24; i+=4) {
3002
			a = t4_framer_in(wc, span, 0x70 + (i>>2));
3003
			/* Get high channel in low bits */
3004
			rxs = (a & 0x3) << 2;
3005
			if (!(ts->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
3006
				if (ts->span.chans[i+3]->rxsig != rxs)
3007
					dahdi_rbsbits(ts->span.chans[i+3], rxs);
3008
			}
3009
			rxs = (a & 0xc);
3010
			if (!(ts->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
3011
				if (ts->span.chans[i+2]->rxsig != rxs)
3012
					dahdi_rbsbits(ts->span.chans[i+2], rxs);
3013
			}
3014
			rxs = (a >> 2) & 0xc;
3015
			if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
3016
				if (ts->span.chans[i+1]->rxsig != rxs)
3017
					dahdi_rbsbits(ts->span.chans[i+1], rxs);
3018
			}
3019
			rxs = (a >> 4) & 0xc;
3020
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
3021
				if (ts->span.chans[i]->rxsig != rxs)
3022
					dahdi_rbsbits(ts->span.chans[i], rxs);
3023
			}
3024
		}
3025
	} else {
3026
		for (i = 0; i < 24; i+=2) {
3027
			a = t4_framer_in(wc, span, 0x70 + (i>>1));
3028
			/* Get high channel in low bits */
3029
			rxs = (a & 0xf);
3030
			if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
3031
				/* XXX Not really reset on every trans! XXX */
3032
				if (ts->span.chans[i+1]->rxsig != rxs) {
3033
					dahdi_rbsbits(ts->span.chans[i+1], rxs);
3034
				}
3035
			}
3036
			rxs = (a >> 4) & 0xf;
3037
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
3038
				/* XXX Not really reset on every trans! XXX */
3039
				if (ts->span.chans[i]->rxsig != rxs) {
3040
					dahdi_rbsbits(ts->span.chans[i], rxs);
3041
				}
3042
			}
3043
		}
3044
	}
3045
}
3046
3047
static void t4_check_alarms(struct t4 *wc, int span)
3048
{
3049
	unsigned char c, d, e;
3050
	int alarms;
3051
	int x,j;
3052
	struct t4_span *ts = wc->tspans[span];
3053
	unsigned long flags;
3054
3055
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
3056
		return;
3057
3058
	spin_lock_irqsave(&wc->reglock, flags);
3059
3060
	c = __t4_framer_in(wc, span, 0x4c);
3061
	d = __t4_framer_in(wc, span, 0x4d);
3062
3063
	/* Assume no alarms */
3064
	alarms = 0;
3065
3066
	/* And consider only carrier alarms */
3067
	ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
3068
3069
	if (ts->spantype == TYPE_E1) {
3070
		if (c & 0x04) {
3071
			/* No multiframe found, force RAI high after 400ms only if
3072
			   we haven't found a multiframe since last loss
3073
			   of frame */
3074
			if (!(ts->spanflags & FLAG_NMF)) {
3075
				__t4_framer_out(wc, span, 0x20, 0x9f | 0x20);	/* LIM0: Force RAI High */
3076
				ts->spanflags |= FLAG_NMF;
3077
				dev_notice(&wc->dev->dev,
3078
					"NMF workaround on!\n");
3079
			}
3080
			__t4_framer_out(wc, span, 0x1e, 0xc3);	/* Reset to CRC4 mode */
3081
			__t4_framer_out(wc, span, 0x1c, 0xf2);	/* Force Resync */
3082
			__t4_framer_out(wc, span, 0x1c, 0xf0);	/* Force Resync */
3083
		} else if (!(c & 0x02)) {
3084
			if ((ts->spanflags & FLAG_NMF)) {
3085
				__t4_framer_out(wc, span, 0x20, 0x9f);	/* LIM0: Clear forced RAI */
3086
				ts->spanflags &= ~FLAG_NMF;
3087
				dev_notice(&wc->dev->dev,
3088
					"NMF workaround off!\n");
3089
			}
3090
		}
3091
	} else {
3092
		/* Detect loopup code if we're not sending one */
3093
		if ((!ts->span.mainttimer) && (d & 0x08)) {
3094
			/* Loop-up code detected */
3095
			if ((ts->loopupcnt++ > 80)  && (ts->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
3096
				__t4_framer_out(wc, span, 0x36, 0x08);	/* LIM0: Disable any local loop */
3097
				__t4_framer_out(wc, span, 0x37, 0xf6 );	/* LIM1: Enable remote loop */
3098
				ts->span.maintstat = DAHDI_MAINT_REMOTELOOP;
3099
			}
3100
		} else
3101
			ts->loopupcnt = 0;
3102
		/* Same for loopdown code */
3103
		if ((!ts->span.mainttimer) && (d & 0x10)) {
3104
			/* Loop-down code detected */
3105
			if ((ts->loopdowncnt++ > 80)  && (ts->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
3106
				__t4_framer_out(wc, span, 0x36, 0x08);	/* LIM0: Disable any local loop */
3107
				__t4_framer_out(wc, span, 0x37, 0xf0 );	/* LIM1: Disable remote loop */
3108
				ts->span.maintstat = DAHDI_MAINT_NONE;
3109
			}
3110
		} else
3111
			ts->loopdowncnt = 0;
3112
	}
3113
3114
	if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
3115
		for (x=0,j=0;x < ts->span.channels;x++)
3116
			if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
3117
#ifdef CONFIG_DAHDI_NET
3118
					||
3119
			    (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
3120
#endif
3121
			    )
3122
				j++;
3123
		if (!j)
3124
			alarms |= DAHDI_ALARM_NOTOPEN;
3125
	}
3126
3127
	/* Loss of Frame Alignment */
3128
	if (c & 0x20) {
3129
		if (ts->alarmcount >= alarmdebounce) {
3130
3131
			/* Disable Slip Interrupts */
3132
			e = __t4_framer_in(wc, span, 0x17);
3133
			__t4_framer_out(wc, span, 0x17, (e|0x03));
3134
3135
			alarms |= DAHDI_ALARM_RED;
3136
		} else {
3137
			if (unlikely(debug && !ts->alarmcount)) {
3138
				/* starting to debounce LOF/LFA */
3139
				dev_info(&wc->dev->dev, "opvxd115: LOF/LFA "
3140
					"detected on span %d but debouncing "
3141
					"for %d ms\n", span + 1,
3142
					alarmdebounce);
3143
			}
3144
			ts->alarmcount++;
3145
		}
3146
	} else
3147
		ts->alarmcount = 0;
3148
3149
	/* Loss of Signal */
3150
	if (c & 0x80) {
3151
		if (ts->losalarmcount >= losalarmdebounce) {
3152
			/* Disable Slip Interrupts */
3153
			e = __t4_framer_in(wc, span, 0x17);
3154
			__t4_framer_out(wc, span, 0x17, (e|0x03));
3155
3156
			alarms |= DAHDI_ALARM_RED;
3157
		} else {
3158
			if (unlikely(debug && !ts->losalarmcount)) {
3159
				/* starting to debounce LOS */
3160
				dev_info(&wc->dev->dev, "opvxd115: LOS "
3161
					"detected on span %d but debouncing "
3162
					"for %d ms\n",
3163
					span + 1, losalarmdebounce);
3164
			}
3165
			ts->losalarmcount++;
3166
		}
3167
	} else
3168
		ts->losalarmcount = 0;
3169
3170
	/* Alarm Indication Signal */
3171
	if (c & 0x40) {
3172
		if (ts->aisalarmcount >= aisalarmdebounce)
3173
			alarms |= DAHDI_ALARM_BLUE;
3174
		else {
3175
			if (unlikely(debug && !ts->aisalarmcount)) {
3176
				/* starting to debounce AIS */
3177
				dev_info(&wc->dev->dev, "opvxd115: AIS "
3178
					"detected on span %d but debouncing "
3179
					"for %d ms\n",
3180
					span + 1, aisalarmdebounce);
3181
			}
3182
			ts->aisalarmcount++;
3183
		}
3184
	} else
3185
		ts->aisalarmcount = 0;
3186
3187
#ifdef DAHDI_SPAN_OPS
3188
	/* Add detailed alarm status information to a red alarm state */
3189
	if (alarms & DAHDI_ALARM_RED) {
3190
		if (c & FRS0_LOS)
3191
			alarms |= DAHDI_ALARM_LOS;
3192
		if (c & FRS0_LFA)
3193
			alarms |= DAHDI_ALARM_LFA;
3194
		if (c & FRS0_LMFA)
3195
			alarms |= DAHDI_ALARM_LMFA;
3196
	}
3197
3198
	if (unlikely(debug)) {
3199
		/* Check to ensure the xmit line isn't shorted */
3200
		if (unlikely(d & FRS1_XLS)) {
3201
			dev_info(&wc->dev->dev,
3202
				"Detected a possible hardware malfunction"\
3203
				" this card may need servicing\n");
3204
		}
3205
	}
3206
#endif
3207
3208
	if (((!ts->span.alarms) && alarms) || 
3209
	    (ts->span.alarms && (!alarms))) 
3210
		set_bit(T4_CHECK_TIMING, &wc->checkflag);
3211
3212
	/* Keep track of recovering */
3213
	if ((!alarms) && ts->span.alarms) 
3214
		ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
3215
	if (ts->alarmtimer)
3216
		alarms |= DAHDI_ALARM_RECOVER;
3217
3218
	/* If receiving alarms, go into Yellow alarm state */
3219
	if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
3220
		/* We manually do yellow alarm to handle RECOVER and NOTOPEN, otherwise it's auto anyway */
3221
		unsigned char fmr4;
3222
		fmr4 = __t4_framer_in(wc, span, 0x20);
3223
		__t4_framer_out(wc, span, 0x20, fmr4 | 0x20);
3224
		dev_info(&wc->dev->dev, "Setting yellow alarm span %d\n",
3225
								span+1);
3226
		ts->spanflags |= FLAG_SENDINGYELLOW;
3227
	} else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
3228
		unsigned char fmr4;
3229
		/* We manually do yellow alarm to handle RECOVER  */
3230
		fmr4 = __t4_framer_in(wc, span, 0x20);
3231
		__t4_framer_out(wc, span, 0x20, fmr4 & ~0x20);
3232
		dev_info(&wc->dev->dev, "Clearing yellow alarm span %d\n",
3233
								span+1);
3234
3235
		/* Re-enable timing slip interrupts */
3236
		e = __t4_framer_in(wc, span, 0x17);
3237
3238
		__t4_framer_out(wc, span, 0x17, (e & ~(0x03)));
3239
3240
		ts->spanflags &= ~FLAG_SENDINGYELLOW;
3241
	}
3242
3243
	/* Re-check the timing source when we enter/leave alarm, not withstanding
3244
	   yellow alarm */
3245
	if (c & 0x10) { /* receiving yellow (RAI) */
3246
		if (ts->yelalarmcount >= yelalarmdebounce)
3247
			alarms |= DAHDI_ALARM_YELLOW;
3248
		else {
3249
			if (unlikely(debug && !ts->yelalarmcount)) {
3250
				/* starting to debounce AIS */
3251
				dev_info(&wc->dev->dev, "wct%dxxp: yellow "
3252
					"(RAI) detected on span %d but "
3253
					"debouncing for %d ms\n",
3254
					wc->numspans, span + 1,
3255
					yelalarmdebounce);
3256
			}
3257
			ts->yelalarmcount++;
3258
		}
3259
	} else
3260
		ts->yelalarmcount = 0;
3261
3262
	if (ts->span.mainttimer || ts->span.maintstat) 
3263
		alarms |= DAHDI_ALARM_LOOPBACK;
3264
	ts->span.alarms = alarms;
3265
	spin_unlock_irqrestore(&wc->reglock, flags);
3266
	dahdi_alarm_notify(&ts->span);
3267
}
3268
3269
static void t4_do_counters(struct t4 *wc)
3270
{
3271
	int span;
3272
	for (span=0;span<wc->numspans;span++) {
3273
		struct t4_span *ts = wc->tspans[span];
3274
		int docheck=0;
3275
3276
		spin_lock(&wc->reglock);
3277
		if (ts->loopupcnt || ts->loopdowncnt || ts->alarmcount
3278
			|| ts->losalarmcount || ts->aisalarmcount
3279
			|| ts->yelalarmcount)
3280
			docheck++;
3281
3282
		if (ts->alarmtimer) {
3283
			if (!--ts->alarmtimer) {
3284
				docheck++;
3285
				ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
3286
			}
3287
		}
3288
		spin_unlock(&wc->reglock);
3289
		if (docheck) {
3290
			t4_check_alarms(wc, span);
3291
			dahdi_alarm_notify(&ts->span);
3292
		}
3293
	}
3294
}
3295
3296
static inline void __handle_leds(struct t4 *wc)
3297
{
3298
	int x;
3299
3300
	wc->blinktimer++;
3301
	for (x=0;x<wc->numspans;x++) {
3302
		struct t4_span *ts = wc->tspans[x];
3303
		if (ts->span.flags & DAHDI_FLAG_RUNNING) {
3304
			if ((ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) || ts->losalarmcount) {
3305
#ifdef FANCY_ALARM
3306
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
3307
					__t4_set_led(wc, x, WC_RED);
3308
				}
3309
				if (wc->blinktimer == 0xf) {
3310
					__t4_set_led(wc, x, WC_OFF);
3311
				}
3312
#else
3313
				if (wc->blinktimer == 160) {
3314
					__t4_set_led(wc, x, WC_RED);
3315
				} else if (wc->blinktimer == 480) {
3316
					__t4_set_led(wc, x, WC_OFF);
3317
				}
3318
#endif
3319
			} else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
3320
				/* Yellow Alarm */
3321
				__t4_set_led(wc, x, WC_YELLOW);
3322
			} else if (ts->span.mainttimer || ts->span.maintstat) {
3323
#ifdef FANCY_ALARM
3324
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
3325
					__t4_set_led(wc, x, WC_GREEN);
3326
				}
3327
				if (wc->blinktimer == 0xf) {
3328
					__t4_set_led(wc, x, WC_OFF);
3329
				}
3330
#else
3331
				if (wc->blinktimer == 160) {
3332
					__t4_set_led(wc, x, WC_GREEN);
3333
				} else if (wc->blinktimer == 480) {
3334
					__t4_set_led(wc, x, WC_OFF);
3335
				}
3336
#endif
3337
			} else {
3338
				/* No Alarm */
3339
				__t4_set_led(wc, x, WC_GREEN);
3340
			}
3341
		}	else
3342
				__t4_set_led(wc, x, WC_OFF);
3343
3344
	}
3345
#ifdef FANCY_ALARM
3346
	if (wc->blinktimer == 0xf) {
3347
		wc->blinktimer = -1;
3348
		wc->alarmpos++;
3349
		if (wc->alarmpos >= (sizeof(altab) / sizeof(altab[0])))
3350
			wc->alarmpos = 0;
3351
	}
3352
#else
3353
	if (wc->blinktimer == 480)
3354
		wc->blinktimer = 0;
3355
#endif
3356
}
3357
3358
static inline void t4_framer_interrupt(struct t4 *wc, int span)
3359
{
3360
	unsigned char gis, isr0, isr1, isr2, isr3, isr4;
3361
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
3362
	/* Check interrupts for a given span */
3363
	unsigned char reg;
3364
#endif
3365
	int readsize = -1;
3366
	struct t4_span *ts = wc->tspans[span];
3367
	struct dahdi_chan *sigchan;
3368
	unsigned long flags;
3369
3370
3371
	/* 1st gen cards isn't used interrupts */
3372
	gis = t4_framer_in(wc, span, FRMR_GIS);
3373
	isr0 = (gis & FRMR_GIS_ISR0) ? t4_framer_in(wc, span, FRMR_ISR0) : 0;
3374
	isr1 = (gis & FRMR_GIS_ISR1) ? t4_framer_in(wc, span, FRMR_ISR1) : 0;
3375
	isr2 = (gis & FRMR_GIS_ISR2) ? t4_framer_in(wc, span, FRMR_ISR2) : 0;
3376
	isr3 = (gis & FRMR_GIS_ISR3) ? t4_framer_in(wc, span, FRMR_ISR3) : 0;
3377
	isr4 = (gis & FRMR_GIS_ISR4) ? t4_framer_in(wc, span, FRMR_ISR4) : 0;
3378
3379
 	if ((debug & DEBUG_FRAMER) && !(isr3 & ISR3_SEC)) {
3380
 		dev_info(&wc->dev->dev, "gis: %02x, isr0: %02x, isr1: %02x, "\
3381
 			"isr2: %02x, isr3: %08x, isr4: %02x, intcount=%u\n",
3382
 			gis, isr0, isr1, isr2, isr3, isr4, wc->intcount);
3383
 	}
3384
 
3385
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
3386
	/* Collect performance counters once per second */
3387
 	if (isr3 & ISR3_SEC) {
3388
 		ts->span.count.fe += t4_framer_in(wc, span, FECL_T);
3389
 		ts->span.count.crc4 += t4_framer_in(wc, span, CEC1L_T);
3390
 		ts->span.count.cv += t4_framer_in(wc, span, CVCL_T);
3391
 		ts->span.count.ebit += t4_framer_in(wc, span, EBCL_T);
3392
 		ts->span.count.be += t4_framer_in(wc, span, BECL_T);
3393
 		ts->span.count.prbs = t4_framer_in(wc, span, FRS1_T);
3394
 	}
3395
 
3396
	/* Collect errored second counter once per second */
3397
 	if (isr3 & ISR3_ES) {
3398
 		ts->span.count.errsec += 1;
3399
 	}
3400
 
3401
 	if (isr3 & 0x08) {
3402
 		reg = t4_framer_in(wc, span, FRS1_T);
3403
		dev_info(&wc->dev->dev, "FRS1: %d\n", reg);
3404
 		if (reg & LLBDD) {
3405
 			dev_info(&wc->dev->dev, "Line loop-back activation "\
3406
 					"signal detected with status: %01d "\
3407
 					"for span %d\n", reg & LLBAD, span+1);
3408
 		}
3409
 	}
3410
#endif
3411
3412
	if (isr0)
3413
		t4_check_sigbits(wc, span);
3414
3415
	if (ts->spantype == TYPE_E1) {
3416
		/* E1 checks */
3417
		if ((isr3 & 0x38) || isr2 || isr1)
3418
			t4_check_alarms(wc, span);
3419
	} else {
3420
		/* T1 checks */
3421
		if (isr2 || (isr3 & 0x08))
3422
			t4_check_alarms(wc, span);
3423
	}
3424
	if (!ts->span.alarms) {
3425
		if ((isr3 & 0x3) || (isr4 & 0xc0))
3426
			ts->span.count.timingslips++;
3427
3428
		if (debug & DEBUG_MAIN) {
3429
			if (isr3 & 0x02)
3430
				dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
3431
					"slip NEGATIVE on span %d\n",
3432
					span + 1);
3433
			if (isr3 & 0x01)
3434
				dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
3435
					"slip POSITIVE on span %d\n",
3436
					span + 1);
3437
			if (isr4 & 0x80)
3438
				dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
3439
					"slip POSITIVE on span %d\n",
3440
					span + 1);
3441
			if (isr4 & 0x40)
3442
				dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
3443
					"slip NEGATIVE on span %d\n",
3444
					span + 1);
3445
		}
3446
	} else
3447
		ts->span.count.timingslips = 0;
3448
3449
	spin_lock_irqsave(&wc->reglock, flags);
3450
	/* HDLC controller checks - receive side */
3451
	if (!ts->sigchan) {
3452
		spin_unlock_irqrestore(&wc->reglock, flags);
3453
		return;
3454
	}
3455
3456
	sigchan = ts->sigchan;
3457
	spin_unlock_irqrestore(&wc->reglock, flags);
3458
3459
	if (isr0 & FRMR_ISR0_RME) {
3460
		readsize = (t4_framer_in(wc, span, FRMR_RBCH) << 8) | t4_framer_in(wc, span, FRMR_RBCL);
3461
		if (debug & DEBUG_FRAMER)
3462
			dev_notice(&wc->dev->dev, "Received data length is %d "
3463
				"(%d)\n", readsize,
3464
				readsize & FRMR_RBCL_MAX_SIZE);
3465
		/* RPF isn't set on last part of frame */
3466
		if ((readsize > 0) && ((readsize &= FRMR_RBCL_MAX_SIZE) == 0))
3467
			readsize = FRMR_RBCL_MAX_SIZE + 1;
3468
	} else if (isr0 & FRMR_ISR0_RPF)
3469
		readsize = FRMR_RBCL_MAX_SIZE + 1;
3470
3471
	if (readsize > 0) {
3472
		int i;
3473
		unsigned char readbuf[FRMR_RBCL_MAX_SIZE + 1];
3474
3475
		if (debug & DEBUG_FRAMER)
3476
			dev_notice(&wc->dev->dev, "Framer %d: Got RPF/RME! "
3477
				"readsize is %d\n", sigchan->span->offset,
3478
				readsize);
3479
3480
		for (i = 0; i < readsize; i++)
3481
			readbuf[i] = t4_framer_in(wc, span, FRMR_RXFIFO);
3482
3483
		/* Tell the framer to clear the RFIFO */
3484
		t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC);
3485
3486
		if (debug & DEBUG_FRAMER) {
3487
			dev_notice(&wc->dev->dev, "RX(");
3488
			for (i = 0; i < readsize; i++)
3489
				dev_notice(&wc->dev->dev, "%s%02x",
3490
					(i ? " " : ""), readbuf[i]);
3491
			dev_notice(&wc->dev->dev, ")\n");
3492
		}
3493
3494
		if (isr0 & FRMR_ISR0_RME) {
3495
			/* Do checks for HDLC problems */
3496
			unsigned char rsis = readbuf[readsize-1];
3497
#if 0
3498
			unsigned int olddebug = debug;
3499
#endif
3500
			unsigned char rsis_reg = t4_framer_in(wc, span, FRMR_RSIS);
3501
3502
#if 0
3503
			if ((rsis != 0xA2) || (rsis != rsis_reg))
3504
				debug |= DEBUG_FRAMER;
3505
#endif
3506
3507
			++ts->frames_in;
3508
			if ((debug & DEBUG_FRAMER) && !(ts->frames_in & 0x0f))
3509
				dev_notice(&wc->dev->dev, "Received %d frames "
3510
					"on span %d\n", ts->frames_in, span);
3511
			if (debug & DEBUG_FRAMER)
3512
				dev_notice(&wc->dev->dev, "Received HDLC frame"
3513
					" %d.  RSIS = 0x%x (%x)\n",
3514
					ts->frames_in, rsis, rsis_reg);
3515
			if (!(rsis & FRMR_RSIS_CRC16)) {
3516
				if (debug & DEBUG_FRAMER)
3517
					dev_notice(&wc->dev->dev, "CRC check "
3518
							"failed %d\n", span);
3519
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_BADFCS);
3520
			} else if (rsis & FRMR_RSIS_RAB) {
3521
				if (debug & DEBUG_FRAMER)
3522
					dev_notice(&wc->dev->dev, "ABORT of "
3523
						"current frame due to "
3524
						"overflow %d\n", span);
3525
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
3526
			} else if (rsis & FRMR_RSIS_RDO) {
3527
				if (debug & DEBUG_FRAMER)
3528
					dev_notice(&wc->dev->dev, "HDLC "
3529
						"overflow occured %d\n",
3530
						span);
3531
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_OVERRUN);
3532
			} else if (!(rsis & FRMR_RSIS_VFR)) {
3533
				if (debug & DEBUG_FRAMER)
3534
					dev_notice(&wc->dev->dev, "Valid Frame"
3535
						" check failed on span %d\n",
3536
						span);
3537
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
3538
			} else {
3539
				dahdi_hdlc_putbuf(sigchan, readbuf, readsize - 1);
3540
				dahdi_hdlc_finish(sigchan);
3541
				if (debug & DEBUG_FRAMER)
3542
					dev_notice(&wc->dev->dev, "Received "
3543
						"valid HDLC frame on span %d"
3544
						"\n", span);
3545
			}
3546
#if 0
3547
			debug = olddebug;
3548
#endif
3549
		} else if (isr0 & FRMR_ISR0_RPF)
3550
			dahdi_hdlc_putbuf(sigchan, readbuf, readsize);
3551
	}
3552
3553
	/* Transmit side */
3554
	if (isr1 & FRMR_ISR1_XDU) {
3555
		if (debug & DEBUG_FRAMER)
3556
			dev_notice(&wc->dev->dev, "XDU: Resetting signal "
3557
					"controller!\n");
3558
		t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
3559
	} else if (isr1 & FRMR_ISR1_XPR) {
3560
		if (debug & DEBUG_FRAMER)
3561
			dev_notice(&wc->dev->dev, "Sigchan %d is %p\n",
3562
					sigchan->chanpos, sigchan);
3563
3564
		if (debug & DEBUG_FRAMER)
3565
			dev_notice(&wc->dev->dev, "Framer %d: Got XPR!\n",
3566
					sigchan->span->offset);
3567
		t4_hdlc_xmit_fifo(wc, span, ts);
3568
	}
3569
3570
	if (isr1 & FRMR_ISR1_ALLS) {
3571
		if (debug & DEBUG_FRAMER)
3572
			dev_notice(&wc->dev->dev, "ALLS received\n");
3573
	}
3574
}
3575
3576
#ifdef SUPPORT_GEN1
3577
static irqreturn_t t4_interrupt(int irq, void *dev_id)
3578
{
3579
	struct t4 *wc = dev_id;
3580
	unsigned long flags;
3581
	int x;
3582
	
3583
	unsigned int status;
3584
	unsigned int status2;
3585
3586
#if 0
3587
	if (wc->intcount < 20)
3588
		dev_notice(&wc->dev->dev, "Pre-interrupt\n");
3589
#endif
3590
	
3591
	/* Make sure it's really for us */
3592
	status = __t4_pci_in(wc, WC_INTR);
3593
3594
	/* Process framer interrupts */
3595
	status2 = t4_framer_in(wc, 0, FRMR_CIS);
3596
	if (status2 & 0x0f) {
3597
		for (x = 0; x < wc->numspans; ++x) {
3598
			if (status2 & (1 << x))
3599
				t4_framer_interrupt(wc, x);
3600
		}
3601
	}
3602
3603
	/* Ignore if it's not for us */
3604
	if (!status)
3605
		return IRQ_NONE;
3606
3607
	__t4_pci_out(wc, WC_INTR, 0);
3608
3609
	if (!wc->spansstarted) {
3610
		dev_notice(&wc->dev->dev, "Not prepped yet!\n");
3611
		return IRQ_NONE;
3612
	}
3613
3614
	wc->intcount++;
3615
#if 0
3616
	if (wc->intcount < 20)
3617
		dev_notice(&wc->dev->dev, "Got interrupt, status = %08x\n",
3618
				status);
3619
#endif		
3620
3621
	if (status & 0x3) {
3622
		t4_receiveprep(wc, status);
3623
		t4_transmitprep(wc, status);
3624
	}
3625
	
3626
#if 0
3627
	if ((wc->intcount < 10) || !(wc->intcount % 1000)) {
3628
		status2 = t4_framer_in(wc, 0, FRMR_CIS);
3629
		dev_notice(&wc->dev->dev, "Status2: %04x\n", status2);
3630
		for (x = 0;x<wc->numspans;x++) {
3631
			status2 = t4_framer_in(wc, x, FRMR_FRS0);
3632
			dev_notice(&wc->dev->dev, "FRS0/%d: %04x\n", x,
3633
					status2);
3634
		}
3635
	}
3636
#endif
3637
	t4_do_counters(wc);
3638
3639
	x = wc->intcount & 15 /* 63 */;
3640
	switch(x) {
3641
	case 0:
3642
	case 1:
3643
	case 2:
3644
	case 3:
3645
		t4_check_sigbits(wc, x);
3646
		break;
3647
	case 4:
3648
	case 5:
3649
	case 6:
3650
	case 7:
3651
		t4_check_alarms(wc, x - 4);
3652
		break;
3653
	}
3654
3655
	spin_lock_irqsave(&wc->reglock, flags);
3656
3657
	__handle_leds(wc);
3658
3659
	if (test_bit(T4_CHECK_TIMING, &wc->checkflag))
3660
		__t4_set_timing_source_auto(wc);
3661
3662
	spin_unlock_irqrestore(&wc->reglock, flags);
3663
3664
	return IRQ_RETVAL(1);
3665
}
3666
#endif
3667
3668
static int t4_allocate_buffers(struct t4 *wc, int numbufs, volatile unsigned int **oldalloc, dma_addr_t *oldwritedma)
3669
{
3670
	volatile unsigned int *alloc;
3671
	dma_addr_t writedma;
3672
3673
	alloc =
3674
		/* 32 channels, Double-buffer, Read/Write, 4 spans */
3675
		(unsigned int *)pci_alloc_consistent(wc->dev, numbufs * T4_BASE_SIZE * 2, &writedma);
3676
3677
	if (!alloc) {
3678
		dev_notice(&wc->dev->dev, "wct%dxxp: Unable to allocate "
3679
				"DMA-able memory\n", wc->numspans);
3680
		return -ENOMEM;
3681
	}
3682
3683
	if (oldwritedma)
3684
		*oldwritedma = wc->writedma;
3685
	if (oldalloc)
3686
		*oldalloc = wc->writechunk;
3687
3688
	wc->writechunk = alloc;
3689
	wc->writedma = writedma;
3690
3691
	/* Read is after the whole write piece (in words) */
3692
	wc->readchunk = wc->writechunk + (T4_BASE_SIZE * numbufs) / 4;
3693
	
3694
	/* Same thing but in bytes...  */
3695
	wc->readdma = wc->writedma + (T4_BASE_SIZE * numbufs);
3696
3697
	wc->numbufs = numbufs;
3698
	
3699
	/* Initialize Write/Buffers to all blank data */
3700
	memset((void *)wc->writechunk,0x00, T4_BASE_SIZE * numbufs);
3701
	memset((void *)wc->readchunk,0xff, T4_BASE_SIZE * numbufs);
3702
3703
	dev_notice(&wc->dev->dev, "DMA memory base of size %d at %p.  Read: "
3704
		"%p and Write %p\n", numbufs * T4_BASE_SIZE * 2,
3705
		wc->writechunk, wc->readchunk, wc->writechunk);
3706
3707
	return 0;
3708
}
3709
3710
static void t4_increase_latency(struct t4 *wc, int newlatency)
3711
{
3712
	unsigned long flags;
3713
	volatile unsigned int *oldalloc;
3714
	dma_addr_t oldaddr;
3715
	int oldbufs;
3716
3717
	spin_lock_irqsave(&wc->reglock, flags);
3718
3719
	__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3720
	/* Acknowledge any pending interrupts */
3721
	__t4_pci_out(wc, WC_INTR, 0x00000000);
3722
3723
	__t4_pci_in(wc, WC_VERSION);
3724
3725
	oldbufs = wc->numbufs;
3726
3727
	if (t4_allocate_buffers(wc, newlatency, &oldalloc, &oldaddr)) {
3728
		dev_info(&wc->dev->dev, "Error allocating latency buffers for "
3729
				"latency of %d\n", newlatency);
3730
		__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3731
		spin_unlock_irqrestore(&wc->reglock, flags);
3732
		return;
3733
	}
3734
3735
	__t4_pci_out(wc, WC_RDADDR, wc->readdma);
3736
	__t4_pci_out(wc, WC_WRADDR, wc->writedma);
3737
3738
	__t4_pci_in(wc, WC_VERSION);
3739
3740
	__t4_pci_out(wc, 5, (ms_per_irq << 16) | newlatency);
3741
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3742
3743
	__t4_pci_in(wc, WC_VERSION);
3744
3745
	wc->rxident = 0;
3746
	wc->lastindex = 0;
3747
3748
	spin_unlock_irqrestore(&wc->reglock, flags);
3749
3750
	pci_free_consistent(wc->dev, T4_BASE_SIZE * oldbufs * 2, (void *)oldalloc, oldaddr);
3751
3752
	dev_info(&wc->dev->dev, "Increased latency to %d\n", newlatency);
3753
3754
}
3755
3756
static void t4_isr_bh(unsigned long data)
3757
{
3758
	struct t4 *wc = (struct t4 *)data;
3759
3760
	if (test_bit(T4_CHANGE_LATENCY, &wc->checkflag)) {
3761
		if (wc->needed_latency != wc->numbufs) {
3762
			t4_increase_latency(wc, wc->needed_latency);
3763
			clear_bit(T4_CHANGE_LATENCY, &wc->checkflag);
3764
		}
3765
	}
3766
#ifdef VPM_SUPPORT
3767
	if (wc->vpm) {
3768
		if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) {
3769
			if (wc->vpm450m) {
3770
				/* How stupid is it that the octasic can't generate an
3771
				   interrupt when there's a tone, in spite of what their
3772
				   documentation says? */
3773
				t4_check_vpm450(wc);
3774
			} else
3775
				t4_check_vpm400(wc, wc->vpm400checkstatus);
3776
		}
3777
	}
3778
#endif
3779
}
3780
3781
static irqreturn_t t4_interrupt_gen2(int irq, void *dev_id)
3782
{
3783
	struct t4 *wc = dev_id;
3784
	unsigned int status;
3785
	unsigned char rxident, expected;
3786
	
3787
	/* Check this first in case we get a spurious interrupt */
3788
	if (unlikely(test_bit(T4_STOP_DMA, &wc->checkflag))) {
3789
		/* Stop DMA cleanly if requested */
3790
		wc->dmactrl = 0x0;
3791
		t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3792
		/* Acknowledge any pending interrupts */
3793
		t4_pci_out(wc, WC_INTR, 0x00000000);
3794
		spin_lock(&wc->reglock);
3795
		__t4_set_sclk_src(wc, WC_SELF, 0, 0);
3796
		spin_unlock(&wc->reglock);
3797
		return IRQ_RETVAL(1);
3798
	}
3799
3800
	/* Make sure it's really for us */
3801
	status = __t4_pci_in(wc, WC_INTR);
3802
3803
	/* Ignore if it's not for us */
3804
	if (!(status & 0x7)) {
3805
		return IRQ_NONE;
3806
	}
3807
3808
#ifdef ENABLE_WORKQUEUES
3809
	__t4_pci_out(wc, WC_INTR, status & 0x00000008);
3810
#endif
3811
3812
	if (unlikely(!wc->spansstarted)) {
3813
		dev_info(&wc->dev->dev, "Not prepped yet!\n");
3814
		return IRQ_NONE;
3815
	}
3816
3817
	wc->intcount++;
3818
3819
	if ((wc->flags & FLAG_5THGEN) && (status & 0x2)) {
3820
		rxident = (status >> 16) & 0x7f;
3821
		expected = (wc->rxident + ms_per_irq) % 128;
3822
	
3823
		if ((rxident != expected) && !test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
3824
			int needed_latency;
3825
			int smallest_max;
3826
3827
			if (debug & DEBUG_MAIN)
3828
				dev_warn(&wc->dev->dev, "Missed interrupt.  "
3829
					"Expected ident of %d and got ident "
3830
					"of %d\n", expected, rxident);
3831
3832
			if (test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
3833
				dev_info(&wc->dev->dev,
3834
					"Should have ignored latency\n");
3835
			}
3836
			if (rxident > wc->rxident) {
3837
				needed_latency = rxident - wc->rxident;
3838
			} else {
3839
				needed_latency = (128 - wc->rxident) + rxident;
3840
			}
3841
3842
			needed_latency += 1;
3843
3844
			smallest_max = (max_latency >= GEN5_MAX_LATENCY) ? GEN5_MAX_LATENCY : max_latency;
3845
3846
			if (needed_latency > smallest_max) {
3847
				dev_info(&wc->dev->dev, "Truncating latency "
3848
					"request to %d instead of %d\n",
3849
					smallest_max, needed_latency);
3850
				needed_latency = smallest_max;
3851
			}
3852
3853
			if (needed_latency > wc->numbufs) {
3854
				int x;
3855
3856
				dev_info(&wc->dev->dev, "Need to increase "
3857
					"latency.  Estimated latency should "
3858
					"be %d\n", needed_latency);
3859
				for (x = 0; x < wc->numspans; x++)
3860
					wc->ddev->irqmisses++;
3861
				wc->needed_latency = needed_latency;
3862
				__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3863
				set_bit(T4_CHANGE_LATENCY, &wc->checkflag);
3864
				goto out;
3865
			}
3866
		}
3867
	
3868
		wc->rxident = rxident;
3869
	}
3870
3871
	if (unlikely((wc->intcount < 20)))
3872
3873
		dev_info(&wc->dev->dev, "2G: Got interrupt, status = %08x, "
3874
			"CIS = %04x\n", status, t4_framer_in(wc, 0, FRMR_CIS));
3875
3876
	if (likely(status & 0x2)) {
3877
#ifdef ENABLE_WORKQUEUES
3878
		int cpus = num_online_cpus();
3879
		atomic_set(&wc->worklist, wc->numspans);
3880
		if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
3881
			t4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
3882
		else
3883
			atomic_dec(&wc->worklist);
3884
#else
3885
#if 1
3886
		unsigned int reg5 = __t4_pci_in(wc, 5);
3887
		if (wc->intcount < 20) {
3888
3889
			dev_info(&wc->dev->dev, "Reg 5 is %08x\n", reg5);
3890
		}
3891
#endif
3892
3893
		if (wc->flags & FLAG_5THGEN) {
3894
			unsigned int current_index = (reg5 >> 8) & 0x7f;
3895
3896
			while (((wc->lastindex + 1) % wc->numbufs) != current_index) {
3897
				wc->lastindex = (wc->lastindex + 1) % wc->numbufs;
3898
				setup_chunks(wc, wc->lastindex);
3899
				t4_prep_gen2(wc);
3900
			}
3901
		} else {
3902
			t4_prep_gen2(wc);
3903
		}
3904
3905
#endif
3906
		t4_do_counters(wc);
3907
		spin_lock(&wc->reglock);
3908
		__handle_leds(wc);
3909
		spin_unlock(&wc->reglock);
3910
3911
	}
3912
3913
	if (unlikely(status & 0x1)) {
3914
		unsigned char cis;
3915
3916
		cis = t4_framer_in(wc, 0, FRMR_CIS);
3917
		if (cis & FRMR_CIS_GIS1)
3918
			t4_framer_interrupt(wc, 0);
3919
		if (cis & FRMR_CIS_GIS2)
3920
			t4_framer_interrupt(wc, 1);
3921
		if (cis & FRMR_CIS_GIS3)
3922
			t4_framer_interrupt(wc, 2);
3923
		if (cis & FRMR_CIS_GIS4)
3924
			t4_framer_interrupt(wc, 3);
3925
	}
3926
3927
	if (wc->vpm && vpmdtmfsupport) {
3928
		if (wc->vpm450m) {
3929
			/* How stupid is it that the octasic can't generate an
3930
			   interrupt when there's a tone, in spite of what their
3931
			   documentation says? */
3932
			if (!(wc->intcount & 0xf)) {
3933
				set_bit(T4_CHECK_VPM, &wc->checkflag);
3934
			}
3935
		} else if ((status & 0xff00) != 0xff00) {
3936
			wc->vpm400checkstatus = (status & 0xff00) >> 8;
3937
			set_bit(T4_CHECK_VPM, &wc->checkflag);
3938
		}
3939
	}
3940
3941
	spin_lock(&wc->reglock);
3942
3943
	if (unlikely(test_bit(T4_CHECK_TIMING, &wc->checkflag))) {
3944
		__t4_set_timing_source_auto(wc);
3945
	}
3946
3947
	spin_unlock(&wc->reglock);
3948
3949
out:
3950
	if (unlikely(test_bit(T4_CHANGE_LATENCY, &wc->checkflag) || test_bit(T4_CHECK_VPM, &wc->checkflag)))
3951
		tasklet_schedule(&wc->t4_tlet);
3952
3953
#ifndef ENABLE_WORKQUEUES
3954
	__t4_pci_out(wc, WC_INTR, 0);
3955
#endif	
3956
3957
	return IRQ_RETVAL(1);
3958
}
3959
3960
#ifdef SUPPORT_GEN1
3961
static int t4_reset_dma(struct t4 *wc)
3962
{
3963
	/* Turn off DMA and such */
3964
	wc->dmactrl = 0x0;
3965
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3966
	t4_pci_out(wc, WC_COUNT, 0);
3967
	t4_pci_out(wc, WC_RDADDR, 0);
3968
	t4_pci_out(wc, WC_WRADDR, 0);
3969
	t4_pci_out(wc, WC_INTR, 0);
3970
	/* Turn it all back on */
3971
	t4_pci_out(wc, WC_RDADDR, wc->readdma);
3972
	t4_pci_out(wc, WC_WRADDR, wc->writedma);
3973
	t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
3974
	t4_pci_out(wc, WC_INTR, 0);
3975
#ifdef VPM_SUPPORT
3976
	wc->dmactrl = 0xc0000000 | (1 << 29) | wc->vpm;
3977
#else	
3978
	wc->dmactrl = 0xc0000000 | (1 << 29);
3979
#endif
3980
	if (noburst)
3981
		wc->dmactrl |= (1 << 26);
3982
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3983
	return 0;
3984
}
3985
#endif
3986
3987
#ifdef VPM_SUPPORT
3988
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold)
3989
{
3990
	unsigned int x;
3991
3992
	for (x = 0; x < 8; x++) {
3993
		t4_vpm_out(wc, x, 0xC4, (threshold >> 8) & 0xFF);
3994
		t4_vpm_out(wc, x, 0xC5, (threshold & 0xFF));
3995
	}
3996
	dev_info(&wc->dev->dev, "VPM: DTMF threshold set to %d\n", threshold);
3997
}
3998
3999
static unsigned int t4_vpm_mask(int chip)
4000
{
4001
	unsigned int mask=0;
4002
	switch(vpmspans) {
4003
	case 4:
4004
		mask = 0x55555555 << (chip >> 2);
4005
		break;
4006
	case 2:
4007
		mask = 0x11111111 << (chip >> 1);
4008
		break;
4009
	case 1:
4010
		mask = 0x01010101 << chip;
4011
		break;
4012
	}
4013
	return mask;
4014
}
4015
4016
static int t4_vpm_spanno(int chip)
4017
{
4018
	int spanno = 0;
4019
	switch(vpmspans) {
4020
	case 4:
4021
		spanno = chip & 0x3;
4022
		break;
4023
	case 2:
4024
		spanno = chip & 0x1;
4025
		break;
4026
	/* Case 1 is implicit */
4027
	}
4028
	return spanno;
4029
}
4030
4031
static int t4_vpm_echotail(void)
4032
{
4033
	int echotail = 0x01ff;
4034
	switch(vpmspans) {
4035
	case 4:
4036
		echotail = 0x007f;
4037
		break;
4038
	case 2:
4039
		echotail = 0x00ff;
4040
		break;
4041
	/* Case 1 is implicit */
4042
	}
4043
	return echotail;
4044
}
4045
4046
static void t4_vpm450_init(struct t4 *wc)
4047
{
4048
	unsigned int check1, check2;
4049
	int laws[1] = { 0, };
4050
	int x;
4051
	unsigned int vpm_capacity;
4052
	struct firmware embedded_firmware;
4053
	const struct firmware *firmware = &embedded_firmware;
4054
#if !defined(HOTPLUG_FIRMWARE)
4055
	extern void _binary_dahdi_fw_oct6114_032_bin_size;
4056
	extern void _binary_dahdi_fw_oct6114_064_bin_size;
4057
	extern void _binary_dahdi_fw_oct6114_128_bin_size;
4058
	extern u8 _binary_dahdi_fw_oct6114_032_bin_start[];
4059
	extern u8 _binary_dahdi_fw_oct6114_064_bin_start[];
4060
	extern u8 _binary_dahdi_fw_oct6114_128_bin_start[];
4061
#else
4062
	static const char oct032_firmware[] = "dahdi-fw-oct6114-032.bin";
4063
	static const char oct064_firmware[] = "dahdi-fw-oct6114-064.bin";
4064
	static const char oct128_firmware[] = "dahdi-fw-oct6114-128.bin";
4065
#endif
4066
4067
	if (!vpmsupport) {
4068
		dev_info(&wc->dev->dev, "VPM450: Support Disabled\n");
4069
		return;
4070
	}
4071
4072
	/* Turn on GPIO/DATA mux if supported */
4073
	t4_gpio_setdir(wc, (1 << 24), (1 << 24));
4074
	__t4_raw_oct_out(wc, 0x000a, 0x5678);
4075
	__t4_raw_oct_out(wc, 0x0004, 0x1234);
4076
	check1 = __t4_raw_oct_in(wc, 0x0004);
4077
	check2 = __t4_raw_oct_in(wc, 0x000a);
4078
	if (debug)
4079
		dev_notice(&wc->dev->dev, "OCT Result: %04x/%04x\n",
4080
			__t4_raw_oct_in(wc, 0x0004),
4081
			__t4_raw_oct_in(wc, 0x000a));
4082
	if (__t4_raw_oct_in(wc, 0x0004) != 0x1234) {
4083
		dev_notice(&wc->dev->dev, "VPM450: Not Present\n");
4084
		return;
4085
	}
4086
4087
	/* Setup alaw vs ulaw rules */
4088
	for (x = 0;x < wc->numspans; x++) {
4089
		if (wc->tspans[x]->span.channels > 24)
4090
			laws[x] = 1;
4091
	}
4092
4093
	switch ((vpm_capacity = get_vpm450m_capacity(wc))) {
4094
	case 32:
4095
#if defined(HOTPLUG_FIRMWARE)
4096
		if ((request_firmware(&firmware, oct032_firmware, &wc->dev->dev) != 0) ||
4097
		    !firmware) {
4098
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4099
				"available from userspace\n", oct032_firmware);
4100
			return;
4101
		}
4102
#else
4103
		embedded_firmware.data = _binary_dahdi_fw_oct6114_032_bin_start;
4104
		/* Yes... this is weird. objcopy gives us a symbol containing
4105
		   the size of the firmware, not a pointer a variable containing
4106
		   the size. The only way we can get the value of the symbol
4107
		   is to take its address, so we define it as a pointer and
4108
		   then cast that value to the proper type.
4109
	      */
4110
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_032_bin_size;
4111
#endif
4112
		break;
4113
	case 64:
4114
#if defined(HOTPLUG_FIRMWARE)
4115
		if ((request_firmware(&firmware, oct064_firmware, &wc->dev->dev) != 0) ||
4116
		    !firmware) {
4117
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4118
				"available from userspace\n", oct064_firmware);
4119
			return;
4120
		}
4121
#else
4122
		embedded_firmware.data = _binary_dahdi_fw_oct6114_064_bin_start;
4123
		/* Yes... this is weird. objcopy gives us a symbol containing
4124
		   the size of the firmware, not a pointer a variable containing
4125
		   the size. The only way we can get the value of the symbol
4126
		   is to take its address, so we define it as a pointer and
4127
		   then cast that value to the proper type.
4128
	      */
4129
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_064_bin_size;
4130
#endif
4131
		break;
4132
	case 128:
4133
#if defined(HOTPLUG_FIRMWARE)
4134
		if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
4135
		    !firmware) {
4136
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4137
				"available from userspace\n", oct128_firmware);
4138
			return;
4139
		}
4140
#else
4141
		embedded_firmware.data = _binary_dahdi_fw_oct6114_128_bin_start;
4142
		/* Yes... this is weird. objcopy gives us a symbol containing
4143
		   the size of the firmware, not a pointer a variable containing
4144
		   the size. The only way we can get the value of the symbol
4145
		   is to take its address, so we define it as a pointer and
4146
		   then cast that value to the proper type.
4147
		*/
4148
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_128_bin_size;
4149
#endif
4150
		break;
4151
	default:
4152
		dev_notice(&wc->dev->dev, "Unsupported channel capacity found "
4153
				"on VPM module (%d).\n", vpm_capacity);
4154
		return;
4155
	}
4156
4157
	if (!(wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) {
4158
		dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
4159
		if (firmware != &embedded_firmware)
4160
			release_firmware(firmware);
4161
		return;
4162
	}
4163
4164
	if (firmware != &embedded_firmware)
4165
		release_firmware(firmware);
4166
4167
	if (vpmdtmfsupport == -1) {
4168
		dev_notice(&wc->dev->dev, "VPM450: hardware DTMF disabled.\n");
4169
		vpmdtmfsupport = 0;
4170
	}
4171
4172
	wc->vpm = T4_VPM_PRESENT;
4173
	dev_info(&wc->dev->dev, "VPM450: Present and operational servicing %d "
4174
			"span(s)\n", wc->numspans);
4175
		
4176
}
4177
4178
static void t4_vpm400_init(struct t4 *wc)
4179
{
4180
	unsigned char reg;
4181
	unsigned int mask;
4182
	unsigned int ver;
4183
	unsigned int i, x, y, gen2vpm=0;
4184
4185
	if (!vpmsupport) {
4186
		dev_info(&wc->dev->dev, "VPM400: Support Disabled\n");
4187
		return;
4188
	}
4189
4190
	switch(vpmspans) {
4191
	case 4:
4192
	case 2:
4193
	case 1:
4194
		break;
4195
	default:
4196
		dev_notice(&wc->dev->dev, "VPM400: %d is not a valid vpmspans "
4197
				"value, using 4\n", vpmspans);
4198
		vpmspans = 1;
4199
	}
4200
4201
	for (x=0;x<8;x++) {
4202
		int spanno = t4_vpm_spanno(x);
4203
		struct t4_span *ts = wc->tspans[spanno];
4204
		int echotail = t4_vpm_echotail();
4205
4206
		ver = t4_vpm_in(wc, x, 0x1a0); /* revision */
4207
		if ((ver != 0x26) && (ver != 0x33)) {
4208
			if (x)
4209
				dev_notice(&wc->dev->dev,
4210
					"VPM400: Inoperable\n");
4211
			return;
4212
		}
4213
		if (ver == 0x33) {
4214
			if (x && !gen2vpm) {
4215
				dev_notice(&wc->dev->dev,
4216
					"VPM400: Inconsistent\n");
4217
				return;
4218
			}
4219
			ts->spanflags |= FLAG_VPM2GEN;
4220
			gen2vpm++;
4221
		} else if (gen2vpm) {
4222
			dev_notice(&wc->dev->dev,
4223
				"VPM400: Inconsistent\n");
4224
			return;
4225
		}
4226
4227
4228
		/* Setup GPIO's */
4229
		for (y=0;y<4;y++) {
4230
			t4_vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
4231
			t4_vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
4232
			t4_vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
4233
		}
4234
4235
		/* Setup TDM path - sets fsync and tdm_clk as inputs */
4236
		reg = t4_vpm_in(wc, x, 0x1a3); /* misc_con */
4237
		t4_vpm_out(wc, x, 0x1a3, reg & ~2);
4238
4239
		/* Setup timeslots */
4240
		t4_vpm_out(wc, x, 0x02f, 0x20 | (spanno << 3)); 
4241
4242
		/* Setup Echo length (128 taps) */
4243
		t4_vpm_out(wc, x, 0x022, (echotail >> 8));
4244
		t4_vpm_out(wc, x, 0x023, (echotail & 0xff));
4245
		
4246
		/* Setup the tdm channel masks for all chips*/
4247
		mask = t4_vpm_mask(x);
4248
		for (i = 0; i < 4; i++)
4249
			t4_vpm_out(wc, x, 0x30 + i, (mask >> (i << 3)) & 0xff);
4250
4251
		/* Setup convergence rate */
4252
		reg = t4_vpm_in(wc,x,0x20);
4253
		reg &= 0xE0;
4254
		if (ts->spantype == TYPE_E1) {
4255
			if (x < vpmspans)
4256
				dev_info(&wc->dev->dev, "VPM400: Span %d "
4257
						"A-law mode\n", spanno);
4258
			reg |= 0x01;
4259
		} else {
4260
			if (x < vpmspans)
4261
				dev_info(&wc->dev->dev, "VPM400: Span %d "
4262
						"U-law mode\n", spanno);
4263
			reg &= ~0x01;
4264
		}
4265
		t4_vpm_out(wc,x,0x20,(reg | 0x20));
4266
		
4267
		/* Initialize echo cans */
4268
		for (i = 0 ; i < MAX_TDM_CHAN; i++) {
4269
			if (mask & (0x00000001 << i))
4270
				t4_vpm_out(wc,x,i,0x00);
4271
		}
4272
4273
		wait_a_little();
4274
4275
		/* Put in bypass mode */
4276
		for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
4277
			if (mask & (0x00000001 << i)) {
4278
				t4_vpm_out(wc,x,i,0x01);
4279
			}
4280
		}
4281
4282
		/* Enable bypass */
4283
		for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
4284
			if (mask & (0x00000001 << i))
4285
				t4_vpm_out(wc,x,0x78 + i,0x01);
4286
		}
4287
      
4288
		/* set DTMF detection threshold */
4289
		t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
4290
4291
		/* Enable DTMF detectors (always DTMF detect all spans) */
4292
		for (i = 0; i < MAX_DTMF_DET; i++) {
4293
			t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 0 : 1));
4294
		}
4295
		for (i = 0x34; i < 0x38; i++)
4296
			t4_vpm_out(wc, x, i, 0x00);
4297
		for (i = 0x3C; i < 0x40; i++)
4298
			t4_vpm_out(wc, x, i, 0x00);
4299
4300
		for (i = 0x48; i < 0x4B; i++)
4301
			t4_vpm_out(wc, x, i, 0x00);
4302
		for (i = 0x50; i < 0x53; i++)
4303
			t4_vpm_out(wc, x, i, 0x00);
4304
		for (i = 0xB8; i < 0xBE; i++)
4305
			t4_vpm_out(wc, x, i, 0xFF);
4306
		if (gen2vpm) {
4307
			for (i = 0xBE; i < 0xC0; i++)
4308
				t4_vpm_out(wc, x, i, 0xFF);
4309
		} else {
4310
			for (i = 0xBE; i < 0xC0; i++)
4311
				t4_vpm_out(wc, x, i, 0x00);
4312
		}
4313
		for (i = 0xC0; i < 0xC4; i++)
4314
			t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA);
4315
4316
	} 
4317
	if (vpmdtmfsupport == -1) {
4318
		dev_info(&wc->dev->dev, "VPM400: hardware DTMF enabled.\n");
4319
		vpmdtmfsupport = 0;
4320
	}
4321
	dev_info(&wc->dev->dev, "VPM400%s: Present and operational servicing "
4322
		"%d span(s)\n", (gen2vpm ? " (2nd Gen)" : ""), wc->numspans);
4323
	wc->vpm = T4_VPM_PRESENT;
4324
}
4325
4326
#endif
4327
4328
static void t4_tsi_reset(struct t4 *wc) 
4329
{
4330
	int x;
4331
	for (x=0;x<128;x++) {
4332
		wc->dmactrl &= ~0x00007fff;
4333
		wc->dmactrl |= (0x00004000 | (x << 7));
4334
		t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4335
	}
4336
	wc->dmactrl &= ~0x00007fff;
4337
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4338
}
4339
4340
/* Note that channels here start from 1 */
4341
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan)
4342
{
4343
	unsigned long flags;
4344
	int fromts, tots;
4345
4346
	fromts = (fromspan << 5) |(fromchan);
4347
	tots = (tospan << 5) | (tochan);
4348
4349
	if (!wc->t1e1) {
4350
		fromts += 4;
4351
		tots += 4;
4352
	}
4353
	spin_lock_irqsave(&wc->reglock, flags);
4354
	wc->dmactrl &= ~0x00007fff;
4355
	wc->dmactrl |= (0x00004000 | (tots << 7) | (fromts));
4356
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4357
	wc->dmactrl &= ~0x00007fff;
4358
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4359
	spin_unlock_irqrestore(&wc->reglock, flags);
4360
}
4361
4362
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan)
4363
{
4364
	unsigned long flags;
4365
	int tots;
4366
4367
	tots = (tospan << 5) | (tochan);
4368
4369
	if (!wc->t1e1) 
4370
		tots += 4;
4371
	spin_lock_irqsave(&wc->reglock, flags);
4372
	wc->dmactrl &= ~0x00007fff;
4373
	wc->dmactrl |= (0x00004000 | (tots << 7));
4374
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4375
	if (debug & DEBUG_TSI)
4376
		dev_notice(&wc->dev->dev, "Sending '%08x\n", wc->dmactrl);
4377
	wc->dmactrl &= ~0x00007fff;
4378
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4379
	spin_unlock_irqrestore(&wc->reglock, flags);
4380
}
4381
#ifdef CONFIG_EXTENDED_RESET
4382
static void t4_extended_reset(struct t4 *wc)
4383
{
4384
	unsigned int oldreg = t4_pci_in(wc, 0x4);
4385
4386
	udelay(1000);
4387
4388
	t4_pci_out(wc, 0x4, 0x42000000);
4389
	t4_pci_out(wc, 0xa, 0x42000000);
4390
	t4_pci_out(wc, 0xa, 0x00080000);
4391
	t4_pci_out(wc, 0xa, 0x00080000);
4392
	t4_pci_out(wc, 0xa, 0x00080000);
4393
	t4_pci_out(wc, 0xa, 0x00180000);
4394
	t4_pci_out(wc, 0xa, 0x00080000);
4395
	t4_pci_out(wc, 0xa, 0x00180000);
4396
	t4_pci_out(wc, 0xa, 0x00080000);
4397
	t4_pci_out(wc, 0xa, 0x00180000);
4398
	t4_pci_out(wc, 0xa, 0x00080000);
4399
	t4_pci_out(wc, 0xa, 0x00180000);
4400
	t4_pci_out(wc, 0xa, 0x00080000);
4401
	t4_pci_out(wc, 0xa, 0x00180000);
4402
	t4_pci_out(wc, 0xa, 0x00080000);
4403
	t4_pci_out(wc, 0xa, 0x00180000);
4404
	t4_pci_out(wc, 0x4, oldreg);
4405
4406
	udelay(1000);
4407
}
4408
#endif
4409
4410
static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
4411
{
4412
	unsigned int version;
4413
4414
	version = t4_pci_in(wc, WC_VERSION);
4415
	dev_info(&wc->dev->dev, "Firmware Version: %08x\n", version);
4416
	dev_info(&wc->dev->dev, "Burst Mode: %s\n",
4417
		(!(cardflags & FLAG_BURST) && noburst) ? "Off" : "On");
4418
#ifdef ENABLE_WORKQUEUES
4419
	dev_info(&wc->dev->dev, "Work Queues: Enabled\n");
4420
#endif
4421
4422
#ifdef CONFIG_EXTENDED_RESET
4423
	t4_extended_reset(wc);
4424
#endif
4425
4426
	/* Make sure DMA engine is not running and interrupts are acknowledged */
4427
	wc->dmactrl = 0x0;
4428
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4429
	/* Reset Framer and friends */
4430
	t4_pci_out(wc, WC_LEDS, 0x00000000);
4431
4432
	/* Set DMA addresses */
4433
	t4_pci_out(wc, WC_RDADDR, wc->readdma);
4434
	t4_pci_out(wc, WC_WRADDR, wc->writedma);
4435
4436
	/* Setup counters, interrupt flags (ignored in Gen2) */
4437
	if (cardflags & FLAG_2NDGEN) {
4438
		t4_tsi_reset(wc);
4439
	} else {
4440
		t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
4441
	}
4442
	
4443
	/* Reset pending interrupts */
4444
	t4_pci_out(wc, WC_INTR, 0x00000000);
4445
4446
	/* Read T1/E1 status */
4447
	if (t1e1override > -1)
4448
		wc->t1e1 = t1e1override;
4449
	else
4450
		wc->t1e1 = ((t4_pci_in(wc, WC_LEDS)) & 0x0f00) >> 8;
4451
	wc->order = ((t4_pci_in(wc, WC_LEDS)) & 0xf0000000) >> 28;
4452
	order_index[wc->order]++;
4453
	return 0;
4454
}
4455
4456
static int t4_hardware_init_2(struct t4 *wc)
4457
{
4458
	int x;
4459
	unsigned int regval;
4460
4461
	if (t4_pci_in(wc, WC_VERSION) >= 0xc01a0165) {
4462
		wc->tspans[0]->spanflags |= FLAG_OCTOPT;
4463
		dev_info(&wc->dev->dev, "Octasic Optimizations: Enabled\n");
4464
	}
4465
	/* Setup LEDS, take out of reset */
4466
	t4_pci_out(wc, WC_LEDS, 0x000000ff);
4467
	t4_activate(wc);
4468
4469
	/* 
4470
	 * In order to find out the QFALC framer version, we have to temporarily term off compat
4471
	 * mode and take a peak at VSTR.  We turn compat back on when we are done.
4472
	 */
4473
	if (t4_framer_in(wc, 0, 0x4a) != 0x05)
4474
		dev_info(&wc->dev->dev, "WARNING: FALC framer not intialized "
4475
				"in compatibility mode.\n");
4476
	regval = t4_framer_in(wc, 0 ,0xd6);
4477
	regval |= (1 << 5); /* set COMP_DIS*/
4478
	t4_framer_out(wc, 0, 0xd6, regval);
4479
	regval = t4_framer_in(wc, 0, 0x4a);
4480
	if (regval == 0x05)
4481
		dev_info(&wc->dev->dev, "FALC Framer Version: 2.1 or "
4482
				"earlier\n");
4483
	else if (regval == 0x20) {
4484
		dev_info(&wc->dev->dev, "FALC Framer Version: 3.1\n");
4485
		wc->falc31 = 1;
4486
	} else
4487
		dev_info(&wc->dev->dev, "FALC Framer Version: Unknown "
4488
				"(VSTR = 0x%02x)\n", regval);
4489
	regval = t4_framer_in(wc, 0 ,0xd6);
4490
	regval &= ~(1 << 5); /* clear COMP_DIS*/
4491
	t4_framer_out(wc, 0, 0xd6, regval);
4492
	
4493
	t4_framer_out(wc, 0, 0x4a, 0xaa);
4494
	dev_info(&wc->dev->dev, "Board ID: %02x\n", wc->order);
4495
4496
	for (x=0;x< 11;x++)
4497
		dev_info(&wc->dev->dev, "Reg %d: 0x%08x\n", x,
4498
				t4_pci_in(wc, x));
4499
	return 0;
4500
}
4501
4502
static int __devinit t4_launch(struct t4 *wc)
4503
{
4504
	int x;
4505
	unsigned long flags;
4506
	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &wc->tspans[0]->span.flags))
4507
		return 0;
4508
	dev_info(&wc->dev->dev, "opvxd115: Launching card: %d\n",
4509
			wc->order);
4510
4511
	/* Setup serial parameters and system interface */
4512
	for (x=0;x<PORTS_PER_FRAMER;x++)
4513
		t4_serial_setup(wc, x);
4514
4515
	for (x = 0; x < wc->numspans; ++x) {
4516
		list_add_tail(&wc->tspans[x]->span.device_node,
4517
			      &wc->ddev->spans);
4518
	}
4519
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
4520
		dev_err(&wc->dev->dev, "Unable to register span %s\n",
4521
				wc->tspans[0]->span.name);
4522
		return -1;
4523
	}
4524
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
4525
	spin_lock_irqsave(&wc->reglock, flags);
4526
	__t4_set_sclk_src(wc, WC_SELF, 0, 0);
4527
	spin_unlock_irqrestore(&wc->reglock, flags);
4528
	tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
4529
	return 0;
4530
}
4531
4532
static void free_wc(struct t4 *wc)
4533
{
4534
	unsigned int x, y;
4535
4536
	for (x = 0; x < sizeof(wc->tspans)/sizeof(wc->tspans[0]); x++) {
4537
		if (!wc->tspans[x]) {
4538
			continue;
4539
		}
4540
4541
		for (y = 0; y < sizeof(wc->tspans[x]->chans)/sizeof(wc->tspans[x]->chans[0]); y++) {
4542
			if (wc->tspans[x]->chans[y]) {
4543
				kfree(wc->tspans[x]->chans[y]);
4544
			}
4545
			if (wc->tspans[x]->ec[y])
4546
				kfree(wc->tspans[x]->ec[y]);
4547
		}
4548
		kfree(wc->tspans[x]);
4549
	}
4550
	kfree(wc);
4551
}
4552
4553
static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
4554
{
4555
	struct t4 *wc;
4556
	struct devtype *dt;
4557
	unsigned int x, f;
4558
	int init_latency;
4559
	
4560
	if (pci_enable_device(pdev)) {
4561
		return -EIO;
4562
	}
4563
4564
	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
4565
		return -ENOMEM;
4566
	}
4567
4568
	memset(wc, 0x0, sizeof(*wc));
4569
	spin_lock_init(&wc->reglock);
4570
	dt = (struct devtype *) (ent->driver_data);
4571
4572
	wc->flags = dt->flags;
4573
4574
	wc->numspans = 1;
4575
	
4576
	wc->variety = dt->desc;
4577
	
4578
	wc->memaddr = pci_resource_start(pdev, 0);
4579
	wc->memlen = pci_resource_len(pdev, 0);
4580
	wc->membase = ioremap(wc->memaddr, wc->memlen);
4581
	/* This rids of the Double missed interrupt message after loading */
4582
	wc->last0 = 1;
4583
#if 0
4584
	if (!request_mem_region(wc->memaddr, wc->memlen, wc->variety))
4585
		dev_info(&wc->dev->dev, "opvxd115: Unable to request memory "
4586
				"region :(, using anyway...\n");
4587
#endif
4588
	if (pci_request_regions(pdev, wc->variety))
4589
		dev_info(&pdev->dev, "opvxd115: Unable to request regions\n");
4590
	
4591
	dev_info(&pdev->dev, "Found opvxd115 at base address %08lx, remapped "
4592
			"to %p\n", wc->memaddr, wc->membase);
4593
	
4594
	wc->dev = pdev;
4595
	
4596
	/* Enable bus mastering */
4597
	pci_set_master(pdev);
4598
4599
	/* Keep track of which device we are */
4600
	pci_set_drvdata(pdev, wc);
4601
4602
	if (wc->flags & FLAG_5THGEN) {
4603
		if ((ms_per_irq > 1) && (latency <= ((ms_per_irq) << 1))) {
4604
			init_latency = ms_per_irq << 1;
4605
		} else {
4606
			if (latency > 2)
4607
				init_latency = latency;
4608
			else
4609
				init_latency = 2;
4610
		}
4611
		dev_info(&wc->dev->dev, "5th gen card with initial latency of "
4612
			"%d and %d ms per IRQ\n", init_latency, ms_per_irq);
4613
	} else {
4614
		if (wc->flags & FLAG_2NDGEN)
4615
			init_latency = 1;
4616
		else
4617
			init_latency = 2;
4618
	}
4619
4620
	if (max_latency < init_latency) {
4621
		printk(KERN_INFO "maxlatency must be set to something greater than %d ms, increasing it to %d\n", init_latency, init_latency);
4622
		max_latency = init_latency;
4623
	}
4624
	
4625
	if (t4_allocate_buffers(wc, init_latency, NULL, NULL)) {
4626
		return -ENOMEM;
4627
	}
4628
4629
	/* Initialize hardware */
4630
	t4_hardware_init_1(wc, wc->flags);
4631
	
4632
	for(x = 0; x < MAX_T4_CARDS; x++) {
4633
		if (!cards[x])
4634
			break;
4635
	}
4636
	
4637
	if (x >= MAX_T4_CARDS) {
4638
		dev_notice(&wc->dev->dev, "No cards[] slot available!!\n");
4639
		kfree(wc);
4640
		return -ENOMEM;
4641
	}
4642
	
4643
	wc->num = x;
4644
	cards[x] = wc;
4645
	
4646
#ifdef ENABLE_WORKQUEUES
4647
	if (wc->flags & FLAG_2NDGEN) {
4648
		char tmp[20];
4649
4650
		sprintf(tmp, "opvxd115");
4651
		wc->workq = create_workqueue(tmp);
4652
	}
4653
#endif			
4654
4655
	/* Allocate pieces we need here */
4656
	for (x = 0; x < PORTS_PER_FRAMER; x++) {
4657
		if (!(wc->tspans[x] = kmalloc(sizeof(*wc->tspans[x]), GFP_KERNEL))) {
4658
			free_wc(wc);
4659
			return -ENOMEM;
4660
		}
4661
4662
		memset(wc->tspans[x], 0, sizeof(*wc->tspans[x]));
4663
4664
		if (wc->t1e1 & (1 << x)) {
4665
			wc->tspans[x]->spantype = TYPE_E1;
4666
		} else {
4667
			if (j1mode)
4668
				wc->tspans[x]->spantype = TYPE_J1;
4669
			else
4670
				wc->tspans[x]->spantype = TYPE_T1;
4671
		}
4672
4673
		for (f = 0; f < (wc->tspans[x]->spantype == TYPE_E1 ? 31 : 24); f++) {
4674
			if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
4675
				free_wc(wc);
4676
				return -ENOMEM;
4677
			}
4678
			memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
4679
			if (!(wc->tspans[x]->ec[f] = kmalloc(sizeof(*wc->tspans[x]->ec[f]), GFP_KERNEL))) {
4680
				free_wc(wc);
4681
				return -ENOMEM;
4682
			}
4683
			memset(wc->tspans[x]->ec[f], 0, sizeof(*wc->tspans[x]->ec[f]));
4684
		}
4685
4686
#ifdef ENABLE_WORKQUEUES
4687
		INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
4688
#endif				
4689
		wc->tspans[x]->spanflags |= wc->flags;
4690
	}
4691
	
4692
	/* Continue hardware intiialization */
4693
	t4_hardware_init_2(wc);
4694
	
4695
#ifdef SUPPORT_GEN1
4696
	if (request_irq(pdev->irq, (wc->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, IRQF_SHARED, "opvxd115", wc)) 
4697
#else
4698
		if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
4699
			dev_notice(&wc->dev->dev, "This driver does not "
4700
					"support 1st gen modules\n");
4701
			free_wc(wc);
4702
			return -ENODEV;
4703
		}	
4704
			if (request_irq(pdev->irq, t4_interrupt_gen2, IRQF_SHARED, "opvxd115", wc)) 
4705
#endif
4706
	{
4707
		dev_notice(&wc->dev->dev, "opvxd115: Unable to request IRQ %d\n",
4708
				pdev->irq);
4709
		free_wc(wc);
4710
		return -EIO;
4711
	}
4712
	
4713
	init_spans(wc);
4714
	/* get the current number of probed cards and run a slice of a tail
4715
	 * insertion sort */
4716
	for (x = 0; x < MAX_T4_CARDS; x++) {
4717
		if (!cards[x+1])
4718
			break;
4719
	}
4720
	for ( ; x > 0; x--) {
4721
		if (cards[x]->order < cards[x-1]->order) {
4722
			struct t4 *tmp = cards[x];
4723
			cards[x] = cards[x-1];
4724
			cards[x-1] = tmp;
4725
		} else {
4726
			/* if we're not moving it, we won't move any more
4727
			 * since all cards are sorted on addition */
4728
			break;
4729
		}
4730
	}
4731
	
4732
	dev_info(&wc->dev->dev, "Found an OpenVox Card: %s\n", wc->variety);
4733
	wc->gpio = 0x00000000;
4734
	t4_pci_out(wc, WC_GPIO, wc->gpio);
4735
	t4_gpio_setdir(wc, (1 << 17), (1 << 17));
4736
	t4_gpio_setdir(wc, (0xff), (0xff));
4737
4738
	create_sysfs_files(wc);
4739
	
4740
#if 0
4741
	for (x=0;x<0x10000;x++) {
4742
		__t4_raw_oct_out(wc, 0x0004, x);
4743
		__t4_raw_oct_out(wc, 0x000a, x ^ 0xffff);
4744
		if (__t4_raw_oct_in(wc, 0x0004) != x) 
4745
			dev_notice(&wc->dev->dev, "Register 4 failed %04x\n",
4746
					x);
4747
		if (__t4_raw_oct_in(wc, 0x000a) != (x ^ 0xffff))
4748
			dev_notice(&wc->dev->dev, "Register 10 failed %04x\n",
4749
					x);
4750
	}
4751
#endif
4752
4753
	return 0;
4754
}
4755
4756
static int t4_hardware_stop(struct t4 *wc)
4757
{
4758
4759
	/* Turn off DMA, leave interrupts enabled */
4760
	set_bit(T4_STOP_DMA, &wc->checkflag);
4761
4762
	/* Wait for interrupts to stop */
4763
	msleep(25);
4764
4765
	/* Turn off counter, address, etc */
4766
	if (wc->tspans[0]->spanflags & FLAG_2NDGEN) {
4767
		t4_tsi_reset(wc);
4768
	} else {
4769
		t4_pci_out(wc, WC_COUNT, 0x000000);
4770
	}
4771
	t4_pci_out(wc, WC_RDADDR, 0x0000000);
4772
	t4_pci_out(wc, WC_WRADDR, 0x0000000);
4773
	wc->gpio = 0x00000000;
4774
	t4_pci_out(wc, WC_GPIO, wc->gpio);
4775
	t4_pci_out(wc, WC_LEDS, 0x00000000);
4776
4777
	dev_notice(&wc->dev->dev, "\nStopped opvxd115, Turned off DMA\n");
4778
	return 0;
4779
}
4780
4781
static void __devexit t4_remove_one(struct pci_dev *pdev)
4782
{
4783
	struct t4 *wc = pci_get_drvdata(pdev);
4784
	int basesize;
4785
4786
	if (!wc) {
4787
		return;
4788
	}
4789
4790
	remove_sysfs_files(wc);
4791
4792
	/* Stop hardware */
4793
	t4_hardware_stop(wc);
4794
	
4795
	/* Release vpm450m */
4796
	if (wc->vpm450m)
4797
		release_vpm450m(wc->vpm450m);
4798
	wc->vpm450m = NULL;
4799
	/* Unregister spans */
4800
4801
	basesize = DAHDI_MAX_CHUNKSIZE * 32 * 4;
4802
	if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN))
4803
		basesize = basesize * 2;
4804
4805
	dahdi_unregister_device(wc->ddev);
4806
	kfree(wc->ddev->location);
4807
	kfree(wc->ddev->devicetype);
4808
	dahdi_free_device(wc->ddev);
4809
#ifdef ENABLE_WORKQUEUES
4810
	if (wc->workq) {
4811
		flush_workqueue(wc->workq);
4812
		destroy_workqueue(wc->workq);
4813
	}
4814
#endif			
4815
	
4816
	free_irq(pdev->irq, wc);
4817
	
4818
	if (wc->membase)
4819
		iounmap(wc->membase);
4820
	
4821
	pci_release_regions(pdev);		
4822
	
4823
	/* Immediately free resources */
4824
	pci_free_consistent(pdev, T4_BASE_SIZE * wc->numbufs * 2, (void *)wc->writechunk, wc->writedma);
4825
	
4826
	order_index[wc->order]--;
4827
	
4828
	cards[wc->num] = NULL;
4829
	pci_set_drvdata(pdev, NULL);
4830
	free_wc(wc);
4831
}
4832
4833
4834
static struct pci_device_id t4_pci_tbl[] __devinitdata =
4835
{
4836
	{ 0x1b74, 0x0115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd115 }, /* OpenVox D115P/D115E */
4837
	{ 0x1b74, 0xd130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd130 }, /* OpenVox D130P/D130E */
4838
	{ 0, }
4839
};
4840
4841
static struct pci_driver t4_driver = {
4842
	.name = "opvxd115",
4843
	.probe = t4_init_one,
4844
	.remove = __devexit_p(t4_remove_one),
4845
	.id_table = t4_pci_tbl,
4846
};
4847
4848
static int __init t4_init(void)
4849
{
4850
	int res;
4851
	res = pci_register_driver(&t4_driver);
4852
	if (res)
4853
		return -ENODEV;
4854
	/* initialize cards since we have all of them */
4855
	/* warn for missing zero and duplicate numbers */
4856
	if (cards[0] && cards[0]->order != 0) {
4857
		printk(KERN_NOTICE "opvxd115: Ident of first card is not zero (%d)\n",
4858
			cards[0]->order);
4859
	}
4860
	for (res = 0; cards[res]; res++) {
4861
		/* warn the user of duplicate ident values it is probably
4862
		 * unintended */
4863
		if (debug && res < 15 && cards[res+1] &&
4864
		    cards[res]->order == cards[res+1]->order) {
4865
			printk(KERN_NOTICE "opvxd115: Duplicate ident value found (%d)\n",
4866
				cards[res]->order);
4867
		}
4868
		t4_launch(cards[res]);
4869
	}
4870
	return 0;
4871
}
4872
4873
static void __exit t4_cleanup(void)
4874
{
4875
	pci_unregister_driver(&t4_driver);
4876
}
4877
4878
4879
MODULE_AUTHOR("mark.liu <mark.liu@openvox.cn>");
4880
MODULE_DESCRIPTION("Unified OpenVox Single T1/E1/J1 Card Driver");
4881
MODULE_ALIAS("opvxd115");
4882
MODULE_LICENSE("GPL v2");
4883
4884
module_param(pedanticpci, int, 0600);
4885
module_param(debug, int, 0600);
4886
module_param(noburst, int, 0600);
4887
module_param(timingcable, int, 0600);
4888
module_param(t1e1override, int, 0600);
4889
module_param(alarmdebounce, int, 0600);
4890
module_param(losalarmdebounce, int, 0600);
4891
module_param(aisalarmdebounce, int, 0600);
4892
module_param(yelalarmdebounce, int, 0600);
4893
module_param(max_latency, int, 0600);
4894
module_param(j1mode, int, 0600);
4895
module_param(sigmode, int, 0600);
4896
module_param(latency, int, 0600);
4897
module_param(ms_per_irq, int, 0600);
4898
#ifdef VPM_SUPPORT
4899
module_param(vpmsupport, int, 0600);
4900
module_param(vpmdtmfsupport, int, 0600);
4901
module_param(vpmspans, int, 0600);
4902
module_param(dtmfthreshold, int, 0600);
4903
#endif
4904
4905
MODULE_DEVICE_TABLE(pci, t4_pci_tbl);
4906
4907
module_init(t4_init);
4908
module_exit(t4_cleanup);
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/opvxd115-diag.c (+427 lines)
Line 0 Link Here
1
/*
2
 * See http://www.asterisk.org for more information about
3
 * the Asterisk project. Please do not directly contact
4
 * any of the maintainers of this project for assistance;
5
 * the project provides a web site, mailing lists and IRC
6
 * channels for your use.
7
 *
8
 * This program is free software, distributed under the terms of
9
 * the GNU General Public License Version 2 as published by the
10
 * Free Software Foundation. See the LICENSE file included with
11
 * this program for more details.
12
 */
13
14
#include <fcntl.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <unistd.h>
18
#include <sys/ioctl.h>
19
#include <errno.h>
20
#include <string.h>
21
#include <dahdi/user.h>
22
#include "opvxd115.h"
23
24
struct t4_reg_def {
25
	int reg;
26
	char *name;
27
	int global;
28
};
29
static struct t4_reg_def xreginfo[] = {
30
	{ 0x00, "RDADDR" },
31
	{ 0x01, "WRADDR" },
32
	{ 0x02, "COUNT" },
33
	{ 0x03, "DMACTRL" },
34
	{ 0x04, "WCINTR" },
35
	{ 0x06, "VERSION" },
36
	{ 0x07, "LEDS" },
37
	{ 0x08, "GPIOCTL" },
38
	{ 0x09, "GPIO" }, 
39
	{ 0x0A, "LADDR" },
40
	{ 0x0b, "LDATA" },
41
};
42
43
static struct t4_reg_def reginfo[] = {
44
	{ 0x00, "XFIFO" },
45
	{ 0x01, "XFIFO" },
46
	{ 0x02, "CMDR" },
47
	{ 0x03, "MODE" },
48
	{ 0x04, "RAH1" },
49
	{ 0x05, "RAH2" },
50
	{ 0x06, "RAL1" },
51
	{ 0x07, "RAL2" },
52
	{ 0x08, "IPC", 1 },
53
	{ 0x09, "CCR1" },
54
	{ 0x0a, "CCR2" },
55
	{ 0x0c, "RTR1" },
56
	{ 0x0d, "RTR2" },
57
	{ 0x0e, "RTR3" },
58
	{ 0x0f, "RTR4" },
59
	{ 0x10, "TTR1" },
60
	{ 0x11, "TTR2" },
61
	{ 0x12, "TTR3" },
62
	{ 0x13, "TTR4" },
63
	{ 0x14, "IMR0" },
64
	{ 0x15, "IMR1" },
65
	{ 0x16, "IMR2" },
66
	{ 0x17, "IMR3" },
67
	{ 0x18, "IMR4" },
68
	{ 0x1b, "IERR" },
69
	{ 0x1c, "FMR0" },
70
	{ 0x1d, "FMR1" },
71
	{ 0x1e, "FMR2" },
72
	{ 0x1f, "LOOP" },
73
	{ 0x20, "XSW" },
74
	{ 0x21, "XSP" },
75
	{ 0x22, "XC0" },
76
	{ 0x23, "XC1" },
77
	{ 0x24, "RC0" },
78
	{ 0x25, "RC1" },
79
	{ 0x26, "XPM0" },
80
	{ 0x27, "XPM1" },
81
	{ 0x28, "XPM2" },
82
	{ 0x29, "TSWM" },
83
	{ 0x2b, "IDLE" },
84
	{ 0x2c, "XSA4" },
85
	{ 0x2d, "XSA5" },
86
	{ 0x2e, "XSA6" },
87
	{ 0x2f, "XSA7" },
88
	{ 0x30, "XSA8" },
89
	{ 0x31, "FMR3" },
90
	{ 0x32, "ICB1" },
91
	{ 0x33, "ICB2" },
92
	{ 0x34, "ICB3" },
93
	{ 0x35, "ICB4" },
94
	{ 0x36, "LIM0" },
95
	{ 0x37, "LIM1" },
96
	{ 0x38, "PCD" },
97
	{ 0x39, "PCR" },
98
	{ 0x3a, "LIM2" },
99
	{ 0x3b, "LCR1" },
100
	{ 0x3c, "LCR2" },
101
	{ 0x3d, "LCR3" },
102
	{ 0x3e, "SIC1" },
103
	{ 0x3f, "SIC2" },
104
	{ 0x40, "SIC3" },
105
	{ 0x44, "CMR1" },
106
	{ 0x45, "CMR2" },
107
	{ 0x46, "GCR" },
108
	{ 0x47, "ESM" },
109
	{ 0x60, "DEC" },
110
	{ 0x70, "XS1" },
111
	{ 0x71, "XS2" },
112
	{ 0x72, "XS3" },
113
	{ 0x73, "XS4" },
114
	{ 0x74, "XS5" },
115
	{ 0x75, "XS6" },
116
	{ 0x76, "XS7" },
117
	{ 0x77, "XS8" },
118
	{ 0x78, "XS9" },
119
	{ 0x79, "XS10" },
120
	{ 0x7a, "XS11" },
121
	{ 0x7b, "XS12" },
122
	{ 0x7c, "XS13" },
123
	{ 0x7d, "XS14" },
124
	{ 0x7e, "XS15" },
125
	{ 0x7f, "XS16" },
126
	{ 0x80, "PC1" },
127
	{ 0x81, "PC2" },
128
	{ 0x82, "PC3" },
129
	{ 0x83, "PC4" },
130
	{ 0x84, "PC5" },
131
	{ 0x85, "GPC1", 1 },
132
	{ 0x87, "CMDR2" },
133
	{ 0x8d, "CCR5" },
134
	{ 0x92, "GCM1", 1 },
135
	{ 0x93, "GCM2", 1 },
136
	{ 0x94, "GCM3", 1 },
137
	{ 0x95, "GCM4", 1 },
138
	{ 0x96, "GCM5", 1 },
139
	{ 0x97, "GCM6", 1 },
140
	{ 0x98, "GCM7", 1 },
141
	{ 0x99, "GCM8", 1 },
142
	{ 0xa0, "TSEO" },
143
	{ 0xa1, "TSBS1" },
144
	{ 0xa8, "TPC0" },	
145
};
146
147
static struct t4_reg_def t1_reginfo[] = {
148
	{ 0x00, "XFIFO" },
149
	{ 0x01, "XFIFO" },
150
	{ 0x02, "CMDR" },
151
	{ 0x03, "MODE" },
152
	{ 0x04, "RAH1" },
153
	{ 0x05, "RAH2" },
154
	{ 0x06, "RAL1" },
155
	{ 0x07, "RAL2" },
156
	{ 0x08, "IPC", 1 },
157
	{ 0x09, "CCR1" },
158
	{ 0x0a, "CCR2" },
159
	{ 0x0c, "RTR1" },
160
	{ 0x0d, "RTR2" },
161
	{ 0x0e, "RTR3" },
162
	{ 0x0f, "RTR4" },
163
	{ 0x10, "TTR1" },
164
	{ 0x11, "TTR2" },
165
	{ 0x12, "TTR3" },
166
	{ 0x13, "TTR4" },
167
	{ 0x14, "IMR0" },
168
	{ 0x15, "IMR1" },
169
	{ 0x16, "IMR2" },
170
	{ 0x17, "IMR3" },
171
	{ 0x18, "IMR4" },
172
	{ 0x1b, "IERR" },
173
	{ 0x1c, "FMR0" },
174
	{ 0x1d, "FMR1" },
175
	{ 0x1e, "FMR2" },
176
	{ 0x1f, "LOOP" },
177
	{ 0x20, "FMR4" },
178
	{ 0x21, "FMR5" },
179
	{ 0x22, "XC0" },
180
	{ 0x23, "XC1" },
181
	{ 0x24, "RC0" },
182
	{ 0x25, "RC1" },
183
	{ 0x26, "XPM0" },
184
	{ 0x27, "XPM1" },
185
	{ 0x28, "XPM2" },
186
	{ 0x2b, "IDLE" },
187
	{ 0x2c, "XDL1" },
188
	{ 0x2d, "XDL2" },
189
	{ 0x2e, "XDL3" },
190
	{ 0x2f, "CCB1" },
191
	{ 0x30, "CCB2" },
192
	{ 0x31, "CCB3" },
193
	{ 0x32, "ICB1" },
194
	{ 0x33, "ICB2" },
195
	{ 0x34, "ICB3" },
196
	{ 0x36, "LIM0" },
197
	{ 0x37, "LIM1" },
198
	{ 0x38, "PCD" },
199
	{ 0x39, "PCR" },
200
	{ 0x3a, "LIM2" },
201
	{ 0x3b, "LCR1" },
202
	{ 0x3c, "LCR2" },
203
	{ 0x3d, "LCR3" },
204
	{ 0x3e, "SIC1" },
205
	{ 0x3f, "SIC2" },
206
	{ 0x40, "SIC3" },
207
	{ 0x44, "CMR1" },
208
	{ 0x45, "CMR2" },
209
	{ 0x46, "GCR" },
210
	{ 0x47, "ESM" },
211
	{ 0x60, "DEC" },
212
	{ 0x70, "XS1" },
213
	{ 0x71, "XS2" },
214
	{ 0x72, "XS3" },
215
	{ 0x73, "XS4" },
216
	{ 0x74, "XS5" },
217
	{ 0x75, "XS6" },
218
	{ 0x76, "XS7" },
219
	{ 0x77, "XS8" },
220
	{ 0x78, "XS9" },
221
	{ 0x79, "XS10" },
222
	{ 0x7a, "XS11" },
223
	{ 0x7b, "XS12" },
224
	{ 0x80, "PC1" },
225
	{ 0x81, "PC2" },
226
	{ 0x82, "PC3" },
227
	{ 0x83, "PC4" },
228
	{ 0x84, "PC5" },
229
	{ 0x85, "GPC1", 1 },
230
	{ 0x87, "CMDR2" },
231
	{ 0x8d, "CCR5" },
232
	{ 0x92, "GCM1", 1 },
233
	{ 0x93, "GCM2", 1 },
234
	{ 0x94, "GCM3", 1 },
235
	{ 0x95, "GCM4", 1 },
236
	{ 0x96, "GCM5", 1 },
237
	{ 0x97, "GCM6", 1 },
238
	{ 0x98, "GCM7", 1 },
239
	{ 0x99, "GCM8", 1 },
240
	{ 0xa0, "TSEO" },
241
	{ 0xa1, "TSBS1" },
242
	{ 0xa8, "TPC0" },	
243
};
244
245
static struct t4_reg_def t1_sreginfo[] = {
246
	{ 0x00, "RFIFO" },
247
	{ 0x01, "RFIFO" },
248
	{ 0x49, "RBD" },
249
	{ 0x4a, "VSTR", 1 },
250
	{ 0x4b, "RES" },
251
	{ 0x4c, "FRS0" },
252
	{ 0x4d, "FRS1" },
253
	{ 0x4e, "FRS2" },
254
	{ 0x4f, "Old FRS1" },
255
	{ 0x50, "FECL" },
256
	{ 0x51, "FECH" },
257
	{ 0x52, "CVCL" },
258
	{ 0x53, "CVCH" },
259
	{ 0x54, "CECL" },
260
	{ 0x55, "CECH" },
261
	{ 0x56, "EBCL" },
262
	{ 0x57, "EBCH" },
263
	{ 0x58, "BECL" },
264
	{ 0x59, "BECH" },
265
	{ 0x5a, "COEC" },
266
	{ 0x5c, "RDL1" },
267
	{ 0x5d, "RDL2" },
268
	{ 0x5e, "RDL3" },
269
	{ 0x62, "RSP1" },
270
	{ 0x63, "RSP2" },
271
	{ 0x64, "SIS" },
272
	{ 0x65, "RSIS" },
273
	{ 0x66, "RBCL" },
274
	{ 0x67, "RBCH" },
275
	{ 0x68, "ISR0" },
276
	{ 0x69, "ISR1" },
277
	{ 0x6a, "ISR2" },
278
	{ 0x6b, "ISR3" },
279
	{ 0x6c, "ISR4" },
280
	{ 0x6e, "GIS" },
281
	{ 0x6f, "CIS", 1 },
282
	{ 0x70, "RS1" },
283
	{ 0x71, "RS2" },
284
	{ 0x72, "RS3" },
285
	{ 0x73, "RS4" },
286
	{ 0x74, "RS5" },
287
	{ 0x75, "RS6" },
288
	{ 0x76, "RS7" },
289
	{ 0x77, "RS8" },
290
	{ 0x78, "RS9" },
291
	{ 0x79, "RS10" },
292
	{ 0x7a, "RS11" },
293
	{ 0x7b, "RS12" },
294
};
295
296
static struct t4_reg_def sreginfo[] = {
297
	{ 0x00, "RFIFO" },
298
	{ 0x01, "RFIFO" },
299
	{ 0x49, "RBD" },
300
	{ 0x4a, "VSTR", 1 },
301
	{ 0x4b, "RES" },
302
	{ 0x4c, "FRS0" },
303
	{ 0x4d, "FRS1" },
304
	{ 0x4e, "RSW" },
305
	{ 0x4f, "RSP" },
306
	{ 0x50, "FECL" },
307
	{ 0x51, "FECH" },
308
	{ 0x52, "CVCL" },
309
	{ 0x53, "CVCH" },
310
	{ 0x54, "CEC1L" },
311
	{ 0x55, "CEC1H" },
312
	{ 0x56, "EBCL" },
313
	{ 0x57, "EBCH" },
314
	{ 0x58, "CEC2L" },
315
	{ 0x59, "CEC2H" },
316
	{ 0x5a, "CEC3L" },
317
	{ 0x5b, "CEC3H" },
318
	{ 0x5c, "RSA4" },
319
	{ 0x5d, "RSA5" },
320
	{ 0x5e, "RSA6" },
321
	{ 0x5f, "RSA7" },
322
	{ 0x60, "RSA8" },
323
	{ 0x61, "RSA6S" },
324
	{ 0x62, "RSP1" },
325
	{ 0x63, "RSP2" },
326
	{ 0x64, "SIS" },
327
	{ 0x65, "RSIS" },
328
	{ 0x66, "RBCL" },
329
	{ 0x67, "RBCH" },
330
	{ 0x68, "ISR0" },
331
	{ 0x69, "ISR1" },
332
	{ 0x6a, "ISR2" },
333
	{ 0x6b, "ISR3" },
334
	{ 0x6c, "ISR4" },
335
	{ 0x6e, "GIS" },
336
	{ 0x6f, "CIS", 1 },
337
	{ 0x70, "RS1" },
338
	{ 0x71, "RS2" },
339
	{ 0x72, "RS3" },
340
	{ 0x73, "RS4" },
341
	{ 0x74, "RS5" },
342
	{ 0x75, "RS6" },
343
	{ 0x76, "RS7" },
344
	{ 0x77, "RS8" },
345
	{ 0x78, "RS9" },
346
	{ 0x79, "RS10" },
347
	{ 0x7a, "RS11" },
348
	{ 0x7b, "RS12" },
349
	{ 0x7c, "RS13" },
350
	{ 0x7d, "RS14" },
351
	{ 0x7e, "RS15" },
352
	{ 0x7f, "RS16" },
353
};
354
355
static char *tobin(int x)
356
{
357
	static char s[9] = "";
358
	int y,z=0;
359
	for (y=7;y>=0;y--) {
360
		if (x & (1 << y))
361
			s[z++] = '1';
362
		else
363
			s[z++] = '0';
364
	}
365
	s[z] = '\0';
366
	return s;
367
}
368
369
static char *tobin32(unsigned int x)
370
{
371
	static char s[33] = "";
372
	int y,z=0;
373
	for (y=31;y>=0;y--) {
374
		if (x & (1 << y))
375
			s[z++] = '1';
376
		else
377
			s[z++] = '0';
378
	}
379
	s[z] = '\0';
380
	return s;
381
}
382
383
int main(int argc, char *argv[])
384
{
385
	int fd;
386
	int x;
387
	char fn[256];
388
	struct t4_regs regs;
389
	if ((argc < 2) || ((*(argv[1]) != '/') && !atoi(argv[1]))) {
390
		fprintf(stderr, "Usage: opvxd115-diag <channel>\n");
391
		exit(1);
392
	}
393
	if (*(argv[1]) == '/')
394
		dahdi_copy_string(fn, argv[1], sizeof(fn));
395
	else
396
		snprintf(fn, sizeof(fn), "/dev/dahdi/%d", atoi(argv[1]));
397
	fd = open(fn, O_RDWR);
398
	if (fd <0) {
399
		fprintf(stderr, "Unable to open '%s': %s\n", fn, strerror(errno));
400
		exit(1);
401
	}
402
	if (ioctl(fd, WCT4_GET_REGS, &regs)) {
403
		fprintf(stderr, "Unable to get registers: %s\n", strerror(errno));
404
		exit(1);
405
	}
406
	printf("PCI Registers:\n");
407
	for (x=0;x<sizeof(xreginfo) / sizeof(xreginfo[0]);x++) {
408
		fprintf(stdout, "%s (%02x): %08x (%s)\n", xreginfo[x].name, xreginfo[x].reg, regs.pci[xreginfo[x].reg], tobin32(regs.pci[xreginfo[x].reg]));
409
	}
410
	printf("\nE1 Control Registers:\n");
411
	for (x=0;x<sizeof(reginfo) / sizeof(reginfo[0]);x++) {
412
		fprintf(stdout, "%s (%02x): %02x (%s)\n", reginfo[x].name, reginfo[x].reg, regs.regs[reginfo[x].reg], tobin(regs.regs[reginfo[x].reg]));
413
	}
414
	printf("\nE1 Status Registers:\n");
415
	for (x=0;x<sizeof(sreginfo) / sizeof(sreginfo[0]);x++) {
416
		fprintf(stdout, "%s (%02x): %02x (%s)\n", sreginfo[x].name, sreginfo[x].reg, regs.regs[sreginfo[x].reg], tobin(regs.regs[sreginfo[x].reg]));
417
	}
418
	printf("\nT1 Control Registers:\n");
419
	for (x=0;x<sizeof(t1_reginfo) / sizeof(t1_reginfo[0]);x++) {
420
		fprintf(stdout, "%s (%02x): %02x (%s)\n", t1_reginfo[x].name, t1_reginfo[x].reg, regs.regs[t1_reginfo[x].reg], tobin(regs.regs[t1_reginfo[x].reg]));
421
	}
422
	printf("\nT1 Status Registers:\n");
423
	for (x=0;x<sizeof(t1_sreginfo) / sizeof(t1_sreginfo[0]);x++) {
424
		fprintf(stdout, "%s (%02x): %02x (%s)\n", t1_sreginfo[x].name, t1_sreginfo[x].reg, regs.regs[t1_sreginfo[x].reg], tobin(regs.regs[t1_sreginfo[x].reg]));
425
	}
426
	exit(0);
427
}
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/opvxd115.h (+124 lines)
Line 0 Link Here
1
/*
2
 * Wildcard T400P FXS Interface Driver for DAHDI Telephony interface
3
 *
4
 * Written by Mark Spencer <markster@linux-support.net>
5
 *
6
 * Copyright (C) 2001-2008, Digium, Inc.
7
 *
8
 * All rights reserved.
9
 *
10
 */
11
12
/*
13
 * See http://www.asterisk.org for more information about
14
 * the Asterisk project. Please do not directly contact
15
 * any of the maintainers of this project for assistance;
16
 * the project provides a web site, mailing lists and IRC
17
 * channels for your use.
18
 *
19
 * This program is free software, distributed under the terms of
20
 * the GNU General Public License Version 2 as published by the
21
 * Free Software Foundation. See the LICENSE file included with
22
 * this program for more details.
23
 */
24
25
#include <linux/ioctl.h>
26
27
#define FRMR_TTR_BASE 0x10
28
#define FRMR_RTR_BASE 0x0c
29
#define FRMR_TSEO 0xa0
30
#define FRMR_TSBS1 0xa1
31
#define FRMR_CCR1 0x09
32
#define FRMR_CCR1_ITF 0x08
33
#define FRMR_CCR1_EITS 0x10
34
#define FRMR_CCR2 0x0a
35
#define FRMR_CCR2_RCRC 0x04
36
#define FRMR_CCR2_RADD 0x10
37
#define FRMR_MODE 0x03
38
#define FRMR_MODE_NO_ADDR_CMP 0x80
39
#define FRMR_MODE_SS7 0x20
40
#define FRMR_MODE_HRAC 0x08
41
#define FRMR_IMR0 0x14
42
#define FRMR_IMR0_RME 0x80
43
#define FRMR_IMR0_RPF 0x01
44
#define FRMR_IMR1 0x15
45
#define FRMR_IMR1_ALLS 0x20
46
#define FRMR_IMR1_XDU 0x10
47
#define FRMR_IMR1_XPR 0x01
48
#define FRMR_XC0 0x22
49
#define FRMR_XC1 0x23
50
#define FRMR_RC0 0x24
51
#define FRMR_RC1 0x25
52
#define FRMR_SIC1 0x3e
53
#define FRMR_SIC2 0x3f
54
#define FRMR_SIC3 0x40
55
#define FRMR_CMR1 0x44
56
#define FRMR_CMR2 0x45
57
#define FRMR_GCR 0x46
58
#define FRMR_ISR0 0x68
59
#define FRMR_ISR0_RME 0x80
60
#define FRMR_ISR0_RPF 0x01
61
#define FRMR_ISR1 0x69
62
#define FRMR_ISR1_ALLS 0x20
63
#define FRMR_ISR1_XDU 0x10
64
#define FRMR_ISR1_XPR 0x01
65
#define FRMR_ISR2 0x6a
66
#define FRMR_ISR3 0x6b
67
#define FRMR_ISR4 0x6c
68
#define FRMR_GIS  0x6e
69
#define FRMR_GIS_ISR0 0x01
70
#define FRMR_GIS_ISR1 0x02
71
#define FRMR_GIS_ISR2 0x04
72
#define FRMR_GIS_ISR3 0x08
73
#define FRMR_GIS_ISR4 0x10
74
#define FRMR_CIS 0x6f
75
#define FRMR_CIS_GIS1 0x01
76
#define FRMR_CIS_GIS2 0x02
77
#define FRMR_CIS_GIS3 0x04
78
#define FRMR_CIS_GIS4 0x08
79
#define FRMR_CMDR 0x02
80
#define FRMR_CMDR_SRES 0x01
81
#define FRMR_CMDR_XRES 0x10
82
#define FRMR_CMDR_RMC 0x80
83
#define FRMR_CMDR_XTF 0x04
84
#define FRMR_CMDR_XHF 0x08
85
#define FRMR_CMDR_XME 0x02
86
#define FRMR_RSIS 0x65
87
#define FRMR_RSIS_VFR 0x80
88
#define FRMR_RSIS_RDO 0x40
89
#define FRMR_RSIS_CRC16 0x20
90
#define FRMR_RSIS_RAB 0x10
91
#define FRMR_RBCL 0x66
92
#define FRMR_RBCL_MAX_SIZE 0x1f
93
#define FRMR_RBCH 0x67
94
#define FRMR_RXFIFO 0x00
95
#define FRMR_SIS 0x64
96
#define FRMR_SIS_XFW 0x40
97
#define FRMR_TXFIFO 0x00
98
99
#define FRS0 0x4c
100
#define FRS0_LOS (1<<7)
101
#define FRS0_LFA (1<<5)
102
#define FRS0_LMFA (1<<1)
103
104
#define FRS1 0x4d
105
#define FRS1_XLS (1<<1)
106
#define FRS1_XLO (1<<0)
107
108
#define NUM_REGS 0xa9
109
#define NUM_PCI 12
110
111
struct t4_regs {
112
	unsigned int pci[NUM_PCI];
113
	unsigned char regs[NUM_REGS];
114
};
115
116
#define T4_CHECK_VPM		0
117
#define T4_LOADING_FW		1
118
#define T4_STOP_DMA		2
119
#define T4_CHECK_TIMING		3
120
#define T4_CHANGE_LATENCY	4
121
#define T4_IGNORE_LATENCY	5
122
123
#define WCT4_GET_REGS	_IOW (DAHDI_CODE, 60, struct t4_regs)
124
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/vpm450m.c (+598 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2005-2006 Digium, Inc.
3
 *
4
 * Mark Spencer <markster@digium.com>
5
 * Modified by mark.liu@openvox.cn 06/16/2009
6
 
7
 * All Rights Reserved
8
 */
9
10
/*
11
 * See http://www.asterisk.org for more information about
12
 * the Asterisk project. Please do not directly contact
13
 * any of the maintainers of this project for assistance;
14
 * the project provides a web site, mailing lists and IRC
15
 * channels for your use.
16
 *
17
 * This program is free software, distributed under the terms of
18
 * the GNU General Public License Version 2 as published by the
19
 * Free Software Foundation. See the LICENSE file included with
20
 * this program for more details.
21
 */
22
23
#include <linux/slab.h>
24
#include <linux/vmalloc.h>
25
#include <linux/string.h>
26
#include <linux/time.h>
27
#include <linux/version.h>
28
29
#include "vpm450m.h"
30
#include "oct6100api/oct6100_api.h"
31
32
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
33
#include <linux/config.h>
34
#endif
35
36
/* API for Octasic access */
37
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
38
{
39
	/* Why couldn't they just take a timeval like everyone else? */
40
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
41
        struct timeval tv;
42
#else
43
	struct timespec64 tv;
44
#endif	
45
        unsigned long long total_usecs;
46
	unsigned int mask = ~0;
47
48
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
49
	do_gettimeofday(&tv);
50
	total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) + 
51
				  (((unsigned long long)(tv.tv_usec)));
52
#else
53
	ktime_get_real_ts64(&tv);
54
		total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
55
				  (((unsigned long long)(tv.tv_nsec)) / 1000);
56
#endif
57
58
	f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
59
	f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
60
	return cOCT6100_ERR_OK;
61
}
62
63
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
64
{
65
	memset(f_pAddress, f_ulPattern, f_ulLength);
66
	return cOCT6100_ERR_OK;
67
}
68
69
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
70
{
71
	memcpy(f_pDestination, f_pSource, f_ulLength);
72
	return cOCT6100_ERR_OK;
73
}
74
75
UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
76
{
77
	return cOCT6100_ERR_OK;
78
}
79
80
UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
81
{
82
#ifdef OCTASIC_DEBUG
83
	printk(KERN_DEBUG "I should never be called! (destroy serialize object)\n");
84
#endif
85
	return cOCT6100_ERR_OK;
86
}
87
88
UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
89
{
90
	/* Not needed */
91
	return cOCT6100_ERR_OK;
92
}
93
94
UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
95
{
96
	/* Not needed */
97
	return cOCT6100_ERR_OK;
98
}
99
100
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
101
{
102
	oct_set_reg(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
103
	return cOCT6100_ERR_OK;
104
}
105
106
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
107
{
108
	unsigned int x;
109
	for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
110
		oct_set_reg(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
111
	}
112
	return cOCT6100_ERR_OK;
113
}
114
115
UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
116
{
117
	unsigned int x;
118
	for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
119
		oct_set_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
120
	}
121
	return cOCT6100_ERR_OK;
122
}
123
124
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
125
{
126
	*(f_pReadParams->pusReadData) = oct_get_reg(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
127
	return cOCT6100_ERR_OK;
128
}
129
130
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
131
{
132
	unsigned int x;
133
	for (x=0;x<f_pBurstParams->ulReadLength;x++) {
134
		f_pBurstParams->pusReadData[x] = oct_get_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
135
	}
136
	return cOCT6100_ERR_OK;
137
}
138
139
#define SOUT_G168_1100GB_ON 0x40000004
140
#define SOUT_DTMF_1 0x40000011
141
#define SOUT_DTMF_2 0x40000012
142
#define SOUT_DTMF_3 0x40000013
143
#define SOUT_DTMF_A 0x4000001A
144
#define SOUT_DTMF_4 0x40000014
145
#define SOUT_DTMF_5 0x40000015
146
#define SOUT_DTMF_6 0x40000016
147
#define SOUT_DTMF_B 0x4000001B
148
#define SOUT_DTMF_7 0x40000017
149
#define SOUT_DTMF_8 0x40000018
150
#define SOUT_DTMF_9 0x40000019
151
#define SOUT_DTMF_C 0x4000001C
152
#define SOUT_DTMF_STAR 0x4000001E
153
#define SOUT_DTMF_0 0x40000010
154
#define SOUT_DTMF_POUND 0x4000001F
155
#define SOUT_DTMF_D 0x4000001D
156
157
#define ROUT_G168_2100GB_ON 0x10000000
158
#define ROUT_G168_2100GB_WSPR 0x10000002
159
#define ROUT_SOUT_G168_2100HB_END 0x50000003
160
#define ROUT_G168_1100GB_ON 0x10000004
161
162
#define ROUT_DTMF_1 0x10000011
163
#define ROUT_DTMF_2 0x10000012
164
#define ROUT_DTMF_3 0x10000013
165
#define ROUT_DTMF_A 0x1000001A
166
#define ROUT_DTMF_4 0x10000014
167
#define ROUT_DTMF_5 0x10000015
168
#define ROUT_DTMF_6 0x10000016
169
#define ROUT_DTMF_B 0x1000001B
170
#define ROUT_DTMF_7 0x10000017
171
#define ROUT_DTMF_8 0x10000018
172
#define ROUT_DTMF_9 0x10000019
173
#define ROUT_DTMF_C 0x1000001C
174
#define ROUT_DTMF_STAR 0x1000001E
175
#define ROUT_DTMF_0 0x10000010
176
#define ROUT_DTMF_POUND 0x1000001F
177
#define ROUT_DTMF_D 0x1000001D
178
179
#if 0 
180
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
181
#else
182
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
183
#endif
184
185
struct vpm450m {
186
	tPOCT6100_INSTANCE_API pApiInstance;
187
	UINT32 aulEchoChanHndl[ 128 ];
188
	int chanflags[128];
189
	int ecmode[128];
190
	int numchans;
191
};
192
193
#define FLAG_DTMF	 (1 << 0)
194
#define FLAG_MUTE	 (1 << 1)
195
#define FLAG_ECHO	 (1 << 2)
196
197
static unsigned int tones[] = {
198
	SOUT_DTMF_1,
199
	SOUT_DTMF_2,
200
	SOUT_DTMF_3,
201
	SOUT_DTMF_A,
202
	SOUT_DTMF_4,
203
	SOUT_DTMF_5,
204
	SOUT_DTMF_6,
205
	SOUT_DTMF_B,
206
	SOUT_DTMF_7,
207
	SOUT_DTMF_8,
208
	SOUT_DTMF_9,
209
	SOUT_DTMF_C,
210
	SOUT_DTMF_STAR,
211
	SOUT_DTMF_0,
212
	SOUT_DTMF_POUND,
213
	SOUT_DTMF_D,
214
	SOUT_G168_1100GB_ON,
215
216
	ROUT_DTMF_1,
217
	ROUT_DTMF_2,
218
	ROUT_DTMF_3,
219
	ROUT_DTMF_A,
220
	ROUT_DTMF_4,
221
	ROUT_DTMF_5,
222
	ROUT_DTMF_6,
223
	ROUT_DTMF_B,
224
	ROUT_DTMF_7,
225
	ROUT_DTMF_8,
226
	ROUT_DTMF_9,
227
	ROUT_DTMF_C,
228
	ROUT_DTMF_STAR,
229
	ROUT_DTMF_0,
230
	ROUT_DTMF_POUND,
231
	ROUT_DTMF_D,
232
	ROUT_G168_1100GB_ON,
233
};
234
235
static void vpm450m_setecmode(struct vpm450m *vpm450m, int channel, int mode)
236
{
237
	tOCT6100_CHANNEL_MODIFY *modify;
238
	UINT32 ulResult;
239
240
	if (vpm450m->ecmode[channel] == mode)
241
		return;
242
	modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
243
	if (!modify) {
244
		printk(KERN_NOTICE "opvxd115: Unable to allocate memory for setec!\n");
245
		return;
246
	}
247
	Oct6100ChannelModifyDef(modify);
248
	modify->ulEchoOperationMode = mode;
249
	modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
250
	ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
251
	if (ulResult != GENERIC_OK) {
252
		printk(KERN_NOTICE "Failed to apply echo can changes on channel %d!\n", channel);
253
	} else {
254
#ifdef OCTASIC_DEBUG
255
		printk(KERN_DEBUG "Echo can on channel %d set to %d\n", channel, mode);
256
#endif
257
		vpm450m->ecmode[channel] = mode;
258
	}
259
	kfree(modify);
260
}
261
262
void vpm450m_setdtmf(struct vpm450m *vpm450m, int channel, int detect, int mute)
263
{
264
	tOCT6100_CHANNEL_MODIFY *modify;
265
	UINT32 ulResult;
266
267
	modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_KERNEL);
268
	if (!modify) {
269
		printk(KERN_NOTICE "opvxd115: Unable to allocate memory for setdtmf!\n");
270
		return;
271
	}
272
	Oct6100ChannelModifyDef(modify);
273
	modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
274
	if (mute) {
275
		vpm450m->chanflags[channel] |= FLAG_MUTE;
276
		modify->VqeConfig.fDtmfToneRemoval = TRUE;
277
	} else {
278
		vpm450m->chanflags[channel] &= ~FLAG_MUTE;
279
		modify->VqeConfig.fDtmfToneRemoval = FALSE;
280
	}
281
	if (detect)
282
		vpm450m->chanflags[channel] |= FLAG_DTMF;
283
	else
284
		vpm450m->chanflags[channel] &= ~FLAG_DTMF;
285
	if (vpm450m->chanflags[channel] & (FLAG_DTMF|FLAG_MUTE)) {
286
		if (!(vpm450m->chanflags[channel] & FLAG_ECHO)) {
287
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
288
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
289
		}
290
	} else {
291
		if (!(vpm450m->chanflags[channel] & FLAG_ECHO))
292
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
293
	}
294
295
	ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
296
	if (ulResult != GENERIC_OK) {
297
		printk(KERN_NOTICE "Failed to apply dtmf mute changes on channel %d!\n", channel);
298
	}
299
/*	printk(KERN_DEBUG "VPM450m: Setting DTMF on channel %d: %s / %s\n", channel, (detect ? "DETECT" : "NO DETECT"), (mute ? "MUTE" : "NO MUTE")); */
300
	kfree(modify);
301
}
302
303
void vpm450m_setec(struct vpm450m *vpm450m, int channel, int eclen)
304
{
305
	if (eclen) {
306
		vpm450m->chanflags[channel] |= FLAG_ECHO;
307
		vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
308
		vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
309
	} else {
310
		vpm450m->chanflags[channel] &= ~FLAG_ECHO;
311
		if (vpm450m->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
312
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
313
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
314
		} else
315
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
316
	}
317
/*	printk(KERN_DEBUG "VPM450m: Setting EC on channel %d to %d\n", channel, eclen); */
318
}
319
320
int vpm450m_checkirq(struct vpm450m *vpm450m)
321
{
322
	tOCT6100_INTERRUPT_FLAGS InterruptFlags;
323
	
324
	Oct6100InterruptServiceRoutineDef(&InterruptFlags);
325
	Oct6100InterruptServiceRoutine(vpm450m->pApiInstance, &InterruptFlags);
326
327
	return InterruptFlags.fToneEventsPending ? 1 : 0;
328
}
329
330
int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start)
331
{
332
	tOCT6100_TONE_EVENT tonefound;
333
	tOCT6100_EVENT_GET_TONE tonesearch;
334
	UINT32 ulResult;
335
	
336
	Oct6100EventGetToneDef(&tonesearch);
337
	tonesearch.pToneEvent = &tonefound;
338
	tonesearch.ulMaxToneEvent = 1;
339
	ulResult = Oct6100EventGetTone(vpm450m->pApiInstance, &tonesearch);
340
	if (tonesearch.ulNumValidToneEvent) {
341
		if (channel)
342
			*channel = tonefound.ulUserChanId;
343
		if (tone) {
344
			switch(tonefound.ulToneDetected) {
345
			case SOUT_DTMF_1:
346
				*tone = '1';
347
				break;
348
			case SOUT_DTMF_2:
349
				*tone = '2';
350
				break;
351
			case SOUT_DTMF_3:
352
				*tone = '3';
353
				break;
354
			case SOUT_DTMF_A:
355
				*tone = 'A';
356
				break;
357
			case SOUT_DTMF_4:
358
				*tone = '4';
359
				break;
360
			case SOUT_DTMF_5:
361
				*tone = '5';
362
				break;
363
			case SOUT_DTMF_6:
364
				*tone = '6';
365
				break;
366
			case SOUT_DTMF_B:
367
				*tone = 'B';
368
				break;
369
			case SOUT_DTMF_7:
370
				*tone = '7';
371
				break;
372
			case SOUT_DTMF_8:
373
				*tone = '8';
374
				break;
375
			case SOUT_DTMF_9:
376
				*tone = '9';
377
				break;
378
			case SOUT_DTMF_C:
379
				*tone = 'C';
380
				break;
381
			case SOUT_DTMF_STAR:
382
				*tone = '*';
383
				break;
384
			case SOUT_DTMF_0:
385
				*tone = '0';
386
				break;
387
			case SOUT_DTMF_POUND:
388
				*tone = '#';
389
				break;
390
			case SOUT_DTMF_D:
391
				*tone = 'D';
392
				break;
393
			case SOUT_G168_1100GB_ON:
394
				*tone = 'f';
395
				break;
396
			default:
397
#ifdef OCTASIC_DEBUG
398
				printk(KERN_DEBUG "Unknown tone value %08x\n", tonefound.ulToneDetected);
399
#endif
400
				*tone = 'u';
401
				break;
402
			}
403
		}
404
		if (start)
405
			*start = (tonefound.ulEventType == cOCT6100_TONE_PRESENT);
406
		return 1;
407
	}
408
	return 0;
409
}
410
411
unsigned int get_vpm450m_capacity(void *wc)
412
{
413
	UINT32 ulResult;
414
415
	tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
416
417
	Oct6100ApiGetCapacityPinsDef(&CapacityPins);
418
	CapacityPins.pProcessContext = wc;
419
	CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
420
	CapacityPins.fEnableMemClkOut = TRUE;
421
	CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
422
423
	ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
424
	if (ulResult != cOCT6100_ERR_OK) {
425
		printk(KERN_DEBUG "Failed to get chip capacity, code %08x!\n", ulResult);
426
		return 0;
427
	}
428
429
	return CapacityPins.ulCapacityValue;
430
}
431
432
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
433
{
434
	tOCT6100_CHIP_OPEN *ChipOpen;
435
	tOCT6100_GET_INSTANCE_SIZE InstanceSize;
436
	tOCT6100_CHANNEL_OPEN *ChannelOpen;
437
	UINT32 ulResult;
438
	struct vpm450m *vpm450m;
439
	int x,y,law;
440
#ifdef CONFIG_4KSTACKS
441
	unsigned long flags;
442
#endif
443
	
444
	if (!(vpm450m = kmalloc(sizeof(struct vpm450m), GFP_KERNEL)))
445
		return NULL;
446
447
	memset(vpm450m, 0, sizeof(struct vpm450m));
448
449
	if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
450
		kfree(vpm450m);
451
		return NULL;
452
	}
453
454
	memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
455
456
	if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
457
		kfree(vpm450m);
458
		kfree(ChipOpen);
459
		return NULL;
460
	}
461
462
	memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
463
464
	for (x=0;x<128;x++)
465
		vpm450m->ecmode[x] = -1;
466
467
	vpm450m->numchans = numspans * 32;
468
	printk(KERN_INFO "VPM450: echo cancellation for %d channels\n", vpm450m->numchans);
469
		
470
	Oct6100ChipOpenDef(ChipOpen);
471
472
	/* Setup Chip Open Parameters */
473
	ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
474
	Oct6100GetInstanceSizeDef(&InstanceSize);
475
476
	ChipOpen->pProcessContext = wc;
477
478
	ChipOpen->pbyImageFile = firmware->data;
479
	ChipOpen->ulImageSize = firmware->size;
480
	ChipOpen->fEnableMemClkOut = TRUE;
481
	ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
482
	ChipOpen->ulMaxChannels = vpm450m->numchans;
483
	ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
484
	ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
485
	ChipOpen->ulNumMemoryChips = 1;
486
	ChipOpen->ulMaxTdmStreams = 4;
487
	ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
488
	ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
489
#if 0
490
	ChipOpen->fEnableAcousticEcho = TRUE;
491
#endif		
492
493
	ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
494
	if (ulResult != cOCT6100_ERR_OK) {
495
		printk(KERN_NOTICE "Failed to get instance size, code %08x!\n", ulResult);
496
		kfree(vpm450m);
497
		kfree(ChipOpen);
498
		kfree(ChannelOpen);
499
		return NULL;
500
	}
501
	
502
	
503
	vpm450m->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
504
	if (!vpm450m->pApiInstance) {
505
		printk(KERN_NOTICE "Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
506
		kfree(vpm450m);
507
		kfree(ChipOpen);
508
		kfree(ChannelOpen);
509
		return NULL;
510
	}
511
512
	/* I don't know what to curse more in this comment, the problems caused by
513
	 * the 4K kernel stack limit change or the octasic API for being so darn
514
	 * stack unfriendly.  Stupid, stupid, stupid.  So we disable IRQs so we
515
	 * don't run the risk of overflowing the stack while we initialize the
516
	 * octasic. */
517
#ifdef CONFIG_4KSTACKS
518
	local_irq_save(flags);
519
#endif
520
	ulResult = Oct6100ChipOpen(vpm450m->pApiInstance, ChipOpen);
521
	if (ulResult != cOCT6100_ERR_OK) {
522
		printk(KERN_NOTICE "Failed to open chip, code %08x!\n", ulResult);
523
#ifdef CONFIG_4KSTACKS
524
		local_irq_restore(flags);
525
#endif
526
		kfree(vpm450m);
527
		kfree(ChipOpen);
528
		kfree(ChannelOpen);
529
		return NULL;
530
	}
531
	for (x=0;x<128;x++) {
532
		if ((x & 0x03) < numspans) {
533
			/* span timeslots are interleaved 12341234... 
534
		 	*  therefore, the lower 2 bits tell us which span this 
535
			*  timeslot/channel
536
		 	*/
537
			if (isalaw[x & 0x03]) 
538
				law = cOCT6100_PCM_A_LAW;
539
			else
540
				law = cOCT6100_PCM_U_LAW;
541
			Oct6100ChannelOpenDef(ChannelOpen);
542
			ChannelOpen->pulChannelHndl = &vpm450m->aulEchoChanHndl[x];
543
			ChannelOpen->ulUserChanId = x;
544
			ChannelOpen->TdmConfig.ulRinPcmLaw = law;
545
			ChannelOpen->TdmConfig.ulRinStream = 0;
546
			ChannelOpen->TdmConfig.ulRinTimeslot = x;
547
			ChannelOpen->TdmConfig.ulSinPcmLaw = law;
548
			ChannelOpen->TdmConfig.ulSinStream = 1;
549
			ChannelOpen->TdmConfig.ulSinTimeslot = x;
550
			ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
551
			ChannelOpen->TdmConfig.ulSoutStream = 2;
552
			ChannelOpen->TdmConfig.ulSoutTimeslot = x;
553
			ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
554
			ChannelOpen->TdmConfig.ulRoutStream = 3;
555
			ChannelOpen->TdmConfig.ulRoutTimeslot = x;
556
			ChannelOpen->VqeConfig.fEnableNlp = TRUE;
557
			ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
558
			ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
559
			
560
			ChannelOpen->fEnableToneDisabler = TRUE;
561
			ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
562
			
563
			ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, ChannelOpen);
564
			if (ulResult != GENERIC_OK) {
565
				printk(KERN_NOTICE "Failed to open channel %d!\n", x);
566
			}
567
			for (y=0;y<sizeof(tones) / sizeof(tones[0]); y++) {
568
				tOCT6100_TONE_DETECTION_ENABLE enable;
569
				Oct6100ToneDetectionEnableDef(&enable);
570
				enable.ulChannelHndl = vpm450m->aulEchoChanHndl[x];
571
				enable.ulToneNumber = tones[y];
572
				if (Oct6100ToneDetectionEnable(vpm450m->pApiInstance, &enable) != GENERIC_OK) 
573
					printk(KERN_NOTICE "Failed to enable tone detection on channel %d for tone %d!\n", x, y);
574
			}
575
		}
576
	}
577
578
#ifdef CONFIG_4KSTACKS
579
	local_irq_restore(flags);
580
#endif
581
	kfree(ChipOpen);
582
	kfree(ChannelOpen);
583
	return vpm450m;
584
}
585
586
void release_vpm450m(struct vpm450m *vpm450m)
587
{
588
	UINT32 ulResult;
589
	tOCT6100_CHIP_CLOSE ChipClose;
590
591
	Oct6100ChipCloseDef(&ChipClose);
592
	ulResult = Oct6100ChipClose(vpm450m->pApiInstance, &ChipClose);
593
	if (ulResult != cOCT6100_ERR_OK) {
594
		printk(KERN_NOTICE "Failed to close chip, code %08x!\n", ulResult);
595
	}
596
	vfree(vpm450m->pApiInstance);
597
	kfree(vpm450m);
598
}
(-)dahdi-linux-3.1.0.original/drivers/dahdi/opvxd115/vpm450m.h (+43 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2005-2006 Digium, Inc.
3
 *
4
 * Mark Spencer <markster@digium.com>
5
 *
6
 * All Rights Reserved
7
 *
8
 */
9
10
/*
11
 * See http://www.asterisk.org for more information about
12
 * the Asterisk project. Please do not directly contact
13
 * any of the maintainers of this project for assistance;
14
 * the project provides a web site, mailing lists and IRC
15
 * channels for your use.
16
 *
17
 * This program is free software, distributed under the terms of
18
 * the GNU General Public License Version 2 as published by the
19
 * Free Software Foundation. See the LICENSE file included with
20
 * this program for more details.
21
 */
22
23
#ifndef _VPM450M_H
24
#define _VPM450M_H
25
26
#include <linux/firmware.h>
27
28
struct vpm450m;
29
30
/* From driver */
31
unsigned int oct_get_reg(void *data, unsigned int reg);
32
void oct_set_reg(void *data, unsigned int reg, unsigned int val);
33
34
/* From vpm450m */
35
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
36
unsigned int get_vpm450m_capacity(void *wc);
37
void vpm450m_setec(struct vpm450m *instance, int channel, int eclen);
38
void vpm450m_setdtmf(struct vpm450m *instance, int channel, int dtmfdetect, int dtmfmute);
39
int vpm450m_checkirq(struct vpm450m *vpm450m);
40
int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start);
41
void release_vpm450m(struct vpm450m *instance);
42
43
#endif
(-)dahdi-linux-3.1.0.original/drivers/dahdi/vpmadt032_loader/vpmadt032_loader.h (+49 lines)
Line 0 Link Here
1
/*
2
 * DAHDI Telephony Interface to VPMADT032 Firmware Loader
3
 *
4
 * Copyright (C) 2008 Digium, Inc.
5
 *
6
 * All rights reserved.
7
 *
8
 * See http://www.asterisk.org for more information about
9
 * the Asterisk project. Please do not directly contact
10
 * any of the maintainers of this project for assistance;
11
 * the project provides a web site, mailing lists and IRC
12
 * channels for your use.
13
 *
14
 * This program is free software, distributed under the terms of
15
 * the GNU General Public License Version 2 as published by the
16
 * Free Software Foundation. See the LICENSE file included with
17
 * this program for more details.
18
 */
19
20
#if !defined(_VPMADT032_LOADER_H_)
21
#define _VPMADT032_LOADER_H_ 
22
23
#define vpmlinkage __attribute__((regparm(0)))
24
25
vpmlinkage void 
26
__vpmadt032_init(vpmlinkage int (*logger)(const char *format, ...), 
27
                 unsigned int debug, vpmlinkage void *(*memalloc)(size_t len),
28
		 vpmlinkage void (*memfree)(void *ptr));
29
30
vpmlinkage int 
31
__vpmadt032_start_load(uint32_t iobase, uint32_t id, void **context);
32
33
vpmlinkage int
34
__vpmadt032_done(void *context);
35
36
vpmlinkage void
37
__vpmadt032_receive(void *context, void *buffer);
38
39
vpmlinkage void
40
__vpmadt032_transmit(void *context, void *buffer);
41
42
vpmlinkage void
43
__vpmadt032_cleanup(void *context);
44
45
46
47
#endif /* !defined(_VPMADT032_LOADER_H_) */
48
49
(-)dahdi-linux-3.1.0.original/drivers/dahdi/wcopenpci.c (+1784 lines)
Line 0 Link Here
1
/*
2
 * Voicetronix OpenPCI Interface Driver for Zapata Telephony interface
3
 *
4
 * Written by Mark Spencer <markster@linux-support.net>
5
 *            Matthew Fredrickson <creslin@linux-support.net>
6
 *            Ben Kramer <ben@voicetronix.com.au>
7
 *            Ron Lee <ron@voicetronix.com.au>
8
 *
9
 * Copyright (C) 2001, Linux Support Services, Inc.
10
 * Copyright (C) 2005 - 2007, Voicetronix
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
/* Conditional debug options */
31
#define VERBOSE_TIMING 0
32
33
/* Driver constants */
34
#define DRIVER_DESCRIPTION  "Voicetronix OpenPCI DAHDI driver"
35
#define DRIVER_AUTHOR	"Mark Spencer <markster@digium.com> "\
36
			"Voicetronix <support@voicetronix.com.au>"
37
38
#define NAME      "wcopenpci"
39
#define MAX_PORTS 8	    /* Maximum number of ports on each carrier */
40
#define MAX_CARDS 8	    /* Maximum number of carriers per host */
41
42
#define DEFAULT_COUNTRY  "AUSTRALIA"
43
44
45
#include <linux/init.h>
46
#include <linux/module.h>
47
#include <linux/pci.h>
48
#include <linux/delay.h>
49
#include <linux/sched.h>
50
51
#include <dahdi/kernel.h>
52
#include <dahdi/version.h>
53
#include "proslic.h"
54
#include <dahdi/wctdm_user.h>
55
#include <linux/interrupt.h>
56
#include <linux/mutex.h>
57
58
#include "fxo_modes.h"
59
60
static struct ps_country_reg {
61
	const char *country;
62
	unsigned short value;
63
} ps_country_regs[] = {
64
	{"ARGENTINA",  0x8},
65
	{"AUSTRALIA",  0xD},
66
	{"AUSTRIA",    0xD},
67
	{"BAHRAIN",    0xC},
68
	{"BELGIUM",    0xC},
69
	{"BRAZIL",     0x8},
70
	{"BULGARIA",   0xD},
71
	{"CANADA",     0x8},
72
	{"CHILE",      0x8},
73
	{"CHINA",      0xC},
74
	{"COLOMBIA",   0x8},
75
	{"CROATIA",    0xC},
76
	{"CYPRUS",     0xC},
77
	{"CZECH",      0xC},
78
	{"DENMARK",    0xC},
79
	{"ECUADOR",    0x8},
80
	{"EGYPT",      0x8},
81
	{"ELSALVADOR", 0x8},
82
	{"FINLAND",    0xC},
83
	{"FRANCE",     0xC},
84
	{"GERMANY",    0xD},
85
	{"GREECE",     0xC},
86
	{"GUAM",       0x8},
87
	{"HONGKONG",   0x8},
88
	{"HUNGARY",    0x8},
89
	{"ICELAND",    0xC},
90
	{"INDIA",      0xF},
91
	{"INDONESIA",  0x8},
92
	{"IRELAND",    0xC},
93
	{"ISRAEL",     0xC},
94
	{"ITALY",      0xC},
95
	{"JAPAN",      0x8},
96
	{"JORDAN",     0x8},
97
	{"KAZAKHSTAN", 0x8},
98
	{"KUWAIT",     0x8},
99
	{"LATVIA",     0xC},
100
	{"LEBANON",    0xC},
101
	{"LUXEMBOURG", 0xC},
102
	{"MACAO",      0x8},
103
	{"MALAYSIA",   0x8},
104
	{"MALTA",      0xC},
105
	{"MEXICO",     0x8},
106
	{"MOROCCO",    0xC},
107
	{"NETHERLANDS", 0xC},
108
	{"NEWZEALAND", 0xF},
109
	{"NIGERIA",    0xC},
110
	{"NORWAY",     0xC},
111
	{"OMAN",       0x8},
112
	{"PAKISTAN",   0x8},
113
	{"PERU",       0x8},
114
	{"PHILIPPINES", 0x8},
115
	{"POLAND",     0x8},
116
	{"PORTUGAL",   0xC},
117
	{"ROMANIA",    0x8},
118
	{"RUSSIA",     0x8},
119
	{"SAUDIARABIA", 0x8},
120
	{"SINGAPORE",  0x8},
121
	{"SLOVAKIA",   0xE},
122
	{"SLOVENIA",   0xE},
123
	{"SOUTHAFRICA", 0xE},
124
	{"SOUTHKOREA", 0x8},
125
	{"SPAIN",      0xC},
126
	{"SWEDEN",     0xC},
127
	{"SWITZERLAND", 0xC},
128
	{"SYRIA",      0x8},
129
	{"TAIWAN",     0x8},
130
	{"THAILAND",   0x8},
131
	{"UAE",        0x8},
132
	{"UK",         0xC},
133
	{"USA",        0x8},
134
	{"YEMEN",      0x8}
135
};
136
137
#define INOUT 2
138
139
/* Allocate enough memory for two zt chunks, receive and transmit.  Each
140
 * sample uses 32 bits.  Allocate an extra set just for control too */
141
#define VT_PCIDMA_BLOCKSIZE (DAHDI_MAX_CHUNKSIZE * INOUT * MAX_PORTS * 2 * 2)
142
#define VT_PCIDMA_MIDDLE    (DAHDI_MAX_CHUNKSIZE * MAX_PORTS - 4)
143
#define VT_PCIDMA_END       (DAHDI_MAX_CHUNKSIZE * MAX_PORTS * 2 - 4)
144
145
#define ID_DATA_MAXSIZE         30
146
147
#define NUM_CAL_REGS 12
148
#define NUM_FXO_REGS 60
149
150
#define TREG(addr)      (wc->ioaddr + addr)
151
152
#define TJ_CNTL         TREG(0x00)
153
#define TJ_OPER         TREG(0x01)
154
#define TJ_AUXC         TREG(0x02)
155
#define TJ_AUXD         TREG(0x03)
156
#define TJ_MASK0        TREG(0x04)
157
#define TJ_MASK1        TREG(0x05)
158
#define TJ_INTSTAT      TREG(0x06)
159
#define TJ_AUXR         TREG(0x07)
160
161
#define TJ_DMAWS        TREG(0x08)
162
#define TJ_DMAWI        TREG(0x0c)
163
#define TJ_DMAWE        TREG(0x10)
164
#define TJ_DMAWC        TREG(0x14)
165
#define TJ_DMARS        TREG(0x18)
166
#define TJ_DMARI        TREG(0x1c)
167
#define TJ_DMARE        TREG(0x20)
168
#define TJ_DMARC        TREG(0x24)
169
170
#define TJ_AUXINTPOL    TREG(0x2A)
171
172
#define TJ_AUXFUNC      TREG(0x2b)
173
#define TJ_SFDELAY      TREG(0x2c)
174
#define TJ_SERCTL       TREG(0x2d)
175
#define TJ_SFLC         TREG(0x2e)
176
#define TJ_FSCDELAY     TREG(0x2f)
177
178
#define TJ_REGBASE      TREG(0xc0)
179
180
#define PIB(addr)       (TJ_REGBASE + addr * 4)
181
182
#define HTXF_READY      (inb(PIB(0)) & 0x10)
183
#define HRXF_READY      (inb(PIB(0)) & 0x20)
184
185
186
#define VT_PORT_EMPTY	0
187
#define VT_PORT_VDAA	1   /* Voice DAA - FXO */
188
#define VT_PORT_PROSLIC	2   /* ProSLIC - FXS */
189
190
#define VBAT 0xC7
191
192
#define HKMODE_FWDACT   1
193
#define HKMODE_FWDONACT	2
194
#define HKMODE_RINGING	4
195
196
#define HOOK_ONHOOK     0
197
#define HOOK_OFFHOOK    1
198
199
#define	DSP_CODEC_RING		12	/* RING rising edge detected	*/
200
#define	DSP_CODEC_HKOFF		22	/* station port off hook        */
201
#define	DSP_CODEC_HKON		23	/* station port on hook         */
202
#define	DSP_RING_OFF		24	/* RING falling edge detected	*/
203
#define DSP_DROP		25
204
205
#define	DSP_CODEC_FLASH		26	/* station port hook flash      */
206
207
#define DSP_LOOP_OFFHOOK	38	/* Loop Off hook from OpenPCI   */
208
#define DSP_LOOP_ONHOOK		39	/* Loop On hook from OpenPCI    */
209
#define DSP_LOOP_POLARITY	40	/* Loop Polarity from OpenPCI   */
210
#define DSP_LOOP_NOBATT		41
211
212
#define DSP_PROSLIC_SANITY	50	/* Sanity alert from a ProSLIC port */
213
#define DSP_PROSLIC_PWR_ALARM	51	/* Power Alarm from a ProSLIC port  */
214
#define DSP_VDAA_ISO_FRAME_E	52	/* ISO-cap frame sync lost on VDAA port*/
215
216
#if VERBOSE_TIMING
217
 #define REPORT_WAIT(n,x)						    \
218
	 cardinfo(card->cardnum, #n " wait at %d, " #x " = %d", __LINE__, x )
219
#else
220
 #define REPORT_WAIT(n,x)
221
#endif
222
223
#define BUSY_WAIT(countvar,cond,delay,iter,failret)			    \
224
	countvar = 0;							    \
225
	while(cond){							    \
226
	    udelay(delay);						    \
227
	    if (++countvar > iter){					    \
228
		cardcrit(wc->boardnum, "busy wait FAILED at %d", __LINE__); \
229
		return failret;						    \
230
	    }								    \
231
	}								    \
232
	REPORT_WAIT(busy,i)
233
234
#define LOCKED_WAIT(countvar,cond,delay,iter,failret)			    \
235
	countvar = 0;							    \
236
	while(cond){							    \
237
	    udelay(delay);						    \
238
	    if (++countvar > iter){					    \
239
		dbginfo(wc->boardnum,"busy wait failed at %d",__LINE__);    \
240
		spin_unlock_irqrestore(&wc->lock, flags);		    \
241
		return failret;						    \
242
	    }								    \
243
	}								    \
244
	REPORT_WAIT(locked,i)
245
246
#define HTXF_WAIT()                 BUSY_WAIT(i,HTXF_READY,5,500,RET_FAIL)
247
#define HRXF_WAIT()                 BUSY_WAIT(i,!HRXF_READY,5,70000,RET_FAIL)
248
#define HTXF_WAIT_RET(failret)      BUSY_WAIT(i,HTXF_READY,5,500,failret)
249
#define HRXF_WAIT_RET(failret)      BUSY_WAIT(i,!HRXF_READY,5,1000,failret)
250
251
#define HTXF_WAIT_LOCKED()	    LOCKED_WAIT(i,HTXF_READY,5,500,RET_FAIL)
252
#define HRXF_WAIT_LOCKED()	    LOCKED_WAIT(i,!HRXF_READY,5,1000,RET_FAIL)
253
#define HTXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,HTXF_READY,5,500,failret)
254
#define HRXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,!HRXF_READY,5,1000,failret)
255
256
257
static struct openpci {
258
	struct pci_dev *dev;
259
	char *variety;
260
	int boardnum;
261
	int portcount;
262
	int porttype[MAX_PORTS];
263
264
        int firmware;
265
        char serial[ID_DATA_MAXSIZE];
266
267
	spinlock_t lock;
268
269
	//XXX Replace these with proper try_module_get locking in the dahdi driver.
270
	//int usecount;	//XXX
271
	//int dead;	//XXX
272
	union {
273
		struct {
274
			int offhook;
275
		} fxo;
276
		struct {
277
			int ohttimer;
278
			int idletxhookstate;  /* IDLE changing hook state */
279
			int lasttxhook;
280
		} fxs;
281
	} mod[MAX_PORTS];
282
283
	unsigned long		ioaddr;
284
	dma_addr_t		readdma;
285
	dma_addr_t		writedma;
286
	volatile unsigned int  *writechunk;  /* Double-word aligned write memory */
287
	volatile unsigned int  *readchunk;   /* Double-word aligned read memory */
288
289
	struct dahdi_chan _chans[MAX_PORTS];
290
	struct dahdi_chan *chans[MAX_PORTS];
291
	struct dahdi_device *ddev;
292
	struct dahdi_span span;
293
} *cards[MAX_CARDS];
294
295
/* You must hold this lock anytime you access or modify the cards[] array. */
296
static DEFINE_MUTEX(cards_mutex);
297
298
static unsigned char fxo_port_lookup[8] = { 0x0, 0x8, 0x4, 0xc, 0x10, 0x18, 0x14, 0x1c};
299
static unsigned char fxs_port_lookup[8] = { 0x0, 0x1, 0x2, 0x3, 0x10, 0x11, 0x12, 0x13};
300
static char wcopenpci[] = "Voicetronix OpenPCI";
301
302
static char *country = DEFAULT_COUNTRY;
303
static int reversepolarity;  /* = 0 */
304
static int debug;            /* = 0 */
305
306
module_param(country, charp, 0444);
307
module_param(debug, int, 0600);
308
module_param(reversepolarity, int, 0600);
309
MODULE_PARM_DESC(country, "Set the default country name");
310
MODULE_PARM_DESC(debug, "Enable verbose logging");
311
312
/* #define DEBUG_LOOP_VOLTAGE 1 */
313
#ifdef DEBUG_LOOP_VOLTAGE
314
 /* This param is a 32 bit bitfield where bit 1 << cardnum * 8 << portnum
315
  * will enable voltage monitoring on that port (fxo only presently)
316
  */
317
 static int voltmeter;        /* = 0 */
318
 module_param(voltmeter, int, 0600);
319
 MODULE_PARM_DESC(voltmeter, "Enable loop voltage metering");
320
#endif
321
322
323
/* boolean return values */
324
#define RET_OK   1
325
#define RET_FAIL 0
326
327
/* Convenience macros for logging */
328
#define info(format,...) printk(KERN_INFO NAME ": " format "\n" , ## __VA_ARGS__)
329
#define warn(format,...) printk(KERN_WARNING NAME ": " format "\n" , ## __VA_ARGS__)
330
#define crit(format,...) printk(KERN_CRIT NAME ": " format "\n" , ## __VA_ARGS__)
331
#define cardinfo(cardnum,format,...) info("[%02d] " format, cardnum , ## __VA_ARGS__)
332
#define cardwarn(cardnum,format,...) warn("[%02d] " format, cardnum , ## __VA_ARGS__)
333
#define cardcrit(cardnum,format,...) crit("[%02d] " format, cardnum , ## __VA_ARGS__)
334
#define dbginfo(cardnum,format,...) if (debug) info("[%02d] " format, cardnum , ## __VA_ARGS__)
335
336
337
static inline const char *porttype(struct openpci *wc, int port)
338
{
339
	switch( wc->porttype[port] ) {
340
		case VT_PORT_VDAA:    return "VDAA";
341
		case VT_PORT_PROSLIC: return "ProSLIC";
342
		case VT_PORT_EMPTY:   return "empty port";
343
		default:              return "unknown type";
344
	}
345
}
346
347
348
static int __read_reg_fxo(struct openpci *wc, int port, unsigned char reg,
349
		unsigned char *value)
350
{
351
	unsigned char portadr = fxo_port_lookup[port];
352
	int i;
353
354
	if (HRXF_READY) *value = inb(PIB(1));
355
356
	outb(0x11, PIB(1));    HTXF_WAIT();
357
	outb(0x2, PIB(1));     HTXF_WAIT();
358
	outb(portadr, PIB(1)); HTXF_WAIT();
359
	outb(reg, PIB(1));     HTXF_WAIT();
360
	HRXF_WAIT(); *value = inb(PIB(1));
361
362
	return RET_OK;
363
}
364
365
static int read_reg_fxo(struct openpci *wc, int port, unsigned char reg,
366
		unsigned char *value)
367
{
368
	unsigned long flags;
369
370
	spin_lock_irqsave(&wc->lock, flags);
371
	if (__read_reg_fxo(wc, port, reg, value)) {
372
		spin_unlock_irqrestore(&wc->lock, flags);
373
		return RET_OK;
374
	}
375
	spin_unlock_irqrestore(&wc->lock, flags);
376
	cardcrit(wc->boardnum, "FXO port %d, reg %d, read failed!", port, reg);
377
	return RET_FAIL;
378
}
379
380
static int __read_reg_fxs(struct openpci *wc, int port, unsigned char reg,
381
		unsigned char *value)
382
{
383
	unsigned char portadr = fxs_port_lookup[port];
384
	int i;
385
386
	if (HRXF_READY) *value = inb(PIB(1));
387
388
	outb(0x13, PIB(1));    HTXF_WAIT();
389
	outb(0x2, PIB(1));     HTXF_WAIT();
390
	outb(portadr, PIB(1)); HTXF_WAIT();
391
	outb(reg, PIB(1));     HTXF_WAIT();
392
	HRXF_WAIT(); *value = inb(PIB(1));
393
394
	return RET_OK;
395
}
396
397
static int read_reg_fxs(struct openpci *wc, int port, unsigned char reg,
398
		unsigned char *value)
399
{
400
	unsigned long flags;
401
402
	spin_lock_irqsave(&wc->lock, flags);
403
	if ( __read_reg_fxs(wc, port, reg, value) ) {
404
		spin_unlock_irqrestore(&wc->lock, flags);
405
		return RET_OK;
406
	}
407
	spin_unlock_irqrestore(&wc->lock, flags);
408
	cardcrit(wc->boardnum, "FXS port %d, reg %d, read failed!", port, reg);
409
	return RET_FAIL;
410
}
411
412
static int __write_reg_fxo(struct openpci *wc, int port, unsigned char reg,
413
		unsigned char value)
414
{
415
	unsigned char portadr = fxo_port_lookup[port];
416
	int i;
417
418
        outb(0x10, PIB(1) );   HTXF_WAIT();
419
        outb(0x3, PIB(1));     HTXF_WAIT();
420
        outb(portadr, PIB(1)); HTXF_WAIT();
421
        outb(reg, PIB(1));     HTXF_WAIT();
422
        outb(value, PIB(1));   HTXF_WAIT();
423
424
	return RET_OK;
425
}
426
427
static int write_reg_fxo(struct openpci *wc, int port, unsigned char reg,
428
		unsigned char value)
429
{
430
	unsigned long flags;
431
432
	spin_lock_irqsave(&wc->lock, flags);
433
	if (__write_reg_fxo(wc, port, reg, value)) {
434
		spin_unlock_irqrestore(&wc->lock, flags);
435
		return RET_OK;
436
	}
437
	spin_unlock_irqrestore(&wc->lock, flags);
438
	cardcrit(wc->boardnum, "FXO port %d, reg %d, write(%d) failed!",
439
			port, reg, value);
440
	return RET_FAIL;
441
}
442
443
static int __write_reg_fxs(struct openpci *wc, int port, unsigned char reg,
444
		unsigned char value)
445
{
446
	unsigned char portadr = fxs_port_lookup[port];
447
	int i;
448
449
        outb(0x12, PIB(1) );   HTXF_WAIT();
450
        outb(0x3, PIB(1));     HTXF_WAIT();
451
        outb(portadr, PIB(1)); HTXF_WAIT();
452
        outb(reg, PIB(1));     HTXF_WAIT();
453
        outb(value, PIB(1));   HTXF_WAIT();
454
455
	return RET_OK;
456
}
457
458
static int write_reg_fxs(struct openpci *wc, int port, unsigned char reg,
459
		unsigned char value)
460
{
461
	unsigned long flags;
462
463
	spin_lock_irqsave(&wc->lock, flags);
464
	if (__write_reg_fxs(wc, port, reg, value)) {
465
		spin_unlock_irqrestore(&wc->lock, flags);
466
		return RET_OK;
467
	}
468
	spin_unlock_irqrestore(&wc->lock, flags);
469
	cardcrit(wc->boardnum, "FXS port %d, reg %d, write(%d) failed!", port, reg, value);
470
	return RET_FAIL;
471
}
472
473
static int __wait_indreg_fxs(struct openpci *wc, int port)
474
{
475
	unsigned char value;
476
	int count = 100;
477
478
	while (--count) {
479
		if ( __read_reg_fxs(wc, port, I_STATUS, &value)) {
480
			if (value == 0)
481
				return RET_OK;
482
		} else {
483
			cardcrit(wc->boardnum,
484
				 "failed to read port %d PS_IND_ADDR_ST, retrying...",
485
				 port);
486
		}
487
		udelay(5);
488
	}
489
	cardcrit(wc->boardnum, "Failed to wait for indirect reg write to port %d", port);
490
	return RET_FAIL;
491
}
492
493
static int write_indreg_fxs(struct openpci *wc, int port, unsigned char reg,
494
		unsigned short value)
495
{
496
	unsigned long flags;
497
498
	spin_lock_irqsave(&wc->lock, flags);
499
	if (__wait_indreg_fxs(wc, port)
500
	 && __write_reg_fxs(wc, port, IDA_LO, value & 0xff)
501
	 && __write_reg_fxs(wc, port, IDA_HI, (value & 0xff00)>>8)
502
	 && __write_reg_fxs(wc, port, IAA, reg)
503
	 && __wait_indreg_fxs(wc, port))
504
	{
505
		spin_unlock_irqrestore(&wc->lock, flags);
506
		return RET_OK;
507
	}
508
	spin_unlock_irqrestore(&wc->lock, flags);
509
	cardcrit(wc->boardnum, "FXS indreg %d write failed on port %d",
510
			reg, port);
511
	return RET_FAIL;
512
}
513
514
static int read_indreg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned short *value)
515
{
516
	unsigned long flags;
517
	unsigned char lo, hi;
518
519
	spin_lock_irqsave(&wc->lock, flags);
520
	if (__wait_indreg_fxs(wc, port)
521
	 && __write_reg_fxs(wc, port, IAA, reg)
522
	 && __wait_indreg_fxs(wc, port)
523
	 && __read_reg_fxs(wc, port, IDA_LO, &lo)
524
	 && __read_reg_fxs(wc, port, IDA_HI, &hi) )
525
	{
526
		*value = lo | hi << 8;
527
		spin_unlock_irqrestore(&wc->lock, flags);
528
		return RET_OK;
529
	}
530
	spin_unlock_irqrestore(&wc->lock, flags);
531
	return RET_FAIL;
532
}
533
534
static void start_dma(struct openpci *wc)
535
{
536
	outb(0x0f, TJ_CNTL);
537
	set_current_state(TASK_INTERRUPTIBLE);
538
	schedule_timeout(1);
539
	outb(0x01, TJ_CNTL);
540
	outb(0x01, TJ_OPER);
541
}
542
543
static void restart_dma(struct openpci *wc)
544
{
545
	/* Reset Master and TDM */
546
	outb(0x01, TJ_CNTL);
547
	outb(0x01, TJ_OPER);
548
}
549
550
/* You must hold the card spinlock to call this function */
551
static int __ping_arm(struct openpci *wc)
552
{
553
	int i;
554
	int pong = 0;
555
556
	while (pong != 0x02) {
557
		outb(0x02, PIB(1)); HTXF_WAIT();
558
		HRXF_WAIT(); pong = inb(PIB(1));
559
		dbginfo(wc->boardnum, "ping_arm returned %x", pong);
560
	}
561
	while (pong == 0x02) {
562
		// Poke no-ops into the arm while it is still returning data,
563
		// if 500 usec elapses with no further response from it then
564
		// the message queue is should be completely cleared.
565
		outb(0x00, PIB(1)); HTXF_WAIT();
566
		i = 100;
567
		while (!HRXF_READY && --i)
568
			udelay(5);
569
		if (i == 0)
570
			break;
571
		pong = inb(PIB(1));
572
		dbginfo(wc->boardnum, "ping_arm returned %x.", pong);
573
	}
574
	return RET_OK;
575
}
576
577
static void arm_event(struct openpci *wc, char *msg)
578
{
579
	int port = msg[0];
580
581
	switch (msg[1]) {
582
		case DSP_LOOP_OFFHOOK:
583
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
584
			dbginfo(wc->boardnum, "Port %d Loop OffHook", port);
585
			break;
586
587
		case DSP_LOOP_ONHOOK:
588
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
589
			dbginfo(wc->boardnum, "Port %d Loop OnHook", port);
590
			break;
591
592
		case DSP_LOOP_POLARITY:
593
			dahdi_qevent_lock(wc->chans[port], DAHDI_EVENT_POLARITY);
594
			dbginfo(wc->boardnum, "Port %d Loop Polarity", port);
595
			break;
596
597
		case DSP_CODEC_RING:
598
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_RING);
599
			dbginfo(wc->boardnum, "Port %d Ring On", port);
600
			break;
601
602
		case DSP_RING_OFF:
603
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
604
			dbginfo(wc->boardnum, "Port %d Ring Off", port);
605
			break;
606
607
		case DSP_CODEC_HKOFF:
608
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
609
			dbginfo(wc->boardnum, "Port %d Station OffHook", port);
610
			if (reversepolarity)
611
				wc->mod[port].fxs.idletxhookstate = 5;
612
			else
613
				wc->mod[port].fxs.idletxhookstate = 1;
614
			break;
615
616
		case DSP_CODEC_HKON:
617
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
618
			dbginfo(wc->boardnum, "Port %d Station OnHook", port);
619
			if (reversepolarity)
620
				wc->mod[port].fxs.idletxhookstate = 6;
621
			else
622
				wc->mod[port].fxs.idletxhookstate = 2;
623
			break;
624
625
		case DSP_CODEC_FLASH:
626
			dahdi_qevent_lock(wc->chans[port],
627
					DAHDI_EVENT_WINKFLASH);
628
			dbginfo(wc->boardnum, "Port %d Station Flash", port);
629
			break;
630
631
		case DSP_DROP:
632
		case DSP_LOOP_NOBATT:
633
			break;
634
635
			//XXX What to do to recover from these?
636
		case DSP_PROSLIC_SANITY:
637
			dbginfo(wc->boardnum, "Port %d ProSlic has gone insane!", port);
638
			break;
639
640
		case DSP_PROSLIC_PWR_ALARM:
641
		{
642
			char errbuf[32] = " Unknown", *p = errbuf;
643
			int i = 49;
644
645
			msg[2] >>= 2;
646
			for (; i < 55; ++i, msg[2] >>= 1 )
647
			    if (msg[2] & 1) {
648
				    *(++p) = 'Q';
649
				    *(++p) = i;
650
				    *(++p) = ',';
651
			    }
652
			if (p != errbuf)
653
				*p = '\0';
654
			cardcrit(wc->boardnum,"%d: ProSlic power ALARM:%s",
655
					msg[0], errbuf);
656
			//write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook );
657
			return;
658
		}
659
660
		case DSP_VDAA_ISO_FRAME_E:
661
			dbginfo(wc->boardnum, "Port %d VDAA has lost ISO-Cap frame lock", port);
662
			break;
663
664
		default:
665
			cardwarn(wc->boardnum, "Unknown message from Arm[%d] for port %d",
666
						msg[1], port);
667
			break;
668
	}
669
}
670
671
/* You must hold the card spinlock to call this function */
672
static inline int __read_arm_byte( struct openpci *wc, unsigned char *msg)
673
{
674
	int i;
675
676
	HRXF_WAIT(); *msg = inb(PIB(1));
677
	return RET_OK;
678
}
679
680
static inline int read_arm_msg( struct openpci *wc, unsigned char *msg)
681
{
682
	unsigned long flags;
683
	int i, d, count;
684
	int ret = RET_OK;
685
686
	spin_lock_irqsave(&wc->lock, flags);
687
	outb(0x08, PIB(1)); HTXF_WAIT_LOCKED();
688
	//XXX Do we need to clear the interrupt flag even if this fails?
689
	HRXF_WAIT_LOCKED(); count = inb(PIB(1));
690
	if (count == 0) {
691
		ret = RET_FAIL;
692
	} else if ( count < 3 || count > 4 ) {
693
		cardcrit(wc->boardnum, "BOGUS arm message size %d, flushing queue", count);
694
		// NB: This may take a while (up to 500usec or more) to complete
695
		//     and we are in the isr at present when this is called, so
696
		//     we may miss an interrupt or two while this is done in the
697
		//     bottom half, but we are already in trouble, so...
698
		d = debug; debug = 5; __ping_arm( wc ); debug = d;
699
		ret = RET_FAIL;
700
	} else while (--count ) {
701
		if (! __read_arm_byte(wc, msg)) {
702
			cardcrit(wc->boardnum,
703
				 "Failed to read arm message %d more bytes expected",
704
				 count);
705
			ret = RET_FAIL;
706
			break;
707
		}
708
		++msg;
709
	}
710
	outb(0x09, PIB(1)); HTXF_WAIT_LOCKED();
711
	spin_unlock_irqrestore(&wc->lock, flags);
712
	return ret;
713
}
714
715
static void openpci_arm_work( void *cardptr )
716
{
717
	struct openpci *wc = (struct openpci*)cardptr;
718
	unsigned char armmsg[4];
719
720
	if (read_arm_msg(wc, armmsg))
721
		arm_event(wc, armmsg);
722
}
723
724
725
static inline void openpci_write(struct openpci *wc, unsigned char flags)
726
{
727
	int x,y;
728
	volatile unsigned int *writechunk;
729
730
	if (flags & 0x01)
731
		writechunk = wc->writechunk;
732
	else if (flags & 0x02)
733
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE*2;
734
	else {
735
		cardcrit(wc->boardnum, "bad write interrupt flags %x, at %x",
736
					flags, inb(TJ_DMAWC) );
737
		return;
738
	}
739
	/* get data */
740
	dahdi_transmit(&wc->span);
741
	for (y = 0, x = 0; x < DAHDI_CHUNKSIZE; ++x) {
742
		/* Send a sample, as a 32-bit word */
743
#ifdef __BIG_ENDIAN
744
#warning No big endian support (yet)
745
#else
746
		/* transmit second 4 ports */
747
		writechunk[y] = 0;
748
		if (wc->porttype[4])
749
			writechunk[y] |= (wc->chans[4]->writechunk[x] << 24);
750
		else
751
			writechunk[y] |= (0x01 << 24);
752
		if (wc->porttype[5])
753
			writechunk[y] |= (wc->chans[5]->writechunk[x] << 16);
754
		if (wc->porttype[6])
755
			writechunk[y] |= (wc->chans[6]->writechunk[x] << 8);
756
		if (wc->porttype[7])
757
			writechunk[y] |= (wc->chans[7]->writechunk[x]);
758
		++y;
759
760
		/* transmit first 4 ports */
761
		writechunk[y] = 0x01000000;
762
		/* Make sure first port doesnt equal 0x00 */
763
		if (wc->porttype[0]) {
764
			if (wc->chans[0]->writechunk[x] == 0)
765
				writechunk[y] |= (0x01 << 24);
766
			else
767
				writechunk[y] |= (wc->chans[0]->writechunk[x] << 24);
768
		}
769
		//else writechunk[y] |= (0x00 << 24);
770
		if (wc->porttype[1])
771
			writechunk[y] |= (wc->chans[1]->writechunk[x] << 16);
772
		if (wc->porttype[2])
773
			writechunk[y] |= (wc->chans[2]->writechunk[x] << 8);
774
		if (wc->porttype[3])
775
			writechunk[y] |= (wc->chans[3]->writechunk[x]);
776
		++y;
777
#endif
778
	}
779
}
780
781
static inline void openpci_read(struct openpci *wc, unsigned char flags)
782
{
783
	int x,y;
784
	volatile unsigned int *readchunk;
785
786
	if (flags & 0x08)
787
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE*2;
788
	else if (flags & 0x04)
789
		readchunk = wc->readchunk;
790
	else {
791
		cardcrit(wc->boardnum, "bad read interrupt flags %x, at %x",
792
					flags, inb(TJ_DMARC));
793
		return;
794
	}
795
796
	for (y = 0,x = 0; x < DAHDI_CHUNKSIZE; ++x) {
797
#ifdef __BIG_ENDIAN
798
#warning No big endian support (yet)
799
#else
800
		/* Receive first 4 ports */
801
802
		if (wc->porttype[0])
803
			wc->chans[0]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
804
		if (wc->porttype[1])
805
			wc->chans[1]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
806
		if (wc->porttype[2])
807
			wc->chans[2]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
808
		if (wc->porttype[3])
809
			wc->chans[3]->readchunk[x] = (readchunk[y]) & 0xff;
810
		++y;
811
		/* Receive second 4 ports */
812
		if (wc->porttype[4])
813
			wc->chans[4]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
814
		if (wc->porttype[5])
815
			wc->chans[5]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
816
		if (wc->porttype[6])
817
			wc->chans[6]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
818
		if (wc->porttype[7])
819
			wc->chans[7]->readchunk[x] = (readchunk[y]) & 0xff;
820
		++y;
821
#endif
822
	}
823
	/* XXX We're wasting 8 taps.  We should get closer :( */
824
	for (x = 0; x < MAX_PORTS; x++) {
825
		if (wc->porttype[x])
826
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
827
	}
828
	dahdi_receive(&wc->span);
829
}
830
831
static irqreturn_t openpci_isr(int irq, void *dev_id)
832
{
833
	struct openpci *wc = dev_id;
834
	unsigned long flags;
835
	unsigned char status;
836
837
	spin_lock_irqsave(&wc->lock, flags);
838
	status = inb(TJ_INTSTAT);
839
	outb(status, TJ_INTSTAT);
840
841
	if (!status) {
842
		if (inb(TJ_AUXR) & 0x02) {
843
			spin_unlock_irqrestore(&wc->lock, flags);
844
			return IRQ_NONE;
845
		}
846
		spin_unlock_irqrestore(&wc->lock, flags);
847
		openpci_arm_work(wc);
848
		return IRQ_HANDLED;
849
	}
850
	if (status & 0x10) {
851
		/* PCI Master abort */
852
		cardcrit(wc->boardnum, "PCI Master Abort.");
853
		/* Stop DMA, wait for watchdog */
854
		outb(0x00, TJ_OPER);
855
		spin_unlock_irqrestore(&wc->lock, flags);
856
		return IRQ_HANDLED;
857
	}
858
	spin_unlock_irqrestore(&wc->lock, flags);
859
860
	if (status & 0x20) {
861
		/* PCI Target abort */
862
		cardcrit(wc->boardnum, "PCI Target Abort.");
863
		return IRQ_HANDLED;
864
	}
865
	if (status & 0x03) {
866
		openpci_write(wc, status);
867
	}
868
	if (status & 0x0c) {
869
	    #ifdef DEBUG_LOOP_VOLTAGE
870
	    //{{{
871
		static int counter[MAX_CARDS];
872
		int card = wc->boardnum;
873
		int port = ++counter[card] & 0x07;
874
		int ignore = counter[card] & 0xf0;
875
876
		if (!ignore && (voltmeter & ((1 << (card * 8)) << port))) {
877
			unsigned char lv;
878
			if (wc->porttype[port] == VT_PORT_VDAA &&
879
					read_reg_fxo(wc, port, 29, &lv))
880
				cardinfo(wc->boardnum, "Port %d loop voltage %d",
881
							port, lv < 128 ? lv :
882
							lv - 256);
883
		}
884
	    //}}}
885
	    #endif
886
		openpci_read(wc, status);
887
	}
888
889
	return IRQ_HANDLED;
890
}
891
892
static int openpci_ioctl(struct dahdi_chan *chan, unsigned int cmd,
893
		unsigned long data)
894
{
895
	struct wctdm_stats stats;
896
	struct wctdm_regs regs;
897
	struct wctdm_regop regop;
898
	struct wctdm_echo_coefs echoregs;
899
	struct openpci *wc = chan->pvt;
900
	int port = chan->chanpos - 1;
901
	int x;
902
903
	switch (cmd) {
904
	case DAHDI_ONHOOKTRANSFER:
905
		if (wc->porttype[port] != VT_PORT_PROSLIC)
906
			return -EINVAL;
907
		if (get_user(x, (int __user *)data))
908
			return -EFAULT;
909
		wc->mod[port].fxs.ohttimer = x << 3;
910
		if (reversepolarity)
911
			wc->mod[port].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
912
		else
913
			wc->mod[port].fxs.idletxhookstate = 0x2;
914
		switch (wc->mod[port].fxs.lasttxhook) {
915
		    case 0x1:
916
		    case 0x5:
917
			if (reversepolarity)
918
				wc->mod[port].fxs.lasttxhook = 0x6;
919
			else
920
				wc->mod[port].fxs.lasttxhook = 0x2;
921
			if (!write_reg_fxs(wc, port, 64,
922
						wc->mod[port].fxs.lasttxhook))
923
				return -EIO;
924
		}
925
		break;
926
	case DAHDI_SETPOLARITY:
927
		if (get_user(x, (int __user *)data))
928
			return -EFAULT;
929
		if (wc->porttype[port] != VT_PORT_PROSLIC)
930
			return -EINVAL;
931
		/* Can't change polarity while ringing or when open */
932
		if ((wc->mod[port].fxs.lasttxhook == 0x04) ||
933
		    (wc->mod[port].fxs.lasttxhook == 0x00))
934
			return -EINVAL;
935
936
		if ((x && !reversepolarity) || (!x && reversepolarity))
937
			wc->mod[port].fxs.lasttxhook |= 0x04;
938
		else
939
			wc->mod[port].fxs.lasttxhook &= ~0x04;
940
		if (!write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook))
941
			return -EIO;
942
		break;
943
	case WCTDM_GET_STATS:
944
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
945
			unsigned char	linevolt;
946
			if (read_reg_fxs(wc, port, 80, &linevolt))
947
				stats.tipvolt = linevolt * -376;
948
			else
949
				return -EIO;
950
			if (read_reg_fxs(wc, port, 81, &linevolt))
951
				stats.ringvolt = linevolt * -376;
952
			else
953
				return -EIO;
954
			if (read_reg_fxs(wc, port, 82, &linevolt))
955
				stats.batvolt = linevolt * -376;
956
			else
957
				return -EIO;
958
		} else if (wc->porttype[port] == VT_PORT_VDAA) {
959
			unsigned char	linevolt;
960
			if (read_reg_fxo(wc, port, 29, &linevolt))
961
				stats.tipvolt = stats.ringvolt = stats.batvolt = linevolt * 1000;
962
			else
963
				return -EIO;
964
		} else
965
			return -EINVAL;
966
		if (copy_to_user((void __user *)data, &stats, sizeof(stats)))
967
			return -EFAULT;
968
		break;
969
	case WCTDM_GET_REGS:
970
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
971
			for (x = 0; x < NUM_INDIRECT_REGS; x++)
972
				if (!read_indreg_fxs(wc, port, x,
973
							&regs.indirect[x]))
974
					return -EIO;
975
			for (x = 0; x < NUM_REGS; x++)
976
				if (!read_reg_fxs(wc, port, x, &regs.direct[x]))
977
					return -EIO;
978
		} else {
979
			memset(&regs, 0, sizeof(regs));
980
			for (x = 0; x < NUM_FXO_REGS; x++) {
981
				if (!read_reg_fxo(wc, port, x, &regs.direct[x]))
982
					return -EIO;
983
			}
984
		}
985
		if (copy_to_user((void __user *)data, &regs, sizeof(regs)))
986
			return -EFAULT;
987
		break;
988
	case WCTDM_SET_REG:
989
		if (copy_from_user(&regop, (void __user *)data, sizeof(regop)))
990
			return -EFAULT;
991
		if (regop.indirect) {
992
			if (wc->porttype[port] != VT_PORT_PROSLIC)
993
				return -EINVAL;
994
			printk("Setting indirect %d to 0x%04x on %d\n",
995
				regop.reg, regop.val, chan->chanpos);
996
			if (!write_indreg_fxs(wc, port, regop.reg, regop.val))
997
				return -EIO;
998
		} else {
999
			regop.val &= 0xff;
1000
			printk("Setting direct %d to %04x on %d\n",
1001
				regop.reg, regop.val, chan->chanpos);
1002
			if (wc->porttype[port] == VT_PORT_PROSLIC) {
1003
				if (!write_reg_fxs(wc, port, regop.reg,
1004
							regop.val))
1005
					return -EIO;
1006
			} else {
1007
				if (!write_reg_fxo(wc, port, regop.reg,
1008
							regop.val))
1009
					return -EIO;
1010
			}
1011
		}
1012
		break;
1013
	case WCTDM_SET_ECHOTUNE:
1014
		cardinfo(wc->boardnum, "Setting echo registers");
1015
		if (copy_from_user(&echoregs, (void __user *)data, sizeof(echoregs)))
1016
			return -EFAULT;
1017
1018
		if (wc->porttype[port] == VT_PORT_VDAA) {
1019
			/* Set the ACIM and digital echo canceller registers */
1020
			if (!write_reg_fxo(wc, port, 30, echoregs.acim)
1021
			 || ! write_reg_fxo(wc, port, 45, echoregs.coef1)
1022
			 || ! write_reg_fxo(wc, port, 46, echoregs.coef2)
1023
			 || ! write_reg_fxo(wc, port, 47, echoregs.coef3)
1024
			 || ! write_reg_fxo(wc, port, 48, echoregs.coef4)
1025
			 || ! write_reg_fxo(wc, port, 49, echoregs.coef5)
1026
			 || ! write_reg_fxo(wc, port, 50, echoregs.coef6)
1027
			 || ! write_reg_fxo(wc, port, 51, echoregs.coef7)
1028
			 || ! write_reg_fxo(wc, port, 52, echoregs.coef8))
1029
			{
1030
				cardcrit(wc->boardnum, "Failed to set echo registers");
1031
				return -EIO;
1032
			}
1033
			break;
1034
		} else {
1035
			return -EINVAL;
1036
		}
1037
		break;
1038
	default:
1039
		return -ENOTTY;
1040
	}
1041
	return 0;
1042
}
1043
1044
static int openpci_open(struct dahdi_chan *chan)
1045
{
1046
	struct openpci *wc = chan->pvt;
1047
	if (!wc->porttype[chan->chanpos-1])
1048
		return -ENODEV;
1049
1050
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1051
	//    as the owner of the span that holds the pointer to this function,
1052
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1053
	//    fatal call to an invalid pointer is made.
1054
	//if (wc->dead) return -ENODEV;
1055
	//wc->usecount++;
1056
	try_module_get(THIS_MODULE);  //XXX
1057
1058
	return 0;
1059
}
1060
1061
static inline struct openpci* openpci_from_span(struct dahdi_span *span) {
1062
	return container_of(span, struct openpci, span);
1063
}
1064
1065
static int openpci_watchdog(struct dahdi_span *span, int event)
1066
{
1067
	info("TDM: Restarting DMA");
1068
	restart_dma(openpci_from_span(span));
1069
	return 0;
1070
}
1071
1072
static int openpci_close(struct dahdi_chan *chan)
1073
{
1074
	struct openpci *wc = chan->pvt;
1075
	int port = chan->chanpos - 1;
1076
1077
	//XXX wc->usecount--;
1078
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1079
	//    as the owner of the span that holds the pointer to this function,
1080
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1081
	//    fatal call to an invalid pointer is made.
1082
	module_put(THIS_MODULE);
1083
	if (wc->porttype[port] == VT_PORT_PROSLIC) {
1084
		if (reversepolarity)
1085
			wc->mod[port].fxs.idletxhookstate = 5;
1086
		else
1087
			wc->mod[port].fxs.idletxhookstate = 1;
1088
	}
1089
	/* If we're dead, release us now */
1090
	//XXX if (!wc->usecount && wc->dead) openpci_release(wc);
1091
1092
	return 0;
1093
}
1094
1095
static int openpci_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
1096
{
1097
	struct openpci *wc = chan->pvt;
1098
	int port = chan->chanpos - 1;
1099
	int new_hk_state;
1100
1101
	dbginfo(wc->boardnum, "Setting %s port %d hook state %s",
1102
		 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1103
		 port,
1104
		 txsig == 0 ? "ONHOOK" :
1105
		 txsig == 1 ? "OFFHOOK" :
1106
		 txsig == 2 ? "START" :
1107
		 txsig == 3 ? "KEWL" : "UNKNOWN" );
1108
1109
	switch(wc->porttype[port]) {
1110
	    case VT_PORT_VDAA:
1111
		switch(txsig) {
1112
		    case DAHDI_TXSIG_START:
1113
		    case DAHDI_TXSIG_OFFHOOK:
1114
			if (write_reg_fxo(wc, port, 5, 0x9)
1115
					&& write_reg_fxo(wc, port, 0x20, 0x0))
1116
				wc->mod[port].fxo.offhook = 1;
1117
			else
1118
				cardcrit(wc->boardnum,
1119
						"Failed set fxo off-hook");
1120
			break;
1121
1122
		    case DAHDI_TXSIG_ONHOOK:
1123
			if (write_reg_fxo(wc, port, 5, 0x8)
1124
			 && write_reg_fxo(wc, port, 0x20, 0x3))
1125
				wc->mod[port].fxo.offhook = 0;
1126
			else
1127
				cardcrit(wc->boardnum, "Failed set fxo on-hook");
1128
			break;
1129
1130
		    default:
1131
			cardcrit(wc->boardnum,
1132
				 "Can't set FXO port %d tx state to %d",
1133
				 port, txsig);
1134
		}
1135
		break;
1136
1137
	    case VT_PORT_PROSLIC:
1138
		new_hk_state = wc->mod[port].fxs.lasttxhook;
1139
		switch(txsig) {
1140
		    case DAHDI_TXSIG_ONHOOK:
1141
			switch(chan->sig) {
1142
			case DAHDI_SIG_EM:
1143
			case DAHDI_SIG_FXOKS:
1144
			case DAHDI_SIG_FXOLS:
1145
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1146
				break;
1147
			case DAHDI_SIG_FXOGS:
1148
				new_hk_state = 3;
1149
				break;
1150
			}
1151
			break;
1152
1153
		    case DAHDI_TXSIG_OFFHOOK:
1154
			switch(chan->sig) {
1155
			case DAHDI_SIG_EM:
1156
				new_hk_state = 5;
1157
				break;
1158
			default:
1159
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1160
				break;
1161
			}
1162
			break;
1163
1164
		    case DAHDI_TXSIG_START:
1165
			new_hk_state = 4;
1166
			break;
1167
1168
		    case DAHDI_TXSIG_KEWL:
1169
			new_hk_state = 0;
1170
			break;
1171
1172
		    default:
1173
			cardinfo(wc->boardnum,
1174
				 "Can't set FXS port %d tx state to %d",
1175
				 port, txsig);
1176
		}
1177
		dbginfo(wc->boardnum, "%s port %d hook state old %d, new %d",
1178
			 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1179
			 port, wc->mod[port].fxs.lasttxhook, new_hk_state );
1180
1181
		if (new_hk_state != wc->mod[port].fxs.lasttxhook) {
1182
			if (write_reg_fxs(wc, port, 64, new_hk_state))
1183
				wc->mod[port].fxs.lasttxhook = new_hk_state;
1184
			else
1185
				cardcrit(wc->boardnum,
1186
					 "Failed to set port %d fxs hookstate from %d to %d",
1187
					 port, wc->mod[port].fxs.lasttxhook,
1188
					 new_hk_state);
1189
		}
1190
		break;
1191
1192
	    default:
1193
		cardcrit(wc->boardnum,
1194
			 "Unknown module type %d in openpci_hooksig",
1195
			 wc->porttype[port] );
1196
	}
1197
	return 0;
1198
}
1199
1200
static const struct dahdi_span_ops openpci_span_ops = {
1201
	.owner = THIS_MODULE,
1202
	.hooksig = openpci_hooksig,
1203
	.open = openpci_open,
1204
	.close = openpci_close,
1205
	.ioctl = openpci_ioctl,
1206
	.watchdog = openpci_watchdog
1207
};
1208
1209
static int span_initialize(struct openpci *wc)
1210
{
1211
	int x;
1212
1213
	wc->ddev = dahdi_create_device();
1214
	//XXX Set a THIS_MODULE as the owner of the span...
1215
	/* Zapata stuff */
1216
	sprintf(wc->span.name, "WCTDM/%d", wc->boardnum);
1217
	sprintf(wc->span.desc, "%s Board %d", wc->variety, wc->boardnum + 1);
1218
	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
1219
				      wc->dev->bus->number,
1220
				      PCI_SLOT(wc->dev->devfn) + 1);
1221
	if (!wc->ddev->location)
1222
		return -ENOMEM;
1223
	for (x = 0; x < MAX_PORTS; x++) {
1224
		struct dahdi_chan *chan = &wc->_chans[x];
1225
		wc->chans[x] = chan;
1226
		sprintf(chan->name, "WCTDM/%d/%d", wc->boardnum, x);
1227
		chan->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS
1228
			| DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM
1229
			| DAHDI_SIG_CLEAR;
1230
		chan->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS
1231
			| DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
1232
		chan->chanpos = x+1;
1233
		chan->pvt = wc;
1234
	}
1235
	wc->ddev->manufacturer = "Voicetronix";
1236
	wc->ddev->devicetype = wc->variety;
1237
	wc->span.deflaw = DAHDI_LAW_MULAW;
1238
	wc->span.chans = wc->chans;
1239
	wc->span.channels = MAX_PORTS;
1240
	wc->span.flags = DAHDI_FLAG_RBS;
1241
	wc->span.ops = &openpci_span_ops;
1242
1243
	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
1244
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
1245
		cardcrit(wc->boardnum, "Unable to register device with dahdi");
1246
		return RET_FAIL;
1247
	}
1248
	return RET_OK;
1249
}
1250
1251
static int get_port_type(struct openpci *wc, int port)
1252
{
1253
	int i, type;
1254
	unsigned long flags;
1255
1256
	spin_lock_irqsave(&wc->lock, flags);
1257
	outb(0x20, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1258
	outb(port, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1259
	HRXF_WAIT_LOCKED_RET(VT_PORT_EMPTY); type = inb(PIB(1));
1260
	spin_unlock_irqrestore(&wc->lock, flags);
1261
1262
	return type;
1263
}
1264
1265
static int check_ports(struct openpci *wc)
1266
{
1267
	int i = 0;
1268
1269
	wc->portcount = 0;
1270
	for (; i < MAX_PORTS; ++i ) {
1271
		wc->porttype[i] = get_port_type(wc, i);
1272
		dbginfo(wc->boardnum,"%d: %s", i, porttype(wc,i));
1273
1274
		switch( wc->porttype[i] ) {
1275
		    case VT_PORT_PROSLIC:
1276
			/* By default, don't send on hook */
1277
			if (reversepolarity)
1278
				wc->mod[i].fxs.idletxhookstate = 5;
1279
			else
1280
				wc->mod[i].fxs.idletxhookstate = 1;
1281
1282
		    case VT_PORT_VDAA:
1283
			++wc->portcount;
1284
		}
1285
	}
1286
	/* we 'succeed' if any ports were discovered. */
1287
	return wc->portcount ? RET_OK : RET_FAIL;
1288
}
1289
1290
static int configure_vdaa_country(struct openpci *wc, int port, char *name)
1291
{
1292
	unsigned char value;
1293
	int i;
1294
1295
	for (i = 0; i < sizeof(fxo_modes)/sizeof(struct fxo_mode); ++i) {
1296
		if (!strcmp(fxo_modes[i].name, name)) {
1297
			dbginfo(wc->boardnum, "%d: Setting country to %s",
1298
					port, name);
1299
			goto part2;
1300
		}
1301
	}
1302
	i = 3;
1303
	cardinfo(wc->boardnum, "Using default country %s", fxo_modes[i].name);
1304
1305
part2:
1306
	value  = (fxo_modes[i].ohs << 6);
1307
	value |= (fxo_modes[i].rz << 1);
1308
	value |= (fxo_modes[i].rt << 0);
1309
	if (!write_reg_fxo(wc, port, 16, value)) goto hell;
1310
1311
	/* DC Termination Control - Register 26 */
1312
	value  = (fxo_modes[i].dcv << 6);
1313
	value |= (fxo_modes[i].mini << 4);
1314
	value |= (fxo_modes[i].ilim << 1);
1315
	if (!write_reg_fxo(wc, port, 26, value)) goto hell;
1316
1317
	/* AC Termination Control - Register 30 */
1318
	value = (fxo_modes[i].acim << 0);
1319
	if (!write_reg_fxo(wc, port, 30, value)) goto hell;
1320
1321
	/* DAA Control 5 - Register 31 */
1322
	msleep(1);
1323
	if (!read_reg_fxo(wc, port, 31, &value)) goto hell;
1324
1325
	value = (value & 0xf7) | (fxo_modes[i].ohs2 << 3);
1326
	value = value | 0x02;
1327
	if (! write_reg_fxo(wc, port, 31, value)) goto hell;
1328
1329
	return RET_OK;
1330
1331
hell:
1332
	cardcrit(wc->boardnum, "port %d failed configure vdaa country", port);
1333
	return RET_FAIL;
1334
}
1335
1336
/* Do not call this from an interrupt context, it may sleep. */
1337
static void configure_vdaa_port(struct openpci *wc, int port)
1338
{
1339
	/* Set Country - default to Australia */
1340
	if (configure_vdaa_country(wc, port, country))
1341
		++wc->portcount;
1342
	else {
1343
		cardcrit(wc->boardnum, "FAILED to configure vdaa port %d.  Disabled.", port);
1344
		wc->porttype[port] = VT_PORT_EMPTY;
1345
	}
1346
}
1347
1348
static int configure_proslic_country(struct openpci *wc, int port,
1349
		const char *name)
1350
{
1351
	int i;
1352
1353
	for (i = 0; i < sizeof(ps_country_regs)/sizeof(struct ps_country_reg);
1354
			++i) {
1355
		if (!strcmp(ps_country_regs[i].country, name)) {
1356
			dbginfo(wc->boardnum, "%d: Setting country to %s",
1357
					port, name);
1358
			goto part2;
1359
		}
1360
	}
1361
	return -EINVAL;
1362
1363
part2:
1364
1365
	if (!write_reg_fxs(wc, port, 10, ps_country_regs[i].value)) {
1366
		cardcrit(wc->boardnum,"%d: failed to write PS_IMPEDANCE", port);
1367
		return -EIO;
1368
	}
1369
	return 0;
1370
}
1371
1372
/* Do not call this from an interrupt context, it may sleep. */
1373
static void configure_proslic_port(struct openpci *wc, int port)
1374
{
1375
	/* Set Country - default to Australia */
1376
	switch (configure_proslic_country(wc, port, country)) {
1377
		case 0:
1378
			break;
1379
1380
		case -EINVAL:
1381
			cardwarn(wc->boardnum, "%d: Country '%s' unknown, using default",
1382
					port, country);
1383
			if (configure_proslic_country(wc, port,
1384
						DEFAULT_COUNTRY) == 0 )
1385
				goto hell;
1386
1387
		default:
1388
			goto hell;
1389
	}
1390
1391
	++wc->portcount;
1392
	return;
1393
1394
hell:
1395
	cardcrit(wc->boardnum, "FAILED to configure proslic port %d.  Disabled.",
1396
			port);
1397
	wc->porttype[port] = VT_PORT_EMPTY;
1398
}
1399
1400
/* Do not call this from an interrupt context, it may (indirectly) sleep. */
1401
static int configure_ports(struct openpci *wc)
1402
{
1403
	unsigned long flags;
1404
	int i;
1405
1406
	wc->portcount = 0;
1407
	for (i = 0; i < MAX_PORTS; ++i) {
1408
		switch (wc->porttype[i]) {
1409
		    case VT_PORT_VDAA:    configure_vdaa_port(wc,i);    break;
1410
		    case VT_PORT_PROSLIC: configure_proslic_port(wc,i); break;
1411
		}
1412
	}
1413
1414
	spin_lock_irqsave(&wc->lock, flags);
1415
	outb(0x2c, PIB(1)); HTXF_WAIT_LOCKED();
1416
	outb(0xff, PIB(1)); HTXF_WAIT_LOCKED();
1417
	spin_unlock_irqrestore(&wc->lock, flags);
1418
1419
	/* otherwise we 'succeed' if any ports were configured successfully. */
1420
	return wc->portcount ? RET_OK : RET_FAIL;
1421
}
1422
1423
static int __get_arm_id(struct openpci *wc, int field, char *value)
1424
{
1425
	int i;
1426
	int x = 0;
1427
	int count = 0;
1428
1429
	outb(0x01, PIB(1));  HTXF_WAIT();
1430
	outb(field, PIB(1)); HTXF_WAIT();
1431
	HRXF_WAIT(); count = inb(PIB(1));
1432
	if (count > ID_DATA_MAXSIZE) {
1433
		cardcrit(wc->boardnum, "Too many bytes of id(%d) data %d/%d",
1434
					 field, count, ID_DATA_MAXSIZE);
1435
		return RET_FAIL;
1436
	}
1437
	//cardinfo(wc->boardnum, "get_arm_id(%d): byte count %d",field,count);
1438
	for (; x < count; ++x) {
1439
		HRXF_WAIT(); *value = inb(PIB(1));
1440
		//cardinfo(wc->boardnum, "get_arm_id(%d): byte %d => 0x%02x",field,x,tmp);
1441
		++value;
1442
	}
1443
	return RET_OK;
1444
}
1445
1446
static void enable_interrupts(struct openpci *wc)
1447
{
1448
	outb(0x3f, TJ_MASK0);
1449
	outb(0x02, TJ_MASK1);
1450
}
1451
1452
static void disable_interrupts(struct openpci *wc)
1453
{
1454
	outb(0x00, TJ_MASK0);
1455
	outb(0x00, TJ_MASK1);
1456
}
1457
1458
/* Do not call this from an interrupt context, it may sleep. */
1459
static int check_arm(struct openpci *wc)
1460
{
1461
	char model[ID_DATA_MAXSIZE + 1] = { 0 };
1462
	char date[ID_DATA_MAXSIZE + 1]  = { 0 };
1463
	unsigned long flags;
1464
	int i = 0;
1465
	int tmp = 0;
1466
1467
	spin_lock_irqsave(&wc->lock, flags);
1468
	while ((tmp != 0x88) && (++i < 100)) {
1469
		outb(0x88, PIB(0));
1470
		msleep(1);
1471
		tmp = inb(PIB(1));
1472
	}
1473
	if (i >= 1000)
1474
		goto limbo;
1475
	dbginfo(wc->boardnum, "Arm responded on attempt %d", i);
1476
1477
	/* Flush out the queue if we sent several pings before a response. */
1478
	if (i > 1)
1479
		__ping_arm(wc);
1480
1481
	if (!__get_arm_id(wc, 0, model))
1482
		goto hell;
1483
	sscanf(model, "OpenPCI8.%02d", &(wc->firmware));
1484
	cardinfo(wc->boardnum, "  model: %s", model);
1485
1486
	if (!__get_arm_id(wc, 1, date))
1487
		goto hell;
1488
	cardinfo(wc->boardnum, "  date: %s", date);
1489
1490
	if (!__get_arm_id(wc, 2, wc->serial))
1491
		goto hell;
1492
	cardinfo(wc->boardnum, "  serial: %s", wc->serial);
1493
1494
	spin_unlock_irqrestore(&wc->lock, flags);
1495
	return RET_OK;
1496
1497
hell:
1498
	spin_unlock_irqrestore(&wc->lock, flags);
1499
	cardwarn(wc->boardnum, "Found ARM processor, dumb firmware.");
1500
	return RET_OK;
1501
1502
limbo:
1503
	spin_unlock_irqrestore(&wc->lock, flags);
1504
	return RET_FAIL;
1505
}
1506
1507
static int arm_monitor(struct openpci *wc, int on)
1508
{
1509
	int i;
1510
	outb(on ? 0x06 : 0x07, PIB(1)); HTXF_WAIT();
1511
	return RET_OK;
1512
}
1513
1514
static int __devinit openpci_probe_board(struct pci_dev *pdev,
1515
		const struct pci_device_id *ent)
1516
{
1517
	struct openpci *wc;
1518
	int boardnum = 0;
1519
	int failret = -ENOMEM;
1520
	int tmp = 0;
1521
	int i;
1522
	unsigned long flags;
1523
1524
	if (ent->driver_data != (kernel_ulong_t)&wcopenpci) {
1525
		info("Probe of non-OpenPCI card, ignoring.");
1526
		return -EINVAL;
1527
	}
1528
	wc = kzalloc(sizeof(struct openpci), GFP_KERNEL);
1529
	if (!wc)
1530
		return -ENOMEM;
1531
1532
	mutex_lock(&cards_mutex);
1533
	for (; boardnum < MAX_CARDS && cards[boardnum]; ++boardnum)
1534
		;
1535
	if (boardnum >= MAX_CARDS) {
1536
		crit("Too many OpenPCI cards(%d), max is %d.",
1537
				boardnum, MAX_CARDS);
1538
		mutex_unlock(&cards_mutex);
1539
		goto hell;
1540
	}
1541
	cards[boardnum] = wc;
1542
	mutex_unlock(&cards_mutex);
1543
1544
	spin_lock_init(&wc->lock);
1545
	pci_set_drvdata(pdev, wc);
1546
1547
	wc->boardnum = boardnum;
1548
	wc->dev      = pdev;
1549
	wc->variety  = wcopenpci;
1550
1551
	cardinfo(boardnum, "Initialising card");
1552
	if (pci_enable_device(pdev)) {
1553
		failret = -EIO;
1554
		goto hell_2;
1555
	}
1556
	wc->ioaddr = pci_resource_start(pdev, 0);
1557
	if (!request_region(wc->ioaddr, 0xff, NAME)) {
1558
		cardcrit(boardnum, "Failed to lock IO region, another driver already using it");
1559
		failret = -EBUSY;
1560
		goto hell_2;
1561
	}
1562
1563
	spin_lock_irqsave(&wc->lock, flags);
1564
	outb(0xff, TJ_AUXD);		/* Set up TJ to access the ARM */
1565
	outb(0x78, TJ_AUXC);		/* Set up for Jtag */
1566
	outb(0x00, TJ_CNTL);		/* pull ERST low */
1567
	spin_unlock_irqrestore(&wc->lock, flags);
1568
	msleep(1);			/* Wait a bit */
1569
1570
	dbginfo(boardnum, "Starting ARM");
1571
	spin_lock_irqsave(&wc->lock, flags);
1572
	outb(0x01, TJ_CNTL);            /* pull ERST high again */
1573
	spin_unlock_irqrestore(&wc->lock, flags);
1574
	msleep(100);                    /* Give it all a chance to boot */
1575
1576
	if (!check_arm(wc)) {
1577
		cardcrit(boardnum, "Couldnt find ARM processor");
1578
		failret = -EIO;
1579
		goto hell_3;
1580
	}
1581
	if (wc->firmware < 11) {
1582
		cardcrit(boardnum,
1583
			 "Firmware version %d not supported by this driver",
1584
			 wc->firmware);
1585
		cardcrit(boardnum, " contact Voicetronix to have it updated");
1586
		failret = -ENODEV;
1587
		goto hell_3;
1588
	}
1589
	if (!check_ports(wc)) {
1590
		cardcrit(boardnum, "Couldnt find ports!");
1591
		failret = -EIO;
1592
		goto hell_3;
1593
	}
1594
1595
	wc->writechunk = pci_alloc_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1596
			&wc->writedma);
1597
	if (!wc->writechunk) {
1598
		cardcrit(boardnum, "Couldnt get DMA memory.");
1599
		goto hell_3;
1600
	}
1601
	wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE *
1602
		(MAX_PORTS * 2 / sizeof(int));
1603
	wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_PORTS*2);
1604
1605
	memset((void *)wc->writechunk, 0, VT_PCIDMA_BLOCKSIZE);
1606
1607
	spin_lock_irqsave(&wc->lock, flags);
1608
	outb(0xc1, TJ_SERCTL);
1609
	outb(0x0, TJ_FSCDELAY);
1610
1611
	outl(wc->writedma,                    TJ_DMAWS);
1612
	outl(wc->writedma + VT_PCIDMA_MIDDLE, TJ_DMAWI);
1613
	outl(wc->writedma + VT_PCIDMA_END,    TJ_DMAWE);
1614
	outl(wc->readdma,                     TJ_DMARS);
1615
	outl(wc->readdma + VT_PCIDMA_MIDDLE,  TJ_DMARI);
1616
	outl(wc->readdma + VT_PCIDMA_END,     TJ_DMARE);
1617
1618
	/* Clear interrupts */
1619
	outb(0xff, TJ_INTSTAT);
1620
	spin_unlock_irqrestore(&wc->lock, flags);
1621
1622
	if (!arm_monitor(wc, 1)) {
1623
		cardcrit(boardnum, "failed to start arm monitoring");
1624
		failret = -EIO;
1625
		goto hell_4;
1626
	}
1627
	msleep(1000);
1628
1629
	i = 0;
1630
	while (tmp != 0x88 && ++i < 1000) {
1631
		outb(0x88, PIB(0));
1632
		msleep(250);
1633
		tmp = inb(PIB(1));
1634
	}
1635
	if (i >= 1000) {
1636
		cardcrit(boardnum, "FAILED to initialise board");
1637
		goto hell_4;
1638
	}
1639
1640
	if (!check_ports(wc)) {
1641
		cardcrit(boardnum, "FAILED to initialise ports");
1642
		failret = -EIO;
1643
		goto hell_4;
1644
	}
1645
	if (!configure_ports(wc)) {
1646
		cardcrit(boardnum, "Failed to configure ports.");
1647
		failret = -EIO;
1648
		goto hell_4;
1649
	}
1650
	cardinfo(wc->boardnum, "have %d configured ports", wc->portcount);
1651
1652
	if (!span_initialize(wc)) {
1653
		cardcrit(boardnum, "Failed to register with dahdi driver");
1654
		failret = -EFAULT;
1655
		goto hell_4;
1656
	}
1657
1658
	/* Finalize signalling  */
1659
	for (i = 0; i < MAX_PORTS; ++i) {
1660
		if (wc->porttype[i] == VT_PORT_VDAA)
1661
			wc->chans[i]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS
1662
				| DAHDI_SIG_CLEAR | DAHDI_SIG_SF;
1663
		else if (wc->porttype[i] == VT_PORT_PROSLIC)
1664
			wc->chans[i]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS
1665
				| DAHDI_SIG_FXOGS | DAHDI_SIG_SF
1666
				| DAHDI_SIG_CLEAR | DAHDI_SIG_EM;
1667
		else if (wc->porttype[i])
1668
			cardcrit(wc->boardnum, "Port %d has unknown type (%d)",
1669
					i, wc->porttype[i]);
1670
	}
1671
1672
	/* Enable bus mastering */
1673
	pci_set_master(pdev);
1674
1675
	if (request_irq(pdev->irq, openpci_isr, IRQF_SHARED, NAME, wc)) {
1676
		cardcrit(boardnum, "Cant get IRQ!");
1677
		failret = -EIO;
1678
		goto hell_5;
1679
	}
1680
	cardinfo(boardnum, "Got IRQ %d", pdev->irq);
1681
1682
	enable_interrupts(wc);
1683
	start_dma(wc);
1684
1685
	cardinfo(boardnum, "Initialised card.");
1686
	return 0;
1687
1688
hell_5:
1689
	dahdi_unregister_device(wc->ddev);
1690
hell_4:
1691
	if (wc->writechunk)
1692
		pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1693
				    (void *)wc->writechunk, wc->writedma);
1694
hell_3:
1695
	outb(0x00, TJ_CNTL);
1696
	release_region(wc->ioaddr, 0xff);
1697
hell_2:
1698
	cards[boardnum] = NULL;
1699
hell:
1700
	kfree(wc->ddev->location);
1701
	dahdi_free_device(wc->ddev);
1702
	kfree(wc);
1703
	return failret;
1704
}
1705
1706
static void __devexit openpci_remove_board(struct pci_dev *pdev)
1707
{
1708
	struct openpci *wc = pci_get_drvdata(pdev);
1709
1710
	if (!wc)
1711
		return;
1712
1713
	arm_monitor(wc, 0);
1714
1715
	/* Stop DMA */
1716
	outb(0x00, TJ_OPER);
1717
	disable_interrupts(wc);
1718
1719
	//XXX Replace this usecount business...
1720
	//    and do this BEFORE we invalidate everything above...
1721
	//    check that we wont try to write to it in the meantime.
1722
	/* Release span, possibly delayed */
1723
	//XXX if (!wc->usecount) openpci_release(wc); else wc->dead = 1;
1724
1725
	dahdi_unregister_device(wc->ddev);
1726
	outb(0x00, TJ_CNTL);
1727
1728
	pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1729
			(void *)wc->writechunk, wc->writedma);
1730
	free_irq(pdev->irq, wc);
1731
1732
	release_region(wc->ioaddr, 0xff);
1733
1734
	mutex_lock(&cards_mutex);
1735
	cards[wc->boardnum] = NULL;
1736
	mutex_unlock(&cards_mutex);
1737
1738
	kfree(wc->ddev->location);
1739
	dahdi_free_device(wc->ddev);
1740
	kfree(wc);
1741
	cardinfo(wc->boardnum, "Removed OpenPCI card.");
1742
}
1743
1744
static DEFINE_PCI_DEVICE_TABLE(openpci_pci_tbl) = {
1745
	{ 0xe159, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t) &wcopenpci },
1746
	{ 0 }
1747
};
1748
1749
MODULE_DEVICE_TABLE(pci, openpci_pci_tbl);
1750
1751
static struct pci_driver openpci_driver = {
1752
	.name = NAME,
1753
	.probe = openpci_probe_board,
1754
	.remove = __devexit_p(openpci_remove_board),
1755
	.id_table = openpci_pci_tbl,
1756
};
1757
1758
static int __init openpci_init(void)
1759
{
1760
#ifdef __BIG_ENDIAN
1761
	warn("No big endian support (yet)");
1762
	return -ENODEV;
1763
#endif
1764
1765
	if (pci_register_driver(&openpci_driver))
1766
		return -ENODEV;
1767
1768
	info("Module loaded %s", debug ? "with debug enabled" : "");
1769
	return 0;
1770
}
1771
1772
static void __exit openpci_cleanup(void)
1773
{
1774
	pci_unregister_driver(&openpci_driver);
1775
	info("Module exit");
1776
}
1777
1778
module_init(openpci_init);
1779
module_exit(openpci_cleanup);
1780
1781
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
1782
MODULE_AUTHOR(DRIVER_AUTHOR);
1783
MODULE_VERSION(DAHDI_VERSION);
1784
MODULE_LICENSE("GPL");
(-)dahdi-linux-3.1.0.original/drivers/dahdi/wctc4xxp/base.c (-1 lines)
Lines 832-838 Link Here
832
	memset(dr->desc, 0, (sizeof(*d) + dr->padding) * dr->size);
832
	memset(dr->desc, 0, (sizeof(*d) + dr->padding) * dr->size);
833
	for (i = 0; i < dr->size; ++i) {
833
	for (i = 0; i < dr->size; ++i) {
834
		d = wctc4xxp_descriptor(dr, i);
834
		d = wctc4xxp_descriptor(dr, i);
835
		memset(d, 0, sizeof(*d));
836
		d->des1 = cpu_to_le32(des1);
835
		d->des1 = cpu_to_le32(des1);
837
	}
836
	}
838
837
(-)dahdi-linux-3.1.0.original/drivers/dahdi/zaphfc/Kbuild (+10 lines)
Line 0 Link Here
1
obj-m += zaphfc.o
2
3
EXTRA_CFLAGS := -I$(src)/.. -Wno-undef
4
5
zaphfc-objs := base.o fifo.o
6
7
$(obj)/base.o: $(src)/zaphfc.h
8
$(obj)/fifo.o: $(src)/fifo.h
9
10
(-)dahdi-linux-3.1.0.original/drivers/dahdi/zaphfc/base.c (+1720 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.c - Dahdi driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * Dahdi rewrite in hardhdlc mode
5
 * Jose A. Deniz <odicha@hotmail.com>
6
 *
7
 * Copyright (C) 2009, Jose A. Deniz
8
 * Copyright (C) 2006, headiisue GmbH; Jens Wilke
9
 * Copyright (C) 2004 Daniele Orlandi
10
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
11
 *
12
 * Jens Wilke <jw_vzaphfc@headissue.com>
13
 *
14
 * Original author of this code is
15
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
16
 *
17
 * Major rewrite of the driver made by
18
 * Klaus-Peter Junghanns <kpj@junghanns.net>
19
 *
20
 * This program is free software and may be modified and
21
 * distributed under the terms of the GNU Public License.
22
 *
23
 * Please read the README file for important infos.
24
 */
25
26
#include <linux/spinlock.h>
27
#include <linux/init.h>
28
#include <linux/pci.h>
29
#include <linux/interrupt.h>
30
#include <linux/module.h>
31
#include <linux/moduleparam.h>
32
#include <linux/version.h>
33
#include <linux/kernel.h>
34
#include <linux/delay.h>
35
#include <linux/sched.h>
36
#include <linux/proc_fs.h>
37
#include <linux/if_arp.h>
38
39
#include <dahdi/kernel.h>
40
41
#include "zaphfc.h"
42
#include "fifo.h"
43
44
#if CONFIG_PCI
45
46
#define DAHDI_B1 0
47
#define DAHDI_B2 1
48
#define DAHDI_D 2
49
50
#define D 0
51
#define B1 1
52
#define B2 2
53
54
/*
55
 * Mode Te for all
56
 */
57
static int modes;
58
static int nt_modes[hfc_MAX_BOARDS];
59
static int nt_modes_count;
60
static int force_l1_up;
61
static struct proc_dir_entry *hfc_proc_zaphfc_dir;
62
63
#ifdef DEBUG
64
int debug_level;
65
#endif
66
67
#ifndef FALSE
68
#define FALSE 0
69
#endif
70
#ifndef TRUE
71
#define TRUE (!FALSE)
72
#endif
73
74
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
75
#define	SET_PROC_DIRENTRY_OWNER(p)  do { (p)->owner = THIS_MODULE; } while (0);
76
#else
77
#define	SET_PROC_DIRENTRY_OWNER(p)	do { } while (0);
78
#endif
79
80
static struct pci_device_id hfc_pci_ids[] = {
81
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0,
82
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000,
84
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
85
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006,
86
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007,
88
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008,
90
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
91
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009,
92
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
93
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A,
94
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
95
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B,
96
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
97
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C,
98
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
99
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100,
100
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
101
	{PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1,
102
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
103
	{PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675,
104
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
105
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT,
106
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
107
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T,
108
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
109
	{PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575,
110
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
111
	{PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0,
112
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
113
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,
114
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
115
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,
116
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
117
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,
118
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,
120
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
121
	{PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_3069,
122
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
123
	{0,}
124
};
125
126
MODULE_DEVICE_TABLE(pci, hfc_pci_ids);
127
128
static int __devinit hfc_probe(struct pci_dev *dev
129
			, const struct pci_device_id *ent);
130
static void __devexit hfc_remove(struct pci_dev *dev);
131
132
static struct pci_driver hfc_driver = {
133
	.name     = hfc_DRIVER_NAME,
134
	.id_table = hfc_pci_ids,
135
	.probe    = hfc_probe,
136
	.remove   = hfc_remove,
137
};
138
139
/******************************************
140
 * HW routines
141
 ******************************************/
142
143
static void hfc_softreset(struct hfc_card *card)
144
{
145
	printk(KERN_INFO hfc_DRIVER_PREFIX
146
		"card %d: "
147
		"resetting\n",
148
		card->cardnum);
149
150
/*
151
 * Softreset procedure. Put it on, wait and off again
152
 */
153
	hfc_outb(card, hfc_CIRM, hfc_CIRM_RESET);
154
	udelay(6);
155
	hfc_outb(card, hfc_CIRM, 0);
156
157
	set_current_state(TASK_UNINTERRUPTIBLE);
158
	schedule_timeout((hfc_RESET_DELAY * HZ) / 1000);
159
}
160
161
static void hfc_resetCard(struct hfc_card *card)
162
{
163
	card->regs.m1 = 0;
164
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
165
166
	card->regs.m2 = 0;
167
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
168
169
	hfc_softreset(card);
170
171
	card->regs.trm = 0;
172
	hfc_outb(card, hfc_TRM, card->regs.trm);
173
174
	/*
175
	 * Select the non-capacitive line mode for the S/T interface
176
	 */
177
	card->regs.sctrl = hfc_SCTRL_NONE_CAP;
178
179
	if (card->nt_mode) {
180
		/*
181
		 * ST-Bit delay for NT-Mode
182
		 */
183
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_NT);
184
185
		card->regs.sctrl |= hfc_SCTRL_MODE_NT;
186
	} else {
187
		/*
188
		 * ST-Bit delay for TE-Mode
189
		 */
190
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_TE);
191
192
		card->regs.sctrl |= hfc_SCTRL_MODE_TE;
193
	}
194
195
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
196
197
	/*
198
	 * S/T Auto awake
199
	 */
200
	card->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
201
	hfc_outb(card, hfc_SCTRL_E, card->regs.sctrl_e);
202
203
	/*
204
	 * No B-channel enabled at startup
205
	 */
206
	card->regs.sctrl_r = 0;
207
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
208
209
	/*
210
	 * HFC Master Mode
211
	 */
212
	hfc_outb(card, hfc_MST_MODE, hfc_MST_MODE_MASTER);
213
214
	/*
215
	 * Connect internal blocks
216
	 */
217
	card->regs.connect =
218
		hfc_CONNECT_B1_HFC_from_ST |
219
		hfc_CONNECT_B1_ST_from_HFC |
220
		hfc_CONNECT_B1_GCI_from_HFC |
221
		hfc_CONNECT_B2_HFC_from_ST |
222
		hfc_CONNECT_B2_ST_from_HFC |
223
		hfc_CONNECT_B2_GCI_from_HFC;
224
	hfc_outb(card, hfc_CONNECT, card->regs.connect);
225
226
	/*
227
	 * All bchans are HDLC by default, not useful, actually
228
	 * since mode is set during open()
229
	 */
230
	hfc_outb(card, hfc_CTMT, 0);
231
232
	/*
233
	 * bit order
234
	 */
235
	hfc_outb(card, hfc_CIRM, 0);
236
237
	/*
238
	 * Enable D-rx FIFO. At least one FIFO must be enabled (by specs)
239
	 */
240
	card->regs.fifo_en = hfc_FIFOEN_DRX;
241
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
242
243
	card->late_irqs = 0;
244
245
	/*
246
	 * Clear already pending ints
247
	 */
248
	hfc_inb(card, hfc_INT_S1);
249
	hfc_inb(card, hfc_INT_S2);
250
251
	/*
252
	 * Enable IRQ output
253
	 */
254
	card->regs.m1 = hfc_INTS_DREC | hfc_INTS_L1STATE | hfc_INTS_TIMER;
255
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
256
257
	card->regs.m2 = hfc_M2_IRQ_ENABLE;
258
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
259
260
	/*
261
	 * Unlocks the states machine
262
	 */
263
	hfc_outb(card, hfc_STATES, 0);
264
265
	/*
266
	 * There's no need to explicitly activate L1 now.
267
	 * Activation is managed inside the interrupt routine.
268
	 */
269
}
270
271
static void hfc_update_fifo_state(struct hfc_card *card)
272
{
273
	/*
274
	 * I'm not sure if irqsave is needed but there could be a race
275
	 * condition since hfc_update_fifo_state could be called from
276
	 * both the IRQ handler and the *_(open|close) functions
277
	 */
278
279
	unsigned long flags;
280
	spin_lock_irqsave(&card->chans[B1].lock, flags);
281
	if (!card->fifo_suspended &&
282
		(card->chans[B1].status == open_framed ||
283
		card->chans[B1].status == open_voice)) {
284
285
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1RX)) {
286
			card->regs.fifo_en |= hfc_FIFOEN_B1RX;
287
			hfc_clear_fifo_rx(&card->chans[B1].rx);
288
		}
289
290
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1TX)) {
291
			card->regs.fifo_en |= hfc_FIFOEN_B1TX;
292
			hfc_clear_fifo_tx(&card->chans[B1].tx);
293
		}
294
	} else {
295
		if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
296
			card->regs.fifo_en &= ~hfc_FIFOEN_B1RX;
297
		if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
298
			card->regs.fifo_en &= ~hfc_FIFOEN_B1TX;
299
	}
300
	spin_unlock_irqrestore(&card->chans[B1].lock, flags);
301
302
	spin_lock_irqsave(&card->chans[B2].lock, flags);
303
	if (!card->fifo_suspended &&
304
		(card->chans[B2].status == open_framed ||
305
		card->chans[B2].status == open_voice ||
306
		card->chans[B2].status == sniff_aux)) {
307
308
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2RX)) {
309
			card->regs.fifo_en |= hfc_FIFOEN_B2RX;
310
			hfc_clear_fifo_rx(&card->chans[B2].rx);
311
		}
312
313
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2TX)) {
314
			card->regs.fifo_en |= hfc_FIFOEN_B2TX;
315
			hfc_clear_fifo_tx(&card->chans[B2].tx);
316
		}
317
	} else {
318
		if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
319
			card->regs.fifo_en &= ~hfc_FIFOEN_B2RX;
320
		if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
321
			card->regs.fifo_en &= ~hfc_FIFOEN_B2TX;
322
	}
323
	spin_unlock_irqrestore(&card->chans[B2].lock, flags);
324
325
	spin_lock_irqsave(&card->chans[D].lock, flags);
326
	if (!card->fifo_suspended &&
327
		card->chans[D].status == open_framed) {
328
329
		if (!(card->regs.fifo_en & hfc_FIFOEN_DTX)) {
330
			card->regs.fifo_en |= hfc_FIFOEN_DTX;
331
332
			card->chans[D].tx.ugly_framebuf_size = 0;
333
			card->chans[D].tx.ugly_framebuf_off = 0;
334
		}
335
	} else {
336
		if (card->regs.fifo_en & hfc_FIFOEN_DTX)
337
			card->regs.fifo_en &= ~hfc_FIFOEN_DTX;
338
	}
339
	spin_unlock_irqrestore(&card->chans[D].lock, flags);
340
341
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
342
}
343
344
static inline void hfc_suspend_fifo(struct hfc_card *card)
345
{
346
	card->fifo_suspended = TRUE;
347
348
	hfc_update_fifo_state(card);
349
350
	/*
351
	 * When L1 goes down D rx receives garbage; it is nice to
352
	 * clear it to avoid a CRC error on reactivation
353
	 * udelay is needed because the FIFO deactivation happens
354
	 * in 250us
355
	 */
356
	udelay(250);
357
	hfc_clear_fifo_rx(&card->chans[D].rx);
358
359
#ifdef DEBUG
360
	if (debug_level >= 3) {
361
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
362
			"card %d: "
363
			"FIFOs suspended\n",
364
			card->cardnum);
365
	}
366
#endif
367
}
368
369
static inline void hfc_resume_fifo(struct hfc_card *card)
370
{
371
	card->fifo_suspended = FALSE;
372
373
	hfc_update_fifo_state(card);
374
375
#ifdef DEBUG
376
	if (debug_level >= 3) {
377
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
378
			"card %d: "
379
			"FIFOs resumed\n",
380
			card->cardnum);
381
	}
382
#endif
383
}
384
385
static void hfc_check_l1_up(struct hfc_card *card)
386
{
387
	if ((!card->nt_mode && card->l1_state != 7)
388
		|| (card->nt_mode && card->l1_state != 3)) {
389
390
		hfc_outb(card, hfc_STATES, hfc_STATES_DO_ACTION |
391
			hfc_STATES_ACTIVATE|
392
				hfc_STATES_NT_G2_G3);
393
394
	/*
395
	 * 0 because this is quite verbose when an inferface is unconnected, jaw
396
	 */
397
#if 0
398
		if (debug_level >= 1) {
399
			printk(KERN_DEBUG hfc_DRIVER_PREFIX
400
				"card %d: "
401
				"L1 is down, bringing up L1.\n",
402
				card->cardnum);
403
		}
404
#endif
405
	}
406
}
407
408
409
/*******************
410
 * Dahdi interface *
411
 *******************/
412
413
static int hfc_zap_open(struct dahdi_chan *zaptel_chan)
414
{
415
	struct hfc_chan_duplex *chan = zaptel_chan->pvt;
416
	struct hfc_card *card = chan->card;
417
418
	spin_lock(&chan->lock);
419
420
	switch (chan->number) {
421
	case D:
422
		if (chan->status != free &&
423
			chan->status != open_framed) {
424
			spin_unlock(&chan->lock);
425
			return -EBUSY;
426
		}
427
		chan->status = open_framed;
428
	break;
429
430
	case B1:
431
	case B2:
432
		if (chan->status != free) {
433
			spin_unlock(&chan->lock);
434
			return -EBUSY;
435
		}
436
		chan->status = open_voice;
437
	break;
438
	}
439
440
	chan->open_by_zaptel = TRUE;
441
	try_module_get(THIS_MODULE);
442
	spin_unlock(&chan->lock);
443
444
	switch (chan->number) {
445
	case D:
446
	break;
447
448
	case B1:
449
		card->regs.m2 |= hfc_M2_PROC_TRANS;
450
		/*
451
		 * Enable transparent mode
452
		 */
453
		card->regs.ctmt |= hfc_CTMT_TRANSB1;
454
		/*
455
		* Reversed bit order
456
		*/
457
		card->regs.cirm |= hfc_CIRM_B1_REV;
458
		/*
459
		 * Enable transmission
460
		 */
461
		card->regs.sctrl |= hfc_SCTRL_B1_ENA;
462
		/*
463
		 * Enable reception
464
		 */
465
		card->regs.sctrl_r |= hfc_SCTRL_R_B1_ENA;
466
	break;
467
468
	case B2:
469
		card->regs.m2 |= hfc_M2_PROC_TRANS;
470
		card->regs.ctmt |= hfc_CTMT_TRANSB2;
471
		card->regs.cirm |= hfc_CIRM_B2_REV;
472
		card->regs.sctrl |= hfc_SCTRL_B2_ENA;
473
		card->regs.sctrl_r |= hfc_SCTRL_R_B2_ENA;
474
	break;
475
476
	}
477
478
	/*
479
	 * If not already enabled, enable processing transition (8KHz)
480
	 * interrupt
481
	 */
482
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
483
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
484
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
485
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
486
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
487
488
	hfc_update_fifo_state(card);
489
490
	printk(KERN_INFO hfc_DRIVER_PREFIX
491
		"card %d: "
492
		"chan %s opened as %s.\n",
493
		card->cardnum,
494
		chan->name,
495
		zaptel_chan->name);
496
497
	return 0;
498
}
499
500
static int hfc_zap_close(struct dahdi_chan *zaptel_chan)
501
{
502
	struct hfc_chan_duplex *chan = zaptel_chan->pvt;
503
	struct hfc_card *card = chan->card;
504
505
	if (!card) {
506
		printk(KERN_CRIT hfc_DRIVER_PREFIX
507
			"hfc_zap_close called with NULL card\n");
508
		return -1;
509
	}
510
511
	spin_lock(&chan->lock);
512
513
	if (chan->status == free) {
514
		spin_unlock(&chan->lock);
515
		return -EINVAL;
516
	}
517
518
	chan->status = free;
519
	chan->open_by_zaptel = FALSE;
520
521
	spin_unlock(&chan->lock);
522
523
	switch (chan->number) {
524
	case D:
525
	break;
526
527
	case B1:
528
		card->regs.ctmt &= ~hfc_CTMT_TRANSB1;
529
		card->regs.cirm &= ~hfc_CIRM_B1_REV;
530
		card->regs.sctrl &= ~hfc_SCTRL_B1_ENA;
531
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B1_ENA;
532
	break;
533
534
	case B2:
535
		card->regs.ctmt &= ~hfc_CTMT_TRANSB2;
536
		card->regs.cirm &= ~hfc_CIRM_B2_REV;
537
		card->regs.sctrl &= ~hfc_SCTRL_B2_ENA;
538
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B2_ENA;
539
	break;
540
	}
541
542
	if (card->chans[B1].status == free &&
543
		card->chans[B2].status == free)
544
		card->regs.m2 &= ~hfc_M2_PROC_TRANS;
545
546
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
547
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
548
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
549
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
550
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
551
552
	hfc_update_fifo_state(card);
553
554
	module_put(THIS_MODULE);
555
556
	printk(KERN_INFO hfc_DRIVER_PREFIX
557
		"card %d: "
558
		"chan %s closed as %s.\n",
559
		card->cardnum,
560
		chan->name,
561
		zaptel_chan->name);
562
563
	return 0;
564
}
565
566
static int hfc_zap_rbsbits(struct dahdi_chan *chan, int bits)
567
{
568
	return 0;
569
}
570
571
static int hfc_zap_ioctl(struct dahdi_chan *chan,
572
		unsigned int cmd, unsigned long data)
573
{
574
	switch (cmd) {
575
576
	default:
577
		return -ENOTTY;
578
	}
579
580
	return 0;
581
}
582
583
static void hfc_hdlc_hard_xmit(struct dahdi_chan *d_chan)
584
{
585
	struct hfc_chan_duplex *chan = d_chan->pvt;
586
	struct hfc_card *card = chan->card;
587
	struct dahdi_hfc *hfccard = card->ztdev;
588
589
	atomic_inc(&hfccard->hdlc_pending);
590
591
}
592
593
static int hfc_zap_startup(struct file *file, struct dahdi_span *span)
594
{
595
	struct dahdi_hfc *zthfc = dahdi_hfc_from_span(span);
596
	struct hfc_card *hfctmp = zthfc->card;
597
	int alreadyrunning;
598
599
	if (!hfctmp) {
600
		printk(KERN_INFO hfc_DRIVER_PREFIX
601
			"card %d: "
602
			"no card for span at startup!\n",
603
			hfctmp->cardnum);
604
	}
605
606
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
607
608
	if (!alreadyrunning)
609
		span->flags |= DAHDI_FLAG_RUNNING;
610
611
	return 0;
612
}
613
614
static int hfc_zap_shutdown(struct dahdi_span *span)
615
{
616
	return 0;
617
}
618
619
static int hfc_zap_maint(struct dahdi_span *span, int cmd)
620
{
621
	return 0;
622
}
623
624
static int hfc_zap_chanconfig(struct file *file, struct dahdi_chan *d_chan,
625
		int sigtype)
626
{
627
	struct hfc_chan_duplex *chan = d_chan->pvt;
628
	struct hfc_card *card = chan->card;
629
	struct dahdi_hfc *hfccard = card->ztdev;
630
631
	if ((sigtype == DAHDI_SIG_HARDHDLC) && (hfccard->sigchan == d_chan)) {
632
		hfccard->sigactive = 0;
633
		atomic_set(&hfccard->hdlc_pending, 0);
634
	}
635
636
	return 0;
637
}
638
639
static int hfc_zap_spanconfig(struct file *file, struct dahdi_span *span,
640
		struct dahdi_lineconfig *lc)
641
{
642
	span->lineconfig = lc->lineconfig;
643
644
	return 0;
645
}
646
647
static const struct dahdi_span_ops hfc_zap_span_ops = {
648
	.owner = THIS_MODULE,
649
	.chanconfig = hfc_zap_chanconfig,
650
	.spanconfig = hfc_zap_spanconfig,
651
	.startup = hfc_zap_startup,
652
	.shutdown = hfc_zap_shutdown,
653
	.maint = hfc_zap_maint,
654
	.rbsbits = hfc_zap_rbsbits,
655
	.open = hfc_zap_open,
656
	.close = hfc_zap_close,
657
	.ioctl = hfc_zap_ioctl,
658
	.hdlc_hard_xmit = hfc_hdlc_hard_xmit
659
};
660
661
static int hfc_zap_initialize(struct dahdi_hfc *hfccard)
662
{
663
	 struct hfc_card *hfctmp = hfccard->card;
664
	int i;
665
666
	hfccard->ddev = dahdi_create_device();
667
	hfccard->ddev->manufacturer = "Cologne Chips";
668
	hfccard->ddev->devicetype = "HFC-S PCI-A ISDN";
669
	hfccard->ddev->location = kasprintf(GFP_KERNEL,
670
			"PCI Bus %02d Slot %02d",
671
			hfctmp->pcidev->bus->number,
672
			PCI_SLOT(hfctmp->pcidev->devfn) + 1);
673
	memset(&hfccard->span, 0x0, sizeof(struct dahdi_span));
674
	sprintf(hfccard->span.name, "ZTHFC%d", hfctmp->cardnum + 1);
675
	sprintf(hfccard->span.desc,
676
			"HFC-S PCI A ISDN card %d [%s] ",
677
			hfctmp->cardnum,
678
			hfctmp->nt_mode ? "NT" : "TE");
679
	hfccard->span.spantype = hfctmp->nt_mode ? SPANTYPE_DIGITAL_BRI_NT : 
680
		SPANTYPE_DIGITAL_BRI_TE;
681
	hfccard->span.flags = 0;
682
	hfccard->span.ops = &hfc_zap_span_ops;
683
	hfccard->span.chans = hfccard->_chans;
684
	hfccard->span.channels = 3;
685
	for (i = 0; i < hfccard->span.channels; i++)
686
		hfccard->_chans[i] = &hfccard->chans[i];
687
	hfccard->span.deflaw = DAHDI_LAW_ALAW;
688
	hfccard->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS;
689
	hfccard->span.offset = 0;
690
691
	for (i = 0; i < hfccard->span.channels; i++) {
692
		memset(&hfccard->chans[i], 0x0, sizeof(struct dahdi_chan));
693
694
		sprintf(hfccard->chans[i].name,
695
				"ZTHFC%d/%d/%d",
696
				hfctmp->cardnum + 1, 0, i + 1);
697
698
		printk(KERN_INFO hfc_DRIVER_PREFIX
699
			"card %d: "
700
			"registered %s\n",
701
			hfctmp->cardnum,
702
			hfccard->chans[i].name);
703
704
		if (i == hfccard->span.channels - 1) {
705
			hfccard->chans[i].sigcap = DAHDI_SIG_HARDHDLC;
706
			hfccard->sigchan = &hfccard->chans[DAHDI_D];
707
			hfccard->sigactive = 0;
708
			atomic_set(&hfccard->hdlc_pending, 0);
709
		} else {
710
			hfccard->chans[i].sigcap =
711
				DAHDI_SIG_CLEAR | DAHDI_SIG_DACS;
712
		}
713
714
		hfccard->chans[i].chanpos = i + 1;
715
	}
716
717
	hfccard->chans[DAHDI_D].readchunk  =
718
		hfctmp->chans[D].rx.zaptel_buffer;
719
720
	hfccard->chans[DAHDI_D].writechunk =
721
		hfctmp->chans[D].tx.zaptel_buffer;
722
723
	hfccard->chans[DAHDI_D].pvt = &hfctmp->chans[D];
724
725
	hfccard->chans[DAHDI_B1].readchunk  =
726
		hfctmp->chans[B1].rx.zaptel_buffer;
727
728
	hfccard->chans[DAHDI_B1].writechunk =
729
		hfctmp->chans[B1].tx.zaptel_buffer;
730
731
	hfccard->chans[DAHDI_B1].pvt = &hfctmp->chans[B1];
732
733
	hfccard->chans[DAHDI_B2].readchunk  =
734
		hfctmp->chans[B2].rx.zaptel_buffer;
735
736
	hfccard->chans[DAHDI_B2].writechunk =
737
		hfctmp->chans[B2].tx.zaptel_buffer;
738
739
	hfccard->chans[DAHDI_B2].pvt = &hfctmp->chans[B2];
740
741
	list_add_tail(&hfccard->span.device_node, &hfccard->ddev->spans);
742
	if (dahdi_register_device(hfccard->ddev, &hfctmp->pcidev->dev)) {
743
		printk(KERN_ERR "unable to register DAHDI device %s!\n",
744
				hfccard->span.name);
745
		return -1; /* FIXME: release resources? */
746
	}
747
748
	return 0;
749
}
750
751
static void hfc_dahdi_free(struct dahdi_hfc *hfccard)
752
{
753
	kfree(hfccard->ddev->location);
754
	dahdi_free_device(hfccard->ddev);
755
}
756
757
static void hfc_zap_transmit(struct hfc_chan_simplex *chan)
758
{
759
	hfc_fifo_put(chan, chan->zaptel_buffer, DAHDI_CHUNKSIZE);
760
}
761
762
static void hfc_zap_receive(struct hfc_chan_simplex *chan)
763
{
764
	hfc_fifo_get(chan, chan->zaptel_buffer, DAHDI_CHUNKSIZE);
765
}
766
767
/******************************************
768
 * Interrupt Handler
769
 ******************************************/
770
771
static void hfc_handle_timer_interrupt(struct hfc_card *card);
772
static void hfc_handle_state_interrupt(struct hfc_card *card);
773
static void hfc_handle_processing_interrupt(struct hfc_card *card);
774
static void hfc_frame_arrived(struct hfc_chan_duplex *chan);
775
static void hfc_handle_voice(struct hfc_card *card);
776
777
#if (KERNEL_VERSION(2, 6, 24) < LINUX_VERSION_CODE)
778
static irqreturn_t hfc_interrupt(int irq, void *dev_id)
779
#else
780
static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
781
#endif
782
{
783
	struct hfc_card *card = dev_id;
784
	unsigned long flags;
785
	u8 status, s1, s2;
786
787
	if (!card) {
788
		printk(KERN_CRIT hfc_DRIVER_PREFIX
789
			"spurious interrupt (IRQ %d)\n",
790
			irq);
791
		return IRQ_NONE;
792
	}
793
794
	spin_lock_irqsave(&card->lock, flags);
795
	status = hfc_inb(card, hfc_STATUS);
796
	if (!(status & hfc_STATUS_ANYINT)) {
797
		/*
798
		 * maybe we are sharing the irq
799
		 */
800
		spin_unlock_irqrestore(&card->lock, flags);
801
		return IRQ_NONE;
802
	}
803
804
	/* We used to ingore the IRQ when the card was in processing
805
	 * state but apparently there is no restriction to access the
806
	 * card in such state:
807
	 *
808
	 * Joerg Ciesielski wrote:
809
	 * > There is no restriction for the IRQ handler to access
810
	 * > HFC-S PCI during processing phase. A IRQ latency of 375 us
811
	 * > is also no problem since there are no interrupt sources in
812
	 * > HFC-S PCI which must be handled very fast.
813
	 * > Due to its deep fifos the IRQ latency can be several ms with
814
	 * > out the risk of loosing data. Even the S/T state interrupts
815
	 * > must not be handled with a latency less than <5ms.
816
	 * >
817
	 * > The processing phase only indicates that HFC-S PCI is
818
	 * > processing the Fifos as PCI master so that data is read and
819
	 * > written in the 32k memory window. But there is no restriction
820
	 * > to access data in the memory window during this time.
821
	 *
822
	 * // if (status & hfc_STATUS_PCI_PROC) {
823
	 * // return IRQ_HANDLED;
824
	 * // }
825
	 */
826
827
	s1 = hfc_inb(card, hfc_INT_S1);
828
	s2 = hfc_inb(card, hfc_INT_S2);
829
830
	if (s1 != 0) {
831
		if (s1 & hfc_INTS_TIMER) {
832
			/*
833
			 * timer (bit 7)
834
			 */
835
			hfc_handle_timer_interrupt(card);
836
		}
837
838
		if (s1 & hfc_INTS_L1STATE) {
839
			/*
840
			 * state machine (bit 6)
841
			 */
842
			hfc_handle_state_interrupt(card);
843
		}
844
845
		if (s1 & hfc_INTS_DREC) {
846
			/*
847
			 * D chan RX (bit 5)
848
			 */
849
			hfc_frame_arrived(&card->chans[D]);
850
		}
851
852
		if (s1 & hfc_INTS_B1REC) {
853
			/*
854
			 * B1 chan RX (bit 3)
855
			 */
856
			hfc_frame_arrived(&card->chans[B1]);
857
		}
858
859
		if (s1 & hfc_INTS_B2REC) {
860
			/*
861
			 * B2 chan RX (bit 4)
862
			 */
863
			hfc_frame_arrived(&card->chans[B2]);
864
		}
865
866
		if (s1 & hfc_INTS_DTRANS) {
867
			/*
868
			 * D chan TX (bit 2)
869
			 */
870
		}
871
872
		if (s1 & hfc_INTS_B1TRANS) {
873
			/*
874
			 * B1 chan TX (bit 0)
875
			 */
876
		}
877
878
		if (s1 & hfc_INTS_B2TRANS) {
879
			/*
880
			 * B2 chan TX (bit 1)
881
			 */
882
		}
883
884
	}
885
886
	if (s2 != 0) {
887
		if (s2 & hfc_M2_PMESEL) {
888
			/*
889
			 * kaboom irq (bit 7)
890
			 *
891
			 * CologneChip says:
892
			 *
893
			 * the meaning of this fatal error bit is that HFC-S
894
			 * PCI as PCI master could not access the PCI bus
895
			 * within 125us to finish its data processing. If this
896
			 * happens only very seldom it does not cause big
897
			 * problems but of course some B-channel or D-channel
898
			 * data will be corrupted due to this event.
899
			 *
900
			 * Unfortunately this bit is only set once after the
901
			 * problem occurs and can only be reseted by a
902
			 * software reset. That means it is not easily
903
			 * possible to check how often this fatal error
904
			 * happens.
905
			 *
906
			 */
907
908
			if (!card->sync_loss_reported) {
909
				printk(KERN_CRIT hfc_DRIVER_PREFIX
910
					"card %d: "
911
					"sync lost, pci performance too low!\n",
912
					card->cardnum);
913
914
				card->sync_loss_reported = TRUE;
915
			}
916
		}
917
918
		if (s2 & hfc_M2_GCI_MON_REC) {
919
			/*
920
			 * RxR monitor channel (bit 2)
921
			 */
922
		}
923
924
		if (s2 & hfc_M2_GCI_I_CHG) {
925
			/*
926
			 * GCI I-change  (bit 1)
927
			 */
928
		}
929
930
		if (s2 & hfc_M2_PROC_TRANS) {
931
			/*
932
			 * processing/non-processing transition  (bit 0)
933
			 */
934
			hfc_handle_processing_interrupt(card);
935
		}
936
937
	}
938
939
	spin_unlock_irqrestore(&card->lock, flags);
940
941
	return IRQ_HANDLED;
942
}
943
944
static void hfc_handle_timer_interrupt(struct hfc_card *card)
945
{
946
	if (card->ignore_first_timer_interrupt) {
947
		card->ignore_first_timer_interrupt = FALSE;
948
		return;
949
	}
950
951
	if ((card->nt_mode && card->l1_state == 3) ||
952
		(!card->nt_mode && card->l1_state == 7)) {
953
954
		card->regs.ctmt &= ~hfc_CTMT_TIMER_MASK;
955
		hfc_outb(card, hfc_CTMT, card->regs.ctmt);
956
957
		hfc_resume_fifo(card);
958
	}
959
}
960
961
static void hfc_handle_state_interrupt(struct hfc_card *card)
962
{
963
	u8 new_state = hfc_inb(card, hfc_STATES)  & hfc_STATES_STATE_MASK;
964
965
#ifdef DEBUG
966
	if (debug_level >= 1) {
967
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
968
			"card %d: "
969
			"layer 1 state = %c%d\n",
970
			card->cardnum,
971
			card->nt_mode ? 'G' : 'F',
972
			new_state);
973
	}
974
#endif
975
976
	if (card->nt_mode) {
977
		/*
978
		 * NT mode
979
		 */
980
981
		if (new_state == 3) {
982
			/*
983
			 * fix to G3 state (see specs)
984
			 */
985
			hfc_outb(card, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
986
		}
987
988
		if (new_state == 3 && card->l1_state != 3)
989
			hfc_resume_fifo(card);
990
991
		if (new_state != 3 && card->l1_state == 3)
992
			hfc_suspend_fifo(card);
993
994
	} else {
995
		if (new_state == 3) {
996
			/*
997
			 * Keep L1 up... zaptel & libpri expects
998
			 * a always up L1...
999
			 * Enable only  when using an unpatched libpri
1000
			 */
1001
1002
			if (force_l1_up) {
1003
				hfc_outb(card, hfc_STATES,
1004
					hfc_STATES_DO_ACTION |
1005
					hfc_STATES_ACTIVATE|
1006
					hfc_STATES_NT_G2_G3);
1007
			}
1008
		}
1009
1010
		if (new_state == 7 && card->l1_state != 7) {
1011
			/*
1012
			 * TE is now active, schedule FIFO activation after
1013
			 * some time, otherwise the first frames are lost
1014
			 */
1015
1016
			card->regs.ctmt |= hfc_CTMT_TIMER_50 |
1017
				hfc_CTMT_TIMER_CLEAR;
1018
			hfc_outb(card, hfc_CTMT, card->regs.ctmt);
1019
1020
			/*
1021
			 * Activating the timer firest an
1022
			 * interrupt immediately, we
1023
			 * obviously need to ignore it
1024
			 */
1025
			card->ignore_first_timer_interrupt = TRUE;
1026
		}
1027
1028
		if (new_state != 7 && card->l1_state == 7) {
1029
			/*
1030
			 * TE has become inactive, disable FIFO
1031
			 */
1032
			hfc_suspend_fifo(card);
1033
		}
1034
	}
1035
1036
	card->l1_state = new_state;
1037
}
1038
1039
static void hfc_handle_processing_interrupt(struct hfc_card *card)
1040
{
1041
	int available_bytes = 0;
1042
1043
	/*
1044
	 * Synchronize with the first enabled channel
1045
	 */
1046
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1047
		available_bytes = hfc_fifo_used_rx(&card->chans[B1].rx);
1048
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1049
		available_bytes = hfc_fifo_used_rx(&card->chans[B2].rx);
1050
	else
1051
		available_bytes = -1;
1052
1053
	if ((available_bytes == -1 && card->ticks == 8) ||
1054
		available_bytes >= DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD) {
1055
		card->ticks = 0;
1056
1057
		if (available_bytes > DAHDI_CHUNKSIZE*2 + hfc_RX_FIFO_PRELOAD) {
1058
			card->late_irqs++;
1059
			/*
1060
			 * we are out of sync, clear fifos, jaw
1061
			 */
1062
			hfc_clear_fifo_rx(&card->chans[B1].rx);
1063
			hfc_clear_fifo_tx(&card->chans[B1].tx);
1064
			hfc_clear_fifo_rx(&card->chans[B2].rx);
1065
			hfc_clear_fifo_tx(&card->chans[B2].tx);
1066
1067
#ifdef DEBUG
1068
			if (debug_level >= 4) {
1069
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1070
					"card %d: "
1071
					"late IRQ, %d bytes late\n",
1072
					card->cardnum,
1073
					available_bytes -
1074
						(DAHDI_CHUNKSIZE +
1075
						 hfc_RX_FIFO_PRELOAD));
1076
			}
1077
#endif
1078
		} else {
1079
			hfc_handle_voice(card);
1080
		}
1081
	}
1082
1083
	card->ticks++;
1084
}
1085
1086
1087
static void hfc_handle_voice(struct hfc_card *card)
1088
{
1089
	struct dahdi_hfc *hfccard = card->ztdev;
1090
	int frame_left, res;
1091
	unsigned char buf[hfc_HDLC_BUF_LEN];
1092
	unsigned int size = sizeof(buf) / sizeof(buf[0]);
1093
1094
1095
	if (card->chans[B1].status != open_voice &&
1096
		card->chans[B2].status != open_voice)
1097
		return;
1098
1099
	dahdi_transmit(&hfccard->span);
1100
1101
	if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
1102
		hfc_zap_transmit(&card->chans[B1].tx);
1103
	if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
1104
		hfc_zap_transmit(&card->chans[B2].tx);
1105
1106
	/*
1107
	 * dahdi hdlc frame tx
1108
	 */
1109
1110
	if (atomic_read(&hfccard->hdlc_pending)) {
1111
		hfc_check_l1_up(card);
1112
		res = dahdi_hdlc_getbuf(hfccard->sigchan, buf, &size);
1113
			if (size > 0) {
1114
				hfccard->sigactive = 1;
1115
				memcpy(card->chans[D].tx.ugly_framebuf +
1116
				card->chans[D].tx.ugly_framebuf_size,
1117
				buf, size);
1118
				card->chans[D].tx.ugly_framebuf_size += size;
1119
			if (res != 0) {
1120
					hfc_fifo_put_frame(&card->chans[D].tx,
1121
					card->chans[D].tx.ugly_framebuf,
1122
					card->chans[D].tx.ugly_framebuf_size);
1123
					++hfccard->frames_out;
1124
					hfccard->sigactive = 0;
1125
					card->chans[D].tx.ugly_framebuf_size
1126
						= 0;
1127
					atomic_dec(&hfccard->hdlc_pending);
1128
				}
1129
			}
1130
	}
1131
	/*
1132
	 * dahdi hdlc frame tx done
1133
	 */
1134
1135
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1136
		hfc_zap_receive(&card->chans[B1].rx);
1137
	else
1138
		memset(&card->chans[B1].rx.zaptel_buffer, 0x7f,
1139
			sizeof(card->chans[B1].rx.zaptel_buffer));
1140
1141
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1142
		hfc_zap_receive(&card->chans[B2].rx);
1143
	else
1144
		memset(&card->chans[B2].rx.zaptel_buffer, 0x7f,
1145
			sizeof(card->chans[B1].rx.zaptel_buffer));
1146
1147
	/*
1148
	 * Echo cancellation
1149
	 */
1150
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B1],
1151
			card->chans[B1].rx.zaptel_buffer,
1152
			card->chans[B1].tx.zaptel_buffer);
1153
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B2],
1154
			card->chans[B2].rx.zaptel_buffer,
1155
			card->chans[B2].tx.zaptel_buffer);
1156
1157
	/*
1158
	 * dahdi hdlc frame rx
1159
	 */
1160
	if (hfc_fifo_has_frames(&card->chans[D].rx))
1161
		hfc_frame_arrived(&card->chans[D]);
1162
1163
	if (card->chans[D].rx.ugly_framebuf_size) {
1164
		frame_left = card->chans[D].rx.ugly_framebuf_size -
1165
			card->chans[D].rx.ugly_framebuf_off ;
1166
		if (frame_left > hfc_HDLC_BUF_LEN) {
1167
			dahdi_hdlc_putbuf(hfccard->sigchan,
1168
					card->chans[D].rx.ugly_framebuf +
1169
					card->chans[D].rx.ugly_framebuf_off,
1170
					hfc_HDLC_BUF_LEN);
1171
			card->chans[D].rx.ugly_framebuf_off +=
1172
				hfc_HDLC_BUF_LEN;
1173
		} else {
1174
			dahdi_hdlc_putbuf(hfccard->sigchan,
1175
					card->chans[D].rx.ugly_framebuf +
1176
					card->chans[D].rx.ugly_framebuf_off,
1177
					frame_left);
1178
			dahdi_hdlc_finish(hfccard->sigchan);
1179
			card->chans[D].rx.ugly_framebuf_size = 0;
1180
			card->chans[D].rx.ugly_framebuf_off = 0;
1181
		}
1182
	}
1183
	/*
1184
	 * dahdi hdlc frame rx done
1185
	 */
1186
1187
	if (hfccard->span.flags & DAHDI_FLAG_RUNNING)
1188
		dahdi_receive(&hfccard->span);
1189
1190
}
1191
1192
static void hfc_frame_arrived(struct hfc_chan_duplex *chan)
1193
{
1194
	struct hfc_card *card = chan->card;
1195
	int antiloop = 16;
1196
	struct sk_buff *skb;
1197
1198
	while (hfc_fifo_has_frames(&chan->rx) && --antiloop) {
1199
		int frame_size = hfc_fifo_get_frame_size(&chan->rx);
1200
1201
		if (frame_size < 3) {
1202
#ifdef DEBUG
1203
			if (debug_level >= 2)
1204
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1205
					"card %d: "
1206
					"chan %s: "
1207
					"invalid frame received, "
1208
					"just %d bytes\n",
1209
					card->cardnum,
1210
					chan->name,
1211
					frame_size);
1212
#endif
1213
1214
			hfc_fifo_drop_frame(&chan->rx);
1215
1216
1217
			continue;
1218
		} else if (frame_size == 3) {
1219
#ifdef DEBUG
1220
			if (debug_level >= 2)
1221
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1222
					"card %d: "
1223
					"chan %s: "
1224
					"empty frame received\n",
1225
					card->cardnum,
1226
					chan->name);
1227
#endif
1228
1229
			hfc_fifo_drop_frame(&chan->rx);
1230
1231
1232
			continue;
1233
		}
1234
1235
		if (chan->open_by_zaptel &&
1236
			card->chans[D].rx.ugly_framebuf_size) {
1237
1238
				/*
1239
				 * We have to wait for Dahdi to transmit the
1240
				 * frame... wait for next time
1241
				 */
1242
1243
				 break;
1244
		}
1245
1246
		skb = dev_alloc_skb(frame_size - 3);
1247
1248
		if (!skb) {
1249
			printk(KERN_ERR hfc_DRIVER_PREFIX
1250
				"card %d: "
1251
				"chan %s: "
1252
				"cannot allocate skb: frame dropped\n",
1253
				card->cardnum,
1254
				chan->name);
1255
1256
			hfc_fifo_drop_frame(&chan->rx);
1257
1258
1259
			continue;
1260
		}
1261
1262
1263
		/*
1264
		* HFC does the checksum
1265
		*/
1266
#ifndef CHECKSUM_HW
1267
		skb->ip_summed = CHECKSUM_COMPLETE;
1268
#else
1269
		skb->ip_summed = CHECKSUM_HW;
1270
#endif
1271
1272
		if (chan->open_by_zaptel) {
1273
			card->chans[D].rx.ugly_framebuf_size = frame_size - 1;
1274
1275
			if (hfc_fifo_get_frame(&card->chans[D].rx,
1276
				card->chans[D].rx.ugly_framebuf,
1277
				frame_size - 1) == -1) {
1278
				dev_kfree_skb(skb);
1279
				continue;
1280
			}
1281
1282
			memcpy(skb_put(skb, frame_size - 3),
1283
				card->chans[D].rx.ugly_framebuf,
1284
				frame_size - 3);
1285
		} else {
1286
			if (hfc_fifo_get_frame(&chan->rx,
1287
				skb_put(skb, frame_size - 3),
1288
				frame_size - 3) == -1) {
1289
				dev_kfree_skb(skb);
1290
				continue;
1291
			}
1292
		}
1293
	}
1294
1295
	if (!antiloop)
1296
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1297
			"card %d: "
1298
			"Infinite loop detected\n",
1299
			card->cardnum);
1300
}
1301
1302
/******************************************
1303
 * Module initialization and cleanup
1304
 ******************************************/
1305
1306
static int __devinit hfc_probe(struct pci_dev *pci_dev,
1307
	const struct pci_device_id *ent)
1308
{
1309
	static int cardnum;
1310
	int err;
1311
	int i;
1312
1313
	struct hfc_card *card = NULL;
1314
	struct dahdi_hfc *zthfc = NULL;
1315
	card = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
1316
	if (!card) {
1317
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1318
			"unable to kmalloc!\n");
1319
		err = -ENOMEM;
1320
		goto err_alloc_hfccard;
1321
	}
1322
1323
	memset(card, 0x00, sizeof(struct hfc_card));
1324
	card->cardnum = cardnum;
1325
	card->pcidev = pci_dev;
1326
	spin_lock_init(&card->lock);
1327
1328
	pci_set_drvdata(pci_dev, card);
1329
1330
	err = pci_enable_device(pci_dev);
1331
	if (err)
1332
		goto err_pci_enable_device;
1333
1334
	err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT);
1335
	if (err) {
1336
		printk(KERN_ERR hfc_DRIVER_PREFIX
1337
			"card %d: "
1338
			"No suitable DMA configuration available.\n",
1339
			card->cardnum);
1340
		goto err_pci_set_dma_mask;
1341
	}
1342
1343
	pci_write_config_word(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
1344
	err = pci_request_regions(pci_dev, hfc_DRIVER_NAME);
1345
	if (err) {
1346
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1347
			"card %d: "
1348
			"cannot request I/O memory region\n",
1349
			card->cardnum);
1350
		goto err_pci_request_regions;
1351
	}
1352
1353
	pci_set_master(pci_dev);
1354
1355
	if (!pci_dev->irq) {
1356
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1357
			"card %d: "
1358
			"no irq!\n",
1359
			card->cardnum);
1360
		err = -ENODEV;
1361
		goto err_noirq;
1362
	}
1363
1364
	card->io_bus_mem = pci_resource_start(pci_dev, 1);
1365
	if (!card->io_bus_mem) {
1366
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1367
			"card %d: "
1368
			"no iomem!\n",
1369
			card->cardnum);
1370
		err = -ENODEV;
1371
		goto err_noiobase;
1372
	}
1373
1374
	card->io_mem = ioremap(card->io_bus_mem, hfc_PCI_MEM_SIZE);
1375
	if (!(card->io_mem)) {
1376
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1377
			"card %d: "
1378
			"cannot ioremap I/O memory\n",
1379
			card->cardnum);
1380
		err = -ENODEV;
1381
		goto err_ioremap;
1382
	}
1383
1384
	/*
1385
	 * pci_alloc_consistent guarantees alignment
1386
	 * (Documentation/DMA-mapping.txt)
1387
	 */
1388
	card->fifo_mem = pci_alloc_consistent(pci_dev,
1389
			hfc_FIFO_SIZE, &card->fifo_bus_mem);
1390
	if (!card->fifo_mem) {
1391
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1392
			"card %d: "
1393
			"unable to allocate FIFO DMA memory!\n",
1394
			card->cardnum);
1395
		err = -ENOMEM;
1396
		goto err_alloc_fifo;
1397
	}
1398
1399
	memset(card->fifo_mem, 0x00, hfc_FIFO_SIZE);
1400
1401
	card->fifos = card->fifo_mem;
1402
1403
	pci_write_config_dword(card->pcidev, hfc_PCI_MWBA, card->fifo_bus_mem);
1404
1405
	err = request_irq(card->pcidev->irq, &hfc_interrupt,
1406
1407
#if (KERNEL_VERSION(2, 6, 23) < LINUX_VERSION_CODE)
1408
		IRQF_SHARED, hfc_DRIVER_NAME, card);
1409
#else
1410
		SA_SHIRQ, hfc_DRIVER_NAME, card);
1411
#endif
1412
1413
	if (err) {
1414
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1415
			"card %d: "
1416
			"unable to register irq\n",
1417
			card->cardnum);
1418
		goto err_request_irq;
1419
	}
1420
1421
	card->nt_mode = FALSE;
1422
1423
	if (modes & (1 << card->cardnum))
1424
		card->nt_mode = TRUE;
1425
1426
	for (i = 0; i < nt_modes_count; i++) {
1427
		if (nt_modes[i] == card->cardnum)
1428
			card->nt_mode = TRUE;
1429
	}
1430
1431
	/*
1432
	 * D Channel
1433
	 */
1434
	card->chans[D].card = card;
1435
	card->chans[D].name = "D";
1436
	card->chans[D].status = free;
1437
	card->chans[D].number = D;
1438
	spin_lock_init(&card->chans[D].lock);
1439
1440
	card->chans[D].rx.chan      = &card->chans[D];
1441
	card->chans[D].rx.fifo_base = card->fifos + 0x4000;
1442
	card->chans[D].rx.z_base    = card->fifos + 0x4000;
1443
	card->chans[D].rx.z1_base   = card->fifos + 0x6080;
1444
	card->chans[D].rx.z2_base   = card->fifos + 0x6082;
1445
	card->chans[D].rx.z_min     = 0x0000;
1446
	card->chans[D].rx.z_max     = 0x01FF;
1447
	card->chans[D].rx.f_min     = 0x10;
1448
	card->chans[D].rx.f_max     = 0x1F;
1449
	card->chans[D].rx.f1        = card->fifos + 0x60a0;
1450
	card->chans[D].rx.f2        = card->fifos + 0x60a1;
1451
	card->chans[D].rx.fifo_size = card->chans[D].rx.z_max
1452
		- card->chans[D].rx.z_min + 1;
1453
	card->chans[D].rx.f_num     = card->chans[D].rx.f_max
1454
		- card->chans[D].rx.f_min + 1;
1455
1456
	card->chans[D].tx.chan      = &card->chans[D];
1457
	card->chans[D].tx.fifo_base = card->fifos + 0x0000;
1458
	card->chans[D].tx.z_base    = card->fifos + 0x0000;
1459
	card->chans[D].tx.z1_base   = card->fifos + 0x2080;
1460
	card->chans[D].tx.z2_base   = card->fifos + 0x2082;
1461
	card->chans[D].tx.z_min     = 0x0000;
1462
	card->chans[D].tx.z_max     = 0x01FF;
1463
	card->chans[D].tx.f_min     = 0x10;
1464
	card->chans[D].tx.f_max     = 0x1F;
1465
	card->chans[D].tx.f1        = card->fifos + 0x20a0;
1466
	card->chans[D].tx.f2        = card->fifos + 0x20a1;
1467
	card->chans[D].tx.fifo_size = card->chans[D].tx.z_max -
1468
		card->chans[D].tx.z_min + 1;
1469
	card->chans[D].tx.f_num     = card->chans[D].tx.f_max -
1470
		card->chans[D].tx.f_min + 1;
1471
1472
	/*
1473
	 * B1 Channel
1474
	 */
1475
	card->chans[B1].card = card;
1476
	card->chans[B1].name = "B1";
1477
	card->chans[B1].status = free;
1478
	card->chans[B1].number = B1;
1479
	card->chans[B1].protocol = 0;
1480
	spin_lock_init(&card->chans[B1].lock);
1481
1482
	card->chans[B1].rx.chan      = &card->chans[B1];
1483
	card->chans[B1].rx.fifo_base = card->fifos + 0x4200;
1484
	card->chans[B1].rx.z_base    = card->fifos + 0x4000;
1485
	card->chans[B1].rx.z1_base   = card->fifos + 0x6000;
1486
	card->chans[B1].rx.z2_base   = card->fifos + 0x6002;
1487
	card->chans[B1].rx.z_min     = 0x0200;
1488
	card->chans[B1].rx.z_max     = 0x1FFF;
1489
	card->chans[B1].rx.f_min     = 0x00;
1490
	card->chans[B1].rx.f_max     = 0x1F;
1491
	card->chans[B1].rx.f1        = card->fifos + 0x6080;
1492
	card->chans[B1].rx.f2        = card->fifos + 0x6081;
1493
	card->chans[B1].rx.fifo_size = card->chans[B1].rx.z_max -
1494
		card->chans[B1].rx.z_min + 1;
1495
	card->chans[B1].rx.f_num     = card->chans[B1].rx.f_max -
1496
		card->chans[B1].rx.f_min + 1;
1497
1498
	card->chans[B1].tx.chan      = &card->chans[B1];
1499
	card->chans[B1].tx.fifo_base = card->fifos + 0x0200;
1500
	card->chans[B1].tx.z_base    = card->fifos + 0x0000;
1501
	card->chans[B1].tx.z1_base   = card->fifos + 0x2000;
1502
	card->chans[B1].tx.z2_base   = card->fifos + 0x2002;
1503
	card->chans[B1].tx.z_min     = 0x0200;
1504
	card->chans[B1].tx.z_max     = 0x1FFF;
1505
	card->chans[B1].tx.f_min     = 0x00;
1506
	card->chans[B1].tx.f_max     = 0x1F;
1507
	card->chans[B1].tx.f1        = card->fifos + 0x2080;
1508
	card->chans[B1].tx.f2        = card->fifos + 0x2081;
1509
	card->chans[B1].tx.fifo_size = card->chans[B1].tx.z_max -
1510
		card->chans[B1].tx.z_min + 1;
1511
	card->chans[B1].tx.f_num     = card->chans[B1].tx.f_max -
1512
		card->chans[B1].tx.f_min + 1;
1513
1514
	/*
1515
	 * B2 Channel
1516
	 */
1517
	card->chans[B2].card = card;
1518
	card->chans[B2].name = "B2";
1519
	card->chans[B2].status = free;
1520
	card->chans[B2].number = B2;
1521
	card->chans[B2].protocol = 0;
1522
	spin_lock_init(&card->chans[B2].lock);
1523
1524
	card->chans[B2].rx.chan      = &card->chans[B2];
1525
	card->chans[B2].rx.fifo_base = card->fifos + 0x6200,
1526
	card->chans[B2].rx.z_base    = card->fifos + 0x6000;
1527
	card->chans[B2].rx.z1_base   = card->fifos + 0x6100;
1528
	card->chans[B2].rx.z2_base   = card->fifos + 0x6102;
1529
	card->chans[B2].rx.z_min     = 0x0200;
1530
	card->chans[B2].rx.z_max     = 0x1FFF;
1531
	card->chans[B2].rx.f_min     = 0x00;
1532
	card->chans[B2].rx.f_max     = 0x1F;
1533
	card->chans[B2].rx.f1        = card->fifos + 0x6180;
1534
	card->chans[B2].rx.f2        = card->fifos + 0x6181;
1535
	card->chans[B2].rx.fifo_size = card->chans[B2].rx.z_max -
1536
		card->chans[B2].rx.z_min + 1;
1537
	card->chans[B2].rx.f_num     = card->chans[B2].rx.f_max -
1538
		card->chans[B2].rx.f_min + 1;
1539
1540
	card->chans[B2].tx.chan      = &card->chans[B2];
1541
	card->chans[B2].tx.fifo_base = card->fifos + 0x2200;
1542
	card->chans[B2].tx.z_base    = card->fifos + 0x2000;
1543
	card->chans[B2].tx.z1_base   = card->fifos + 0x2100;
1544
	card->chans[B2].tx.z2_base   = card->fifos + 0x2102;
1545
	card->chans[B2].tx.z_min     = 0x0200;
1546
	card->chans[B2].tx.z_max     = 0x1FFF;
1547
	card->chans[B2].tx.f_min     = 0x00;
1548
	card->chans[B2].tx.f_max     = 0x1F;
1549
	card->chans[B2].tx.f1        = card->fifos + 0x2180;
1550
	card->chans[B2].tx.f2        = card->fifos + 0x2181;
1551
	card->chans[B2].tx.fifo_size = card->chans[B2].tx.z_max -
1552
		card->chans[B2].tx.z_min + 1;
1553
	card->chans[B2].tx.f_num     = card->chans[B2].tx.f_max -
1554
		card->chans[B2].tx.f_min + 1;
1555
1556
	/*
1557
	 * All done
1558
	 */
1559
1560
	zthfc = kmalloc(sizeof(struct dahdi_hfc), GFP_KERNEL);
1561
	if (!zthfc) {
1562
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1563
			"unable to kmalloc!\n");
1564
		goto err_request_irq;
1565
	}
1566
	memset(zthfc, 0x0, sizeof(struct dahdi_hfc));
1567
1568
	zthfc->card = card;
1569
	hfc_zap_initialize(zthfc);
1570
	card->ztdev = zthfc;
1571
1572
	snprintf(card->proc_dir_name,
1573
			sizeof(card->proc_dir_name),
1574
			"%d", card->cardnum);
1575
	card->proc_dir = proc_mkdir(card->proc_dir_name, hfc_proc_zaphfc_dir);
1576
	SET_PROC_DIRENTRY_OWNER(card->proc_dir);
1577
1578
	hfc_resetCard(card);
1579
1580
	printk(KERN_INFO hfc_DRIVER_PREFIX
1581
		"card %d configured for %s mode at mem %#lx (0x%p) IRQ %u\n",
1582
		card->cardnum,
1583
		card->nt_mode ? "NT" : "TE",
1584
		card->io_bus_mem,
1585
		card->io_mem,
1586
		card->pcidev->irq);
1587
1588
	cardnum++;
1589
1590
	return 0;
1591
1592
err_request_irq:
1593
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1594
		card->fifo_mem, card->fifo_bus_mem);
1595
err_alloc_fifo:
1596
	iounmap(card->io_mem);
1597
err_ioremap:
1598
err_noiobase:
1599
err_noirq:
1600
	pci_release_regions(pci_dev);
1601
err_pci_request_regions:
1602
err_pci_set_dma_mask:
1603
err_pci_enable_device:
1604
	kfree(card);
1605
err_alloc_hfccard:
1606
	return err;
1607
}
1608
1609
static void __devexit hfc_remove(struct pci_dev *pci_dev)
1610
{
1611
	struct hfc_card *card = pci_get_drvdata(pci_dev);
1612
1613
1614
	printk(KERN_INFO hfc_DRIVER_PREFIX
1615
		"card %d: "
1616
		"shutting down card at %p.\n",
1617
		card->cardnum,
1618
		card->io_mem);
1619
1620
	hfc_softreset(card);
1621
1622
	dahdi_unregister_device(card->ztdev->ddev);
1623
	hfc_dahdi_free(card->ztdev);
1624
1625
1626
	/*
1627
	 * disable memio and bustmaster
1628
	 */
1629
	pci_write_config_word(pci_dev, PCI_COMMAND, 0);
1630
1631
	remove_proc_entry("bufs", card->proc_dir);
1632
	remove_proc_entry("fifos", card->proc_dir);
1633
	remove_proc_entry("info", card->proc_dir);
1634
	remove_proc_entry(card->proc_dir_name, hfc_proc_zaphfc_dir);
1635
1636
	free_irq(pci_dev->irq, card);
1637
1638
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1639
		card->fifo_mem, card->fifo_bus_mem);
1640
1641
	iounmap(card->io_mem);
1642
1643
	pci_release_regions(pci_dev);
1644
1645
	pci_disable_device(pci_dev);
1646
1647
	kfree(card);
1648
}
1649
1650
/******************************************
1651
 * Module stuff
1652
 ******************************************/
1653
1654
static int __init hfc_init_module(void)
1655
{
1656
	int ret;
1657
1658
	printk(KERN_INFO hfc_DRIVER_PREFIX
1659
		hfc_DRIVER_STRING " loading\n");
1660
1661
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1662
	hfc_proc_zaphfc_dir = proc_mkdir(hfc_DRIVER_NAME, NULL);
1663
#else
1664
	hfc_proc_zaphfc_dir = proc_mkdir(hfc_DRIVER_NAME, proc_root_driver);
1665
#endif
1666
1667
	ret = pci_register_driver(&hfc_driver);
1668
	return ret;
1669
}
1670
1671
module_init(hfc_init_module);
1672
1673
static void __exit hfc_module_exit(void)
1674
{
1675
	pci_unregister_driver(&hfc_driver);
1676
1677
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1678
	remove_proc_entry(hfc_DRIVER_NAME, NULL);
1679
#else
1680
	remove_proc_entry(hfc_DRIVER_NAME, proc_root_driver);
1681
#endif
1682
1683
	printk(KERN_INFO hfc_DRIVER_PREFIX
1684
		hfc_DRIVER_STRING " unloaded\n");
1685
}
1686
1687
module_exit(hfc_module_exit);
1688
1689
#endif
1690
1691
MODULE_DESCRIPTION(hfc_DRIVER_DESCR);
1692
MODULE_AUTHOR("Jens Wilke <jw_vzaphfc@headissue.com>, "
1693
		"Daniele (Vihai) Orlandi <daniele@orlandi.com>, "
1694
		"Jose A. Deniz <odicha@hotmail.com>");
1695
MODULE_ALIAS("vzaphfc");
1696
#ifdef MODULE_LICENSE
1697
MODULE_LICENSE("GPL");
1698
#endif
1699
1700
1701
module_param(modes, int, 0444);
1702
1703
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
1704
module_param_array(nt_modes, int, &nt_modes_count, 0444);
1705
#else
1706
module_param_array(nt_modes, int, nt_modes_count, 0444);
1707
#endif
1708
1709
module_param(force_l1_up, int, 0444);
1710
#ifdef DEBUG
1711
module_param(debug_level, int, 0444);
1712
#endif
1713
1714
MODULE_PARM_DESC(modes, "[Deprecated] bit-mask to configure NT mode");
1715
MODULE_PARM_DESC(nt_modes,
1716
		"Comma-separated list of card IDs to configure in NT mode");
1717
MODULE_PARM_DESC(force_l1_up, "Don't allow L1 to go down");
1718
#ifdef DEBUG
1719
MODULE_PARM_DESC(debug_level, "Debug verbosity level");
1720
#endif
(-)dahdi-linux-3.1.0.original/drivers/dahdi/zaphfc/fifo.c (+375 lines)
Line 0 Link Here
1
/*
2
 * fifo.c - HFC FIFO management routines
3
 *
4
 * Copyright (C) 2006 headissue GmbH; Jens Wilke
5
 * Copyright (C) 2004 Daniele Orlandi
6
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
7
 *
8
 * Original author of this code is
9
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
10
 *
11
 * This program is free software and may be modified and
12
 * distributed under the terms of the GNU Public License.
13
 *
14
 */
15
16
#include <linux/kernel.h>
17
18
#include <dahdi/kernel.h>
19
20
#include "fifo.h"
21
22
static void hfc_fifo_mem_read(struct hfc_chan_simplex *chan,
23
	int z_start,
24
	void *data, int size)
25
{
26
	int bytes_to_boundary = chan->z_max - z_start + 1;
27
	if (bytes_to_boundary >= size) {
28
		memcpy(data,
29
			chan->z_base + z_start,
30
			size);
31
	} else {
32
		/*
33
		 * Buffer wrap
34
		 */
35
		memcpy(data,
36
			chan->z_base + z_start,
37
			bytes_to_boundary);
38
39
		memcpy(data + bytes_to_boundary,
40
			chan->fifo_base,
41
			size - bytes_to_boundary);
42
	}
43
}
44
45
static void hfc_fifo_mem_write(struct hfc_chan_simplex *chan,
46
	void *data, int size)
47
{
48
	int bytes_to_boundary = chan->z_max - *Z1_F1(chan) + 1;
49
	if (bytes_to_boundary >= size) {
50
		memcpy(chan->z_base + *Z1_F1(chan),
51
			data,
52
			size);
53
	} else {
54
		/*
55
		 * FIFO wrap
56
		 */
57
58
		memcpy(chan->z_base + *Z1_F1(chan),
59
			data,
60
			bytes_to_boundary);
61
62
		memcpy(chan->fifo_base,
63
			data + bytes_to_boundary,
64
			size - bytes_to_boundary);
65
	}
66
}
67
68
int hfc_fifo_get(struct hfc_chan_simplex *chan,
69
		void *data, int size)
70
{
71
	int available_bytes;
72
73
	/*
74
	 * Some useless statistic
75
	 */
76
	chan->bytes += size;
77
78
	available_bytes = hfc_fifo_used_rx(chan);
79
80
	if (available_bytes < size && !chan->fifo_underrun++) {
81
		/*
82
		 * print the warning only once
83
		 */
84
		printk(KERN_WARNING hfc_DRIVER_PREFIX
85
			"card %d: "
86
			"chan %s: "
87
			"RX FIFO not enough (%d) bytes to receive!\n",
88
			chan->chan->card->cardnum,
89
			chan->chan->name,
90
			available_bytes);
91
		return -1;
92
	}
93
94
	hfc_fifo_mem_read(chan, *Z2_F2(chan), data, size);
95
	*Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size);
96
	return available_bytes - size;
97
}
98
99
void hfc_fifo_put(struct hfc_chan_simplex *chan,
100
			void *data, int size)
101
{
102
	struct hfc_card *card = chan->chan->card;
103
	int used_bytes = hfc_fifo_used_tx(chan);
104
	int free_bytes = hfc_fifo_free_tx(chan);
105
106
	if (!used_bytes && !chan->fifo_underrun++) {
107
		/*
108
		 * print warning only once, to make timing not worse
109
		 */
110
		printk(KERN_WARNING hfc_DRIVER_PREFIX
111
			"card %d: "
112
			"chan %s: "
113
			"TX FIFO has become empty\n",
114
			card->cardnum,
115
			chan->chan->name);
116
	}
117
	if (free_bytes < size) {
118
		printk(KERN_CRIT hfc_DRIVER_PREFIX
119
			"card %d: "
120
			"chan %s: "
121
			"TX FIFO full!\n",
122
			chan->chan->card->cardnum,
123
			chan->chan->name);
124
		chan->fifo_full++;
125
		hfc_clear_fifo_tx(chan);
126
	}
127
128
	hfc_fifo_mem_write(chan, data, size);
129
	chan->bytes += size;
130
	*Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size);
131
}
132
133
int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size)
134
{
135
	int frame_size;
136
	u16 newz2 ;
137
138
	if (*chan->f1 == *chan->f2) {
139
		/*
140
		 * nothing received, strange uh?
141
		 */
142
		printk(KERN_WARNING hfc_DRIVER_PREFIX
143
			"card %d: "
144
			"chan %s: "
145
			"get_frame called with no frame in FIFO.\n",
146
			chan->chan->card->cardnum,
147
			chan->chan->name);
148
149
		return -1;
150
	}
151
152
	/*
153
	 * frame_size includes CRC+CRC+STAT
154
	 */
155
	frame_size = hfc_fifo_get_frame_size(chan);
156
157
#ifdef DEBUG
158
	if (debug_level == 3) {
159
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
160
			"card %d: "
161
			"chan %s: "
162
			"RX len %2d: ",
163
			chan->chan->card->cardnum,
164
			chan->chan->name,
165
			frame_size);
166
	} else if (debug_level >= 4) {
167
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
168
			"card %d: "
169
			"chan %s: "
170
			"RX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
171
			chan->chan->card->cardnum,
172
			chan->chan->name,
173
			*chan->f1, *chan->f2, *Z1_F2(chan), *Z2_F2(chan),
174
			frame_size);
175
	}
176
177
	if (debug_level >= 3) {
178
		int i;
179
		for (i = 0; i < frame_size; i++) {
180
			printk("%02x", hfc_fifo_u8(chan,
181
				Z_inc(chan, *Z2_F2(chan), i)));
182
		}
183
184
		printk("\n");
185
	}
186
#endif
187
188
	if (frame_size <= 0) {
189
#ifdef DEBUG
190
		if (debug_level >= 2) {
191
			printk(KERN_DEBUG hfc_DRIVER_PREFIX
192
				"card %d: "
193
				"chan %s: "
194
				"invalid (empty) frame received.\n",
195
				chan->chan->card->cardnum,
196
				chan->chan->name);
197
		}
198
#endif
199
200
		hfc_fifo_drop_frame(chan);
201
		return -1;
202
	}
203
204
	/*
205
	 * STAT is not really received
206
	 */
207
	chan->bytes += frame_size - 1;
208
209
	/*
210
	 * Calculate beginning of the next frame
211
	 */
212
	newz2 = Z_inc(chan, *Z2_F2(chan), frame_size);
213
214
	/*
215
	 * We cannot use hfc_fifo_get because of different semantic of
216
	 * "available bytes" and to avoid useless increment of Z2
217
	 */
218
	hfc_fifo_mem_read(chan, *Z2_F2(chan), data,
219
		frame_size < max_size ? frame_size : max_size);
220
221
	if (hfc_fifo_u8(chan, Z_inc(chan, *Z2_F2(chan),
222
		frame_size - 1)) != 0x00) {
223
		/*
224
		 * CRC not ok, frame broken, skipping
225
		 */
226
#ifdef DEBUG
227
		if (debug_level >= 2) {
228
			printk(KERN_WARNING hfc_DRIVER_PREFIX
229
				"card %d: "
230
				"chan %s: "
231
				"Received frame with wrong CRC\n",
232
				chan->chan->card->cardnum,
233
				chan->chan->name);
234
		}
235
#endif
236
237
		chan->crc++;
238
239
		hfc_fifo_drop_frame(chan);
240
		return -1;
241
	}
242
243
	chan->frames++;
244
245
	*chan->f2 = F_inc(chan, *chan->f2, 1);
246
247
	/*
248
	 * Set Z2 for the next frame we're going to receive
249
	 */
250
	*Z2_F2(chan) = newz2;
251
252
	return frame_size;
253
}
254
255
void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan)
256
{
257
	int available_bytes;
258
	u16 newz2;
259
260
	if (*chan->f1 == *chan->f2) {
261
		/*
262
		 * nothing received, strange eh?
263
		 */
264
		printk(KERN_WARNING hfc_DRIVER_PREFIX
265
			"card %d: "
266
			"chan %s: "
267
			"skip_frame called with no frame in FIFO.\n",
268
			chan->chan->card->cardnum,
269
			chan->chan->name);
270
271
		return;
272
	}
273
274
	available_bytes = hfc_fifo_used_rx(chan) + 1;
275
276
	/*
277
	 * Calculate beginning of the next frame
278
	 */
279
	newz2 = Z_inc(chan, *Z2_F2(chan), available_bytes);
280
281
	*chan->f2 = F_inc(chan, *chan->f2, 1);
282
283
	/*
284
	 * Set Z2 for the next frame we're going to receive
285
	 */
286
	*Z2_F2(chan) = newz2;
287
}
288
289
void hfc_fifo_put_frame(struct hfc_chan_simplex *chan,
290
		 void *data, int size)
291
{
292
	u16 newz1;
293
	int available_frames;
294
295
#ifdef DEBUG
296
	if (debug_level == 3) {
297
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
298
			"card %d: "
299
			"chan %s: "
300
			"TX len %2d: ",
301
			chan->chan->card->cardnum,
302
			chan->chan->name,
303
			size);
304
	} else if (debug_level >= 4) {
305
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
306
			"card %d: "
307
			"chan %s: "
308
			"TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
309
			chan->chan->card->cardnum,
310
			chan->chan->name,
311
			*chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan),
312
			size);
313
	}
314
315
	if (debug_level >= 3) {
316
		int i;
317
		for (i = 0; i < size; i++)
318
			printk("%02x", ((u8 *)data)[i]);
319
320
		printk("\n");
321
	}
322
#endif
323
324
	available_frames = hfc_fifo_free_frames(chan);
325
326
	if (available_frames >= chan->f_num) {
327
		printk(KERN_CRIT hfc_DRIVER_PREFIX
328
			"card %d: "
329
			"chan %s: "
330
			"TX FIFO total number of frames exceeded!\n",
331
			chan->chan->card->cardnum,
332
			chan->chan->name);
333
334
		chan->fifo_full++;
335
336
		return;
337
	}
338
339
	hfc_fifo_put(chan, data, size);
340
341
	newz1 = *Z1_F1(chan);
342
343
	*chan->f1 = F_inc(chan, *chan->f1, 1);
344
345
	*Z1_F1(chan) = newz1;
346
347
	chan->frames++;
348
}
349
350
void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan)
351
{
352
	*chan->f2 = *chan->f1;
353
	*Z2_F2(chan) = *Z1_F2(chan);
354
}
355
356
void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan)
357
{
358
	*chan->f1 = *chan->f2;
359
	*Z1_F1(chan) = *Z2_F1(chan);
360
361
	if (chan->chan->status == open_voice) {
362
		/*
363
		 * Make sure that at least hfc_TX_FIFO_PRELOAD bytes are
364
		 * present in the TX FIFOs
365
		 * Create hfc_TX_FIFO_PRELOAD bytes of empty data
366
		 * (0x7f is mute audio)
367
		 */
368
		u8 empty_fifo[hfc_TX_FIFO_PRELOAD +
369
			DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD];
370
		memset(empty_fifo, 0x7f, sizeof(empty_fifo));
371
372
		hfc_fifo_put(chan, empty_fifo, sizeof(empty_fifo));
373
	}
374
}
375
(-)dahdi-linux-3.1.0.original/drivers/dahdi/zaphfc/fifo.h (+139 lines)
Line 0 Link Here
1
/*
2
 * fifo.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * Copyright (C) 2004 Daniele Orlandi
5
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
6
 *
7
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
8
 *
9
 * Major rewrite of the driver made by
10
 * Klaus-Peter Junghanns <kpj@junghanns.net>
11
 *
12
 * This program is free software and may be modified and
13
 * distributed under the terms of the GNU Public License.
14
 *
15
 */
16
17
#ifndef _HFC_FIFO_H
18
#define _HFC_FIFO_H
19
20
#include "zaphfc.h"
21
22
static inline u16 *Z1_F1(struct hfc_chan_simplex *chan)
23
{
24
	return chan->z1_base + (*chan->f1 * 4);
25
}
26
27
static inline u16 *Z2_F1(struct hfc_chan_simplex *chan)
28
{
29
	return chan->z2_base + (*chan->f1 * 4);
30
}
31
32
static inline u16 *Z1_F2(struct hfc_chan_simplex *chan)
33
{
34
	return chan->z1_base + (*chan->f2 * 4);
35
}
36
37
static inline u16 *Z2_F2(struct hfc_chan_simplex *chan)
38
{
39
	return chan->z2_base + (*chan->f2 * 4);
40
}
41
42
static inline u16 Z_inc(struct hfc_chan_simplex *chan, u16 z, u16 inc)
43
{
44
	/*
45
	 * declared as u32 in order to manage overflows
46
	 */
47
	u32 newz = z + inc;
48
	if (newz > chan->z_max)
49
		newz -= chan->fifo_size;
50
51
	return newz;
52
}
53
54
static inline u8 F_inc(struct hfc_chan_simplex *chan, u8 f, u8 inc)
55
{
56
	/*
57
	 * declared as u16 in order to manage overflows
58
	 */
59
	u16 newf = f + inc;
60
	if (newf > chan->f_max)
61
		newf -= chan->f_num;
62
63
	return newf;
64
}
65
66
static inline u16 hfc_fifo_used_rx(struct hfc_chan_simplex *chan)
67
{
68
	return (*Z1_F2(chan) - *Z2_F2(chan) +
69
			chan->fifo_size) % chan->fifo_size;
70
}
71
72
static inline u16 hfc_fifo_get_frame_size(struct hfc_chan_simplex *chan)
73
{
74
 /*
75
  * This +1 is needed because in frame mode the available bytes are Z2-Z1+1
76
  * while in transparent mode I wouldn't consider the byte pointed by Z2 to
77
  * be available, otherwise, the FIFO would always contain one byte, even
78
  * when Z1==Z2
79
  */
80
81
	return hfc_fifo_used_rx(chan) + 1;
82
}
83
84
static inline u8 hfc_fifo_u8(struct hfc_chan_simplex *chan, u16 z)
85
{
86
	return *((u8 *)(chan->z_base + z));
87
}
88
89
static inline u16 hfc_fifo_used_tx(struct hfc_chan_simplex *chan)
90
{
91
	return (*Z1_F1(chan) - *Z2_F1(chan) +
92
			chan->fifo_size) % chan->fifo_size;
93
}
94
95
static inline u16 hfc_fifo_free_rx(struct hfc_chan_simplex *chan)
96
{
97
	u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan);
98
99
	if (free_bytes > 0)
100
		return free_bytes;
101
	else
102
		return free_bytes + chan->fifo_size;
103
}
104
105
static inline u16 hfc_fifo_free_tx(struct hfc_chan_simplex *chan)
106
{
107
	u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan);
108
109
	if (free_bytes > 0)
110
		return free_bytes;
111
	else
112
		return free_bytes + chan->fifo_size;
113
}
114
115
static inline int hfc_fifo_has_frames(struct hfc_chan_simplex *chan)
116
{
117
	return *chan->f1 != *chan->f2;
118
}
119
120
static inline u8 hfc_fifo_used_frames(struct hfc_chan_simplex *chan)
121
{
122
	return (*chan->f1 - *chan->f2 + chan->f_num) % chan->f_num;
123
}
124
125
static inline u8 hfc_fifo_free_frames(struct hfc_chan_simplex *chan)
126
{
127
	return (*chan->f2 - *chan->f1 + chan->f_num) % chan->f_num;
128
}
129
130
int hfc_fifo_get(struct hfc_chan_simplex *chan, void *data, int size);
131
void hfc_fifo_put(struct hfc_chan_simplex *chan, void *data, int size);
132
void hfc_fifo_drop(struct hfc_chan_simplex *chan, int size);
133
int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size);
134
void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan);
135
void hfc_fifo_put_frame(struct hfc_chan_simplex *chan, void *data, int size);
136
void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan);
137
void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan);
138
139
#endif
(-)dahdi-linux-3.1.0.original/drivers/dahdi/zaphfc/zaphfc.h (+419 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * Dahdi port by Jose A. Deniz <odicha@hotmail.com>
5
 *
6
 * Copyright (C) 2009 Jose A. Deniz
7
 * Copyright (C) 2006 headissue GmbH; Jens Wilke
8
 * Copyright (C) 2004 Daniele Orlandi
9
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
10
 *
11
 * Jens Wilke <jw_vzaphfc@headissue.com>
12
 *
13
 * Orginal author of this code is
14
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
15
 *
16
 * Major rewrite of the driver made by
17
 * Klaus-Peter Junghanns <kpj@junghanns.net>
18
 *
19
 * This program is free software and may be modified and
20
 * distributed under the terms of the GNU Public License.
21
 *
22
 */
23
24
#ifndef _HFC_ZAPHFC_H
25
#define _HFC_ZAPHFC_H
26
27
#include <asm/io.h>
28
29
#define hfc_DRIVER_NAME "vzaphfc"
30
#define hfc_DRIVER_PREFIX hfc_DRIVER_NAME ": "
31
#define hfc_DRIVER_DESCR "HFC-S PCI A ISDN"
32
#define hfc_DRIVER_VERSION "1.42"
33
#define hfc_DRIVER_STRING hfc_DRIVER_DESCR " (V" hfc_DRIVER_VERSION ")"
34
35
#define hfc_MAX_BOARDS 32
36
37
#ifndef PCI_DMA_32BIT
38
#define PCI_DMA_32BIT	0x00000000ffffffffULL
39
#endif
40
41
#ifndef PCI_VENDOR_ID_SITECOM
42
#define PCI_VENDOR_ID_SITECOM 0x182D
43
#endif
44
45
#ifndef PCI_DEVICE_ID_SITECOM_3069
46
#define PCI_DEVICE_ID_SITECOM_3069 0x3069
47
#endif
48
49
#define hfc_RESET_DELAY 20
50
51
#define hfc_CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
52
#define hfc_CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
53
54
/* PCI memory mapped I/O */
55
56
#define hfc_PCI_MEM_SIZE	0x0100
57
#define hfc_PCI_MWBA		0x80
58
59
/* GCI/IOM bus monitor registers */
60
61
#define hfc_C_I       0x08
62
#define hfc_TRxR      0x0C
63
#define hfc_MON1_D    0x28
64
#define hfc_MON2_D    0x2C
65
66
67
/* GCI/IOM bus timeslot registers */
68
69
#define hfc_B1_SSL    0x80
70
#define hfc_B2_SSL    0x84
71
#define hfc_AUX1_SSL  0x88
72
#define hfc_AUX2_SSL  0x8C
73
#define hfc_B1_RSL    0x90
74
#define hfc_B2_RSL    0x94
75
#define hfc_AUX1_RSL  0x98
76
#define hfc_AUX2_RSL  0x9C
77
78
/* GCI/IOM bus data registers */
79
80
#define hfc_B1_D      0xA0
81
#define hfc_B2_D      0xA4
82
#define hfc_AUX1_D    0xA8
83
#define hfc_AUX2_D    0xAC
84
85
/* GCI/IOM bus configuration registers */
86
87
#define hfc_MST_EMOD  0xB4
88
#define hfc_MST_MODE	 0xB8
89
#define hfc_CONNECT	 0xBC
90
91
92
/* Interrupt and status registers */
93
94
#define hfc_FIFO_EN   0x44
95
#define hfc_TRM       0x48
96
#define hfc_B_MODE    0x4C
97
#define hfc_CHIP_ID   0x58
98
#define hfc_CIRM	 0x60
99
#define hfc_CTMT	 0x64
100
#define hfc_INT_M1	 0x68
101
#define hfc_INT_M2	 0x6C
102
#define hfc_INT_S1	 0x78
103
#define hfc_INT_S2	 0x7C
104
#define hfc_STATUS	 0x70
105
106
/* S/T section registers */
107
108
#define hfc_STATES	 0xC0
109
#define hfc_SCTRL	 0xC4
110
#define hfc_SCTRL_E   0xC8
111
#define hfc_SCTRL_R   0xCC
112
#define hfc_SQ	 0xD0
113
#define hfc_CLKDEL	 0xDC
114
#define hfc_B1_REC    0xF0
115
#define hfc_B1_SEND   0xF0
116
#define hfc_B2_REC    0xF4
117
#define hfc_B2_SEND   0xF4
118
#define hfc_D_REC     0xF8
119
#define hfc_D_SEND    0xF8
120
#define hfc_E_REC     0xFC
121
122
/* Bits and values in various HFC PCI registers */
123
124
/* bits in status register (READ) */
125
#define hfc_STATUS_PCI_PROC	0x02
126
#define hfc_STATUS_NBUSY	0x04
127
#define hfc_STATUS_TIMER_ELAP	0x10
128
#define hfc_STATUS_STATINT	0x20
129
#define hfc_STATUS_FRAMEINT	0x40
130
#define hfc_STATUS_ANYINT	0x80
131
132
/* bits in CTMT (Write) */
133
#define hfc_CTMT_TRANSB1	0x01
134
#define hfc_CTMT_TRANSB2	0x02
135
#define hfc_CTMT_TIMER_CLEAR	0x80
136
#define hfc_CTMT_TIMER_MASK	0x1C
137
#define hfc_CTMT_TIMER_3_125	(0x01 << 2)
138
#define hfc_CTMT_TIMER_6_25	(0x02 << 2)
139
#define hfc_CTMT_TIMER_12_5	(0x03 << 2)
140
#define hfc_CTMT_TIMER_25	(0x04 << 2)
141
#define hfc_CTMT_TIMER_50	(0x05 << 2)
142
#define hfc_CTMT_TIMER_400	(0x06 << 2)
143
#define hfc_CTMT_TIMER_800	(0x07 << 2)
144
#define hfc_CTMT_AUTO_TIMER	0x20
145
146
/* bits in CIRM (Write) */
147
#define hfc_CIRM_AUX_MSK	0x07
148
#define hfc_CIRM_RESET		0x08
149
#define hfc_CIRM_B1_REV		0x40
150
#define hfc_CIRM_B2_REV		0x80
151
152
/* bits in INT_M1 and INT_S1 */
153
#define hfc_INTS_B1TRANS	0x01
154
#define hfc_INTS_B2TRANS	0x02
155
#define hfc_INTS_DTRANS		0x04
156
#define hfc_INTS_B1REC		0x08
157
#define hfc_INTS_B2REC		0x10
158
#define hfc_INTS_DREC		0x20
159
#define hfc_INTS_L1STATE	0x40
160
#define hfc_INTS_TIMER		0x80
161
162
/* bits in INT_M2 */
163
#define hfc_M2_PROC_TRANS	0x01
164
#define hfc_M2_GCI_I_CHG	0x02
165
#define hfc_M2_GCI_MON_REC	0x04
166
#define hfc_M2_IRQ_ENABLE	0x08
167
#define hfc_M2_PMESEL		0x80
168
169
/* bits in STATES */
170
#define hfc_STATES_STATE_MASK	0x0F
171
#define hfc_STATES_LOAD_STATE	0x10
172
#define hfc_STATES_ACTIVATE	0x20
173
#define hfc_STATES_DO_ACTION	0x40
174
#define hfc_STATES_NT_G2_G3	0x80
175
176
/* bits in HFCD_MST_MODE */
177
#define hfc_MST_MODE_MASTER	0x01
178
#define hfc_MST_MODE_SLAVE	0x00
179
/* remaining bits are for codecs control */
180
181
/* bits in HFCD_SCTRL */
182
#define hfc_SCTRL_B1_ENA	0x01
183
#define hfc_SCTRL_B2_ENA	0x02
184
#define hfc_SCTRL_MODE_TE       0x00
185
#define hfc_SCTRL_MODE_NT       0x04
186
#define hfc_SCTRL_LOW_PRIO	0x08
187
#define hfc_SCTRL_SQ_ENA	0x10
188
#define hfc_SCTRL_TEST		0x20
189
#define hfc_SCTRL_NONE_CAP	0x40
190
#define hfc_SCTRL_PWR_DOWN	0x80
191
192
/* bits in SCTRL_E  */
193
#define hfc_SCTRL_E_AUTO_AWAKE	0x01
194
#define hfc_SCTRL_E_DBIT_1	0x04
195
#define hfc_SCTRL_E_IGNORE_COL	0x08
196
#define hfc_SCTRL_E_CHG_B1_B2	0x80
197
198
/* bits in SCTRL_R  */
199
#define hfc_SCTRL_R_B1_ENA	0x01
200
#define hfc_SCTRL_R_B2_ENA	0x02
201
202
/* bits in FIFO_EN register */
203
#define hfc_FIFOEN_B1TX		0x01
204
#define hfc_FIFOEN_B1RX		0x02
205
#define hfc_FIFOEN_B2TX		0x04
206
#define hfc_FIFOEN_B2RX		0x08
207
#define hfc_FIFOEN_DTX		0x10
208
#define hfc_FIFOEN_DRX		0x20
209
210
#define hfc_FIFOEN_B1		(hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
211
#define hfc_FIFOEN_B2		(hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
212
#define hfc_FIFOEN_D		(hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
213
214
/* bits in the CONNECT register */
215
#define	hfc_CONNECT_B1_HFC_from_ST		0x00
216
#define	hfc_CONNECT_B1_HFC_from_GCI		0x01
217
#define hfc_CONNECT_B1_ST_from_HFC		0x00
218
#define hfc_CONNECT_B1_ST_from_GCI		0x02
219
#define hfc_CONNECT_B1_GCI_from_HFC		0x00
220
#define hfc_CONNECT_B1_GCI_from_ST		0x04
221
222
#define	hfc_CONNECT_B2_HFC_from_ST		0x00
223
#define	hfc_CONNECT_B2_HFC_from_GCI		0x08
224
#define hfc_CONNECT_B2_ST_from_HFC		0x00
225
#define hfc_CONNECT_B2_ST_from_GCI		0x10
226
#define hfc_CONNECT_B2_GCI_from_HFC		0x00
227
#define hfc_CONNECT_B2_GCI_from_ST		0x20
228
229
/* bits in the TRM register */
230
#define hfc_TRM_TRANS_INT_00	0x00
231
#define hfc_TRM_TRANS_INT_01	0x01
232
#define hfc_TRM_TRANS_INT_10	0x02
233
#define hfc_TRM_TRANS_INT_11	0x04
234
#define hfc_TRM_ECHO		0x20
235
#define hfc_TRM_B1_PLUS_B2	0x40
236
#define hfc_TRM_IOM_TEST_LOOP	0x80
237
238
/* bits in the __SSL and __RSL registers */
239
#define	hfc_SRSL_STIO		0x40
240
#define hfc_SRSL_ENABLE		0x80
241
#define hfc_SRCL_SLOT_MASK	0x1f
242
243
/* FIFO memory definitions */
244
245
#define hfc_FIFO_SIZE		0x8000
246
247
#define hfc_UGLY_FRAMEBUF	0x2000
248
249
#define hfc_TX_FIFO_PRELOAD	(DAHDI_CHUNKSIZE + 2)
250
#define hfc_RX_FIFO_PRELOAD	4
251
252
/* HDLC STUFF */
253
#define hfc_HDLC_BUF_LEN	32
254
/* arbitrary, just the max # of byts we will send to DAHDI per call */
255
256
257
/* NOTE: FIFO pointers are not declared volatile because accesses to the
258
 *       FIFOs are inherently safe.
259
 */
260
261
#ifdef DEBUG
262
extern int debug_level;
263
#endif
264
265
struct hfc_chan;
266
267
struct hfc_chan_simplex {
268
	struct hfc_chan_duplex *chan;
269
270
	u8 zaptel_buffer[DAHDI_CHUNKSIZE];
271
272
	u8 ugly_framebuf[hfc_UGLY_FRAMEBUF];
273
	int ugly_framebuf_size;
274
	u16 ugly_framebuf_off;
275
276
	void *z1_base, *z2_base;
277
	void *fifo_base;
278
	void *z_base;
279
	u16 z_min;
280
	u16 z_max;
281
	u16 fifo_size;
282
283
	u8 *f1, *f2;
284
	u8 f_min;
285
	u8 f_max;
286
	u8 f_num;
287
288
	unsigned long long frames;
289
	unsigned long long bytes;
290
	unsigned long long fifo_full;
291
	unsigned long long crc;
292
	unsigned long long fifo_underrun;
293
};
294
295
enum hfc_chan_status {
296
	free,
297
	open_framed,
298
	open_voice,
299
	sniff_aux,
300
	loopback,
301
};
302
303
struct hfc_chan_duplex {
304
	struct hfc_card *card;
305
306
	char *name;
307
	int number;
308
309
	enum hfc_chan_status status;
310
	int open_by_netdev;
311
	int open_by_zaptel;
312
313
	unsigned short protocol;
314
315
	spinlock_t lock;
316
317
	struct hfc_chan_simplex rx;
318
	struct hfc_chan_simplex tx;
319
320
};
321
322
typedef struct hfc_card {
323
	int cardnum;
324
	struct pci_dev *pcidev;
325
	struct dahdi_hfc *ztdev;
326
	struct proc_dir_entry *proc_dir;
327
	char proc_dir_name[32];
328
329
	struct proc_dir_entry *proc_info;
330
	struct proc_dir_entry *proc_fifos;
331
	struct proc_dir_entry *proc_bufs;
332
333
	unsigned long io_bus_mem;
334
	void __iomem *io_mem;
335
336
	dma_addr_t fifo_bus_mem;
337
	void *fifo_mem;
338
	void *fifos;
339
340
	int nt_mode;
341
	int sync_loss_reported;
342
	int late_irqs;
343
344
	u8 l1_state;
345
	int fifo_suspended;
346
	int ignore_first_timer_interrupt;
347
348
	struct {
349
		u8 m1;
350
		u8 m2;
351
		u8 fifo_en;
352
		u8 trm;
353
		u8 connect;
354
		u8 sctrl;
355
		u8 sctrl_r;
356
		u8 sctrl_e;
357
		u8 ctmt;
358
		u8 cirm;
359
	} regs;
360
361
	struct hfc_chan_duplex chans[3];
362
	int echo_enabled;
363
364
365
366
	int debug_event;
367
368
	spinlock_t lock;
369
	unsigned int irq;
370
	unsigned int iomem;
371
	int ticks;
372
	int clicks;
373
	unsigned char *pci_io;
374
	void *fifomem;		/* start of the shared mem */
375
376
	unsigned int pcibus;
377
	unsigned int pcidevfn;
378
379
	int	drecinframe;
380
381
	unsigned char cardno;
382
	struct hfc_card *next;
383
384
} hfc_card;
385
386
typedef struct dahdi_hfc {
387
	unsigned int usecount;
388
	struct dahdi_device *ddev;
389
	struct dahdi_span span;
390
	struct dahdi_chan chans[3];
391
	struct dahdi_chan *_chans[3];
392
	struct hfc_card *card;
393
394
	/* pointer to the signalling channel for this span */
395
	struct dahdi_chan *sigchan;
396
	/* nonzero means we're in the middle of sending an HDLC frame */
397
	int sigactive;
398
	/* hdlc_hard_xmit() increments, hdlc_tx_frame() decrements */
399
	atomic_t hdlc_pending;
400
	int frames_out;
401
	int frames_in;
402
} dahdi_hfc;
403
404
static inline struct dahdi_hfc *dahdi_hfc_from_span(struct dahdi_span *span)
405
{
406
	return container_of(span, struct dahdi_hfc, span);
407
}
408
409
static inline u8 hfc_inb(struct hfc_card *card, int offset)
410
{
411
	return readb(card->io_mem + offset);
412
}
413
414
static inline void hfc_outb(struct hfc_card *card, int offset, u8 value)
415
{
416
	writeb(value, card->io_mem + offset);
417
}
418
419
#endif
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/Kbuild (+6 lines)
Line 0 Link Here
1
ifdef DAHDI_USE_MMX
2
EXTRA_CFLAGS += -DUSE_MMX
3
endif
4
5
# An explicit 'obj-m' , unlike the Makefile
6
obj-m += echo.o
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/echo.c (+662 lines)
Line 0 Link Here
1
/*
2
 * SpanDSP - a series of DSP components for telephony
3
 *
4
 * echo.c - A line echo canceller.  This code is being developed
5
 *          against and partially complies with G168.
6
 *
7
 * Written by Steve Underwood <steveu@coppice.org>
8
 *         and David Rowe <david_at_rowetel_dot_com>
9
 *
10
 * Copyright (C) 2001, 2003 Steve Underwood, 2007 David Rowe
11
 *
12
 * Based on a bit from here, a bit from there, eye of toad, ear of
13
 * bat, 15 years of failed attempts by David and a few fried brain
14
 * cells.
15
 *
16
 * All rights reserved.
17
 *
18
 * This program is free software; you can redistribute it and/or modify
19
 * it under the terms of the GNU General Public License version 2, as
20
 * published by the Free Software Foundation.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program; if not, write to the Free Software
29
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30
 */
31
32
/*! \file */
33
34
/* Implementation Notes
35
   David Rowe
36
   April 2007
37
38
   This code started life as Steve's NLMS algorithm with a tap
39
   rotation algorithm to handle divergence during double talk.  I
40
   added a Geigel Double Talk Detector (DTD) [2] and performed some
41
   G168 tests.  However I had trouble meeting the G168 requirements,
42
   especially for double talk - there were always cases where my DTD
43
   failed, for example where near end speech was under the 6dB
44
   threshold required for declaring double talk.
45
46
   So I tried a two path algorithm [1], which has so far given better
47
   results.  The original tap rotation/Geigel algorithm is available
48
   in SVN http://svn.rowetel.com/software/oslec/tags/before_16bit.
49
   It's probably possible to make it work if some one wants to put some
50
   serious work into it.
51
52
   At present no special treatment is provided for tones, which
53
   generally cause NLMS algorithms to diverge.  Initial runs of a
54
   subset of the G168 tests for tones (e.g ./echo_test 6) show the
55
   current algorithm is passing OK, which is kind of surprising.  The
56
   full set of tests needs to be performed to confirm this result.
57
58
   One other interesting change is that I have managed to get the NLMS
59
   code to work with 16 bit coefficients, rather than the original 32
60
   bit coefficents.  This reduces the MIPs and storage required.
61
   I evaulated the 16 bit port using g168_tests.sh and listening tests
62
   on 4 real-world samples.
63
64
   I also attempted the implementation of a block based NLMS update
65
   [2] but although this passes g168_tests.sh it didn't converge well
66
   on the real-world samples.  I have no idea why, perhaps a scaling
67
   problem.  The block based code is also available in SVN
68
   http://svn.rowetel.com/software/oslec/tags/before_16bit.  If this
69
   code can be debugged, it will lead to further reduction in MIPS, as
70
   the block update code maps nicely onto DSP instruction sets (it's a
71
   dot product) compared to the current sample-by-sample update.
72
73
   Steve also has some nice notes on echo cancellers in echo.h
74
75
   References:
76
77
   [1] Ochiai, Areseki, and Ogihara, "Echo Canceller with Two Echo
78
       Path Models", IEEE Transactions on communications, COM-25,
79
       No. 6, June
80
       1977.
81
       http://www.rowetel.com/images/echo/dual_path_paper.pdf
82
83
   [2] The classic, very useful paper that tells you how to
84
       actually build a real world echo canceller:
85
	 Messerschmitt, Hedberg, Cole, Haoui, Winship, "Digital Voice
86
	 Echo Canceller with a TMS320020,
87
	 http://www.rowetel.com/images/echo/spra129.pdf
88
89
   [3] I have written a series of blog posts on this work, here is
90
       Part 1: http://www.rowetel.com/blog/?p=18
91
92
   [4] The source code http://svn.rowetel.com/software/oslec/
93
94
   [5] A nice reference on LMS filters:
95
	 http://en.wikipedia.org/wiki/Least_mean_squares_filter
96
97
   Credits:
98
99
   Thanks to Steve Underwood, Jean-Marc Valin, and Ramakrishnan
100
   Muthukrishnan for their suggestions and email discussions.  Thanks
101
   also to those people who collected echo samples for me such as
102
   Mark, Pawel, and Pavel.
103
*/
104
105
#include <linux/kernel.h>
106
#include <linux/module.h>
107
#include <linux/slab.h>
108
109
#include "echo.h"
110
111
#define MIN_TX_POWER_FOR_ADAPTION	64
112
#define MIN_RX_POWER_FOR_ADAPTION	64
113
#define DTD_HANGOVER			600	/* 600 samples, or 75ms     */
114
#define DC_LOG2BETA			3	/* log2() of DC filter Beta */
115
116
117
/* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
118
119
#ifdef __bfin__
120
static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
121
				    int shift)
122
{
123
	int i, j;
124
	int offset1;
125
	int offset2;
126
	int factor;
127
	int exp;
128
	int16_t *phist;
129
	int n;
130
131
	if (shift > 0)
132
		factor = clean << shift;
133
	else
134
		factor = clean >> -shift;
135
136
	/* Update the FIR taps */
137
138
	offset2 = ec->curr_pos;
139
	offset1 = ec->taps - offset2;
140
	phist = &ec->fir_state_bg.history[offset2];
141
142
	/* st: and en: help us locate the assembler in echo.s */
143
144
	/* asm("st:"); */
145
	n = ec->taps;
146
	for (i = 0, j = offset2; i < n; i++, j++) {
147
		exp = *phist++ * factor;
148
		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
149
	}
150
	/* asm("en:"); */
151
152
	/* Note the asm for the inner loop above generated by Blackfin gcc
153
	   4.1.1 is pretty good (note even parallel instructions used):
154
155
	   R0 = W [P0++] (X);
156
	   R0 *= R2;
157
	   R0 = R0 + R3 (NS) ||
158
	   R1 = W [P1] (X) ||
159
	   nop;
160
	   R0 >>>= 15;
161
	   R0 = R0 + R1;
162
	   W [P1++] = R0;
163
164
	   A block based update algorithm would be much faster but the
165
	   above can't be improved on much.  Every instruction saved in
166
	   the loop above is 2 MIPs/ch!  The for loop above is where the
167
	   Blackfin spends most of it's time - about 17 MIPs/ch measured
168
	   with speedtest.c with 256 taps (32ms).  Write-back and
169
	   Write-through cache gave about the same performance.
170
	 */
171
}
172
173
/*
174
   IDEAS for further optimisation of lms_adapt_bg():
175
176
   1/ The rounding is quite costly.  Could we keep as 32 bit coeffs
177
   then make filter pluck the MS 16-bits of the coeffs when filtering?
178
   However this would lower potential optimisation of filter, as I
179
   think the dual-MAC architecture requires packed 16 bit coeffs.
180
181
   2/ Block based update would be more efficient, as per comments above,
182
   could use dual MAC architecture.
183
184
   3/ Look for same sample Blackfin LMS code, see if we can get dual-MAC
185
   packing.
186
187
   4/ Execute the whole e/c in a block of say 20ms rather than sample
188
   by sample.  Processing a few samples every ms is inefficient.
189
*/
190
191
#else
192
static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
193
				    int shift)
194
{
195
	int i;
196
197
	int offset1;
198
	int offset2;
199
	int factor;
200
	int exp;
201
202
	if (shift > 0)
203
		factor = clean << shift;
204
	else
205
		factor = clean >> -shift;
206
207
	/* Update the FIR taps */
208
209
	offset2 = ec->curr_pos;
210
	offset1 = ec->taps - offset2;
211
212
	for (i = ec->taps - 1; i >= offset1; i--) {
213
		exp = (ec->fir_state_bg.history[i - offset1] * factor);
214
		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
215
	}
216
	for (; i >= 0; i--) {
217
		exp = (ec->fir_state_bg.history[i + offset2] * factor);
218
		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
219
	}
220
}
221
#endif
222
223
static inline int top_bit(unsigned int bits)
224
{
225
	if (bits == 0)
226
		return -1;
227
	else
228
		return (int)fls((int32_t)bits)-1;
229
}
230
231
struct oslec_state *oslec_create(int len, int adaption_mode)
232
{
233
	struct oslec_state *ec;
234
	int i;
235
236
	ec = kzalloc(sizeof(*ec), GFP_KERNEL);
237
	if (!ec)
238
		return NULL;
239
240
	ec->taps = len;
241
	ec->log2taps = top_bit(len);
242
	ec->curr_pos = ec->taps - 1;
243
244
	for (i = 0; i < 2; i++) {
245
		ec->fir_taps16[i] =
246
		    kcalloc(ec->taps, sizeof(int16_t), GFP_KERNEL);
247
		if (!ec->fir_taps16[i])
248
			goto error_oom;
249
	}
250
251
	fir16_create(&ec->fir_state, ec->fir_taps16[0], ec->taps);
252
	fir16_create(&ec->fir_state_bg, ec->fir_taps16[1], ec->taps);
253
254
	for (i = 0; i < 5; i++)
255
		ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
256
257
	ec->cng_level = 1000;
258
	oslec_adaption_mode(ec, adaption_mode);
259
260
	ec->snapshot = kcalloc(ec->taps, sizeof(int16_t), GFP_KERNEL);
261
	if (!ec->snapshot)
262
		goto error_oom;
263
264
	ec->cond_met = 0;
265
	ec->Pstates = 0;
266
	ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
267
	ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
268
	ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
269
	ec->Lbgn = ec->Lbgn_acc = 0;
270
	ec->Lbgn_upper = 200;
271
	ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
272
273
	return ec;
274
275
error_oom:
276
	for (i = 0; i < 2; i++)
277
		kfree(ec->fir_taps16[i]);
278
279
	kfree(ec);
280
	return NULL;
281
}
282
EXPORT_SYMBOL_GPL(oslec_create);
283
284
void oslec_free(struct oslec_state *ec)
285
{
286
	int i;
287
288
	fir16_free(&ec->fir_state);
289
	fir16_free(&ec->fir_state_bg);
290
	for (i = 0; i < 2; i++)
291
		kfree(ec->fir_taps16[i]);
292
	kfree(ec->snapshot);
293
	kfree(ec);
294
}
295
EXPORT_SYMBOL_GPL(oslec_free);
296
297
void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
298
{
299
	ec->adaption_mode = adaption_mode;
300
}
301
EXPORT_SYMBOL_GPL(oslec_adaption_mode);
302
303
void oslec_flush(struct oslec_state *ec)
304
{
305
	int i;
306
307
	ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
308
	ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
309
	ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
310
311
	ec->Lbgn = ec->Lbgn_acc = 0;
312
	ec->Lbgn_upper = 200;
313
	ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
314
315
	ec->nonupdate_dwell = 0;
316
317
	fir16_flush(&ec->fir_state);
318
	fir16_flush(&ec->fir_state_bg);
319
	ec->fir_state.curr_pos = ec->taps - 1;
320
	ec->fir_state_bg.curr_pos = ec->taps - 1;
321
	for (i = 0; i < 2; i++)
322
		memset(ec->fir_taps16[i], 0, ec->taps * sizeof(int16_t));
323
324
	ec->curr_pos = ec->taps - 1;
325
	ec->Pstates = 0;
326
}
327
EXPORT_SYMBOL_GPL(oslec_flush);
328
329
void oslec_snapshot(struct oslec_state *ec)
330
{
331
	memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
332
}
333
EXPORT_SYMBOL_GPL(oslec_snapshot);
334
335
/* Dual Path Echo Canceller */
336
337
int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
338
{
339
	int32_t echo_value;
340
	int clean_bg;
341
	int tmp, tmp1;
342
343
	/*
344
	 * Input scaling was found be required to prevent problems when tx
345
	 * starts clipping.  Another possible way to handle this would be the
346
	 * filter coefficent scaling.
347
	 */
348
349
	ec->tx = tx;
350
	ec->rx = rx;
351
	tx >>= 1;
352
	rx >>= 1;
353
354
	/*
355
	 * Filter DC, 3dB point is 160Hz (I think), note 32 bit precision
356
	 * required otherwise values do not track down to 0. Zero at DC, Pole
357
	 * at (1-Beta) on real axis.  Some chip sets (like Si labs) don't
358
	 * need this, but something like a $10 X100P card does.  Any DC really
359
	 * slows down convergence.
360
	 *
361
	 * Note: removes some low frequency from the signal, this reduces the
362
	 * speech quality when listening to samples through headphones but may
363
	 * not be obvious through a telephone handset.
364
	 *
365
	 * Note that the 3dB frequency in radians is approx Beta, e.g. for Beta
366
	 * = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
367
	 */
368
369
	if (ec->adaption_mode & ECHO_CAN_USE_RX_HPF) {
370
		tmp = rx << 15;
371
372
		/*
373
		 * Make sure the gain of the HPF is 1.0. This can still
374
		 * saturate a little under impulse conditions, and it might
375
		 * roll to 32768 and need clipping on sustained peak level
376
		 * signals. However, the scale of such clipping is small, and
377
		 * the error due to any saturation should not markedly affect
378
		 * the downstream processing.
379
		 */
380
		tmp -= (tmp >> 4);
381
382
		ec->rx_1 += -(ec->rx_1 >> DC_LOG2BETA) + tmp - ec->rx_2;
383
384
		/*
385
		 * hard limit filter to prevent clipping.  Note that at this
386
		 * stage rx should be limited to +/- 16383 due to right shift
387
		 * above
388
		 */
389
		tmp1 = ec->rx_1 >> 15;
390
		if (tmp1 > 16383)
391
			tmp1 = 16383;
392
		if (tmp1 < -16383)
393
			tmp1 = -16383;
394
		rx = tmp1;
395
		ec->rx_2 = tmp;
396
	}
397
398
	/* Block average of power in the filter states.  Used for
399
	   adaption power calculation. */
400
401
	{
402
		int new, old;
403
404
		/* efficient "out with the old and in with the new" algorithm so
405
		   we don't have to recalculate over the whole block of
406
		   samples. */
407
		new = (int)tx * (int)tx;
408
		old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
409
		    (int)ec->fir_state.history[ec->fir_state.curr_pos];
410
		ec->Pstates +=
411
		    ((new - old) + (1 << (ec->log2taps-1))) >> ec->log2taps;
412
		if (ec->Pstates < 0)
413
			ec->Pstates = 0;
414
	}
415
416
	/* Calculate short term average levels using simple single pole IIRs */
417
418
	ec->Ltxacc += abs(tx) - ec->Ltx;
419
	ec->Ltx = (ec->Ltxacc + (1 << 4)) >> 5;
420
	ec->Lrxacc += abs(rx) - ec->Lrx;
421
	ec->Lrx = (ec->Lrxacc + (1 << 4)) >> 5;
422
423
	/* Foreground filter */
424
425
	ec->fir_state.coeffs = ec->fir_taps16[0];
426
	echo_value = fir16(&ec->fir_state, tx);
427
	ec->clean = rx - echo_value;
428
	ec->Lcleanacc += abs(ec->clean) - ec->Lclean;
429
	ec->Lclean = (ec->Lcleanacc + (1 << 4)) >> 5;
430
431
	/* Background filter */
432
433
	echo_value = fir16(&ec->fir_state_bg, tx);
434
	clean_bg = rx - echo_value;
435
	ec->Lclean_bgacc += abs(clean_bg) - ec->Lclean_bg;
436
	ec->Lclean_bg = (ec->Lclean_bgacc + (1 << 4)) >> 5;
437
438
	/* Background Filter adaption */
439
440
	/* Almost always adap bg filter, just simple DT and energy
441
	   detection to minimise adaption in cases of strong double talk.
442
	   However this is not critical for the dual path algorithm.
443
	 */
444
	ec->factor = 0;
445
	ec->shift = 0;
446
	if ((ec->nonupdate_dwell == 0)) {
447
		int P, logP, shift;
448
449
		/* Determine:
450
451
		   f = Beta * clean_bg_rx/P ------ (1)
452
453
		   where P is the total power in the filter states.
454
455
		   The Boffins have shown that if we obey (1) we converge
456
		   quickly and avoid instability.
457
458
		   The correct factor f must be in Q30, as this is the fixed
459
		   point format required by the lms_adapt_bg() function,
460
		   therefore the scaled version of (1) is:
461
462
		   (2^30) * f  = (2^30) * Beta * clean_bg_rx/P
463
		   factor      = (2^30) * Beta * clean_bg_rx/P     ----- (2)
464
465
		   We have chosen Beta = 0.25 by experiment, so:
466
467
		   factor      = (2^30) * (2^-2) * clean_bg_rx/P
468
469
						(30 - 2 - log2(P))
470
		   factor      = clean_bg_rx 2                     ----- (3)
471
472
		   To avoid a divide we approximate log2(P) as top_bit(P),
473
		   which returns the position of the highest non-zero bit in
474
		   P.  This approximation introduces an error as large as a
475
		   factor of 2, but the algorithm seems to handle it OK.
476
477
		   Come to think of it a divide may not be a big deal on a
478
		   modern DSP, so its probably worth checking out the cycles
479
		   for a divide versus a top_bit() implementation.
480
		 */
481
482
		P = MIN_TX_POWER_FOR_ADAPTION + ec->Pstates;
483
		logP = top_bit(P) + ec->log2taps;
484
		shift = 30 - 2 - logP;
485
		ec->shift = shift;
486
487
		lms_adapt_bg(ec, clean_bg, shift);
488
	}
489
490
	/* very simple DTD to make sure we dont try and adapt with strong
491
	   near end speech */
492
493
	ec->adapt = 0;
494
	if ((ec->Lrx > MIN_RX_POWER_FOR_ADAPTION) && (ec->Lrx > ec->Ltx))
495
		ec->nonupdate_dwell = DTD_HANGOVER;
496
	if (ec->nonupdate_dwell)
497
		ec->nonupdate_dwell--;
498
499
	/* Transfer logic */
500
501
	/* These conditions are from the dual path paper [1], I messed with
502
	   them a bit to improve performance. */
503
504
	if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
505
	    (ec->nonupdate_dwell == 0) &&
506
	    /* (ec->Lclean_bg < 0.875*ec->Lclean) */
507
	    (8 * ec->Lclean_bg < 7 * ec->Lclean) &&
508
	    /* (ec->Lclean_bg < 0.125*ec->Ltx) */
509
	    (8 * ec->Lclean_bg < ec->Ltx)) {
510
		if (ec->cond_met == 6) {
511
			/*
512
			 * BG filter has had better results for 6 consecutive
513
			 * samples
514
			 */
515
			ec->adapt = 1;
516
			memcpy(ec->fir_taps16[0], ec->fir_taps16[1],
517
				ec->taps * sizeof(int16_t));
518
		} else
519
			ec->cond_met++;
520
	} else
521
		ec->cond_met = 0;
522
523
	/* Non-Linear Processing */
524
525
	ec->clean_nlp = ec->clean;
526
	if (ec->adaption_mode & ECHO_CAN_USE_NLP) {
527
		/*
528
		 * Non-linear processor - a fancy way to say "zap small
529
		 * signals, to avoid residual echo due to (uLaw/ALaw)
530
		 * non-linearity in the channel.".
531
		 */
532
533
		if ((16 * ec->Lclean < ec->Ltx)) {
534
			/*
535
			 * Our e/c has improved echo by at least 24 dB (each
536
			 * factor of 2 is 6dB, so 2*2*2*2=16 is the same as
537
			 * 6+6+6+6=24dB)
538
			 */
539
			if (ec->adaption_mode & ECHO_CAN_USE_CNG) {
540
				ec->cng_level = ec->Lbgn;
541
542
				/*
543
				 * Very elementary comfort noise generation.
544
				 * Just random numbers rolled off very vaguely
545
				 * Hoth-like.  DR: This noise doesn't sound
546
				 * quite right to me - I suspect there are some
547
				 * overlfow issues in the filtering as it's too
548
				 * "crackly".
549
				 * TODO: debug this, maybe just play noise at
550
				 * high level or look at spectrum.
551
				 */
552
553
				ec->cng_rndnum =
554
				    1664525U * ec->cng_rndnum + 1013904223U;
555
				ec->cng_filter =
556
				    ((ec->cng_rndnum & 0xFFFF) - 32768 +
557
				     5 * ec->cng_filter) >> 3;
558
				ec->clean_nlp =
559
				    (ec->cng_filter * ec->cng_level * 8) >> 14;
560
561
			} else if (ec->adaption_mode & ECHO_CAN_USE_CLIP) {
562
				/* This sounds much better than CNG */
563
				if (ec->clean_nlp > ec->Lbgn)
564
					ec->clean_nlp = ec->Lbgn;
565
				if (ec->clean_nlp < -ec->Lbgn)
566
					ec->clean_nlp = -ec->Lbgn;
567
			} else {
568
				/*
569
				 * just mute the residual, doesn't sound very
570
				 * good, used mainly in G168 tests
571
				 */
572
				ec->clean_nlp = 0;
573
			}
574
		} else {
575
			/*
576
			 * Background noise estimator.  I tried a few
577
			 * algorithms here without much luck.  This very simple
578
			 * one seems to work best, we just average the level
579
			 * using a slow (1 sec time const) filter if the
580
			 * current level is less than a (experimentally
581
			 * derived) constant.  This means we dont include high
582
			 * level signals like near end speech.  When combined
583
			 * with CNG or especially CLIP seems to work OK.
584
			 */
585
			if (ec->Lclean < 40) {
586
				ec->Lbgn_acc += abs(ec->clean) - ec->Lbgn;
587
				ec->Lbgn = (ec->Lbgn_acc + (1 << 11)) >> 12;
588
			}
589
		}
590
	}
591
592
	/* Roll around the taps buffer */
593
	if (ec->curr_pos <= 0)
594
		ec->curr_pos = ec->taps;
595
	ec->curr_pos--;
596
597
	if (ec->adaption_mode & ECHO_CAN_DISABLE)
598
		ec->clean_nlp = rx;
599
600
	/* Output scaled back up again to match input scaling */
601
602
	return (int16_t) ec->clean_nlp << 1;
603
}
604
EXPORT_SYMBOL_GPL(oslec_update);
605
606
/* This function is seperated from the echo canceller is it is usually called
607
   as part of the tx process.  See rx HP (DC blocking) filter above, it's
608
   the same design.
609
610
   Some soft phones send speech signals with a lot of low frequency
611
   energy, e.g. down to 20Hz.  This can make the hybrid non-linear
612
   which causes the echo canceller to fall over.  This filter can help
613
   by removing any low frequency before it gets to the tx port of the
614
   hybrid.
615
616
   It can also help by removing and DC in the tx signal.  DC is bad
617
   for LMS algorithms.
618
619
   This is one of the classic DC removal filters, adjusted to provide
620
   sufficient bass rolloff to meet the above requirement to protect hybrids
621
   from things that upset them. The difference between successive samples
622
   produces a lousy HPF, and then a suitably placed pole flattens things out.
623
   The final result is a nicely rolled off bass end. The filtering is
624
   implemented with extended fractional precision, which noise shapes things,
625
   giving very clean DC removal.
626
*/
627
628
int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
629
{
630
	int tmp, tmp1;
631
632
	if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF) {
633
		tmp = tx << 15;
634
635
		/*
636
		 * Make sure the gain of the HPF is 1.0. The first can still
637
		 * saturate a little under impulse conditions, and it might
638
		 * roll to 32768 and need clipping on sustained peak level
639
		 * signals. However, the scale of such clipping is small, and
640
		 * the error due to any saturation should not markedly affect
641
		 * the downstream processing.
642
		 */
643
		tmp -= (tmp >> 4);
644
645
		ec->tx_1 += -(ec->tx_1 >> DC_LOG2BETA) + tmp - ec->tx_2;
646
		tmp1 = ec->tx_1 >> 15;
647
		if (tmp1 > 32767)
648
			tmp1 = 32767;
649
		if (tmp1 < -32767)
650
			tmp1 = -32767;
651
		tx = tmp1;
652
		ec->tx_2 = tmp;
653
	}
654
655
	return tx;
656
}
657
EXPORT_SYMBOL_GPL(oslec_hpf_tx);
658
659
MODULE_LICENSE("GPL");
660
MODULE_AUTHOR("David Rowe");
661
MODULE_DESCRIPTION("Open Source Line Echo Canceller");
662
MODULE_VERSION("0.3.0");
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/echo.h (+175 lines)
Line 0 Link Here
1
/*
2
 * SpanDSP - a series of DSP components for telephony
3
 *
4
 * echo.c - A line echo canceller.  This code is being developed
5
 *          against and partially complies with G168.
6
 *
7
 * Written by Steve Underwood <steveu@coppice.org>
8
 *         and David Rowe <david_at_rowetel_dot_com>
9
 *
10
 * Copyright (C) 2001 Steve Underwood and 2007 David Rowe
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License version 2, as
16
 * published by the Free Software Foundation.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
 */
27
28
#ifndef __ECHO_H
29
#define __ECHO_H
30
31
/*
32
Line echo cancellation for voice
33
34
What does it do?
35
36
This module aims to provide G.168-2002 compliant echo cancellation, to remove
37
electrical echoes (e.g. from 2-4 wire hybrids) from voice calls.
38
39
40
How does it work?
41
42
The heart of the echo cancellor is FIR filter. This is adapted to match the
43
echo impulse response of the telephone line. It must be long enough to
44
adequately cover the duration of that impulse response. The signal transmitted
45
to the telephone line is passed through the FIR filter. Once the FIR is
46
properly adapted, the resulting output is an estimate of the echo signal
47
received from the line. This is subtracted from the received signal. The result
48
is an estimate of the signal which originated at the far end of the line, free
49
from echos of our own transmitted signal.
50
51
The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and
52
was introduced in 1960. It is the commonest form of filter adaption used in
53
things like modem line equalisers and line echo cancellers. There it works very
54
well.  However, it only works well for signals of constant amplitude. It works
55
very poorly for things like speech echo cancellation, where the signal level
56
varies widely.  This is quite easy to fix. If the signal level is normalised -
57
similar to applying AGC - LMS can work as well for a signal of varying
58
amplitude as it does for a modem signal. This normalised least mean squares
59
(NLMS) algorithm is the commonest one used for speech echo cancellation. Many
60
other algorithms exist - e.g. RLS (essentially the same as Kalman filtering),
61
FAP, etc. Some perform significantly better than NLMS.  However, factors such
62
as computational complexity and patents favour the use of NLMS.
63
64
A simple refinement to NLMS can improve its performance with speech. NLMS tends
65
to adapt best to the strongest parts of a signal. If the signal is white noise,
66
the NLMS algorithm works very well. However, speech has more low frequency than
67
high frequency content. Pre-whitening (i.e. filtering the signal to flatten its
68
spectrum) the echo signal improves the adapt rate for speech, and ensures the
69
final residual signal is not heavily biased towards high frequencies. A very
70
low complexity filter is adequate for this, so pre-whitening adds little to the
71
compute requirements of the echo canceller.
72
73
An FIR filter adapted using pre-whitened NLMS performs well, provided certain
74
conditions are met:
75
76
    - The transmitted signal has poor self-correlation.
77
    - There is no signal being generated within the environment being
78
      cancelled.
79
80
The difficulty is that neither of these can be guaranteed.
81
82
If the adaption is performed while transmitting noise (or something fairly
83
noise like, such as voice) the adaption works very well. If the adaption is
84
performed while transmitting something highly correlative (typically narrow
85
band energy such as signalling tones or DTMF), the adaption can go seriously
86
wrong. The reason is there is only one solution for the adaption on a near
87
random signal - the impulse response of the line. For a repetitive signal,
88
there are any number of solutions which converge the adaption, and nothing
89
guides the adaption to choose the generalised one. Allowing an untrained
90
canceller to converge on this kind of narrowband energy probably a good thing,
91
since at least it cancels the tones. Allowing a well converged canceller to
92
continue converging on such energy is just a way to ruin its generalised
93
adaption. A narrowband detector is needed, so adapation can be suspended at
94
appropriate times.
95
96
The adaption process is based on trying to eliminate the received signal. When
97
there is any signal from within the environment being cancelled it may upset
98
the adaption process. Similarly, if the signal we are transmitting is small,
99
noise may dominate and disturb the adaption process. If we can ensure that the
100
adaption is only performed when we are transmitting a significant signal level,
101
and the environment is not, things will be OK. Clearly, it is easy to tell when
102
we are sending a significant signal. Telling, if the environment is generating
103
a significant signal, and doing it with sufficient speed that the adaption will
104
not have diverged too much more we stop it, is a little harder.
105
106
The key problem in detecting when the environment is sourcing significant
107
energy is that we must do this very quickly. Given a reasonably long sample of
108
the received signal, there are a number of strategies which may be used to
109
assess whether that signal contains a strong far end component. However, by the
110
time that assessment is complete the far end signal will have already caused
111
major mis-convergence in the adaption process. An assessment algorithm is
112
needed which produces a fairly accurate result from a very short burst of far
113
end energy.
114
115
How do I use it?
116
117
The echo cancellor processes both the transmit and receive streams sample by
118
sample. The processing function is not declared inline. Unfortunately,
119
cancellation requires many operations per sample, so the call overhead is only
120
a minor burden.
121
*/
122
123
#include "fir.h"
124
#include "oslec.h"
125
126
/*
127
    G.168 echo canceller descriptor. This defines the working state for a line
128
    echo canceller.
129
*/
130
struct oslec_state {
131
	int16_t tx, rx;
132
	int16_t clean;
133
	int16_t clean_nlp;
134
135
	int nonupdate_dwell;
136
	int curr_pos;
137
	int taps;
138
	int log2taps;
139
	int adaption_mode;
140
141
	int cond_met;
142
	int32_t Pstates;
143
	int16_t adapt;
144
	int32_t factor;
145
	int16_t shift;
146
147
	/* Average levels and averaging filter states */
148
	int Ltxacc, Lrxacc, Lcleanacc, Lclean_bgacc;
149
	int Ltx, Lrx;
150
	int Lclean;
151
	int Lclean_bg;
152
	int Lbgn, Lbgn_acc, Lbgn_upper, Lbgn_upper_acc;
153
154
	/* foreground and background filter states */
155
	struct fir16_state_t fir_state;
156
	struct fir16_state_t fir_state_bg;
157
	int16_t *fir_taps16[2];
158
159
	/* DC blocking filter states */
160
	int tx_1, tx_2, rx_1, rx_2;
161
162
	/* optional High Pass Filter states */
163
	int32_t xvtx[5], yvtx[5];
164
	int32_t xvrx[5], yvrx[5];
165
166
	/* Parameters for the optional Hoth noise generator */
167
	int cng_level;
168
	int cng_rndnum;
169
	int cng_filter;
170
171
	/* snapshot sample of coeffs used for development */
172
	int16_t *snapshot;
173
};
174
175
#endif /* __ECHO_H */
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/echo.mod (+2 lines)
Line 0 Link Here
1
/var/tmp/portage/net-misc/dahdi-3.1.0/work/dahdi-linux-3.1.0/drivers/dahdi/../staging/echo/echo.o
2
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/echo.mod.c (+35 lines)
Line 0 Link Here
1
#include <linux/build-salt.h>
2
#include <linux/module.h>
3
#include <linux/vermagic.h>
4
#include <linux/compiler.h>
5
6
BUILD_SALT;
7
8
MODULE_INFO(vermagic, VERMAGIC_STRING);
9
MODULE_INFO(name, KBUILD_MODNAME);
10
11
__visible struct module __this_module
12
__section(.gnu.linkonce.this_module) = {
13
	.name = KBUILD_MODNAME,
14
	.arch = MODULE_ARCH_INIT,
15
};
16
17
#ifdef CONFIG_RETPOLINE
18
MODULE_INFO(retpoline, "Y");
19
#endif
20
21
static const struct modversion_info ____versions[]
22
__used __section(__versions) = {
23
	{ 0xeec9e16d, "module_layout" },
24
	{ 0xc8aa05b8, "kmalloc_caches" },
25
	{ 0xeb233a45, "__kmalloc" },
26
	{ 0xfb578fc5, "memset" },
27
	{ 0xe7107312, "kmem_cache_alloc_trace" },
28
	{ 0x37a0cba, "kfree" },
29
	{ 0x69acdf38, "memcpy" },
30
};
31
32
MODULE_INFO(depends, "");
33
34
35
MODULE_INFO(srcversion, "C113D5B2241DC0505D0F83B");
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/fir.h (+286 lines)
Line 0 Link Here
1
/*
2
 * SpanDSP - a series of DSP components for telephony
3
 *
4
 * fir.h - General telephony FIR routines
5
 *
6
 * Written by Steve Underwood <steveu@coppice.org>
7
 *
8
 * Copyright (C) 2002 Steve Underwood
9
 *
10
 * All rights reserved.
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License version 2, as
14
 * published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
 */
25
26
#if !defined(_FIR_H_)
27
#define _FIR_H_
28
29
/*
30
   Blackfin NOTES & IDEAS:
31
32
   A simple dot product function is used to implement the filter.  This performs
33
   just one MAC/cycle which is inefficient but was easy to implement as a first
34
   pass.  The current Blackfin code also uses an unrolled form of the filter
35
   history to avoid 0 length hardware loop issues.  This is wasteful of
36
   memory.
37
38
   Ideas for improvement:
39
40
   1/ Rewrite filter for dual MAC inner loop.  The issue here is handling
41
   history sample offsets that are 16 bit aligned - the dual MAC needs
42
   32 bit aligmnent.  There are some good examples in libbfdsp.
43
44
   2/ Use the hardware circular buffer facility tohalve memory usage.
45
46
   3/ Consider using internal memory.
47
48
   Using less memory might also improve speed as cache misses will be
49
   reduced. A drop in MIPs and memory approaching 50% should be
50
   possible.
51
52
   The foreground and background filters currenlty use a total of
53
   about 10 MIPs/ch as measured with speedtest.c on a 256 TAP echo
54
   can.
55
*/
56
57
#if defined(USE_MMX)  ||  defined(USE_SSE2)
58
#include "mmx.h"
59
#endif
60
61
/*
62
 * 16 bit integer FIR descriptor. This defines the working state for a single
63
 * instance of an FIR filter using 16 bit integer coefficients.
64
 */
65
struct fir16_state_t {
66
	int taps;
67
	int curr_pos;
68
	const int16_t *coeffs;
69
	int16_t *history;
70
};
71
72
/*
73
 * 32 bit integer FIR descriptor. This defines the working state for a single
74
 * instance of an FIR filter using 32 bit integer coefficients, and filtering
75
 * 16 bit integer data.
76
 */
77
struct fir32_state_t {
78
	int taps;
79
	int curr_pos;
80
	const int32_t *coeffs;
81
	int16_t *history;
82
};
83
84
/*
85
 * Floating point FIR descriptor. This defines the working state for a single
86
 * instance of an FIR filter using floating point coefficients and data.
87
 */
88
struct fir_float_state_t {
89
	int taps;
90
	int curr_pos;
91
	const float *coeffs;
92
	float *history;
93
};
94
95
static inline const int16_t *fir16_create(struct fir16_state_t *fir,
96
					      const int16_t *coeffs, int taps)
97
{
98
	fir->taps = taps;
99
	fir->curr_pos = taps - 1;
100
	fir->coeffs = coeffs;
101
#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
102
	fir->history = kcalloc(2 * taps, sizeof(int16_t), GFP_KERNEL);
103
#else
104
	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
105
#endif
106
	return fir->history;
107
}
108
109
static inline void fir16_flush(struct fir16_state_t *fir)
110
{
111
#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
112
	memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
113
#else
114
	memset(fir->history, 0, fir->taps * sizeof(int16_t));
115
#endif
116
}
117
118
static inline void fir16_free(struct fir16_state_t *fir)
119
{
120
	kfree(fir->history);
121
}
122
123
#ifdef __bfin__
124
static inline int32_t dot_asm(short *x, short *y, int len)
125
{
126
	int dot;
127
128
	len--;
129
130
	__asm__("I0 = %1;\n\t"
131
		"I1 = %2;\n\t"
132
		"A0 = 0;\n\t"
133
		"R0.L = W[I0++] || R1.L = W[I1++];\n\t"
134
		"LOOP dot%= LC0 = %3;\n\t"
135
		"LOOP_BEGIN dot%=;\n\t"
136
		"A0 += R0.L * R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
137
		"LOOP_END dot%=;\n\t"
138
		"A0 += R0.L*R1.L (IS);\n\t"
139
		"R0 = A0;\n\t"
140
		"%0 = R0;\n\t"
141
		: "=&d"(dot)
142
		: "a"(x), "a"(y), "a"(len)
143
		: "I0", "I1", "A1", "A0", "R0", "R1"
144
	);
145
146
	return dot;
147
}
148
#endif
149
150
static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
151
{
152
	int32_t y;
153
#if defined(USE_MMX)
154
	int i;
155
	union mmx_t *mmx_coeffs;
156
	union mmx_t *mmx_hist;
157
158
	fir->history[fir->curr_pos] = sample;
159
	fir->history[fir->curr_pos + fir->taps] = sample;
160
161
	mmx_coeffs = (union mmx_t *) fir->coeffs;
162
	mmx_hist = (union mmx_t *) &fir->history[fir->curr_pos];
163
	i = fir->taps;
164
	pxor_r2r(mm4, mm4);
165
	/* 8 samples per iteration, so the filter must be a multiple of
166
	   8 long. */
167
	while (i > 0) {
168
		movq_m2r(mmx_coeffs[0], mm0);
169
		movq_m2r(mmx_coeffs[1], mm2);
170
		movq_m2r(mmx_hist[0], mm1);
171
		movq_m2r(mmx_hist[1], mm3);
172
		mmx_coeffs += 2;
173
		mmx_hist += 2;
174
		pmaddwd_r2r(mm1, mm0);
175
		pmaddwd_r2r(mm3, mm2);
176
		paddd_r2r(mm0, mm4);
177
		paddd_r2r(mm2, mm4);
178
		i -= 8;
179
	}
180
	movq_r2r(mm4, mm0);
181
	psrlq_i2r(32, mm0);
182
	paddd_r2r(mm0, mm4);
183
	movd_r2m(mm4, y);
184
	emms();
185
#elif defined(USE_SSE2)
186
	int i;
187
	union xmm_t *xmm_coeffs;
188
	union xmm_t *xmm_hist;
189
190
	fir->history[fir->curr_pos] = sample;
191
	fir->history[fir->curr_pos + fir->taps] = sample;
192
193
	xmm_coeffs = (union xmm_t *) fir->coeffs;
194
	xmm_hist = (union xmm_t *) &fir->history[fir->curr_pos];
195
	i = fir->taps;
196
	pxor_r2r(xmm4, xmm4);
197
	/* 16 samples per iteration, so the filter must be a multiple of
198
	   16 long. */
199
	while (i > 0) {
200
		movdqu_m2r(xmm_coeffs[0], xmm0);
201
		movdqu_m2r(xmm_coeffs[1], xmm2);
202
		movdqu_m2r(xmm_hist[0], xmm1);
203
		movdqu_m2r(xmm_hist[1], xmm3);
204
		xmm_coeffs += 2;
205
		xmm_hist += 2;
206
		pmaddwd_r2r(xmm1, xmm0);
207
		pmaddwd_r2r(xmm3, xmm2);
208
		paddd_r2r(xmm0, xmm4);
209
		paddd_r2r(xmm2, xmm4);
210
		i -= 16;
211
	}
212
	movdqa_r2r(xmm4, xmm0);
213
	psrldq_i2r(8, xmm0);
214
	paddd_r2r(xmm0, xmm4);
215
	movdqa_r2r(xmm4, xmm0);
216
	psrldq_i2r(4, xmm0);
217
	paddd_r2r(xmm0, xmm4);
218
	movd_r2m(xmm4, y);
219
#elif defined(__bfin__)
220
	fir->history[fir->curr_pos] = sample;
221
	fir->history[fir->curr_pos + fir->taps] = sample;
222
	y = dot_asm((int16_t *) fir->coeffs, &fir->history[fir->curr_pos],
223
		    fir->taps);
224
#else
225
	int i;
226
	int offset1;
227
	int offset2;
228
229
	fir->history[fir->curr_pos] = sample;
230
231
	offset2 = fir->curr_pos;
232
	offset1 = fir->taps - offset2;
233
	y = 0;
234
	for (i = fir->taps - 1; i >= offset1; i--)
235
		y += fir->coeffs[i] * fir->history[i - offset1];
236
	for (; i >= 0; i--)
237
		y += fir->coeffs[i] * fir->history[i + offset2];
238
#endif
239
	if (fir->curr_pos <= 0)
240
		fir->curr_pos = fir->taps;
241
	fir->curr_pos--;
242
	return (int16_t) (y >> 15);
243
}
244
245
static inline const int16_t *fir32_create(struct fir32_state_t *fir,
246
					      const int32_t *coeffs, int taps)
247
{
248
	fir->taps = taps;
249
	fir->curr_pos = taps - 1;
250
	fir->coeffs = coeffs;
251
	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
252
	return fir->history;
253
}
254
255
static inline void fir32_flush(struct fir32_state_t *fir)
256
{
257
	memset(fir->history, 0, fir->taps * sizeof(int16_t));
258
}
259
260
static inline void fir32_free(struct fir32_state_t *fir)
261
{
262
	kfree(fir->history);
263
}
264
265
static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
266
{
267
	int i;
268
	int32_t y;
269
	int offset1;
270
	int offset2;
271
272
	fir->history[fir->curr_pos] = sample;
273
	offset2 = fir->curr_pos;
274
	offset1 = fir->taps - offset2;
275
	y = 0;
276
	for (i = fir->taps - 1; i >= offset1; i--)
277
		y += fir->coeffs[i] * fir->history[i - offset1];
278
	for (; i >= 0; i--)
279
		y += fir->coeffs[i] * fir->history[i + offset2];
280
	if (fir->curr_pos <= 0)
281
		fir->curr_pos = fir->taps;
282
	fir->curr_pos--;
283
	return (int16_t) (y >> 15);
284
}
285
286
#endif
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/mmx.h (+288 lines)
Line 0 Link Here
1
/*
2
 * mmx.h
3
 * Copyright (C) 1997-2001 H. Dietz and R. Fisher
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
#ifndef AVCODEC_I386MMX_H
22
#define AVCODEC_I386MMX_H
23
24
/*
25
 * The type of an value that fits in an MMX register (note that long
26
 * long constant values MUST be suffixed by LL and unsigned long long
27
 * values by ULL, lest they be truncated by the compiler)
28
 */
29
30
union mmx_t {
31
	long long               q;      /* Quadword (64-bit) value */
32
	unsigned long long      uq;     /* Unsigned Quadword */
33
	int                     d[2];   /* 2 Doubleword (32-bit) values */
34
	unsigned int            ud[2];  /* 2 Unsigned Doubleword */
35
	short                   w[4];   /* 4 Word (16-bit) values */
36
	unsigned short          uw[4];  /* 4 Unsigned Word */
37
	char                    b[8];   /* 8 Byte (8-bit) values */
38
	unsigned char           ub[8];  /* 8 Unsigned Byte */
39
	float                   s[2];   /* Single-precision (32-bit) value */
40
};        /* On an 8-byte (64-bit) boundary */
41
42
/* SSE registers */
43
union xmm_t {
44
	char b[16];
45
};
46
47
48
#define         mmx_i2r(op, imm, reg) \
49
	__asm__ __volatile__ (#op " %0, %%" #reg \
50
			: /* nothing */ \
51
			: "i" (imm))
52
53
#define         mmx_m2r(op, mem, reg) \
54
	__asm__ __volatile__ (#op " %0, %%" #reg \
55
			: /* nothing */ \
56
			: "m" (mem))
57
58
#define         mmx_r2m(op, reg, mem) \
59
	__asm__ __volatile__ (#op " %%" #reg ", %0" \
60
			: "=m" (mem) \
61
			: /* nothing */)
62
63
#define         mmx_r2r(op, regs, regd) \
64
	__asm__ __volatile__ (#op " %" #regs ", %" #regd)
65
66
67
#define         emms() __asm__ __volatile__ ("emms")
68
69
#define         movd_m2r(var, reg)           mmx_m2r(movd, var, reg)
70
#define         movd_r2m(reg, var)           mmx_r2m(movd, reg, var)
71
#define         movd_r2r(regs, regd)         mmx_r2r(movd, regs, regd)
72
73
#define         movq_m2r(var, reg)           mmx_m2r(movq, var, reg)
74
#define         movq_r2m(reg, var)           mmx_r2m(movq, reg, var)
75
#define         movq_r2r(regs, regd)         mmx_r2r(movq, regs, regd)
76
77
#define         packssdw_m2r(var, reg)       mmx_m2r(packssdw, var, reg)
78
#define         packssdw_r2r(regs, regd)     mmx_r2r(packssdw, regs, regd)
79
#define         packsswb_m2r(var, reg)       mmx_m2r(packsswb, var, reg)
80
#define         packsswb_r2r(regs, regd)     mmx_r2r(packsswb, regs, regd)
81
82
#define         packuswb_m2r(var, reg)       mmx_m2r(packuswb, var, reg)
83
#define         packuswb_r2r(regs, regd)     mmx_r2r(packuswb, regs, regd)
84
85
#define         paddb_m2r(var, reg)          mmx_m2r(paddb, var, reg)
86
#define         paddb_r2r(regs, regd)        mmx_r2r(paddb, regs, regd)
87
#define         paddd_m2r(var, reg)          mmx_m2r(paddd, var, reg)
88
#define         paddd_r2r(regs, regd)        mmx_r2r(paddd, regs, regd)
89
#define         paddw_m2r(var, reg)          mmx_m2r(paddw, var, reg)
90
#define         paddw_r2r(regs, regd)        mmx_r2r(paddw, regs, regd)
91
92
#define         paddsb_m2r(var, reg)         mmx_m2r(paddsb, var, reg)
93
#define         paddsb_r2r(regs, regd)       mmx_r2r(paddsb, regs, regd)
94
#define         paddsw_m2r(var, reg)         mmx_m2r(paddsw, var, reg)
95
#define         paddsw_r2r(regs, regd)       mmx_r2r(paddsw, regs, regd)
96
97
#define         paddusb_m2r(var, reg)        mmx_m2r(paddusb, var, reg)
98
#define         paddusb_r2r(regs, regd)      mmx_r2r(paddusb, regs, regd)
99
#define         paddusw_m2r(var, reg)        mmx_m2r(paddusw, var, reg)
100
#define         paddusw_r2r(regs, regd)      mmx_r2r(paddusw, regs, regd)
101
102
#define         pand_m2r(var, reg)           mmx_m2r(pand, var, reg)
103
#define         pand_r2r(regs, regd)         mmx_r2r(pand, regs, regd)
104
105
#define         pandn_m2r(var, reg)          mmx_m2r(pandn, var, reg)
106
#define         pandn_r2r(regs, regd)        mmx_r2r(pandn, regs, regd)
107
108
#define         pcmpeqb_m2r(var, reg)        mmx_m2r(pcmpeqb, var, reg)
109
#define         pcmpeqb_r2r(regs, regd)      mmx_r2r(pcmpeqb, regs, regd)
110
#define         pcmpeqd_m2r(var, reg)        mmx_m2r(pcmpeqd, var, reg)
111
#define         pcmpeqd_r2r(regs, regd)      mmx_r2r(pcmpeqd, regs, regd)
112
#define         pcmpeqw_m2r(var, reg)        mmx_m2r(pcmpeqw, var, reg)
113
#define         pcmpeqw_r2r(regs, regd)      mmx_r2r(pcmpeqw, regs, regd)
114
115
#define         pcmpgtb_m2r(var, reg)        mmx_m2r(pcmpgtb, var, reg)
116
#define         pcmpgtb_r2r(regs, regd)      mmx_r2r(pcmpgtb, regs, regd)
117
#define         pcmpgtd_m2r(var, reg)        mmx_m2r(pcmpgtd, var, reg)
118
#define         pcmpgtd_r2r(regs, regd)      mmx_r2r(pcmpgtd, regs, regd)
119
#define         pcmpgtw_m2r(var, reg)        mmx_m2r(pcmpgtw, var, reg)
120
#define         pcmpgtw_r2r(regs, regd)      mmx_r2r(pcmpgtw, regs, regd)
121
122
#define         pmaddwd_m2r(var, reg)        mmx_m2r(pmaddwd, var, reg)
123
#define         pmaddwd_r2r(regs, regd)      mmx_r2r(pmaddwd, regs, regd)
124
125
#define         pmulhw_m2r(var, reg)         mmx_m2r(pmulhw, var, reg)
126
#define         pmulhw_r2r(regs, regd)       mmx_r2r(pmulhw, regs, regd)
127
128
#define         pmullw_m2r(var, reg)         mmx_m2r(pmullw, var, reg)
129
#define         pmullw_r2r(regs, regd)       mmx_r2r(pmullw, regs, regd)
130
131
#define         por_m2r(var, reg)            mmx_m2r(por, var, reg)
132
#define         por_r2r(regs, regd)          mmx_r2r(por, regs, regd)
133
134
#define         pslld_i2r(imm, reg)          mmx_i2r(pslld, imm, reg)
135
#define         pslld_m2r(var, reg)          mmx_m2r(pslld, var, reg)
136
#define         pslld_r2r(regs, regd)        mmx_r2r(pslld, regs, regd)
137
#define         psllq_i2r(imm, reg)          mmx_i2r(psllq, imm, reg)
138
#define         psllq_m2r(var, reg)          mmx_m2r(psllq, var, reg)
139
#define         psllq_r2r(regs, regd)        mmx_r2r(psllq, regs, regd)
140
#define         psllw_i2r(imm, reg)          mmx_i2r(psllw, imm, reg)
141
#define         psllw_m2r(var, reg)          mmx_m2r(psllw, var, reg)
142
#define         psllw_r2r(regs, regd)        mmx_r2r(psllw, regs, regd)
143
144
#define         psrad_i2r(imm, reg)          mmx_i2r(psrad, imm, reg)
145
#define         psrad_m2r(var, reg)          mmx_m2r(psrad, var, reg)
146
#define         psrad_r2r(regs, regd)        mmx_r2r(psrad, regs, regd)
147
#define         psraw_i2r(imm, reg)          mmx_i2r(psraw, imm, reg)
148
#define         psraw_m2r(var, reg)          mmx_m2r(psraw, var, reg)
149
#define         psraw_r2r(regs, regd)        mmx_r2r(psraw, regs, regd)
150
151
#define         psrld_i2r(imm, reg)          mmx_i2r(psrld, imm, reg)
152
#define         psrld_m2r(var, reg)          mmx_m2r(psrld, var, reg)
153
#define         psrld_r2r(regs, regd)        mmx_r2r(psrld, regs, regd)
154
#define         psrlq_i2r(imm, reg)          mmx_i2r(psrlq, imm, reg)
155
#define         psrlq_m2r(var, reg)          mmx_m2r(psrlq, var, reg)
156
#define         psrlq_r2r(regs, regd)        mmx_r2r(psrlq, regs, regd)
157
#define         psrlw_i2r(imm, reg)          mmx_i2r(psrlw, imm, reg)
158
#define         psrlw_m2r(var, reg)          mmx_m2r(psrlw, var, reg)
159
#define         psrlw_r2r(regs, regd)        mmx_r2r(psrlw, regs, regd)
160
161
#define         psubb_m2r(var, reg)          mmx_m2r(psubb, var, reg)
162
#define         psubb_r2r(regs, regd)        mmx_r2r(psubb, regs, regd)
163
#define         psubd_m2r(var, reg)          mmx_m2r(psubd, var, reg)
164
#define         psubd_r2r(regs, regd)        mmx_r2r(psubd, regs, regd)
165
#define         psubw_m2r(var, reg)          mmx_m2r(psubw, var, reg)
166
#define         psubw_r2r(regs, regd)        mmx_r2r(psubw, regs, regd)
167
168
#define         psubsb_m2r(var, reg)         mmx_m2r(psubsb, var, reg)
169
#define         psubsb_r2r(regs, regd)       mmx_r2r(psubsb, regs, regd)
170
#define         psubsw_m2r(var, reg)         mmx_m2r(psubsw, var, reg)
171
#define         psubsw_r2r(regs, regd)       mmx_r2r(psubsw, regs, regd)
172
173
#define         psubusb_m2r(var, reg)        mmx_m2r(psubusb, var, reg)
174
#define         psubusb_r2r(regs, regd)      mmx_r2r(psubusb, regs, regd)
175
#define         psubusw_m2r(var, reg)        mmx_m2r(psubusw, var, reg)
176
#define         psubusw_r2r(regs, regd)      mmx_r2r(psubusw, regs, regd)
177
178
#define         punpckhbw_m2r(var, reg)      mmx_m2r(punpckhbw, var, reg)
179
#define         punpckhbw_r2r(regs, regd)    mmx_r2r(punpckhbw, regs, regd)
180
#define         punpckhdq_m2r(var, reg)      mmx_m2r(punpckhdq, var, reg)
181
#define         punpckhdq_r2r(regs, regd)    mmx_r2r(punpckhdq, regs, regd)
182
#define         punpckhwd_m2r(var, reg)      mmx_m2r(punpckhwd, var, reg)
183
#define         punpckhwd_r2r(regs, regd)    mmx_r2r(punpckhwd, regs, regd)
184
185
#define         punpcklbw_m2r(var, reg)      mmx_m2r(punpcklbw, var, reg)
186
#define         punpcklbw_r2r(regs, regd)    mmx_r2r(punpcklbw, regs, regd)
187
#define         punpckldq_m2r(var, reg)      mmx_m2r(punpckldq, var, reg)
188
#define         punpckldq_r2r(regs, regd)    mmx_r2r(punpckldq, regs, regd)
189
#define         punpcklwd_m2r(var, reg)      mmx_m2r(punpcklwd, var, reg)
190
#define         punpcklwd_r2r(regs, regd)    mmx_r2r(punpcklwd, regs, regd)
191
192
#define         pxor_m2r(var, reg)           mmx_m2r(pxor, var, reg)
193
#define         pxor_r2r(regs, regd)         mmx_r2r(pxor, regs, regd)
194
195
196
/* 3DNOW extensions */
197
198
#define         pavgusb_m2r(var, reg)        mmx_m2r(pavgusb, var, reg)
199
#define         pavgusb_r2r(regs, regd)      mmx_r2r(pavgusb, regs, regd)
200
201
202
/* AMD MMX extensions - also available in intel SSE */
203
204
205
#define         mmx_m2ri(op, mem, reg, imm) \
206
	__asm__ __volatile__ (#op " %1, %0, %%" #reg \
207
			: /* nothing */ \
208
			: "m" (mem), "i" (imm))
209
#define         mmx_r2ri(op, regs, regd, imm) \
210
	__asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
211
			: /* nothing */ \
212
			: "i" (imm))
213
214
#define         mmx_fetch(mem, hint) \
215
	__asm__ __volatile__ ("prefetch" #hint " %0" \
216
			: /* nothing */ \
217
			: "m" (mem))
218
219
220
#define         maskmovq(regs, maskreg)      mmx_r2ri(maskmovq, regs, maskreg)
221
222
#define         movntq_r2m(mmreg, var)       mmx_r2m(movntq, mmreg, var)
223
224
#define         pavgb_m2r(var, reg)          mmx_m2r(pavgb, var, reg)
225
#define         pavgb_r2r(regs, regd)        mmx_r2r(pavgb, regs, regd)
226
#define         pavgw_m2r(var, reg)          mmx_m2r(pavgw, var, reg)
227
#define         pavgw_r2r(regs, regd)        mmx_r2r(pavgw, regs, regd)
228
229
#define         pextrw_r2r(mmreg, reg, imm)  mmx_r2ri(pextrw, mmreg, reg, imm)
230
231
#define         pinsrw_r2r(reg, mmreg, imm)  mmx_r2ri(pinsrw, reg, mmreg, imm)
232
233
#define         pmaxsw_m2r(var, reg)         mmx_m2r(pmaxsw, var, reg)
234
#define         pmaxsw_r2r(regs, regd)       mmx_r2r(pmaxsw, regs, regd)
235
236
#define         pmaxub_m2r(var, reg)         mmx_m2r(pmaxub, var, reg)
237
#define         pmaxub_r2r(regs, regd)       mmx_r2r(pmaxub, regs, regd)
238
239
#define         pminsw_m2r(var, reg)         mmx_m2r(pminsw, var, reg)
240
#define         pminsw_r2r(regs, regd)       mmx_r2r(pminsw, regs, regd)
241
242
#define         pminub_m2r(var, reg)         mmx_m2r(pminub, var, reg)
243
#define         pminub_r2r(regs, regd)       mmx_r2r(pminub, regs, regd)
244
245
#define         pmovmskb(mmreg, reg) \
246
	__asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
247
248
#define         pmulhuw_m2r(var, reg)        mmx_m2r(pmulhuw, var, reg)
249
#define         pmulhuw_r2r(regs, regd)      mmx_r2r(pmulhuw, regs, regd)
250
251
#define         prefetcht0(mem)              mmx_fetch(mem, t0)
252
#define         prefetcht1(mem)              mmx_fetch(mem, t1)
253
#define         prefetcht2(mem)              mmx_fetch(mem, t2)
254
#define         prefetchnta(mem)             mmx_fetch(mem, nta)
255
256
#define         psadbw_m2r(var, reg)         mmx_m2r(psadbw, var, reg)
257
#define         psadbw_r2r(regs, regd)       mmx_r2r(psadbw, regs, regd)
258
259
#define         pshufw_m2r(var, reg, imm)    mmx_m2ri(pshufw, var, reg, imm)
260
#define         pshufw_r2r(regs, regd, imm)  mmx_r2ri(pshufw, regs, regd, imm)
261
262
#define         sfence() __asm__ __volatile__ ("sfence\n\t")
263
264
/* SSE2 */
265
#define         pshufhw_m2r(var, reg, imm)   mmx_m2ri(pshufhw, var, reg, imm)
266
#define         pshufhw_r2r(regs, regd, imm) mmx_r2ri(pshufhw, regs, regd, imm)
267
#define         pshuflw_m2r(var, reg, imm)   mmx_m2ri(pshuflw, var, reg, imm)
268
#define         pshuflw_r2r(regs, regd, imm) mmx_r2ri(pshuflw, regs, regd, imm)
269
270
#define         pshufd_r2r(regs, regd, imm)  mmx_r2ri(pshufd, regs, regd, imm)
271
272
#define         movdqa_m2r(var, reg)         mmx_m2r(movdqa, var, reg)
273
#define         movdqa_r2m(reg, var)         mmx_r2m(movdqa, reg, var)
274
#define         movdqa_r2r(regs, regd)       mmx_r2r(movdqa, regs, regd)
275
#define         movdqu_m2r(var, reg)         mmx_m2r(movdqu, var, reg)
276
#define         movdqu_r2m(reg, var)         mmx_r2m(movdqu, reg, var)
277
#define         movdqu_r2r(regs, regd)       mmx_r2r(movdqu, regs, regd)
278
279
#define         pmullw_r2m(reg, var)         mmx_r2m(pmullw, reg, var)
280
281
#define         pslldq_i2r(imm, reg)         mmx_i2r(pslldq, imm, reg)
282
#define         psrldq_i2r(imm, reg)         mmx_i2r(psrldq, imm, reg)
283
284
#define         punpcklqdq_r2r(regs, regd)   mmx_r2r(punpcklqdq, regs, regd)
285
#define         punpckhqdq_r2r(regs, regd)   mmx_r2r(punpckhqdq, regs, regd)
286
287
288
#endif /* AVCODEC_I386MMX_H */
(-)dahdi-linux-3.1.0.original/drivers/staging/echo/oslec.h (+94 lines)
Line 0 Link Here
1
/*
2
 *  OSLEC - A line echo canceller.  This code is being developed
3
 *          against and partially complies with G168. Using code from SpanDSP
4
 *
5
 * Written by Steve Underwood <steveu@coppice.org>
6
 *         and David Rowe <david_at_rowetel_dot_com>
7
 *
8
 * Copyright (C) 2001 Steve Underwood and 2007-2008 David Rowe
9
 *
10
 * All rights reserved.
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License version 2, as
14
 * published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
 *
25
 */
26
27
#ifndef __OSLEC_H
28
#define __OSLEC_H
29
30
/* Mask bits for the adaption mode */
31
#define ECHO_CAN_USE_ADAPTION	0x01
32
#define ECHO_CAN_USE_NLP	0x02
33
#define ECHO_CAN_USE_CNG	0x04
34
#define ECHO_CAN_USE_CLIP	0x08
35
#define ECHO_CAN_USE_TX_HPF	0x10
36
#define ECHO_CAN_USE_RX_HPF	0x20
37
#define ECHO_CAN_DISABLE	0x40
38
39
/**
40
 * oslec_state: G.168 echo canceller descriptor.
41
 *
42
 * This defines the working state for a line echo canceller.
43
 */
44
struct oslec_state;
45
46
/**
47
 * oslec_create - Create a voice echo canceller context.
48
 * @len: The length of the canceller, in samples.
49
 * @return: The new canceller context, or NULL if the canceller could not be
50
 * created.
51
 */
52
struct oslec_state *oslec_create(int len, int adaption_mode);
53
54
/**
55
 * oslec_free - Free a voice echo canceller context.
56
 * @ec: The echo canceller context.
57
 */
58
void oslec_free(struct oslec_state *ec);
59
60
/**
61
 * oslec_flush - Flush (reinitialise) a voice echo canceller context.
62
 * @ec: The echo canceller context.
63
 */
64
void oslec_flush(struct oslec_state *ec);
65
66
/**
67
 * oslec_adaption_mode - set the adaption mode of a voice echo canceller context.
68
 * @ec The echo canceller context.
69
 * @adaption_mode: The mode.
70
 */
71
void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode);
72
73
void oslec_snapshot(struct oslec_state *ec);
74
75
/**
76
 * oslec_update: Process a sample through a voice echo canceller.
77
 * @ec: The echo canceller context.
78
 * @tx: The transmitted audio sample.
79
 * @rx: The received audio sample.
80
 *
81
 * The return value is the clean (echo cancelled) received sample.
82
 */
83
int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx);
84
85
/**
86
 * oslec_hpf_tx: Process to high pass filter the tx signal.
87
 * @ec: The echo canceller context.
88
 * @tx: The transmitted auio sample.
89
 *
90
 * The return value is the HP filtered transmit sample, send this to your D/A.
91
 */
92
int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx);
93
94
#endif /* __OSLEC_H */
(-)dahdi-linux-3.1.0.original/include/dahdi/version.h (+6 lines)
Line 0 Link Here
1
/*
2
 * version.h 
3
 * Automatically generated
4
 */
5
#define DAHDI_VERSION "3.1.0"
6

Return to bug 705860