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

Collapse All | Expand All

(-)dahdi-linux-2.2.0.2/drivers/dahdi/Kbuild (+6 lines)
Lines 1-10 Link Here
1
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI)			+= dahdi.o
1
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI)			+= dahdi.o
2
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200)		+= opvxa1200.o
2
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DUMMY)		+= dahdi_dummy.o
3
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DUMMY)		+= dahdi_dummy.o
4
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCOPENPCI)		+= wcopenpci.o
3
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC)		+= dahdi_dynamic.o
5
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC)		+= dahdi_dynamic.o
6
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ZAPHFC)		+= zaphfc/
4
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_LOC)	+= dahdi_dynamic_loc.o
7
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_LOC)	+= dahdi_dynamic_loc.o
8
obj-$(DAHDI_BUILD_ALL)$(CONFIG_ECHO)			+= ../staging/echo/
5
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH)	+= dahdi_dynamic_eth.o
9
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH)	+= dahdi_dynamic_eth.o
10
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_OSLEC)	+= dahdi_echocan_oslec.o
6
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE)		+= dahdi_transcode.o
11
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE)		+= dahdi_transcode.o
7
12
13
8
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP)		+= wct4xxp/
14
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP)		+= wct4xxp/
9
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP)		+= wctc4xxp/
15
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP)		+= wctc4xxp/
10
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP)	+= wctdm24xxp/
16
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP)	+= wctdm24xxp/
(-)dahdi-linux-2.2.0.2/drivers/dahdi/Kconfig (+102 lines)
Lines 279-281 Link Here
279
	  If unsure, say Y.
279
	  If unsure, say Y.
280
280
281
source "drivers/dahdi/xpp/Kconfig"
281
source "drivers/dahdi/xpp/Kconfig"
282
283
284
config DAHDI_OPVXA1200
285
	tristate "OpenVox A1200P FXS/FXO Interface"
286
	depends on DAHDI && PCI
287
	default DAHDI
288
	---help---
289
	  This driver provides support for the OpenVox A1200P FXS/FXO Interface.
290
291
	  To compile this driver as a module, choose M here: the
292
	  module will be called opvxa1200.
293
294
	  If unsure, say Y.
295
296
config DAHDI_WCOPENPCI
297
	tristate "Voicetronix OpenPCI Interface DAHDI driver"
298
	depends on DAHDI && PCI
299
	default DAHDI
300
	---help---
301
	  This driver provides support for the Voicetronix OpenPCI Interface.
302
303
	  To compile this driver as a module, choose M here: the
304
	  module will be called wcopenpci.
305
306
	  If unsure, say Y.
307
308
config DAHDI_ZAPHFC
309
	tristate "HFC-S DAHDI Driver"
310
	depends on DAHDI && PCI
311
	default DAHDI
312
	---help---
313
	  This driver provides DAHDI support for various HFC-S single-port 
314
          ISDN (BRI) cards.
315
316
	  To compile this driver as a module, choose M here: the
317
	  module will be called zaphfc.
318
319
	  If unsure, say Y.
320
321
config ECHO
322
	tristate "Line Echo Canceller support"
323
	default DAHDI
324
	--help--
325
	  This driver provides line echo cancelling support for mISDN and
326
	  DAHDI drivers.
327
328
	  To compile this driver as a module, choose M here: the
329
	  module will be called echo.
330
331
	  If unsure, say Y.
332
333
334
335
config DAHDI_OPVXA1200
336
	tristate "OpenVox A1200P FXS/FXO Interface"
337
	depends on DAHDI && PCI
338
	default DAHDI
339
	---help---
340
	  This driver provides support for the OpenVox A1200P FXS/FXO Interface.
341
342
	  To compile this driver as a module, choose M here: the
343
	  module will be called opvxa1200.
344
345
	  If unsure, say Y.
346
347
config DAHDI_WCOPENPCI
348
	tristate "Voicetronix OpenPCI Interface DAHDI driver"
349
	depends on DAHDI && PCI
350
	default DAHDI
351
	---help---
352
	  This driver provides support for the Voicetronix OpenPCI Interface.
353
354
	  To compile this driver as a module, choose M here: the
355
	  module will be called wcopenpci.
356
357
	  If unsure, say Y.
358
359
config DAHDI_ZAPHFC
360
	tristate "HFC-S DAHDI Driver"
361
	depends on DAHDI && PCI
362
	default DAHDI
363
	---help---
364
	  This driver provides DAHDI support for various HFC-S single-port 
365
          ISDN (BRI) cards.
366
367
	  To compile this driver as a module, choose M here: the
368
	  module will be called zaphfc.
369
370
	  If unsure, say Y.
371
372
config ECHO
373
	tristate "Line Echo Canceller support"
374
	default DAHDI
375
	--help--
376
	  This driver provides line echo cancelling support for mISDN and
377
	  DAHDI drivers.
378
379
	  To compile this driver as a module, choose M here: the
380
	  module will be called echo.
381
382
	  If unsure, say Y.
383
(-)dahdi-linux-2.2.0.2/drivers/dahdi/opvxa1200.c (+3017 lines)
Line 0 Link Here
1
/*
2
 * OpenVox A1200P FXS/FXO Interface Driver for DAHDI Telephony interface
3
 *
4
 * Modify from wctdm.c by MiaoLin<miaolin@openvox.com.cn>
5
 *
6
 * All rights reserved.
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 * 
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 * 
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
21
 *
22
 */
23
24
/* Rev histroy
25
 *
26
 * Rev 0.10 initial version	
27
 * Rev 0.11 
28
 * 	fixed the led light on/off bug.
29
 * 	modify some wctdm print to opvxa1200
30
 * 	support firmware version 1.2, faster i/o operation, and better LED control.
31
 * 
32
 * Rev 0.12 patched to support new pci id 0x8519
33
 * Rev 0.13 patched to remove the warning during compile under kernel 2.6.22 
34
 * Rev 0.14 patched to remove the bug for ZAP_IRQ_SHARED , 3/9/2007 
35
 * Rev 0.15 patched to support new pci ID 0X9532 by james.zhu, 23/10/2007
36
 * Rev 0.16 support new pci id 0x9559 by Miao Lin 21/3/2008
37
 * Rev 0.17 
38
 *	patched a few bugs, 
39
 *	add hwgain support.
40
 *	fixed A800P version check
41
 * Rev 1.4.9.2 
42
 *		Only generate 8 channels for A800P
43
 * 		Version number synced to zaptel distribution.
44
 * Rev 1.4.9.2.a
45
 *		Fixed freeregion.
46
 * 		
47
 * Rev 1.4.9.2.b
48
 *    Add cid before first ring support.
49
 *    New Paremeters:
50
 *          	cidbeforering : set to 1 will cause the card enable cidbeforering function. default 0
51
 * 		cidbuflen : length of cid buffer, in msec, default 3000 msec.
52
 *              cidtimeout : time out of a ring, default 6000msec
53
 *   	User must set cidstart=polarity in zapata.conf to use with this feature
54
 * 		cidsignalling = signalling format send before 1st ring. most likely dtmf.
55
 * 
56
 * Rev 1.4.9.2.c
57
 * 	add driver parameter cidtimeout.
58
 * 
59
 * Rev 1.4.9.2.d 
60
 *  	add debug stuff to test fxs power alarm
61
 *  
62
 * Rev 1.4.11
63
 *  	Support enhanced full scale tx/rx for FXO required by europe standard (Register 30, acim) (module parm fxofullscale)
64
 *  
65
 * Rev 1.4.12 2008/10/17
66
 *      Fixed bug cause FXS module report fake power alarm.
67
 *      Power alarm debug stuff removed.
68
 * 
69
 * Rev 2.0 DAHDI 2008/10/17
70
 *
71
 * Rev 2.0.1 add new pci id 0x9599
72
 * Re 2.0.2 12/01/2009  
73
       add fixedtimepolarity: set time(ms) when send polarity after 1st ring happen. 
74
 *				Sometimes the dtmf cid is sent just after first ring off, and the system do not have 
75
 *				enough time to start detect 1st dtmf.
76
 *				0 means send polarity at the end of 1st ring.
77
 *				x means send ploarity after x ms of 1st ring begin.
78
 * 
79
 * Rev 2.0.3 12/01/2009 
80
 *        Add touch_softlockup_watchdog() in wctdm_hardware_init, to avoid cpu softlockup system message for FXS.
81
 *
82
 *
83
 * Rev 1.4.12.4  17/04/2009 James.zhu
84
 *       Changed wctdm_voicedaa_check_hook() to detect FXO battery and solved the problem with dial(dahdi/go/XXXXXXXXXX)
85
 *       add alarm detection for FXO
86
 *
87
 * Rev 1.4.12.5 01/10/2009 james.zhu
88
 *       Add jiffies for 5 second in wctdm_hardware_init
89
 *
90
 *
91
 */ 
92
93
#include <linux/kernel.h>
94
#include <linux/errno.h>
95
#include <linux/module.h>
96
#include <linux/init.h>
97
#include <linux/errno.h>
98
#include <linux/pci.h>
99
#include <linux/interrupt.h>
100
#include <linux/moduleparam.h>
101
#include <asm/io.h>
102
#include "proslic.h"
103
   
104
/* MiaoLin debug start */
105
#include <linux/string.h>
106
#include <asm/uaccess.h> 	/* get_fs(), set_fs(), KERNEL_DS */
107
#include <linux/file.h> 	/* fput() */
108
/* MiaoLin debug end */
109
  
110
111
/*
112
 *  Define for audio vs. register based ring detection
113
 *  
114
 */
115
/* #define AUDIO_RINGCHECK  */
116
117
/*
118
  Experimental max loop current limit for the proslic
119
  Loop current limit is from 20 mA to 41 mA in steps of 3
120
  (according to datasheet)
121
  So set the value below to:
122
  0x00 : 20mA (default)
123
  0x01 : 23mA
124
  0x02 : 26mA
125
  0x03 : 29mA
126
  0x04 : 32mA
127
  0x05 : 35mA
128
  0x06 : 37mA
129
  0x07 : 41mA
130
*/
131
static int loopcurrent = 20;
132
133
static int reversepolarity = 0;
134
135
static alpha  indirect_regs[] =
136
{
137
{0,255,"DTMF_ROW_0_PEAK",0x55C2},
138
{1,255,"DTMF_ROW_1_PEAK",0x51E6},
139
{2,255,"DTMF_ROW2_PEAK",0x4B85},
140
{3,255,"DTMF_ROW3_PEAK",0x4937},
141
{4,255,"DTMF_COL1_PEAK",0x3333},
142
{5,255,"DTMF_FWD_TWIST",0x0202},
143
{6,255,"DTMF_RVS_TWIST",0x0202},
144
{7,255,"DTMF_ROW_RATIO_TRES",0x0198},
145
{8,255,"DTMF_COL_RATIO_TRES",0x0198},
146
{9,255,"DTMF_ROW_2ND_ARM",0x0611},
147
{10,255,"DTMF_COL_2ND_ARM",0x0202},
148
{11,255,"DTMF_PWR_MIN_TRES",0x00E5},
149
{12,255,"DTMF_OT_LIM_TRES",0x0A1C},
150
{13,0,"OSC1_COEF",0x7B30},
151
{14,1,"OSC1X",0x0063},
152
{15,2,"OSC1Y",0x0000},
153
{16,3,"OSC2_COEF",0x7870},
154
{17,4,"OSC2X",0x007D},
155
{18,5,"OSC2Y",0x0000},
156
{19,6,"RING_V_OFF",0x0000},
157
{20,7,"RING_OSC",0x7EF0},
158
{21,8,"RING_X",0x0160},
159
{22,9,"RING_Y",0x0000},
160
{23,255,"PULSE_ENVEL",0x2000},
161
{24,255,"PULSE_X",0x2000},
162
{25,255,"PULSE_Y",0x0000},
163
//{26,13,"RECV_DIGITAL_GAIN",0x4000},	// playback volume set lower
164
{26,13,"RECV_DIGITAL_GAIN",0x2000},	// playback volume set lower
165
{27,14,"XMIT_DIGITAL_GAIN",0x4000},
166
//{27,14,"XMIT_DIGITAL_GAIN",0x2000},
167
{28,15,"LOOP_CLOSE_TRES",0x1000},
168
{29,16,"RING_TRIP_TRES",0x3600},
169
{30,17,"COMMON_MIN_TRES",0x1000},
170
{31,18,"COMMON_MAX_TRES",0x0200},
171
{32,19,"PWR_ALARM_Q1Q2",0x07C0},
172
{33,20,"PWR_ALARM_Q3Q4",0x2600},
173
{34,21,"PWR_ALARM_Q5Q6",0x1B80},
174
{35,22,"LOOP_CLOSURE_FILTER",0x8000},
175
{36,23,"RING_TRIP_FILTER",0x0320},
176
{37,24,"TERM_LP_POLE_Q1Q2",0x008C},
177
{38,25,"TERM_LP_POLE_Q3Q4",0x0100},
178
{39,26,"TERM_LP_POLE_Q5Q6",0x0010},
179
{40,27,"CM_BIAS_RINGING",0x0C00},
180
{41,64,"DCDC_MIN_V",0x0C00},
181
{42,255,"DCDC_XTRA",0x1000},
182
{43,66,"LOOP_CLOSE_TRES_LOW",0x1000},
183
};
184
185
186
#include <dahdi/kernel.h>
187
#include <dahdi/wctdm_user.h>
188
189
#include "fxo_modes.h"
190
191
#define NUM_FXO_REGS 60
192
193
#define WC_MAX_IFACES 128
194
195
#define WC_OFFSET	4	/* Offset between transmit and receive, in bytes. */
196
#define WC_SYNCFLAG	0xca1ef1ac
197
198
#define WC_CNTL    	0x00
199
#define WC_OPER		0x01
200
#define WC_AUXC    	0x02
201
#define WC_AUXD    	0x03
202
#define WC_MASK0   	0x04
203
#define WC_MASK1   	0x05
204
#define WC_INTSTAT 	0x06
205
#define WC_AUXR		0x07
206
207
#define WC_DMAWS	0x08
208
#define WC_DMAWI	0x0c
209
#define WC_DMAWE	0x10
210
#define WC_DMARS	0x18
211
#define WC_DMARI	0x1c
212
#define WC_DMARE	0x20
213
214
#define WC_AUXFUNC	0x2b
215
#define WC_SERCTL	0x2d
216
#define WC_FSCDELAY	0x2f
217
218
#define WC_REGBASE	0xc0
219
220
#define WC_VER		0x0
221
#define WC_CS		0x1
222
#define WC_SPICTRL	0x2
223
#define WC_SPIDATA	0x3
224
225
#define BIT_SPI_BYHW 	(1 << 0)
226
#define BIT_SPI_BUSY    (1 << 1)	// 0=can read/write spi, 1=spi working.
227
#define BIT_SPI_START	(1 << 2)
228
229
230
#define BIT_LED_CLK     (1 << 0)	// MiaoLin add to control the led. 
231
#define BIT_LED_DATA    (1 << 1)	// MiaoLin add to control the led.
232
233
#define BIT_CS		(1 << 2)
234
#define BIT_SCLK	(1 << 3)
235
#define BIT_SDI		(1 << 4)
236
#define BIT_SDO		(1 << 5)
237
238
#define FLAG_EMPTY	0
239
#define FLAG_WRITE	1
240
#define FLAG_READ	2
241
#define DEFAULT_RING_DEBOUNCE		64		/* Ringer Debounce (64 ms) */
242
#define POLARITY_DEBOUNCE 	64  	/* Polarity debounce (64 ms) */
243
#define OHT_TIMER		6000	/* How long after RING to retain OHT */
244
245
#define FLAG_3215	(1 << 0)
246
#define FLAG_A800	(1 << 7)
247
248
#define MAX_NUM_CARDS 12
249
#define NUM_CARDS 12
250
#define NUM_FLAG  4	/* number of flag channels. */
251
252
253
enum cid_hook_state {
254
	CID_STATE_IDLE = 0,
255
	CID_STATE_RING_ON,
256
	CID_STATE_RING_OFF,
257
	CID_STATE_WAIT_RING_FINISH
258
};
259
260
/* if you want to record the last 8 sec voice before the driver unload, uncomment it and rebuild. */
261
/* #define TEST_LOG_INCOME_VOICE */
262
#define voc_buffer_size (8000*8)
263
264
265
#define MAX_ALARMS 10
266
267
#define MOD_TYPE_FXS	0
268
#define MOD_TYPE_FXO	1
269
270
#define MINPEGTIME	10 * 8		/* 30 ms peak to peak gets us no more than 100 Hz */
271
#define PEGTIME		50 * 8		/* 50ms peak to peak gets us rings of 10 Hz or more */
272
#define PEGCOUNT	5		/* 5 cycles of pegging means RING */
273
274
#define NUM_CAL_REGS 12
275
276
struct calregs {
277
	unsigned char vals[NUM_CAL_REGS];
278
};
279
280
enum proslic_power_warn {
281
	PROSLIC_POWER_UNKNOWN = 0,
282
	PROSLIC_POWER_ON,
283
	PROSLIC_POWER_WARNED,
284
};
285
286
enum battery_state {
287
	BATTERY_UNKNOWN = 0,
288
	BATTERY_PRESENT,
289
	BATTERY_LOST,
290
};
291
struct wctdm {
292
	struct pci_dev *dev;
293
	char *variety;
294
	struct dahdi_span span;
295
	unsigned char ios;
296
	int usecount;
297
	unsigned int intcount;
298
	int dead;
299
	int pos;
300
	int flags[MAX_NUM_CARDS];
301
	int freeregion;
302
	int alt;
303
	int curcard;
304
	int cardflag;		/* Bit-map of present cards */
305
	enum proslic_power_warn proslic_power;
306
	spinlock_t lock;
307
308
	union {
309
		struct fxo {
310
#ifdef AUDIO_RINGCHECK
311
			unsigned int pegtimer;
312
			int pegcount;
313
			int peg;
314
			int ring;
315
#else			
316
			int wasringing;
317
			int lastrdtx;
318
#endif			
319
			int ringdebounce;
320
			int offhook;
321
		    unsigned int battdebounce;
322
			unsigned int battalarm;
323
			enum battery_state battery;
324
		        int lastpol;
325
		        int polarity;
326
		        int polaritydebounce;
327
		} fxo;
328
		struct fxs {
329
			int oldrxhook;
330
			int debouncehook;
331
			int lastrxhook;
332
			int debounce;
333
			int ohttimer;
334
			int idletxhookstate;		/* IDLE changing hook state */
335
			int lasttxhook;
336
			int palarms;
337
			struct calregs calregs;
338
		} fxs;
339
	} mod[MAX_NUM_CARDS];
340
341
	/* Receive hook state and debouncing */
342
	int modtype[MAX_NUM_CARDS];
343
	unsigned char reg0shadow[MAX_NUM_CARDS];
344
	unsigned char reg1shadow[MAX_NUM_CARDS];
345
346
	unsigned long ioaddr;
347
	unsigned long mem_region;	/* 32 bit Region allocated to tiger320 */
348
	unsigned long mem_len;		/* Length of 32 bit region */
349
	volatile unsigned long mem32;	/* Virtual representation of 32 bit memory area */
350
	
351
	dma_addr_t 	readdma;
352
	dma_addr_t	writedma;
353
	volatile unsigned char *writechunk;					/* Double-word aligned write memory */
354
	volatile unsigned char *readchunk;					/* Double-word aligned read memory */
355
	/*struct dahdi_chan chans[MAX_NUM_CARDS];*/
356
	struct dahdi_chan _chans[NUM_CARDS];
357
	struct dahdi_chan *chans[NUM_CARDS];
358
359
360
#ifdef TEST_LOG_INCOME_VOICE	
361
	char * voc_buf[MAX_NUM_CARDS + NUM_FLAG];
362
	int voc_ptr[MAX_NUM_CARDS + NUM_FLAG];
363
#endif
364
	int lastchan;
365
	unsigned short ledstate;
366
	unsigned char fwversion;
367
	int max_cards;
368
	char *card_name;
369
	
370
	char *cid_history_buf[MAX_NUM_CARDS];
371
	int	 cid_history_ptr[MAX_NUM_CARDS];
372
	int  cid_history_clone_cnt[MAX_NUM_CARDS];
373
	enum cid_hook_state cid_state[MAX_NUM_CARDS];
374
   int 	cid_ring_on_time[MAX_NUM_CARDS];
375
};
376
377
static char* A1200P_Name = "A1200P";
378
static char* A800P_Name  = "A800P";
379
380
struct wctdm_desc {
381
	char *name;
382
	int flags;
383
};
384
385
static struct wctdm_desc wctdme = { "OpenVox A1200P/A800P", 0 };
386
static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 };
387
388
static struct wctdm *ifaces[WC_MAX_IFACES];
389
390
static void wctdm_release(struct wctdm *wc);
391
392
static unsigned int battdebounce;
393
static unsigned int battalarm;
394
static unsigned int battthresh;
395
static int ringdebounce = DEFAULT_RING_DEBOUNCE;
396
static int fwringdetect = 0;
397
static int debug = 0;
398
static int robust = 0;
399
static int timingonly = 0;
400
static int lowpower = 0;
401
static int boostringer = 0;
402
static int fastringer = 0;
403
static int _opermode = 0;
404
static char *opermode = "FCC";
405
static int fxshonormode = 0;
406
static int alawoverride = 0;
407
static int fastpickup = 0;
408
static int fxotxgain = 0;
409
static int fxorxgain = 0;
410
static int fxstxgain = 0;
411
static int fxsrxgain = 0;
412
/* special h/w control command */
413
static int spibyhw = 1;
414
static int usememio = 1;
415
static int cidbeforering = 0;
416
static int cidbuflen = 3000;	/* in msec, default 3000 */
417
static int cidtimeout = 6*1000;	/* in msec, default 6000 */
418
static int fxofullscale = 0;	/* fxo full scale tx/rx, register 30, acim */
419
static int fixedtimepolarity=0;	/* time delay in ms when send polarity after rise edge of 1st ring.*/
420
421
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
422
423
static void wctdm_set_led(struct wctdm* wc, int card, int onoff)
424
{
425
	int i;
426
	unsigned char c;
427
	
428
	wc->ledstate &= ~(0x01<<card);
429
	wc->ledstate |= (onoff<<card);
430
	c = (inb(wc->ioaddr + WC_AUXD)&~BIT_LED_CLK)|BIT_LED_DATA;
431
	outb( c,  wc->ioaddr + WC_AUXD);
432
	for(i=MAX_NUM_CARDS-1; i>=0; i--)
433
	{
434
		if(wc->ledstate & (0x0001<<i))
435
			if(wc->fwversion == 0x11)
436
				c &= ~BIT_LED_DATA;
437
			else
438
				c |= BIT_LED_DATA;
439
		else
440
			if(wc->fwversion == 0x11)
441
				c |= BIT_LED_DATA;
442
			else
443
				c &= ~BIT_LED_DATA;
444
			
445
		outb( c,  wc->ioaddr + WC_AUXD);
446
		outb( c|BIT_LED_CLK,  wc->ioaddr + WC_AUXD);
447
		outb( (c&~BIT_LED_CLK)|BIT_LED_DATA,  wc->ioaddr + WC_AUXD);
448
	}	
449
}
450
 
451
452
static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char ints)
453
{
454
	int x, y, chan_offset, pos;
455
	volatile unsigned char *txbuf;
456
	
457
	if (ints & /*0x01*/ 0x04) 
458
		/* Write is at interrupt address.  Start writing from normal offset */
459
		txbuf = wc->writechunk;
460
	else 
461
		txbuf = wc->writechunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
462
		
463
	/* Calculate Transmission */
464
	dahdi_transmit(&wc->span);
465
	
466
	if(wc->lastchan == -1)	// not in sync.
467
		return;
468
	
469
	chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
470
471
	for (y=0;y<DAHDI_CHUNKSIZE;y++) {
472
#ifdef __BIG_ENDIAN
473
	// operation pending...
474
#else
475
		for (x=0;x<(MAX_NUM_CARDS+NUM_FLAG);x++) {
476
			pos = y * (MAX_NUM_CARDS+NUM_FLAG) + ((x + chan_offset + MAX_NUM_CARDS+NUM_FLAG - WC_OFFSET)&0x0f);
477
			if(x<wc->max_cards/*MAX_NUM_CARDS*/)
478
				txbuf[pos] = wc->chans[x]->writechunk[y]; 
479
			else
480
				txbuf[pos] = 0; 
481
		}
482
#endif
483
	}
484
}
485
486
487
#ifdef AUDIO_RINGCHECK
488
static inline void ring_check(struct wctdm *wc, int card)
489
{
490
	int x;
491
	short sample;
492
	if (wc->modtype[card] != MOD_TYPE_FXO)
493
		return;
494
	wc->mod[card].fxo.pegtimer += DAHDI_CHUNKSIZE;
495
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
496
		/* Look for pegging to indicate ringing */
497
		sample = DAHDI_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card])));
498
		if ((sample > 10000) && (wc->mod[card].fxo.peg != 1)) {
499
			if (debug > 1) printk(KERN_DEBUG "High peg!\n");
500
			if ((wc->mod[card].fxo.pegtimer < PEGTIME) && (wc->mod[card].fxo.pegtimer > MINPEGTIME))
501
				wc->mod[card].fxo.pegcount++;
502
			wc->mod[card].fxo.pegtimer = 0;
503
			wc->mod[card].fxo.peg = 1;
504
		} else if ((sample < -10000) && (wc->mod[card].fxo.peg != -1)) {
505
			if (debug > 1) printk(KERN_DEBUG "Low peg!\n");
506
			if ((wc->mod[card].fxo.pegtimer < (PEGTIME >> 2)) && (wc->mod[card].fxo.pegtimer > (MINPEGTIME >> 2)))
507
				wc->mod[card].fxo.pegcount++;
508
			wc->mod[card].fxo.pegtimer = 0;
509
			wc->mod[card].fxo.peg = -1;
510
		}
511
	}
512
	if (wc->mod[card].fxo.pegtimer > PEGTIME) {
513
		/* Reset pegcount if our timer expires */
514
		wc->mod[card].fxo.pegcount = 0;
515
	}
516
	/* Decrement debouncer if appropriate */
517
	if (wc->mod[card].fxo.ringdebounce)
518
		wc->mod[card].fxo.ringdebounce--;
519
	if (!wc->mod[card].fxo.offhook && !wc->mod[card].fxo.ringdebounce) {
520
		if (!wc->mod[card].fxo.ring && (wc->mod[card].fxo.pegcount > PEGCOUNT)) {
521
			/* It's ringing */
522
			if (debug)
523
				printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
524
			if (!wc->mod[card].fxo.offhook)
525
				dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_RING);
526
			wc->mod[card].fxo.ring = 1;
527
		}
528
		if (wc->mod[card].fxo.ring && !wc->mod[card].fxo.pegcount) {
529
			/* No more ring */
530
			if (debug)
531
				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
532
			dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
533
			wc->mod[card].fxo.ring = 0;
534
		}
535
	}
536
}
537
#endif
538
539
540
static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char ints)
541
{
542
	volatile unsigned char *rxbuf;
543
	int x, y, chan_offset;
544
545
546
	if (ints & 0x08/*0x04*/)
547
		/* Read is at interrupt address.  Valid data is available at normal offset */
548
		rxbuf = wc->readchunk;
549
	else
550
		rxbuf = wc->readchunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
551
552
	for(x=0; x<4; x++)
553
		if(  *(int*)(rxbuf+x*4) == WC_SYNCFLAG)
554
			break;
555
	if(x==4)
556
	{
557
		printk("buffer sync misseed!\n");
558
		wc->lastchan = -1;
559
		return;
560
	}
561
	else if(wc->lastchan != x)
562
	{
563
		printk("buffer re-sync occur from %d to %d\n", wc->lastchan, x);
564
		wc->lastchan = x;
565
	}
566
	chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
567
568
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
569
#ifdef __BIG_ENDIAN
570
	// operation pending...
571
#else
572
		for (y=0;y<wc->max_cards/*MAX_NUM_CARDS*/;y++) { 
573
			if (wc->cardflag & (1 << y))
574
				wc->chans[y]->readchunk[x] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset ) & 0x0f)];
575
#ifdef TEST_LOG_INCOME_VOICE
576
			wc->voc_buf[y][wc->voc_ptr[y]] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset) & 0x0f)];
577
			wc->voc_ptr[y]++;
578
			if(wc->voc_ptr[y] >= voc_buffer_size)
579
				wc->voc_ptr[y] = 0;
580
#endif		
581
		}
582
#endif
583
	}
584
	
585
	if(cidbeforering)
586
	{
587
		for(x=0; x<wc->max_cards; x++)
588
		{
589
			if (wc->modtype[wc->chans[x]->chanpos - 1] == MOD_TYPE_FXO)
590
				if(wc->mod[wc->chans[x]->chanpos - 1].fxo.offhook == 0)
591
				{
592
					/*unsigned int *p_readchunk, *p_cid_history;
593
					
594
					p_readchunk = (unsigned int*)wc->chans[x].readchunk;
595
					p_cid_history = (unsigned int*)(wc->cid_history_buf[x] + wc->cid_history_ptr[x]);*/
596
					
597
					if(wc->cid_state[x] == CID_STATE_IDLE)	/* we need copy data to the cid voice buffer */
598
					{
599
						memcpy(wc->cid_history_buf[x] + wc->cid_history_ptr[x], wc->chans[x]->readchunk, DAHDI_CHUNKSIZE);
600
						wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
601
					}
602
					else if (wc->cid_state[x] == CID_STATE_RING_ON)
603
						wc->cid_history_clone_cnt[x] = cidbuflen;
604
					else if (wc->cid_state[x] == CID_STATE_RING_OFF)
605
					{ 
606
						if(wc->cid_history_clone_cnt[x])
607
						{	
608
							memcpy(wc->chans[x]->readchunk, wc->cid_history_buf[x] + wc->cid_history_ptr[x], DAHDI_MAX_CHUNKSIZE);
609
							wc->cid_history_clone_cnt[x]--;
610
							wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_MAX_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
611
						}
612
						else
613
						{
614
							wc->cid_state[x] = CID_STATE_WAIT_RING_FINISH;
615
							wc->cid_history_clone_cnt[x] = cidtimeout; /* wait 6 sec, if no ring, return to idle */
616
						}
617
					}
618
					else if(wc->cid_state[x] == CID_STATE_WAIT_RING_FINISH)
619
					{
620
						if(wc->cid_history_clone_cnt[x] > 0)
621
							wc->cid_history_clone_cnt[x]--;
622
						else
623
						{
624
							wc->cid_state[x] = CID_STATE_IDLE;
625
							wc->cid_history_ptr[x] = 0;
626
							wc->cid_history_clone_cnt[x] = 0;
627
						}
628
					}
629
				}
630
		}		
631
	}
632
	
633
#ifdef AUDIO_RINGCHECK
634
	for (x=0;x<wc->max_cards;x++)
635
		ring_check(wc, x);
636
#endif		
637
	/* XXX We're wasting 8 taps.  We should get closer :( */
638
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
639
		if (wc->cardflag & (1 << x))
640
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
641
	}
642
	dahdi_receive(&wc->span);
643
}
644
645
static void wctdm_stop_dma(struct wctdm *wc);
646
static void wctdm_reset_tdm(struct wctdm *wc);
647
static void wctdm_restart_dma(struct wctdm *wc);
648
649
650
static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg);
651
static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val);
652
653
654
static inline void __write_8bits(struct wctdm *wc, unsigned char bits)
655
{
656
	if(spibyhw == 0)
657
	{
658
		int x;
659
		/* Drop chip select */
660
		wc->ios |= BIT_SCLK;
661
		outb(wc->ios, wc->ioaddr + WC_AUXD);
662
		wc->ios &= ~BIT_CS;
663
		outb(wc->ios, wc->ioaddr + WC_AUXD);
664
		for (x=0;x<8;x++) {
665
			/* Send out each bit, MSB first, drop SCLK as we do so */
666
			if (bits & 0x80)
667
				wc->ios |= BIT_SDI;
668
			else
669
				wc->ios &= ~BIT_SDI;
670
			wc->ios &= ~BIT_SCLK;
671
			outb(wc->ios, wc->ioaddr + WC_AUXD);
672
			/* Now raise SCLK high again and repeat */
673
			wc->ios |= BIT_SCLK;
674
			outb(wc->ios, wc->ioaddr + WC_AUXD);
675
			bits <<= 1;
676
		}
677
		/* Finally raise CS back high again */
678
		wc->ios |= BIT_CS;
679
		outb(wc->ios, wc->ioaddr + WC_AUXD);
680
	}
681
	else
682
	{
683
		__wctdm_setcreg(wc, WC_SPIDATA, bits);
684
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
685
		while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
686
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
687
	}
688
}
689
690
691
static inline void __reset_spi(struct wctdm *wc)
692
{
693
	__wctdm_setcreg(wc, WC_SPICTRL, 0);
694
	
695
	/* Drop chip select and clock once and raise and clock once */
696
	wc->ios |= BIT_SCLK;
697
	outb(wc->ios, wc->ioaddr + WC_AUXD);
698
	wc->ios &= ~BIT_CS;
699
	outb(wc->ios, wc->ioaddr + WC_AUXD);
700
	wc->ios |= BIT_SDI;
701
	wc->ios &= ~BIT_SCLK;
702
	outb(wc->ios, wc->ioaddr + WC_AUXD);
703
	/* Now raise SCLK high again and repeat */
704
	wc->ios |= BIT_SCLK;
705
	outb(wc->ios, wc->ioaddr + WC_AUXD);
706
	/* Finally raise CS back high again */
707
	wc->ios |= BIT_CS;
708
	outb(wc->ios, wc->ioaddr + WC_AUXD);
709
	/* Clock again */
710
	wc->ios &= ~BIT_SCLK;
711
	outb(wc->ios, wc->ioaddr + WC_AUXD);
712
	/* Now raise SCLK high again and repeat */
713
	wc->ios |= BIT_SCLK;
714
	outb(wc->ios, wc->ioaddr + WC_AUXD);
715
	
716
	__wctdm_setcreg(wc, WC_SPICTRL, spibyhw);
717
718
}
719
720
static inline unsigned char __read_8bits(struct wctdm *wc)
721
{
722
	unsigned char res=0, c;
723
	int x;
724
	if(spibyhw == 0)
725
	{
726
		wc->ios &= ~BIT_CS;
727
		outb(wc->ios, wc->ioaddr + WC_AUXD);
728
		/* Drop chip select */
729
		wc->ios &= ~BIT_CS;
730
		outb(wc->ios, wc->ioaddr + WC_AUXD);
731
		for (x=0;x<8;x++) {
732
			res <<= 1;
733
			/* Get SCLK */
734
			wc->ios &= ~BIT_SCLK;
735
			outb(wc->ios, wc->ioaddr + WC_AUXD);
736
			/* Read back the value */
737
			c = inb(wc->ioaddr + WC_AUXR);
738
			if (c & BIT_SDO)
739
				res |= 1;
740
			/* Now raise SCLK high again */
741
			wc->ios |= BIT_SCLK;
742
			outb(wc->ios, wc->ioaddr + WC_AUXD);
743
		}
744
		/* Finally raise CS back high again */
745
		wc->ios |= BIT_CS;
746
		outb(wc->ios, wc->ioaddr + WC_AUXD);
747
		wc->ios &= ~BIT_SCLK;
748
		outb(wc->ios, wc->ioaddr + WC_AUXD);
749
	}
750
	else
751
	{
752
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
753
		while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
754
		res = __wctdm_getcreg(wc, WC_SPIDATA);
755
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
756
	}
757
	
758
	/* And return our result */
759
	return res;
760
}
761
762
static void __wctdm_setcreg_mem(struct wctdm *wc, unsigned char reg, unsigned char val)
763
{
764
	unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
765
	*p = val;
766
}
767
768
static unsigned char __wctdm_getcreg_mem(struct wctdm *wc, unsigned char reg)
769
{
770
	unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
771
	return (*p)&0x00ff;
772
}
773
774
775
static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val)
776
{
777
	if(usememio)
778
		__wctdm_setcreg_mem(wc, reg, val);
779
	else
780
		outb(val, wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
781
}
782
783
static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg)
784
{
785
	if(usememio)
786
		return __wctdm_getcreg_mem(wc, reg);
787
	else
788
		return inb(wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
789
}
790
791
static inline void __wctdm_setcard(struct wctdm *wc, int card)
792
{
793
	if (wc->curcard != card) {
794
		__wctdm_setcreg(wc, WC_CS, card);
795
		wc->curcard = card;
796
		//printk("Select card %d\n", card);
797
	}
798
}
799
800
static void __wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
801
{
802
	__wctdm_setcard(wc, card);
803
	if (wc->modtype[card] == MOD_TYPE_FXO) {
804
		__write_8bits(wc, 0x20);
805
		__write_8bits(wc, reg & 0x7f);
806
	} else {
807
		__write_8bits(wc, reg & 0x7f);
808
	}
809
	__write_8bits(wc, value);
810
}
811
812
static void wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
813
{
814
	unsigned long flags;
815
	spin_lock_irqsave(&wc->lock, flags);
816
	__wctdm_setreg(wc, card, reg, value);
817
	spin_unlock_irqrestore(&wc->lock, flags);
818
}
819
820
static unsigned char __wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
821
{
822
	__wctdm_setcard(wc, card);
823
	if (wc->modtype[card] == MOD_TYPE_FXO) {
824
		__write_8bits(wc, 0x60);
825
		__write_8bits(wc, reg & 0x7f);
826
	} else {
827
		__write_8bits(wc, reg | 0x80);
828
	}
829
	return __read_8bits(wc);
830
}
831
832
static inline void reset_spi(struct wctdm *wc, int card)
833
{
834
	unsigned long flags;
835
	spin_lock_irqsave(&wc->lock, flags);
836
	__wctdm_setcard(wc, card);
837
	__reset_spi(wc);
838
	__reset_spi(wc);
839
	spin_unlock_irqrestore(&wc->lock, flags);
840
}
841
842
static unsigned char wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
843
{
844
	unsigned long flags;
845
	unsigned char res;
846
	spin_lock_irqsave(&wc->lock, flags);
847
	res = __wctdm_getreg(wc, card, reg);
848
	spin_unlock_irqrestore(&wc->lock, flags);
849
	return res;
850
}
851
852
static int __wait_access(struct wctdm *wc, int card)
853
{
854
    unsigned char data = 0;
855
    long origjiffies;
856
    int count = 0;
857
858
    #define MAX 6000 /* attempts */
859
860
861
    origjiffies = jiffies;
862
    /* Wait for indirect access */
863
    while (count++ < MAX)
864
	 {
865
		data = __wctdm_getreg(wc, card, I_STATUS);
866
867
		if (!data)
868
			return 0;
869
870
	 }
871
872
    if(count > (MAX-1)) printk(KERN_NOTICE " ##### Loop error (%02x) #####\n", data);
873
874
	return 0;
875
}
876
877
static unsigned char translate_3215(unsigned char address)
878
{
879
	int x;
880
	for (x=0;x<sizeof(indirect_regs)/sizeof(indirect_regs[0]);x++) {
881
		if (indirect_regs[x].address == address) {
882
			address = indirect_regs[x].altaddr;
883
			break;
884
		}
885
	}
886
	return address;
887
}
888
889
static int wctdm_proslic_setreg_indirect(struct wctdm *wc, int card, unsigned char address, unsigned short data)
890
{
891
	unsigned long flags;
892
	int res = -1;
893
	/* Translate 3215 addresses */
894
	if (wc->flags[card] & FLAG_3215) {
895
		address = translate_3215(address);
896
		if (address == 255)
897
			return 0;
898
	}
899
	spin_lock_irqsave(&wc->lock, flags);
900
	if(!__wait_access(wc, card)) {
901
		__wctdm_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF));
902
		__wctdm_setreg(wc, card, IDA_HI,(unsigned char)((data & 0xFF00)>>8));
903
		__wctdm_setreg(wc, card, IAA,address);
904
		res = 0;
905
	};
906
	spin_unlock_irqrestore(&wc->lock, flags);
907
	return res;
908
}
909
910
static int wctdm_proslic_getreg_indirect(struct wctdm *wc, int card, unsigned char address)
911
{ 
912
	unsigned long flags;
913
	int res = -1;
914
	char *p=NULL;
915
	/* Translate 3215 addresses */
916
	if (wc->flags[card] & FLAG_3215) {
917
		address = translate_3215(address);
918
		if (address == 255)
919
			return 0;
920
	}
921
	spin_lock_irqsave(&wc->lock, flags);
922
	if (!__wait_access(wc, card)) {
923
		__wctdm_setreg(wc, card, IAA, address);
924
		if (!__wait_access(wc, card)) {
925
			unsigned char data1, data2;
926
			data1 = __wctdm_getreg(wc, card, IDA_LO);
927
			data2 = __wctdm_getreg(wc, card, IDA_HI);
928
			res = data1 | (data2 << 8);
929
		} else
930
			p = "Failed to wait inside\n";
931
	} else
932
		p = "failed to wait\n";
933
	spin_unlock_irqrestore(&wc->lock, flags);
934
	if (p)
935
		printk(KERN_NOTICE "%s", p);
936
	return res;
937
}
938
939
static int wctdm_proslic_init_indirect_regs(struct wctdm *wc, int card)
940
{
941
	unsigned char i;
942
943
	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
944
	{
945
		if(wctdm_proslic_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))
946
			return -1;
947
	}
948
949
	return 0;
950
}
951
952
static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card)
953
{ 
954
	int passed = 1;
955
	unsigned short i, initial;
956
	int j;
957
958
	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++) 
959
	{
960
		if((j = wctdm_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
961
			printk(KERN_NOTICE "Failed to read indirect register %d\n", i);
962
			return -1;
963
		}
964
		initial= indirect_regs[i].initial;
965
966
		if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255)))
967
		{
968
			 printk(KERN_NOTICE "!!!!!!! %s  iREG %X = %X  should be %X\n",
969
				indirect_regs[i].name,indirect_regs[i].address,j,initial );
970
			 passed = 0;
971
		}	
972
	}
973
974
    if (passed) {
975
		if (debug)
976
			printk(KERN_DEBUG "Init Indirect Registers completed successfully.\n");
977
    } else {
978
		printk(KERN_NOTICE " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
979
		return -1;
980
    }
981
    return 0;
982
}
983
984
static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card)
985
{
986
	int res;
987
	/* Check loopback */
988
	res = wc->reg1shadow[card];
989
	
990
	if (!res && (res != wc->mod[card].fxs.lasttxhook))     // read real state from register   By wx
991
		res=wctdm_getreg(wc, card, 64);
992
	
993
	if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
994
		res = wctdm_getreg(wc, card, 8);
995
		if (res) {
996
			printk(KERN_NOTICE "Ouch, part reset, quickly restoring reality (%d)\n", card);
997
			wctdm_init_proslic(wc, card, 1, 0, 1);
998
		} else {
999
			if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
1000
				printk(KERN_NOTICE "Power alarm on module %d, resetting!\n", card + 1);
1001
				if (wc->mod[card].fxs.lasttxhook == 4)
1002
					wc->mod[card].fxs.lasttxhook = 1;
1003
				wctdm_setreg(wc, card, 64, wc->mod[card].fxs.lasttxhook);
1004
			} else {
1005
				if (wc->mod[card].fxs.palarms == MAX_ALARMS)
1006
					printk(KERN_NOTICE "Too many power alarms on card %d, NOT resetting!\n", card + 1);
1007
			}
1008
		}
1009
	}
1010
}
1011
static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
1012
{
1013
#define MS_PER_CHECK_HOOK 16
1014
1015
#ifndef AUDIO_RINGCHECK
1016
	unsigned char res;
1017
#endif	
1018
	signed char b;
1019
	int errors = 0;
1020
	struct fxo *fxo = &wc->mod[card].fxo;
1021
1022
	/* Try to track issues that plague slot one FXO's */
1023
	b = wc->reg0shadow[card];
1024
	if ((b & 0x2) || !(b & 0x8)) {
1025
		/* Not good -- don't look at anything else */
1026
		if (debug)
1027
			printk(KERN_DEBUG "Error (%02x) on card %d!\n", b, card + 1); 
1028
		errors++;
1029
	}
1030
	b &= 0x9b;
1031
	if (fxo->offhook) {
1032
		if (b != 0x9)
1033
			wctdm_setreg(wc, card, 5, 0x9);
1034
	} else {
1035
		if (b != 0x8)
1036
			wctdm_setreg(wc, card, 5, 0x8);
1037
	}
1038
	if (errors)
1039
		return;
1040
	if (!fxo->offhook) {
1041
 if(fixedtimepolarity) {
1042
			if ( wc->cid_state[card] == CID_STATE_RING_ON && wc->cid_ring_on_time[card]>0)
1043
			{
1044
 	if(wc->cid_ring_on_time[card]>=fixedtimepolarity )
1045
			{
1046
			dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1047
			wc->cid_ring_on_time[card] = -1;	/* the polarity already sent */	
1048
			}
1049
			else
1050
		wc->cid_ring_on_time[card] += 16;
1051
    }
1052
}
1053
		if (fwringdetect) {
1054
			res = wc->reg0shadow[card] & 0x60;
1055
			if (fxo->ringdebounce) {
1056
				--fxo->ringdebounce;
1057
				if (res && (res != fxo->lastrdtx) &&
1058
				    (fxo->battery == BATTERY_PRESENT)) {
1059
					if (!fxo->wasringing) {
1060
						fxo->wasringing = 1;
1061
						if (debug)
1062
          printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
1063
	if(cidbeforering)
1064
						{
1065
							if(wc->cid_state[card] == CID_STATE_IDLE)
1066
							{
1067
								wc->cid_state[card] = CID_STATE_RING_ON;
1068
								wc->cid_ring_on_time[card] = 16;	/* check every 16ms */
1069
							}
1070
							else
1071
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1072
						}
1073
						else 							
1074
        dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1075
					}
1076
					fxo->lastrdtx = res;
1077
					fxo->ringdebounce = 10;
1078
				} else if (!res) {
1079
					if ((fxo->ringdebounce == 0) && fxo->wasringing) {
1080
				fxo->wasringing = 0;
1081
				if (debug)
1082
				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
1083
	if(cidbeforering)
1084
						{
1085
							if(wc->cid_state[card] == CID_STATE_RING_ON)
1086
							{
1087
								if(fixedtimepolarity==0)
1088
									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1089
								wc->cid_state[card] = CID_STATE_RING_OFF;
1090
							}
1091
							else 
1092
							{
1093
								if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
1094
									wc->cid_history_clone_cnt[card] = cidtimeout;
1095
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1096
							}
1097
						}
1098
						else
1099
1100
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1101
				}
1102
				}
1103
			} else if (res && (fxo->battery == BATTERY_PRESENT)) {
1104
				fxo->lastrdtx = res;
1105
				fxo->ringdebounce = 10;
1106
			}
1107
		} else {
1108
			res = wc->reg0shadow[card];
1109
			if ((res & 0x60) && (fxo->battery == BATTERY_PRESENT)) {
1110
				fxo->ringdebounce += (DAHDI_CHUNKSIZE * 16);
1111
				if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
1112
					if (!fxo->wasringing) {
1113
						fxo->wasringing = 1;
1114
 if(cidbeforering)
1115
						{
1116
							if(wc->cid_state[card] == CID_STATE_IDLE)
1117
							{	
1118
								wc->cid_state[card] = CID_STATE_RING_ON;
1119
								wc->cid_ring_on_time[card] = 16;		/* check every 16ms */
1120
							}
1121
							else
1122
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1123
						}
1124
						else      
1125
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1126
						if (debug)
1127
							printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
1128
					}
1129
					fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
1130
				}
1131
			} else {
1132
				fxo->ringdebounce -= DAHDI_CHUNKSIZE * 4;
1133
				if (fxo->ringdebounce <= 0) {
1134
					if (fxo->wasringing) {
1135
						fxo->wasringing = 0;
1136
	if(cidbeforering)
1137
						{
1138
							if(wc->cid_state[card] == CID_STATE_RING_ON)
1139
							{
1140
								if(fixedtimepolarity==0)
1141
									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1142
								wc->cid_state[card] = CID_STATE_RING_OFF;
1143
							}
1144
							else 
1145
							{
1146
								if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
1147
									wc->cid_history_clone_cnt[card] = cidtimeout;
1148
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1149
							}
1150
						}
1151
						else
1152
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1153
						if (debug)
1154
							printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
1155
					}
1156
					fxo->ringdebounce = 0;
1157
				}
1158
			}
1159
		}
1160
	}
1161
1162
	b = wc->reg1shadow[card];
1163
	if (abs(b) < battthresh) {
1164
		/* possible existing states:
1165
		   battery lost, no debounce timer
1166
		   battery lost, debounce timer (going to battery present)
1167
		   battery present or unknown, no debounce timer
1168
		   battery present or unknown, debounce timer (going to battery lost)
1169
		*/
1170
1171
		if (fxo->battery == BATTERY_LOST) {
1172
			if (fxo->battdebounce) {
1173
				/* we were going to BATTERY_PRESENT, but battery was lost again,
1174
				   so clear the debounce timer */
1175
				fxo->battdebounce = 0;
1176
			}
1177
		} else {
1178
			if (fxo->battdebounce) {
1179
				/* going to BATTERY_LOST, see if we are there yet */
1180
				if (--fxo->battdebounce == 0) {
1181
					fxo->battery = BATTERY_LOST;
1182
					if (debug)
1183
						printk(KERN_DEBUG "NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);
1184
#ifdef	JAPAN
1185
					if (!wc->ohdebounce && wc->offhook) {
1186
						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_ONHOOK);
1187
						if (debug)
1188
							printk(KERN_DEBUG "Signalled On Hook\n");
1189
#ifdef	ZERO_BATT_RING
1190
						wc->onhook++;
1191
#endif
1192
					}
1193
#else
1194
					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
1195
					/* set the alarm timer, taking into account that part of its time
1196
					   period has already passed while debouncing occurred */
1197
					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
1198
#endif
1199
				}
1200
			} else {
1201
				/* start the debounce timer to verify that battery has been lost */
1202
				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
1203
			}
1204
		}
1205
	} else {
1206
		/* possible existing states:
1207
		   battery lost or unknown, no debounce timer
1208
		   battery lost or unknown, debounce timer (going to battery present)
1209
		   battery present, no debounce timer
1210
		   battery present, debounce timer (going to battery lost)
1211
		*/
1212
1213
		if (fxo->battery == BATTERY_PRESENT) {
1214
			if (fxo->battdebounce) {
1215
				/* we were going to BATTERY_LOST, but battery appeared again,
1216
				   so clear the debounce timer */
1217
				fxo->battdebounce = 0;
1218
			}
1219
		} else {
1220
			if (fxo->battdebounce) {
1221
				/* going to BATTERY_PRESENT, see if we are there yet */
1222
				if (--fxo->battdebounce == 0) {
1223
					fxo->battery = BATTERY_PRESENT;
1224
					if (debug)
1225
						printk(KERN_DEBUG "BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1, 
1226
						       (b < 0) ? "-" : "+");			    
1227
#ifdef	ZERO_BATT_RING
1228
					if (wc->onhook) {
1229
						wc->onhook = 0;
1230
						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1231
						if (debug)
1232
							printk(KERN_DEBUG "Signalled Off Hook\n");
1233
					}
1234
#else
1235
					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1236
#endif
1237
					/* set the alarm timer, taking into account that part of its time
1238
					   period has already passed while debouncing occurred */
1239
					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
1240
				}
1241
			} else {
1242
				/* start the debounce timer to verify that battery has appeared */
1243
				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
1244
			}
1245
		}
1246
	}
1247
1248
	if (fxo->lastpol >= 0) {
1249
		if (b < 0) {
1250
			fxo->lastpol = -1;
1251
			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
1252
		}
1253
	} 
1254
	if (fxo->lastpol <= 0) {
1255
		if (b > 0) {
1256
			fxo->lastpol = 1;
1257
			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
1258
		}
1259
	}
1260
1261
	if (fxo->battalarm) {
1262
		if (--fxo->battalarm == 0) {
1263
			/* the alarm timer has expired, so update the battery alarm state
1264
			   for this channel */
1265
			dahdi_alarm_channel(wc->chans[card], fxo->battery == BATTERY_LOST ? DAHDI_ALARM_RED : DAHDI_ALARM_NONE);
1266
		}
1267
	}
1268
1269
	if (fxo->polaritydebounce) {
1270
		if (--fxo->polaritydebounce == 0) {
1271
		    if (fxo->lastpol != fxo->polarity) {
1272
				if (debug)
1273
					printk(KERN_DEBUG "%lu Polarity reversed (%d -> %d)\n", jiffies, 
1274
				       fxo->polarity, 
1275
				       fxo->lastpol);
1276
				if (fxo->polarity)
1277
					dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1278
				fxo->polarity = fxo->lastpol;
1279
		    }
1280
		}
1281
	}
1282
#undef MS_PER_CHECK_HOOK
1283
}
1284
1285
static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
1286
{
1287
	char res;
1288
	int hook;
1289
1290
	/* For some reason we have to debounce the
1291
	   hook detector.  */
1292
1293
	res = wc->reg0shadow[card];
1294
	hook = (res & 1);
1295
	if (hook != wc->mod[card].fxs.lastrxhook) {
1296
		/* Reset the debounce (must be multiple of 4ms) */
1297
		wc->mod[card].fxs.debounce = 8 * (4 * 8);
1298
#if 0
1299
		printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
1300
#endif
1301
	} else {
1302
		if (wc->mod[card].fxs.debounce > 0) {
1303
			wc->mod[card].fxs.debounce-= 16 * DAHDI_CHUNKSIZE;
1304
#if 0
1305
			printk(KERN_DEBUG "Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
1306
#endif
1307
			if (!wc->mod[card].fxs.debounce) {
1308
#if 0
1309
				printk(KERN_DEBUG "Counted down debounce, newhook: %d...\n", hook);
1310
#endif
1311
				wc->mod[card].fxs.debouncehook = hook;
1312
			}
1313
			if (!wc->mod[card].fxs.oldrxhook && wc->mod[card].fxs.debouncehook) {
1314
				/* Off hook */
1315
#if 1
1316
				if (debug)
1317
#endif				
1318
					printk(KERN_DEBUG "opvxa1200: Card %d Going off hook\n", card);
1319
				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1320
				if (robust)
1321
					wctdm_init_proslic(wc, card, 1, 0, 1);
1322
				wc->mod[card].fxs.oldrxhook = 1;
1323
			
1324
			} else if (wc->mod[card].fxs.oldrxhook && !wc->mod[card].fxs.debouncehook) {
1325
				/* On hook */
1326
#if 1
1327
				if (debug)
1328
#endif				
1329
					printk(KERN_DEBUG "opvxa1200: Card %d Going on hook\n", card);
1330
				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
1331
				wc->mod[card].fxs.oldrxhook = 0;
1332
			}
1333
		}
1334
	}
1335
	wc->mod[card].fxs.lastrxhook = hook;
1336
}
1337
1338
DAHDI_IRQ_HANDLER(wctdm_interrupt)
1339
{
1340
	struct wctdm *wc = dev_id;
1341
	unsigned char ints;
1342
	int x, y, z;
1343
	int mode;
1344
1345
	ints = inb(wc->ioaddr + WC_INTSTAT);
1346
1347
	if (!ints)
1348
		return IRQ_NONE;
1349
1350
	outb(ints, wc->ioaddr + WC_INTSTAT);
1351
	
1352
	if (ints & 0x10) {
1353
		/* Stop DMA, wait for watchdog */
1354
		printk(KERN_INFO "TDM PCI Master abort\n");
1355
		wctdm_stop_dma(wc);
1356
		return IRQ_RETVAL(1);
1357
	}
1358
	
1359
	if (ints & 0x20) {
1360
		printk(KERN_INFO "PCI Target abort\n");
1361
		return IRQ_RETVAL(1);
1362
	}
1363
1364
	for (x=0;x<wc->max_cards/*4*3*/;x++) {
1365
		if (wc->cardflag & (1 << x) &&
1366
		    (wc->modtype[x] == MOD_TYPE_FXS)) {
1367
			if (wc->mod[x].fxs.lasttxhook == 0x4) {
1368
				/* RINGing, prepare for OHT */
1369
				wc->mod[x].fxs.ohttimer = OHT_TIMER << 3;
1370
				if (reversepolarity)
1371
					wc->mod[x].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
1372
				else
1373
					wc->mod[x].fxs.idletxhookstate = 0x2; 
1374
			} else {
1375
				if (wc->mod[x].fxs.ohttimer) {
1376
					wc->mod[x].fxs.ohttimer-= DAHDI_CHUNKSIZE;
1377
					if (!wc->mod[x].fxs.ohttimer) {
1378
						if (reversepolarity)
1379
							wc->mod[x].fxs.idletxhookstate = 0x5;	/* Switch to active */
1380
						else
1381
							wc->mod[x].fxs.idletxhookstate = 0x1;
1382
						if ((wc->mod[x].fxs.lasttxhook == 0x2) || (wc->mod[x].fxs.lasttxhook == 0x6)) {
1383
							/* Apply the change if appropriate */
1384
							if (reversepolarity) 
1385
								wc->mod[x].fxs.lasttxhook = 0x5;
1386
							else
1387
								wc->mod[x].fxs.lasttxhook = 0x1;
1388
							wctdm_setreg(wc, x, 64, wc->mod[x].fxs.lasttxhook);
1389
						}
1390
					}
1391
				}
1392
			}
1393
		}
1394
	}
1395
1396
	if (ints & 0x0f) {
1397
		wc->intcount++;
1398
		z = wc->intcount & 0x3;
1399
		mode = wc->intcount & 0xc;
1400
		for(y=0; y<wc->max_cards/4/*3*/; y++)
1401
		{
1402
			x = z + y*4;
1403
			if (wc->cardflag & (1 << x ) ) 
1404
			{
1405
				switch(mode) 
1406
				{
1407
				case 0:
1408
					/* Rest */
1409
					break;
1410
				case 4:
1411
					/* Read first shadow reg */
1412
					if (wc->modtype[x] == MOD_TYPE_FXS)
1413
						wc->reg0shadow[x] = wctdm_getreg(wc, x, 68);
1414
					else if (wc->modtype[x] == MOD_TYPE_FXO)
1415
						wc->reg0shadow[x] = wctdm_getreg(wc, x, 5);
1416
					break;
1417
				case 8:
1418
					/* Read second shadow reg */
1419
					if (wc->modtype[x] == MOD_TYPE_FXS)
1420
						wc->reg1shadow[x] = wctdm_getreg(wc, x, 64);
1421
					else if (wc->modtype[x] == MOD_TYPE_FXO)
1422
						wc->reg1shadow[x] = wctdm_getreg(wc, x, 29);
1423
					break;
1424
				case 12:
1425
					/* Perform processing */
1426
					if (wc->modtype[x] == MOD_TYPE_FXS) {
1427
						wctdm_proslic_check_hook(wc, x);
1428
						if (!(wc->intcount & 0xf0))
1429
							wctdm_proslic_recheck_sanity(wc, x);
1430
					} else if (wc->modtype[x] == MOD_TYPE_FXO) {
1431
						wctdm_voicedaa_check_hook(wc, x);
1432
					}
1433
					break;
1434
				}
1435
			}
1436
		}
1437
		if (!(wc->intcount % 10000)) {
1438
			/* Accept an alarm once per 10 seconds */
1439
			for (x=0;x<wc->max_cards/*4*3*/;x++) 
1440
				if (wc->modtype[x] == MOD_TYPE_FXS) {
1441
					if (wc->mod[x].fxs.palarms)
1442
						wc->mod[x].fxs.palarms--;
1443
				}
1444
		}
1445
		wctdm_receiveprep(wc, ints);
1446
		wctdm_transmitprep(wc, ints);
1447
	}
1448
1449
	return IRQ_RETVAL(1);
1450
1451
}
1452
1453
static int wctdm_voicedaa_insane(struct wctdm *wc, int card)
1454
{
1455
	int blah;
1456
	blah = wctdm_getreg(wc, card, 2);
1457
	if (blah != 0x3)
1458
		return -2;
1459
	blah = wctdm_getreg(wc, card, 11);
1460
	if (debug)
1461
		printk(KERN_DEBUG "VoiceDAA System: %02x\n", blah & 0xf);
1462
	return 0;
1463
}
1464
1465
static int wctdm_proslic_insane(struct wctdm *wc, int card)
1466
{
1467
	int blah,insane_report;
1468
	insane_report=0;
1469
1470
	blah = wctdm_getreg(wc, card, 0);
1471
	if (debug) 
1472
		printk(KERN_DEBUG "ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));
1473
1474
#if 0
1475
	if ((blah & 0x30) >> 4) {
1476
		printk(KERN_DEBUG "ProSLIC on module %d is not a 3210.\n", card);
1477
		return -1;
1478
	}
1479
#endif
1480
	if (((blah & 0xf) == 0) || ((blah & 0xf) == 0xf)) {
1481
		/* SLIC not loaded */
1482
		return -1;
1483
	}
1484
	if ((blah & 0xf) < 2) {
1485
		printk(KERN_NOTICE "ProSLIC 3210 version %d is too old\n", blah & 0xf);
1486
		return -1;
1487
	}
1488
	if (wctdm_getreg(wc, card, 1) & 0x80)
1489
	/* ProSLIC 3215, not a 3210 */
1490
		wc->flags[card] |= FLAG_3215;
1491
	
1492
	blah = wctdm_getreg(wc, card, 8);
1493
	if (blah != 0x2) {
1494
		printk(KERN_NOTICE  "ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
1495
		return -1;
1496
	} else if ( insane_report)
1497
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);
1498
1499
	blah = wctdm_getreg(wc, card, 64);
1500
	if (blah != 0x0) {
1501
		printk(KERN_NOTICE  "ProSLIC on module %d insane (2)\n", card);
1502
		return -1;
1503
	} else if ( insane_report)
1504
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);
1505
1506
	blah = wctdm_getreg(wc, card, 11);
1507
	if (blah != 0x33) {
1508
		printk(KERN_NOTICE  "ProSLIC on module %d insane (3)\n", card);
1509
		return -1;
1510
	} else if ( insane_report)
1511
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);
1512
1513
	/* Just be sure it's setup right. */
1514
	wctdm_setreg(wc, card, 30, 0);
1515
1516
	if (debug) 
1517
		printk(KERN_DEBUG "ProSLIC on module %d seems sane.\n", card);
1518
	return 0;
1519
}
1520
1521
static int wctdm_proslic_powerleak_test(struct wctdm *wc, int card)
1522
{
1523
	unsigned long origjiffies;
1524
	unsigned char vbat;
1525
1526
	/* Turn off linefeed */
1527
	wctdm_setreg(wc, card, 64, 0);
1528
1529
	/* Power down */
1530
	wctdm_setreg(wc, card, 14, 0x10);
1531
1532
	/* Wait for one second */
1533
	origjiffies = jiffies;
1534
1535
	while((vbat = wctdm_getreg(wc, card, 82)) > 0x6) {
1536
		if ((jiffies - origjiffies) >= (HZ/2))
1537
			break;;
1538
	}
1539
1540
	if (vbat < 0x06) {
1541
		printk(KERN_NOTICE "Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,
1542
		       376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ));
1543
		return -1;
1544
	} else if (debug) {
1545
		printk(KERN_NOTICE "Post-leakage voltage: %d volts\n", 376 * vbat / 1000);
1546
	}
1547
	return 0;
1548
}
1549
1550
static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast)
1551
{
1552
	unsigned char vbat;
1553
	unsigned long origjiffies;
1554
	int lim;
1555
1556
	/* Set period of DC-DC converter to 1/64 khz */
1557
	wctdm_setreg(wc, card, 92, 0xff /* was 0xff */);
1558
1559
	/* Wait for VBat to powerup */
1560
	origjiffies = jiffies;
1561
1562
	/* Disable powerdown */
1563
	wctdm_setreg(wc, card, 14, 0);
1564
1565
	/* If fast, don't bother checking anymore */
1566
	if (fast)
1567
		return 0;
1568
1569
	while((vbat = wctdm_getreg(wc, card, 82)) < 0xc0) {
1570
		/* Wait no more than 500ms */
1571
		if ((jiffies - origjiffies) > HZ/2) {
1572
			break;
1573
		}
1574
	}
1575
1576
	if (vbat < 0xc0) {
1577
		if (wc->proslic_power == PROSLIC_POWER_UNKNOWN)
1578
				 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",
1579
					card, (int)(((jiffies - origjiffies) * 1000 / HZ)),
1580
					vbat * 375);
1581
		wc->proslic_power = PROSLIC_POWER_WARNED;
1582
		return -1;
1583
	} else if (debug) {
1584
		printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
1585
		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
1586
	}
1587
	wc->proslic_power = PROSLIC_POWER_ON;
1588
1589
        /* Proslic max allowed loop current, reg 71 LOOP_I_LIMIT */
1590
        /* If out of range, just set it to the default value     */
1591
        lim = (loopcurrent - 20) / 3;
1592
        if ( loopcurrent > 41 ) {
1593
                lim = 0;
1594
                if (debug)
1595
                        printk(KERN_DEBUG "Loop current out of range! Setting to default 20mA!\n");
1596
        }
1597
        else if (debug)
1598
                        printk(KERN_DEBUG "Loop current set to %dmA!\n",(lim*3)+20);
1599
        wctdm_setreg(wc,card,LOOP_I_LIMIT,lim);
1600
1601
	/* Engage DC-DC converter */
1602
	wctdm_setreg(wc, card, 93, 0x19 /* was 0x19 */);
1603
#if 0
1604
	origjiffies = jiffies;
1605
	while(0x80 & wctdm_getreg(wc, card, 93)) {
1606
		if ((jiffies - origjiffies) > 2 * HZ) {
1607
			printk(KERN_DEBUG "Timeout waiting for DC-DC calibration on module %d\n", card);
1608
			return -1;
1609
		}
1610
	}
1611
1612
#if 0
1613
	/* Wait a full two seconds */
1614
	while((jiffies - origjiffies) < 2 * HZ);
1615
1616
	/* Just check to be sure */
1617
	vbat = wctdm_getreg(wc, card, 82);
1618
	printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
1619
		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
1620
#endif
1621
#endif
1622
	return 0;
1623
1624
}
1625
1626
static int wctdm_proslic_manual_calibrate(struct wctdm *wc, int card){
1627
	unsigned long origjiffies;
1628
	unsigned char i;
1629
1630
	wctdm_setreg(wc, card, 21, 0);//(0)  Disable all interupts in DR21
1631
	wctdm_setreg(wc, card, 22, 0);//(0)Disable all interupts in DR21
1632
	wctdm_setreg(wc, card, 23, 0);//(0)Disable all interupts in DR21
1633
	wctdm_setreg(wc, card, 64, 0);//(0)
1634
1635
	wctdm_setreg(wc, card, 97, 0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration.
1636
	wctdm_setreg(wc, card, 96, 0x47); //(0x47)	Calibrate common mode and differential DAC mode DAC + ILIM
1637
1638
	origjiffies=jiffies;
1639
	while( wctdm_getreg(wc,card,96)!=0 ){
1640
		if((jiffies-origjiffies)>80)
1641
			return -1;
1642
	}
1643
//Initialized DR 98 and 99 to get consistant results.
1644
// 98 and 99 are the results registers and the search should have same intial conditions.
1645
1646
/*******************************The following is the manual gain mismatch calibration****************************/
1647
/*******************************This is also available as a function *******************************************/
1648
	// Delay 10ms
1649
	origjiffies=jiffies; 
1650
	while((jiffies-origjiffies)<1);
1651
	wctdm_proslic_setreg_indirect(wc, card, 88,0);
1652
	wctdm_proslic_setreg_indirect(wc,card,89,0);
1653
	wctdm_proslic_setreg_indirect(wc,card,90,0);
1654
	wctdm_proslic_setreg_indirect(wc,card,91,0);
1655
	wctdm_proslic_setreg_indirect(wc,card,92,0);
1656
	wctdm_proslic_setreg_indirect(wc,card,93,0);
1657
1658
	wctdm_setreg(wc, card, 98,0x10); // This is necessary if the calibration occurs other than at reset time
1659
	wctdm_setreg(wc, card, 99,0x10);
1660
1661
	for ( i=0x1f; i>0; i--)
1662
	{
1663
		wctdm_setreg(wc, card, 98,i);
1664
		origjiffies=jiffies; 
1665
		while((jiffies-origjiffies)<4);
1666
		if((wctdm_getreg(wc,card,88)) == 0)
1667
			break;
1668
	} // for
1669
1670
	for ( i=0x1f; i>0; i--)
1671
	{
1672
		wctdm_setreg(wc, card, 99,i);
1673
		origjiffies=jiffies; 
1674
		while((jiffies-origjiffies)<4);
1675
		if((wctdm_getreg(wc,card,89)) == 0)
1676
			break;
1677
	}//for
1678
1679
/*******************************The preceding is the manual gain mismatch calibration****************************/
1680
/**********************************The following is the longitudinal Balance Cal***********************************/
1681
	wctdm_setreg(wc,card,64,1);
1682
	while((jiffies-origjiffies)<10); // Sleep 100?
1683
1684
	wctdm_setreg(wc, card, 64, 0);
1685
	wctdm_setreg(wc, card, 23, 0x4);  // enable interrupt for the balance Cal
1686
	wctdm_setreg(wc, card, 97, 0x1); // this is a singular calibration bit for longitudinal calibration
1687
	wctdm_setreg(wc, card, 96,0x40);
1688
1689
	wctdm_getreg(wc,card,96); /* Read Reg 96 just cause */
1690
1691
	wctdm_setreg(wc, card, 21, 0xFF);
1692
	wctdm_setreg(wc, card, 22, 0xFF);
1693
	wctdm_setreg(wc, card, 23, 0xFF);
1694
1695
	/**The preceding is the longitudinal Balance Cal***/
1696
	return(0);
1697
1698
}
1699
#if 1
1700
static int wctdm_proslic_calibrate(struct wctdm *wc, int card)
1701
{
1702
	unsigned long origjiffies;
1703
	int x;
1704
	/* Perform all calibrations */
1705
	wctdm_setreg(wc, card, 97, 0x1f);
1706
	
1707
	/* Begin, no speedup */
1708
	wctdm_setreg(wc, card, 96, 0x5f);
1709
1710
	/* Wait for it to finish */
1711
	origjiffies = jiffies;
1712
	while(wctdm_getreg(wc, card, 96)) {
1713
		if ((jiffies - origjiffies) > 2 * HZ) {
1714
			printk(KERN_NOTICE "Timeout waiting for calibration of module %d\n", card);
1715
			return -1;
1716
		}
1717
	}
1718
	
1719
	if (debug) {
1720
		/* Print calibration parameters */
1721
		printk(KERN_DEBUG "Calibration Vector Regs 98 - 107: \n");
1722
		for (x=98;x<108;x++) {
1723
			printk(KERN_DEBUG "%d: %02x\n", x, wctdm_getreg(wc, card, x));
1724
		}
1725
	}
1726
	return 0;
1727
}
1728
#endif
1729
1730
static void wait_just_a_bit(int foo)
1731
{
1732
	long newjiffies;
1733
	newjiffies = jiffies + foo;
1734
	while(jiffies < newjiffies);
1735
}
1736
1737
/*********************************************************************
1738
 * Set the hwgain on the analog modules
1739
 *
1740
 * card = the card position for this module (0-23)
1741
 * gain = gain in dB x10 (e.g. -3.5dB  would be gain=-35)
1742
 * tx = (0 for rx; 1 for tx)
1743
 *
1744
 *******************************************************************/
1745
static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
1746
{
1747
	if (!(wc->modtype[card] == MOD_TYPE_FXO)) {
1748
		printk(KERN_NOTICE "Cannot adjust gain.  Unsupported module type!\n");
1749
		return -1;
1750
	}
1751
	if (tx) {
1752
		if (debug)
1753
			printk(KERN_DEBUG "setting FXO tx gain for card=%d to %d\n", card, gain);
1754
		if (gain >=  -150 && gain <= 0) {
1755
			wctdm_setreg(wc, card, 38, 16 + (gain/-10));
1756
			wctdm_setreg(wc, card, 40, 16 + (-gain%10));
1757
		} else if (gain <= 120 && gain > 0) {
1758
			wctdm_setreg(wc, card, 38, gain/10);
1759
			wctdm_setreg(wc, card, 40, (gain%10));
1760
		} else {
1761
			printk(KERN_INFO "FXO tx gain is out of range (%d)\n", gain);
1762
			return -1;
1763
		}
1764
	} else { /* rx */
1765
		if (debug)
1766
			printk(KERN_DEBUG "setting FXO rx gain for card=%d to %d\n", card, gain);
1767
		if (gain >=  -150 && gain <= 0) {
1768
			wctdm_setreg(wc, card, 39, 16+ (gain/-10));
1769
			wctdm_setreg(wc, card, 41, 16 + (-gain%10));
1770
		} else if (gain <= 120 && gain > 0) {
1771
			wctdm_setreg(wc, card, 39, gain/10);
1772
			wctdm_setreg(wc, card, 41, (gain%10));
1773
		} else {
1774
			printk(KERN_INFO "FXO rx gain is out of range (%d)\n", gain);
1775
			return -1;
1776
		}
1777
	}
1778
1779
	return 0;
1780
}
1781
1782
static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane)
1783
{
1784
	unsigned char reg16=0, reg26=0, reg30=0, reg31=0;
1785
	long newjiffies;
1786
	wc->modtype[card] = MOD_TYPE_FXO;
1787
	/* Sanity check the ProSLIC */
1788
	reset_spi(wc, card);
1789
	if (!sane && wctdm_voicedaa_insane(wc, card))
1790
		return -2;
1791
1792
	/* Software reset */
1793
	wctdm_setreg(wc, card, 1, 0x80);
1794
1795
	/* Wait just a bit */
1796
	wait_just_a_bit(HZ/10);
1797
1798
	/* Enable PCM, ulaw */
1799
	if (alawoverride)
1800
		wctdm_setreg(wc, card, 33, 0x20);
1801
	else
1802
		wctdm_setreg(wc, card, 33, 0x28);
1803
1804
	/* Set On-hook speed, Ringer impedence, and ringer threshold */
1805
	reg16 |= (fxo_modes[_opermode].ohs << 6);
1806
	reg16 |= (fxo_modes[_opermode].rz << 1);
1807
	reg16 |= (fxo_modes[_opermode].rt);
1808
	wctdm_setreg(wc, card, 16, reg16);
1809
1810
	if(fwringdetect) {
1811
		/* Enable ring detector full-wave rectifier mode */
1812
		wctdm_setreg(wc, card, 18, 2);
1813
		wctdm_setreg(wc, card, 24, 0);
1814
	} else { 
1815
		/* Set to the device defaults */
1816
		wctdm_setreg(wc, card, 18, 0);
1817
		wctdm_setreg(wc, card, 24, 0x19);
1818
	}
1819
	
1820
	/* Set DC Termination:
1821
	   Tip/Ring voltage adjust, minimum operational current, current limitation */
1822
	reg26 |= (fxo_modes[_opermode].dcv << 6);
1823
	reg26 |= (fxo_modes[_opermode].mini << 4);
1824
	reg26 |= (fxo_modes[_opermode].ilim << 1);
1825
	wctdm_setreg(wc, card, 26, reg26);
1826
1827
	/* Set AC Impedence */ 
1828
	reg30 = (fxofullscale==1) ? (fxo_modes[_opermode].acim|0x10) :  (fxo_modes[_opermode].acim);
1829
	wctdm_setreg(wc, card, 30, reg30);
1830
1831
	/* Misc. DAA parameters */
1832
	if (fastpickup)
1833
		reg31 = 0xb3;
1834
	else
1835
		reg31 = 0xa3;
1836
1837
	reg31 |= (fxo_modes[_opermode].ohs2 << 3);
1838
	wctdm_setreg(wc, card, 31, reg31);
1839
1840
	/* Set Transmit/Receive timeslot */
1841
	//printk("set card %d to %d\n", card, (3-(card%4)) * 8 + (card/4) * 64);
1842
	wctdm_setreg(wc, card, 34, (3-(card%4)) * 8 + (card/4) * 64);
1843
	wctdm_setreg(wc, card, 35, 0x00);
1844
	wctdm_setreg(wc, card, 36, (3-(card%4)) * 8 + (card/4) * 64);
1845
	wctdm_setreg(wc, card, 37, 0x00);
1846
1847
	/* Enable ISO-Cap */
1848
	wctdm_setreg(wc, card, 6, 0x00);
1849
1850
	if (fastpickup)
1851
		wctdm_setreg(wc, card, 17, wctdm_getreg(wc, card, 17) | 0x20);
1852
1853
	/* Wait 1000ms for ISO-cap to come up */
1854
	newjiffies = jiffies;
1855
	newjiffies += 2 * HZ;
1856
	while((jiffies < newjiffies) && !(wctdm_getreg(wc, card, 11) & 0xf0))
1857
		wait_just_a_bit(HZ/10);
1858
1859
	if (!(wctdm_getreg(wc, card, 11) & 0xf0)) {
1860
		printk(KERN_NOTICE "VoiceDAA did not bring up ISO link properly!\n");
1861
		return -1;
1862
	}
1863
	if (debug)
1864
		printk(KERN_DEBUG "ISO-Cap is now up, line side: %02x rev %02x\n", 
1865
		       wctdm_getreg(wc, card, 11) >> 4,
1866
		       (wctdm_getreg(wc, card, 13) >> 2) & 0xf);
1867
	/* Enable on-hook line monitor */
1868
	wctdm_setreg(wc, card, 5, 0x08);
1869
1870
	/* Take values for fxotxgain and fxorxgain and apply them to module */
1871
	wctdm_set_hwgain(wc, card, fxotxgain, 1);
1872
	wctdm_set_hwgain(wc, card, fxorxgain, 0);
1873
1874
	/* NZ -- crank the tx gain up by 7 dB */
1875
	if (!strcmp(fxo_modes[_opermode].name, "NEWZEALAND")) {
1876
		printk(KERN_INFO "Adjusting gain\n");
1877
		wctdm_set_hwgain(wc, card, 7, 1);
1878
	}
1879
1880
	if(debug)
1881
		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));
1882
1883
    return 0;
1884
		
1885
}
1886
1887
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, int sane)
1888
{
1889
1890
	unsigned short tmp[5];
1891
	unsigned char r19, r9;
1892
	int x;
1893
	int fxsmode=0;
1894
1895
	/* Sanity check the ProSLIC */
1896
	if (!sane && wctdm_proslic_insane(wc, card))
1897
		return -2;
1898
1899
	/* By default, don't send on hook */
1900
	if (reversepolarity)
1901
		wc->mod[card].fxs.idletxhookstate = 5;
1902
	else
1903
		wc->mod[card].fxs.idletxhookstate = 1;
1904
		
1905
	if (sane) {
1906
		/* Make sure we turn off the DC->DC converter to prevent anything from blowing up */
1907
		wctdm_setreg(wc, card, 14, 0x10);
1908
	}
1909
1910
	if (wctdm_proslic_init_indirect_regs(wc, card)) {
1911
		printk(KERN_INFO "Indirect Registers failed to initialize on module %d.\n", card);
1912
		return -1;
1913
	}
1914
1915
	/* Clear scratch pad area */
1916
	wctdm_proslic_setreg_indirect(wc, card, 97,0);
1917
1918
	/* Clear digital loopback */
1919
	wctdm_setreg(wc, card, 8, 0);
1920
1921
	/* Revision C optimization */
1922
	wctdm_setreg(wc, card, 108, 0xeb);
1923
1924
	/* Disable automatic VBat switching for safety to prevent
1925
	   Q7 from accidently turning on and burning out. */
1926
	wctdm_setreg(wc, card, 67, 0x07);  /* Note, if pulse dialing has problems at high REN loads
1927
					      change this to 0x17 */
1928
1929
	/* Turn off Q7 */
1930
	wctdm_setreg(wc, card, 66, 1);
1931
1932
	/* Flush ProSLIC digital filters by setting to clear, while
1933
	   saving old values */
1934
	for (x=0;x<5;x++) {
1935
		tmp[x] = wctdm_proslic_getreg_indirect(wc, card, x + 35);
1936
		wctdm_proslic_setreg_indirect(wc, card, x + 35, 0x8000);
1937
	}
1938
1939
	/* Power up the DC-DC converter */
1940
	if (wctdm_powerup_proslic(wc, card, fast)) {
1941
		printk(KERN_NOTICE "Unable to do INITIAL ProSLIC powerup on module %d\n", card);
1942
		return -1;
1943
	}
1944
1945
	if (!fast) {
1946
1947
		/* Check for power leaks */
1948
		if (wctdm_proslic_powerleak_test(wc, card)) {
1949
			printk(KERN_NOTICE "ProSLIC module %d failed leakage test.  Check for short circuit\n", card);
1950
		}
1951
		/* Power up again */
1952
		if (wctdm_powerup_proslic(wc, card, fast)) {
1953
			printk(KERN_NOTICE "Unable to do FINAL ProSLIC powerup on module %d\n", card);
1954
			return -1;
1955
		}
1956
#ifndef NO_CALIBRATION
1957
		/* Perform calibration */
1958
		if(manual) {
1959
			if (wctdm_proslic_manual_calibrate(wc, card)) {
1960
				//printk(KERN_NOTICE "Proslic failed on Manual Calibration\n");
1961
				if (wctdm_proslic_manual_calibrate(wc, card)) {
1962
					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n");
1963
					return -1;
1964
				}
1965
				printk(KERN_NOTICE "Proslic Passed Manual Calibration on Second Attempt\n");
1966
			}
1967
		}
1968
		else {
1969
			if(wctdm_proslic_calibrate(wc, card))  {
1970
				//printk(KERN_NOTICE "ProSlic died on Auto Calibration.\n");
1971
				if (wctdm_proslic_calibrate(wc, card)) {
1972
					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Auto Calibrate\n");
1973
					return -1;
1974
				}
1975
				printk(KERN_NOTICE "Proslic Passed Auto Calibration on Second Attempt\n");
1976
			}
1977
		}
1978
		/* Perform DC-DC calibration */
1979
		wctdm_setreg(wc, card, 93, 0x99);
1980
		r19 = wctdm_getreg(wc, card, 107);
1981
		if ((r19 < 0x2) || (r19 > 0xd)) {
1982
			printk(KERN_NOTICE "DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19);
1983
			wctdm_setreg(wc, card, 107, 0x8);
1984
		}
1985
1986
		/* Save calibration vectors */
1987
		for (x=0;x<NUM_CAL_REGS;x++)
1988
			wc->mod[card].fxs.calregs.vals[x] = wctdm_getreg(wc, card, 96 + x);
1989
#endif
1990
1991
	} else {
1992
		/* Restore calibration registers */
1993
		for (x=0;x<NUM_CAL_REGS;x++)
1994
			wctdm_setreg(wc, card, 96 + x, wc->mod[card].fxs.calregs.vals[x]);
1995
	}
1996
	/* Calibration complete, restore original values */
1997
	for (x=0;x<5;x++) {
1998
		wctdm_proslic_setreg_indirect(wc, card, x + 35, tmp[x]);
1999
	}
2000
2001
	if (wctdm_proslic_verify_indirect_regs(wc, card)) {
2002
		printk(KERN_INFO "Indirect Registers failed verification.\n");
2003
		return -1;
2004
	}
2005
2006
2007
#if 0
2008
    /* Disable Auto Power Alarm Detect and other "features" */
2009
    wctdm_setreg(wc, card, 67, 0x0e);
2010
    blah = wctdm_getreg(wc, card, 67);
2011
#endif
2012
2013
#if 0
2014
    if (wctdm_proslic_setreg_indirect(wc, card, 97, 0x0)) { // Stanley: for the bad recording fix
2015
		 printk(KERN_INFO "ProSlic IndirectReg Died.\n");
2016
		 return -1;
2017
	}
2018
#endif
2019
2020
    if (alawoverride)
2021
    	wctdm_setreg(wc, card, 1, 0x20);
2022
    else
2023
    	wctdm_setreg(wc, card, 1, 0x28);
2024
  // U-Law 8-bit interface
2025
    wctdm_setreg(wc, card, 2, (3-(card%4)) * 8 + (card/4) * 64);    // Tx Start count low byte  0
2026
    wctdm_setreg(wc, card, 3, 0);    // Tx Start count high byte 0
2027
    wctdm_setreg(wc, card, 4, (3-(card%4)) * 8 + (card/4) * 64);    // Rx Start count low byte  0
2028
    wctdm_setreg(wc, card, 5, 0);    // Rx Start count high byte 0
2029
    wctdm_setreg(wc, card, 18, 0xff);     // clear all interrupt
2030
    wctdm_setreg(wc, card, 19, 0xff);
2031
    wctdm_setreg(wc, card, 20, 0xff);
2032
    wctdm_setreg(wc, card, 73, 0x04);
2033
	if (fxshonormode) {
2034
		fxsmode = acim2tiss[fxo_modes[_opermode].acim];
2035
		wctdm_setreg(wc, card, 10, 0x08 | fxsmode);
2036
		if (fxo_modes[_opermode].ring_osc)
2037
			wctdm_proslic_setreg_indirect(wc, card, 20, fxo_modes[_opermode].ring_osc);
2038
		if (fxo_modes[_opermode].ring_x)
2039
			wctdm_proslic_setreg_indirect(wc, card, 21, fxo_modes[_opermode].ring_x);
2040
	}
2041
    if (lowpower)
2042
    	wctdm_setreg(wc, card, 72, 0x10);
2043
2044
#if 0
2045
    wctdm_setreg(wc, card, 21, 0x00); 	// enable interrupt
2046
    wctdm_setreg(wc, card, 22, 0x02); 	// Loop detection interrupt
2047
    wctdm_setreg(wc, card, 23, 0x01); 	// DTMF detection interrupt
2048
#endif
2049
2050
#if 0
2051
    /* Enable loopback */
2052
    wctdm_setreg(wc, card, 8, 0x2);
2053
    wctdm_setreg(wc, card, 14, 0x0);
2054
    wctdm_setreg(wc, card, 64, 0x0);
2055
    wctdm_setreg(wc, card, 1, 0x08);
2056
#endif
2057
2058
	if (fastringer) {
2059
		/* Speed up Ringer */
2060
		wctdm_proslic_setreg_indirect(wc, card, 20, 0x7e6d);
2061
		wctdm_proslic_setreg_indirect(wc, card, 21, 0x01b9);
2062
		/* Beef up Ringing voltage to 89V */
2063
		if (boostringer) {
2064
			wctdm_setreg(wc, card, 74, 0x3f);
2065
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x247)) 
2066
				return -1;
2067
			printk(KERN_INFO  "Boosting fast ringer on slot %d (89V peak)\n", card + 1);
2068
		} else if (lowpower) {
2069
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x14b)) 
2070
				return -1;
2071
			printk(KERN_INFO  "Reducing fast ring power on slot %d (50V peak)\n", card + 1);
2072
		} else
2073
			printk(KERN_INFO  "Speeding up ringer on slot %d (25Hz)\n", card + 1);
2074
	} else {
2075
		/* Beef up Ringing voltage to 89V */
2076
		if (boostringer) {
2077
			wctdm_setreg(wc, card, 74, 0x3f);
2078
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x1d1)) 
2079
				return -1;
2080
			printk(KERN_INFO  "Boosting ringer on slot %d (89V peak)\n", card + 1);
2081
		} else if (lowpower) {
2082
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x108)) 
2083
				return -1;
2084
			printk(KERN_INFO  "Reducing ring power on slot %d (50V peak)\n", card + 1);
2085
		}
2086
	}
2087
2088
	if(fxstxgain || fxsrxgain) {
2089
		r9 = wctdm_getreg(wc, card, 9);
2090
		switch (fxstxgain) {
2091
		
2092
			case 35:
2093
				r9+=8;
2094
				break;
2095
			case -35:
2096
				r9+=4;
2097
				break;
2098
			case 0: 
2099
				break;
2100
		}
2101
	
2102
		switch (fxsrxgain) {
2103
			
2104
			case 35:
2105
				r9+=2;
2106
				break;
2107
			case -35:
2108
				r9+=1;
2109
				break;
2110
			case 0:
2111
				break;
2112
		}
2113
		wctdm_setreg(wc,card,9,r9);
2114
	}
2115
2116
	if(debug)
2117
		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"));
2118
2119
	wctdm_setreg(wc, card, 64, 0x01);
2120
	return 0;
2121
}
2122
2123
2124
static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
2125
{
2126
	struct wctdm_stats stats;
2127
	struct wctdm_regs regs;
2128
	struct wctdm_regop regop;
2129
	struct wctdm_echo_coefs echoregs;
2130
	struct dahdi_hwgain hwgain;
2131
	struct wctdm *wc = chan->pvt;
2132
	int x;
2133
	switch (cmd) {
2134
	case DAHDI_ONHOOKTRANSFER:
2135
		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2136
			return -EINVAL;
2137
		if (get_user(x, (__user  int *)data))
2138
			return -EFAULT;
2139
		wc->mod[chan->chanpos - 1].fxs.ohttimer = x << 3;
2140
		if (reversepolarity)
2141
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
2142
		else
2143
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x2;
2144
		if (wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x1 || wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x5) {
2145
				/* Apply the change if appropriate */
2146
				if (reversepolarity)
2147
					wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x6;
2148
				else
2149
					wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x2;
2150
				wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
2151
		}
2152
		break;
2153
	case DAHDI_SETPOLARITY:
2154
		if (get_user(x, (__user int *)data))
2155
			return -EFAULT;
2156
		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2157
			return -EINVAL;
2158
		/* Can't change polarity while ringing or when open */
2159
		if ((wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x04) ||
2160
		    (wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x00))
2161
			return -EINVAL;
2162
2163
		if ((x && !reversepolarity) || (!x && reversepolarity))
2164
			wc->mod[chan->chanpos - 1].fxs.lasttxhook |= 0x04;
2165
		else
2166
			wc->mod[chan->chanpos - 1].fxs.lasttxhook &= ~0x04;
2167
		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
2168
		break;
2169
	case WCTDM_GET_STATS:
2170
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2171
			stats.tipvolt = wctdm_getreg(wc, chan->chanpos - 1, 80) * -376;
2172
			stats.ringvolt = wctdm_getreg(wc, chan->chanpos - 1, 81) * -376;
2173
			stats.batvolt = wctdm_getreg(wc, chan->chanpos - 1, 82) * -376;
2174
		} else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2175
			stats.tipvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2176
			stats.ringvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2177
			stats.batvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2178
		} else 
2179
			return -EINVAL;
2180
		if (copy_to_user((__user void *)data, &stats, sizeof(stats)))
2181
			return -EFAULT;
2182
		break;
2183
	case WCTDM_GET_REGS:
2184
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2185
			for (x=0;x<NUM_INDIRECT_REGS;x++)
2186
				regs.indirect[x] = wctdm_proslic_getreg_indirect(wc, chan->chanpos -1, x);
2187
			for (x=0;x<NUM_REGS;x++)
2188
				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
2189
		} else {
2190
			memset(&regs, 0, sizeof(regs));
2191
			for (x=0;x<NUM_FXO_REGS;x++)
2192
				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
2193
		}
2194
		if (copy_to_user((__user void *)data, &regs, sizeof(regs)))
2195
			return -EFAULT;
2196
		break;
2197
	case WCTDM_SET_REG:
2198
		if (copy_from_user(&regop, (__user void *)data, sizeof(regop)))
2199
			return -EFAULT;
2200
		if (regop.indirect) {
2201
			if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2202
				return -EINVAL;
2203
			printk(KERN_INFO  "Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos);
2204
			wctdm_proslic_setreg_indirect(wc, chan->chanpos - 1, regop.reg, regop.val);
2205
		} else {
2206
			regop.val &= 0xff;
2207
			printk(KERN_INFO  "Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos);
2208
			wctdm_setreg(wc, chan->chanpos - 1, regop.reg, regop.val);
2209
		}
2210
		break;
2211
	case WCTDM_SET_ECHOTUNE:
2212
		printk(KERN_INFO  "-- Setting echo registers: \n");
2213
		if (copy_from_user(&echoregs, (__user void *)data, sizeof(echoregs)))
2214
			return -EFAULT;
2215
2216
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2217
			/* Set the ACIM register */
2218
			wctdm_setreg(wc, chan->chanpos - 1, 30, (fxofullscale==1) ? (echoregs.acim|0x10) : echoregs.acim);
2219
2220
			/* Set the digital echo canceller registers */
2221
			wctdm_setreg(wc, chan->chanpos - 1, 45, echoregs.coef1);
2222
			wctdm_setreg(wc, chan->chanpos - 1, 46, echoregs.coef2);
2223
			wctdm_setreg(wc, chan->chanpos - 1, 47, echoregs.coef3);
2224
			wctdm_setreg(wc, chan->chanpos - 1, 48, echoregs.coef4);
2225
			wctdm_setreg(wc, chan->chanpos - 1, 49, echoregs.coef5);
2226
			wctdm_setreg(wc, chan->chanpos - 1, 50, echoregs.coef6);
2227
			wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7);
2228
			wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8);
2229
2230
			printk(KERN_INFO  "-- Set echo registers successfully\n");
2231
2232
			break;
2233
		} else {
2234
			return -EINVAL;
2235
2236
		}
2237
		break;
2238
	case DAHDI_SET_HWGAIN:
2239
		if (copy_from_user(&hwgain, (__user void *) data, sizeof(hwgain)))
2240
			return -EFAULT;
2241
2242
		wctdm_set_hwgain(wc, chan->chanpos-1, hwgain.newgain, hwgain.tx);
2243
2244
		if (debug)
2245
			printk(KERN_DEBUG  "Setting hwgain on channel %d to %d for %s direction\n", 
2246
				chan->chanpos-1, hwgain.newgain, hwgain.tx ? "tx" : "rx");
2247
		break;
2248
	default:
2249
		return -ENOTTY;
2250
	}
2251
	return 0;
2252
2253
}
2254
2255
static int wctdm_open(struct dahdi_chan *chan)
2256
{
2257
	struct wctdm *wc = chan->pvt;
2258
	if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
2259
		return -ENODEV;
2260
	if (wc->dead)
2261
		return -ENODEV;
2262
	wc->usecount++;
2263
2264
	/*MOD_INC_USE_COUNT; */
2265
	try_module_get(THIS_MODULE);
2266
	return 0;
2267
}
2268
2269
static int wctdm_watchdog(struct dahdi_span *span, int event)
2270
{
2271
	printk(KERN_INFO "opvxa1200: Restarting DMA\n");
2272
	wctdm_restart_dma(span->pvt);
2273
	return 0;
2274
}
2275
2276
static int wctdm_close(struct dahdi_chan *chan)
2277
{
2278
	struct wctdm *wc = chan->pvt;
2279
	wc->usecount--;
2280
2281
	/*MOD_DEC_USE_COUNT;*/
2282
	module_put(THIS_MODULE);
2283
2284
	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2285
		if (reversepolarity)
2286
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 5;
2287
		else
2288
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 1;
2289
	}
2290
	/* If we're dead, release us now */
2291
	if (!wc->usecount && wc->dead) 
2292
		wctdm_release(wc);
2293
	return 0;
2294
}
2295
2296
static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
2297
{
2298
	struct wctdm *wc = chan->pvt;
2299
	int reg=0;
2300
	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2301
		/* XXX Enable hooksig for FXO XXX */
2302
		switch(txsig) {
2303
		case DAHDI_TXSIG_START:
2304
		case DAHDI_TXSIG_OFFHOOK:
2305
			wc->mod[chan->chanpos - 1].fxo.offhook = 1;
2306
			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x9);
2307
			if(cidbeforering)
2308
			{
2309
				wc->cid_state[chan->chanpos - 1] = CID_STATE_IDLE;
2310
				wc->cid_history_clone_cnt[chan->chanpos - 1] = 0;
2311
				wc->cid_history_ptr[chan->chanpos - 1] = 0;
2312
				memset(wc->cid_history_buf[chan->chanpos - 1], DAHDI_LIN2X(0, chan), cidbuflen * DAHDI_MAX_CHUNKSIZE);
2313
			}
2314
			break;
2315
		case DAHDI_TXSIG_ONHOOK:
2316
			wc->mod[chan->chanpos - 1].fxo.offhook = 0;
2317
			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x8);
2318
			break;
2319
		default:
2320
			printk(KERN_NOTICE "wcfxo: Can't set tx state to %d\n", txsig);
2321
		}
2322
	} else {
2323
		switch(txsig) {
2324
		case DAHDI_TXSIG_ONHOOK:
2325
			switch(chan->sig) {
2326
			case DAHDI_SIG_EM:
2327
			case DAHDI_SIG_FXOKS:
2328
			case DAHDI_SIG_FXOLS:
2329
				wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
2330
				break;
2331
			case DAHDI_SIG_FXOGS:
2332
				wc->mod[chan->chanpos-1].fxs.lasttxhook = 3;
2333
				break;
2334
			}
2335
			break;
2336
		case DAHDI_TXSIG_OFFHOOK:
2337
			switch(chan->sig) {
2338
			case DAHDI_SIG_EM:
2339
				wc->mod[chan->chanpos-1].fxs.lasttxhook = 5;
2340
				break;
2341
			default:
2342
				wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
2343
				break;
2344
			}
2345
			break;
2346
		case DAHDI_TXSIG_START:
2347
			wc->mod[chan->chanpos-1].fxs.lasttxhook = 4;
2348
			break;
2349
		case DAHDI_TXSIG_KEWL:
2350
			wc->mod[chan->chanpos-1].fxs.lasttxhook = 0;
2351
			break;
2352
		default:
2353
			printk(KERN_NOTICE "opvxa1200: Can't set tx state to %d\n", txsig);
2354
		}
2355
		if (debug)
2356
			printk(KERN_DEBUG "Setting FXS hook state to %d (%02x)\n", txsig, reg);
2357
2358
#if 1
2359
		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos-1].fxs.lasttxhook);
2360
#endif
2361
	}
2362
	return 0;
2363
}
2364
2365
static int wctdm_initialize(struct wctdm *wc)
2366
{
2367
	int x;
2368
2369
	/* Dahdi stuff */
2370
	sprintf(wc->span.name, "OPVXA1200/%d", wc->pos);
2371
	snprintf(wc->span.desc, sizeof(wc->span.desc)-1, "%s Board %d", wc->variety, wc->pos + 1);
2372
	snprintf(wc->span.location, sizeof(wc->span.location) - 1,
2373
		 "PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
2374
	wc->span.manufacturer = "OpenVox";
2375
	dahdi_copy_string(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
2376
	if (alawoverride) {
2377
		printk(KERN_INFO "ALAW override parameter detected.  Device will be operating in ALAW\n");
2378
		wc->span.deflaw = DAHDI_LAW_ALAW;
2379
	} else
2380
		wc->span.deflaw = DAHDI_LAW_MULAW;
2381
		
2382
	x = __wctdm_getcreg(wc, WC_VER);
2383
	wc->fwversion = x;
2384
	if( x & FLAG_A800)
2385
	{
2386
		wc->card_name = A800P_Name;
2387
		wc->max_cards = 8;
2388
	}
2389
	else
2390
	{
2391
		wc->card_name = A1200P_Name;
2392
		wc->max_cards = 12;
2393
	}
2394
		
2395
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2396
		sprintf(wc->chans[x]->name, "OPVXA1200/%d/%d", wc->pos, x);
2397
		wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
2398
		wc->chans[x]->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
2399
		wc->chans[x]->chanpos = x+1;
2400
		wc->chans[x]->pvt = wc;
2401
	}
2402
	wc->span.chans = wc->chans;
2403
	wc->span.channels = wc->max_cards;	/*MAX_NUM_CARDS;*/
2404
	wc->span.hooksig = wctdm_hooksig;
2405
	wc->span.irq = wc->dev->irq;
2406
	wc->span.open = wctdm_open;
2407
	wc->span.close = wctdm_close;
2408
	wc->span.flags = DAHDI_FLAG_RBS;
2409
	wc->span.ioctl = wctdm_ioctl;
2410
	wc->span.watchdog = wctdm_watchdog;
2411
	init_waitqueue_head(&wc->span.maintq);
2412
2413
	wc->span.pvt = wc;
2414
	if (dahdi_register(&wc->span, 0)) {
2415
		printk(KERN_NOTICE "Unable to register span with Dahdi\n");
2416
		return -1;
2417
	}
2418
	return 0;
2419
}
2420
2421
static void wctdm_post_initialize(struct wctdm *wc)
2422
{
2423
	int x;
2424
2425
	/* Finalize signalling  */
2426
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2427
		if (wc->cardflag & (1 << x)) {
2428
			if (wc->modtype[x] == MOD_TYPE_FXO)
2429
				wc->chans[x]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
2430
			else
2431
				wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
2432
		} else if (!(wc->chans[x]->sigcap & DAHDI_SIG_BROKEN)) {
2433
			wc->chans[x]->sigcap = 0;
2434
		}
2435
	}
2436
}
2437
2438
static int wctdm_hardware_init(struct wctdm *wc)
2439
{
2440
	/* Hardware stuff */
2441
	unsigned char ver;
2442
	unsigned char x,y;
2443
	int failed;
2444
	long origjiffies; //ml.
2445
	
2446
	/* Signal Reset */
2447
	printk("before raise reset\n");
2448
	outb(0x01, wc->ioaddr + WC_CNTL);
2449
2450
	/* Wait for 5 second */
2451
	
2452
	origjiffies = jiffies;
2453
2454
	while(1) 
2455
	{
2456
		if ((jiffies - origjiffies) >= (HZ*5))
2457
			break;;
2458
	}
2459
2460
	/* printk(KERN_INFO "after raise reset\n");*/
2461
2462
	/* Check OpenVox chip */
2463
	x=inb(wc->ioaddr + WC_CNTL);
2464
	ver = __wctdm_getcreg(wc, WC_VER);
2465
	wc->fwversion = ver;
2466
	/*if( ver & FLAG_A800)
2467
	{
2468
		wc->card_name = A800P_Name;
2469
		wc->max_cards = 8;
2470
	}
2471
	else
2472
	{
2473
		wc->card_name = A1200P_Name;
2474
		wc->max_cards = 12;
2475
	}*/
2476
	printk(KERN_NOTICE "OpenVox %s version: %01x.%01x\n", wc->card_name, (ver&(~FLAG_A800))>>4, ver&0x0f);
2477
	
2478
	failed = 0;
2479
	if (ver != 0x00) {
2480
		for (x=0;x<16;x++) {
2481
			/* Test registers */
2482
			__wctdm_setcreg(wc, WC_CS, x);
2483
			y = __wctdm_getcreg(wc, WC_CS) & 0x0f;
2484
			if (x != y) {
2485
				printk(KERN_INFO "%02x != %02x\n", x, y);
2486
				failed++;
2487
			}
2488
		}
2489
2490
		if (!failed) {
2491
			printk(KERN_INFO "OpenVox %s passed register test\n", wc->card_name);
2492
		} else {
2493
			printk(KERN_NOTICE "OpenVox %s failed register test\n", wc->card_name);
2494
			return -1;
2495
		}
2496
	} else {
2497
		printk(KERN_INFO "No OpenVox chip %02x\n", ver);
2498
	}
2499
2500
	if (spibyhw)
2501
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);	// spi controled by hw MiaoLin;
2502
	else
2503
		__wctdm_setcreg(wc, WC_SPICTRL, 0);	
2504
		
2505
	/* Reset PCI Interface chip and registers (and serial) */
2506
	outb(0x06, wc->ioaddr + WC_CNTL);
2507
	/* Setup our proper outputs for when we switch for our "serial" port */
2508
	wc->ios = BIT_CS | BIT_SCLK | BIT_SDI;
2509
2510
	outb(wc->ios, wc->ioaddr + WC_AUXD);
2511
2512
	/* Set all to outputs except AUX 5, which is an input */
2513
	outb(0xdf, wc->ioaddr + WC_AUXC);
2514
2515
	/* Select alternate function for AUX0 */  /* Useless in OpenVox by MiaoLin. */
2516
	/* outb(0x4, wc->ioaddr + WC_AUXFUNC); */
2517
	
2518
	/* Wait 1/4 of a sec */
2519
	wait_just_a_bit(HZ/4);
2520
2521
	/* Back to normal, with automatic DMA wrap around */
2522
	outb(0x30 | 0x01, wc->ioaddr + WC_CNTL);
2523
	wc->ledstate = 0;
2524
	wctdm_set_led(wc, 0, 0);
2525
	
2526
	/* Make sure serial port and DMA are out of reset */
2527
	outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, wc->ioaddr + WC_CNTL);
2528
	
2529
	/* Configure serial port for MSB->LSB operation */
2530
	outb(0xc1, wc->ioaddr + WC_SERCTL);
2531
2532
	/* Delay FSC by 0 so it's properly aligned */
2533
	outb(0x01, wc->ioaddr + WC_FSCDELAY);  /* Modify to 1 by MiaoLin */
2534
2535
	/* Setup DMA Addresses */
2536
	outl(wc->writedma,                    wc->ioaddr + WC_DMAWS);		/* Write start */
2537
	outl(wc->writedma + DAHDI_CHUNKSIZE * 4 * 4 - 4, wc->ioaddr + WC_DMAWI);		/* Middle (interrupt) */
2538
	outl(wc->writedma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMAWE);			/* End */
2539
	
2540
	outl(wc->readdma,                    	 wc->ioaddr + WC_DMARS);	/* Read start */
2541
	outl(wc->readdma + DAHDI_CHUNKSIZE * 4 * 4 - 4, 	 wc->ioaddr + WC_DMARI);	/* Middle (interrupt) */
2542
	outl(wc->readdma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMARE);	/* End */
2543
	
2544
	/* Clear interrupts */
2545
	outb(0xff, wc->ioaddr + WC_INTSTAT);
2546
2547
	/* Wait 1/4 of a second more */
2548
	wait_just_a_bit(HZ/4);
2549
2550
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2551
		int sane=0,ret=0,readi=0;
2552
#if 1
2553
		touch_softlockup_watchdog();  // avoid showing CPU softlock message
2554
		/* Init with Auto Calibration */
2555
		if (!(ret=wctdm_init_proslic(wc, x, 0, 0, sane))) {
2556
			wc->cardflag |= (1 << x);
2557
                        if (debug) {
2558
                                readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
2559
                                printk("Proslic module %d loop current is %dmA\n",x,
2560
                                ((readi*3)+20));
2561
                        }
2562
			printk(KERN_INFO "Module %d: Installed -- AUTO FXS/DPO\n",x);
2563
			wctdm_set_led(wc, (unsigned int)x, 1);
2564
		} else {
2565
			if(ret!=-2) {
2566
				sane=1;
2567
				
2568
				printk(KERN_INFO "Init ProSlic with Manual Calibration \n");
2569
				/* Init with Manual Calibration */
2570
				if (!wctdm_init_proslic(wc, x, 0, 1, sane)) {
2571
					wc->cardflag |= (1 << x);
2572
                                if (debug) {
2573
                                        readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
2574
                                        printk("Proslic module %d loop current is %dmA\n",x,
2575
                                        ((readi*3)+20));
2576
                                }
2577
					printk(KERN_INFO "Module %d: Installed -- MANUAL FXS\n",x);
2578
				} else {
2579
					printk(KERN_NOTICE "Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");
2580
					wc->chans[x]->sigcap = __DAHDI_SIG_FXO | DAHDI_SIG_BROKEN;
2581
				} 
2582
			} else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) {
2583
				wc->cardflag |= (1 << x);
2584
				printk(KERN_INFO "Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);
2585
				wctdm_set_led(wc, (unsigned int)x, 1);
2586
			} else
2587
				printk(KERN_NOTICE "Module %d: Not installed\n", x);
2588
		}
2589
#endif
2590
	}
2591
2592
	/* Return error if nothing initialized okay. */
2593
	if (!wc->cardflag && !timingonly)
2594
		return -1;
2595
	/*__wctdm_setcreg(wc, WC_SYNC, (wc->cardflag << 1) | 0x1); */  /* removed by MiaoLin */
2596
	return 0;
2597
}
2598
2599
static void wctdm_enable_interrupts(struct wctdm *wc)
2600
{
2601
	/* Clear interrupts */
2602
	outb(0xff, wc->ioaddr + WC_INTSTAT);
2603
2604
	/* Enable interrupts (we care about all of them) */
2605
	outb(0x3c, wc->ioaddr + WC_MASK0);
2606
	/* No external interrupts */
2607
	outb(0x00, wc->ioaddr + WC_MASK1);
2608
}
2609
2610
static void wctdm_restart_dma(struct wctdm *wc)
2611
{
2612
	/* Reset Master and TDM */
2613
	outb(0x01, wc->ioaddr + WC_CNTL);
2614
	outb(0x01, wc->ioaddr + WC_OPER);
2615
}
2616
2617
static void wctdm_start_dma(struct wctdm *wc)
2618
{
2619
	/* Reset Master and TDM */
2620
	outb(0x0f, wc->ioaddr + WC_CNTL);
2621
	set_current_state(TASK_INTERRUPTIBLE);
2622
	schedule_timeout(1);
2623
	outb(0x01, wc->ioaddr + WC_CNTL);
2624
	outb(0x01, wc->ioaddr + WC_OPER);
2625
}
2626
2627
static void wctdm_stop_dma(struct wctdm *wc)
2628
{
2629
	outb(0x00, wc->ioaddr + WC_OPER);
2630
}
2631
2632
static void wctdm_reset_tdm(struct wctdm *wc)
2633
{
2634
	/* Reset TDM */
2635
	outb(0x0f, wc->ioaddr + WC_CNTL);
2636
}
2637
2638
static void wctdm_disable_interrupts(struct wctdm *wc)	
2639
{
2640
	outb(0x00, wc->ioaddr + WC_MASK0);
2641
	outb(0x00, wc->ioaddr + WC_MASK1);
2642
}
2643
2644
static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2645
{
2646
	int res;
2647
	struct wctdm *wc;
2648
	struct wctdm_desc *d = (struct wctdm_desc *)ent->driver_data;
2649
	int x;
2650
	int y;
2651
2652
	static int initd_ifaces=0;
2653
	
2654
	if(initd_ifaces){
2655
		memset((void *)ifaces,0,(sizeof(struct wctdm *))*WC_MAX_IFACES);
2656
		initd_ifaces=1;
2657
	}
2658
	for (x=0;x<WC_MAX_IFACES;x++)
2659
		if (!ifaces[x]) break;
2660
	if (x >= WC_MAX_IFACES) {
2661
		printk(KERN_NOTICE "Too many interfaces\n");
2662
		return -EIO;
2663
	}
2664
	
2665
	if (pci_enable_device(pdev)) {
2666
		res = -EIO;
2667
	} else {
2668
		wc = kmalloc(sizeof(struct wctdm), GFP_KERNEL);
2669
		if (wc) {
2670
			int cardcount = 0;
2671
			
2672
			wc->lastchan = -1;	/* first channel offset = -1; */
2673
			wc->ledstate = 0;
2674
			
2675
			ifaces[x] = wc;
2676
			memset(wc, 0, sizeof(struct wctdm));
2677
			for (x=0; x < sizeof(wc->chans)/sizeof(wc->chans[0]); ++x) {
2678
				wc->chans[x] = &wc->_chans[x];
2679
			}
2680
2681
			spin_lock_init(&wc->lock);
2682
			wc->curcard = -1;
2683
			wc->ioaddr = pci_resource_start(pdev, 0);
2684
			wc->mem_region = pci_resource_start(pdev, 1);
2685
			wc->mem_len = pci_resource_len(pdev, 1);
2686
			wc->mem32 = (unsigned long)ioremap(wc->mem_region, wc->mem_len);
2687
			wc->dev = pdev;
2688
			wc->pos = x;
2689
			wc->variety = d->name;
2690
			for (y=0;y<MAX_NUM_CARDS;y++)
2691
				wc->flags[y] = d->flags;
2692
			/* Keep track of whether we need to free the region */
2693
			if (request_region(wc->ioaddr, 0xff, "opvxa1200")) 
2694
				wc->freeregion = 1;
2695
			else
2696
				wc->freeregion = 0;
2697
			
2698
			if (request_mem_region(wc->mem_region, wc->mem_len, "opvxa1200"))
2699
				wc->freeregion |= 0x02;
2700
2701
			/* Allocate enough memory for two zt chunks, receive and transmit.  Each sample uses
2702
			   8 bits.  */
2703
			wc->writechunk = pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, &wc->writedma);
2704
			if (!wc->writechunk) {
2705
				printk(KERN_NOTICE "opvxa1200: Unable to allocate DMA-able memory\n");
2706
				if (wc->freeregion & 0x01)
2707
					release_region(wc->ioaddr, 0xff);
2708
				if (wc->freeregion & 0x02)
2709
				{
2710
					release_mem_region(wc->mem_region, wc->mem_len);
2711
					iounmap((void *)wc->mem32);
2712
				}
2713
				return -ENOMEM;
2714
			}
2715
2716
			wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
2717
			wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
2718
			
2719
			if (wctdm_initialize(wc)) {
2720
				printk(KERN_NOTICE "opvxa1200: Unable to intialize FXS\n");
2721
				/* Set Reset Low */
2722
				x=inb(wc->ioaddr + WC_CNTL);
2723
				outb((~0x1)&x, wc->ioaddr + WC_CNTL);
2724
				/* Free Resources */
2725
				free_irq(pdev->irq, wc);
2726
				if (wc->freeregion & 0x01)
2727
					release_region(wc->ioaddr, 0xff);
2728
				if (wc->freeregion & 0x02)
2729
				{
2730
					release_mem_region(wc->mem_region, wc->mem_len);
2731
					iounmap((void *)wc->mem32);
2732
				}
2733
			}
2734
2735
			/* Enable bus mastering */
2736
			pci_set_master(pdev);
2737
2738
			/* Keep track of which device we are */
2739
			pci_set_drvdata(pdev, wc);
2740
2741
2742
			if (request_irq(pdev->irq, wctdm_interrupt, DAHDI_IRQ_SHARED, "opvxa1200", wc)) {
2743
				printk(KERN_NOTICE "opvxa1200: Unable to request IRQ %d\n", pdev->irq);
2744
				if (wc->freeregion & 0x01)
2745
					release_region(wc->ioaddr, 0xff);
2746
				if (wc->freeregion & 0x02)
2747
				{
2748
					release_mem_region(wc->mem_region, wc->mem_len);
2749
					iounmap((void *)wc->mem32);
2750
				}
2751
				pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2752
				pci_set_drvdata(pdev, NULL);
2753
				kfree(wc);
2754
				return -EIO;
2755
			}
2756
2757
			if (wctdm_hardware_init(wc)) {
2758
				unsigned char w;
2759
2760
				/* Set Reset Low */
2761
				w=inb(wc->ioaddr + WC_CNTL);
2762
				outb((~0x1)&w, wc->ioaddr + WC_CNTL);
2763
				/* Free Resources */
2764
				free_irq(pdev->irq, wc);
2765
				if (wc->freeregion & 0x01)
2766
					release_region(wc->ioaddr, 0xff);
2767
				if (wc->freeregion & 0x02)
2768
				{
2769
					release_mem_region(wc->mem_region, wc->mem_len);
2770
					iounmap((void *)wc->mem32);
2771
				}
2772
				pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2773
				pci_set_drvdata(pdev, NULL);
2774
				dahdi_unregister(&wc->span);
2775
				kfree(wc);
2776
				return -EIO;
2777
2778
			}
2779
2780
#ifdef TEST_LOG_INCOME_VOICE
2781
			for(x=0; x<MAX_NUM_CARDS+NUM_FLAG; x++)
2782
			{
2783
				wc->voc_buf[x] = kmalloc(voc_buffer_size, GFP_KERNEL);
2784
				wc->voc_ptr[x] = 0;
2785
			}
2786
#endif
2787
2788
			if(cidbeforering) 
2789
			{		
2790
				int len = cidbuflen * DAHDI_MAX_CHUNKSIZE;
2791
				if(debug)
2792
					printk("cidbeforering support enabled, length is %d msec\n", cidbuflen);
2793
				for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) 
2794
				{
2795
					wc->cid_history_buf[x] = kmalloc(len, GFP_KERNEL);
2796
					wc->cid_history_ptr[x] = 0;
2797
					wc->cid_history_clone_cnt[x] = 0;
2798
					wc->cid_state[x] = CID_STATE_IDLE;
2799
				}
2800
			}
2801
			
2802
			wctdm_post_initialize(wc);
2803
2804
			/* Enable interrupts */
2805
			wctdm_enable_interrupts(wc);
2806
			/* Initialize Write/Buffers to all blank data */
2807
			memset((void *)wc->writechunk,0, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2);
2808
2809
			/* Start DMA */
2810
			wctdm_start_dma(wc);
2811
2812
			for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2813
				if (wc->cardflag & (1 << x))
2814
					cardcount++;
2815
			}
2816
2817
			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);
2818
			if(debug)
2819
				printk(KERN_DEBUG "OpenVox %s debug On\n", wc->card_name);
2820
			
2821
			res = 0;
2822
		} else
2823
			res = -ENOMEM;
2824
	}
2825
	return res;
2826
}
2827
2828
static void wctdm_release(struct wctdm *wc)
2829
{
2830
#ifdef TEST_LOG_INCOME_VOICE
2831
	struct file * f = NULL;
2832
	mm_segment_t orig_fs;
2833
	int i;
2834
	char fname[20];
2835
#endif
2836
	
2837
	dahdi_unregister(&wc->span);
2838
	if (wc->freeregion & 0x01)
2839
		release_region(wc->ioaddr, 0xff);
2840
	if (wc->freeregion & 0x02)
2841
	{
2842
		release_mem_region(wc->mem_region, wc->mem_len);
2843
		iounmap((void *)wc->mem32);
2844
	}
2845
	
2846
#ifdef TEST_LOG_INCOME_VOICE
2847
	for(i=0; i<MAX_NUM_CARDS + NUM_FLAG; i++)
2848
	{
2849
		sprintf(fname, "//usr//%d.pcm", i); 
2850
		f = filp_open(fname, O_RDWR|O_CREAT, 00);
2851
	
2852
		if (!f || !f->f_op || !f->f_op->read)
2853
		{
2854
			printk("WARNING: File (read) object is a null pointer!!!\n");
2855
			continue;
2856
		}
2857
	
2858
		f->f_pos = 0;
2859
		
2860
		orig_fs = get_fs();
2861
		set_fs(KERNEL_DS); 
2862
		
2863
		if(wc->voc_buf[i])
2864
		{
2865
			f->f_op->write(f, wc->voc_buf[i], voc_buffer_size, &f->f_pos);
2866
			kfree(wc->voc_buf[i]);
2867
		}
2868
		
2869
		set_fs(orig_fs); 
2870
		fput(f);
2871
	}
2872
#endif
2873
 
2874
	if(cidbeforering) 
2875
	{
2876
		int x;
2877
		for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) 
2878
			kfree(wc->cid_history_buf[x]);
2879
	}
2880
 
2881
	kfree(wc);
2882
	printk(KERN_INFO "Freed a OpenVox A1200 card\n");
2883
}
2884
2885
static void __devexit wctdm_remove_one(struct pci_dev *pdev)
2886
{
2887
	struct wctdm *wc = pci_get_drvdata(pdev);
2888
	if (wc) {
2889
2890
		/* Stop any DMA */
2891
		wctdm_stop_dma(wc);
2892
		wctdm_reset_tdm(wc);
2893
2894
		/* In case hardware is still there */
2895
		wctdm_disable_interrupts(wc);
2896
		
2897
		/* Immediately free resources */
2898
		pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2899
		free_irq(pdev->irq, wc);
2900
2901
		/* Reset PCI chip and registers */
2902
		if(wc->fwversion > 0x11)
2903
			outb(0x0e, wc->ioaddr + WC_CNTL);
2904
		else
2905
		{
2906
			wc->ledstate = 0;
2907
			wctdm_set_led(wc,0,0);	// power off all leds.
2908
		}
2909
2910
		/* Release span, possibly delayed */
2911
		if (!wc->usecount)
2912
			wctdm_release(wc);
2913
		else
2914
			wc->dead = 1;
2915
	}
2916
}
2917
2918
static struct pci_device_id wctdm_pci_tbl[] = {
2919
	{ 0xe159, 0x0001, 0x9100, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2920
	{ 0xe159, 0x0001, 0x9519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2921
	{ 0xe159, 0x0001, 0x95D9, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2922
	{ 0xe159, 0x0001, 0x9500, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2923
	{ 0xe159, 0x0001, 0x9532, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme }, 
2924
	{ 0xe159, 0x0001, 0x8519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2925
	{ 0xe159, 0x0001, 0x9559, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2926
	{ 0xe159, 0x0001, 0x9599, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2927
	{ 0 }
2928
};
2929
2930
MODULE_DEVICE_TABLE(pci, wctdm_pci_tbl);
2931
2932
static struct pci_driver wctdm_driver = {
2933
	.name = "opvxa1200",
2934
	.probe =	wctdm_init_one,
2935
	.remove =	__devexit_p(wctdm_remove_one),
2936
	.suspend = NULL,
2937
	.resume =	NULL,
2938
	.id_table = wctdm_pci_tbl,
2939
};
2940
2941
static int __init wctdm_init(void)
2942
{
2943
	int res;
2944
	int x;
2945
	for (x=0;x<(sizeof(fxo_modes) / sizeof(fxo_modes[0])); x++) {
2946
		if (!strcmp(fxo_modes[x].name, opermode))
2947
			break;
2948
	}
2949
	if (x < sizeof(fxo_modes) / sizeof(fxo_modes[0])) {
2950
		_opermode = x;
2951
	} else {
2952
		printk(KERN_NOTICE "Invalid/unknown operating mode '%s' specified.  Please choose one of:\n", opermode);
2953
		for (x=0;x<sizeof(fxo_modes) / sizeof(fxo_modes[0]); x++)
2954
			printk(KERN_INFO "  %s\n", fxo_modes[x].name);
2955
		printk(KERN_INFO "Note this option is CASE SENSITIVE!\n");
2956
		return -ENODEV;
2957
	}
2958
	if (!strcmp(fxo_modes[_opermode].name, "AUSTRALIA")) {
2959
		boostringer=1;
2960
		fxshonormode=1;
2961
}
2962
	if (battdebounce == 0) {
2963
		battdebounce = fxo_modes[_opermode].battdebounce;
2964
	}
2965
	if (battalarm == 0) {
2966
		battalarm = fxo_modes[_opermode].battalarm;
2967
	}
2968
	if (battthresh == 0) {
2969
		battthresh = fxo_modes[_opermode].battthresh;
2970
	}
2971
2972
	res = dahdi_pci_module(&wctdm_driver);
2973
	if (res)
2974
		return -ENODEV;
2975
	return 0;
2976
}
2977
2978
static void __exit wctdm_cleanup(void)
2979
{
2980
	pci_unregister_driver(&wctdm_driver);
2981
}
2982
2983
module_param(debug, int, 0600);
2984
module_param(loopcurrent, int, 0600);
2985
module_param(reversepolarity, int, 0600);
2986
module_param(robust, int, 0600);
2987
module_param(opermode, charp, 0600);
2988
module_param(timingonly, int, 0600);
2989
module_param(lowpower, int, 0600);
2990
module_param(boostringer, int, 0600);
2991
module_param(fastringer, int, 0600);
2992
module_param(fxshonormode, int, 0600);
2993
module_param(battdebounce, uint, 0600);
2994
module_param(battthresh, uint, 0600);
2995
module_param(battalarm, uint, 0600);
2996
module_param(ringdebounce, int, 0600);
2997
module_param(fwringdetect, int, 0600);
2998
module_param(alawoverride, int, 0600);
2999
module_param(fastpickup, int, 0600);
3000
module_param(fxotxgain, int, 0600);
3001
module_param(fxorxgain, int, 0600);
3002
module_param(fxstxgain, int, 0600);
3003
module_param(fxsrxgain, int, 0600);
3004
module_param(spibyhw, int, 0600);
3005
module_param(usememio, int, 0600);
3006
module_param(cidbeforering, int, 0600);
3007
module_param(cidbuflen, int, 0600);
3008
module_param(cidtimeout, int, 0600);
3009
module_param(fxofullscale, int, 0600);
3010
module_param(fixedtimepolarity, int, 0600);
3011
3012
MODULE_DESCRIPTION("OpenVox A1200 Driver");
3013
MODULE_AUTHOR("MiaoLin <miaolin@openvox.com.cn>");
3014
MODULE_LICENSE("GPL v2");
3015
3016
module_init(wctdm_init);
3017
module_exit(wctdm_cleanup);
(-)dahdi-linux-2.2.0.2/drivers/dahdi/wcopenpci.c (+1841 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
50
#include <dahdi/kernel.h>
51
#include <dahdi/version.h>
52
#include "proslic.h"
53
#include <dahdi/wctdm_user.h>
54
55
56
57
/* Compatibility helpers */
58
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
59
 #include <linux/interrupt.h>
60
#else
61
 typedef void irqreturn_t;
62
 #define IRQ_NONE
63
 #define IRQ_HANDLED
64
 #define IRQ_RETVAL(x)
65
 #define __devexit_p(x) x
66
#endif
67
68
// Centos4.3 uses a modified 2.6.9 kernel, with no indication that
69
// it is different from the mainstream (or even Centos4.2 2.6.9)
70
// kernel, so we must crowbar off the dunce-hat manually here.
71
#if !defined CENTOS4_3 && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
72
 typedef int gfp_t;
73
 static inline void *kzalloc( size_t n, gfp_t flags ){
74
	void *p = kmalloc(n,flags);
75
	if (p) memset(p, 0, n);
76
	return p;
77
 }
78
#endif
79
80
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
81
 #define DEFINE_MUTEX(x)		DECLARE_MUTEX(x)
82
 #define mutex_init(x)			init_MUTEX(x)
83
 #define mutex_lock(x)			down(x)
84
 #define mutex_lock_interruptible(x)	down_interruptible(x)
85
 #define mutex_trylock(x)		down_trylock(x)
86
 #define mutex_unlock(x)		up(x)
87
#else
88
 #include <linux/mutex.h>
89
#endif
90
91
92
static struct fxo_mode {
93
	char *name;
94
	int ohs;
95
	int ohs2;
96
	int rz;
97
	int rt;
98
	int ilim;
99
	int dcv;
100
	int mini;
101
	int acim;
102
	int ring_osc;
103
	int ring_x;
104
} fxo_modes[] =
105
{
106
	{ "FCC", 0, 0, 0, 1, 0, 0x3, 0, 0, }, 	/* US, Canada */
107
	{ "TBR21", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0x7e6c, 0x023a, },
108
		/* Austria, Belgium, Denmark, Finland, France, Germany, 
109
		   Greece, Iceland, Ireland, Italy, Luxembourg, Netherlands,
110
		   Norway, Portugal, Spain, Sweden, Switzerland, and UK */
111
	{ "ARGENTINA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
112
	{ "AUSTRALIA", 1, 0, 0, 0, 0, 0, 0x3, 0x3, },
113
	{ "AUSTRIA", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
114
	{ "BAHRAIN", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
115
	{ "BELGIUM", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
116
	{ "BRAZIL", 0, 0, 0, 0, 0, 0, 0x3, 0, },
117
	{ "BULGARIA", 0, 0, 0, 0, 1, 0x3, 0x0, 0x3, },
118
	{ "CANADA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
119
	{ "CHILE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
120
	{ "CHINA", 0, 0, 0, 0, 0, 0, 0x3, 0xf, },
121
	{ "COLUMBIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
122
	{ "CROATIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
123
	{ "CYRPUS", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
124
	{ "CZECH", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
125
	{ "DENMARK", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
126
	{ "ECUADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
127
	{ "EGYPT", 0, 0, 0, 0, 0, 0, 0x3, 0, },
128
	{ "ELSALVADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
129
	{ "FINLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
130
	{ "FRANCE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
131
	{ "GERMANY", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
132
	{ "GREECE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
133
	{ "GUAM", 0, 0, 0, 0, 0, 0x3, 0, 0, },
134
	{ "HONGKONG", 0, 0, 0, 0, 0, 0x3, 0, 0, },
135
	{ "HUNGARY", 0, 0, 0, 0, 0, 0x3, 0, 0, },
136
	{ "ICELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
137
	{ "INDIA", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
138
	{ "INDONESIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
139
	{ "IRELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
140
	{ "ISRAEL", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
141
	{ "ITALY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
142
	{ "JAPAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
143
	{ "JORDAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
144
	{ "KAZAKHSTAN", 0, 0, 0, 0, 0, 0x3, 0, },
145
	{ "KUWAIT", 0, 0, 0, 0, 0, 0x3, 0, 0, },
146
	{ "LATVIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
147
	{ "LEBANON", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
148
	{ "LUXEMBOURG", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
149
	{ "MACAO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
150
	{ "MALAYSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },	/* Current loop >= 20ma */
151
	{ "MALTA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
152
	{ "MEXICO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
153
	{ "MOROCCO", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
154
	{ "NETHERLANDS", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
155
	{ "NEWZEALAND", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
156
	{ "NIGERIA", 0, 0, 0, 0, 0x1, 0x3, 0, 0x2, },
157
	{ "NORWAY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
158
	{ "OMAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
159
	{ "PAKISTAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
160
	{ "PERU", 0, 0, 0, 0, 0, 0x3, 0, 0, },
161
	{ "PHILIPPINES", 0, 0, 0, 0, 0, 0, 0x3, 0, },
162
	{ "POLAND", 0, 0, 1, 1, 0, 0x3, 0, 0, },
163
	{ "PORTUGAL", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
164
	{ "ROMANIA", 0, 0, 0, 0, 0, 3, 0, 0, },
165
	{ "RUSSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
166
	{ "SAUDIARABIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
167
	{ "SINGAPORE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
168
	{ "SLOVAKIA", 0, 0, 0, 0, 0, 0x3, 0, 0x3, },
169
	{ "SLOVENIA", 0, 0, 0, 0, 0, 0x3, 0, 0x2, },
170
	{ "SOUTHAFRICA", 1, 0, 1, 0, 0, 0x3, 0, 0x3, },
171
	{ "SOUTHKOREA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
172
	{ "SPAIN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
173
	{ "SWEDEN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
174
	{ "SWITZERLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
175
	{ "SYRIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
176
	{ "TAIWAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
177
	{ "THAILAND", 0, 0, 0, 0, 0, 0, 0x3, 0, },
178
	{ "UAE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
179
	{ "UK", 0, 1, 0, 0, 1, 0x3, 0, 0x5, },
180
	{ "USA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
181
	{ "YEMEN", 0, 0, 0, 0, 0, 0x3, 0, 0, },
182
};
183
184
static struct ps_country_reg {
185
	const char *country;
186
	unsigned short value;
187
} ps_country_regs[] = {
188
	{"ARGENTINA",  0x8},
189
	{"AUSTRALIA",  0xD},
190
	{"AUSTRIA",    0xD},
191
	{"BAHRAIN",    0xC},
192
	{"BELGIUM",    0xC},
193
	{"BRAZIL",     0x8},
194
	{"BULGARIA",   0xD},
195
	{"CANADA",     0x8},
196
	{"CHILE",      0x8},
197
	{"CHINA",      0xC},
198
	{"COLOMBIA",   0x8},
199
	{"CROATIA",    0xC},
200
	{"CYPRUS",     0xC},
201
	{"CZECH",      0xC},
202
	{"DENMARK",    0xC},
203
	{"ECUADOR",    0x8},
204
	{"EGYPT",      0x8},
205
	{"ELSALVADOR", 0x8},
206
	{"FINLAND",    0xC},
207
	{"FRANCE",     0xC},
208
	{"GERMANY",    0xD},
209
	{"GREECE",     0xC},
210
	{"GUAM",       0x8},
211
	{"HONGKONG",   0x8},
212
	{"HUNGARY",    0x8},
213
	{"ICELAND",    0xC},
214
	{"INDIA",      0xF},
215
	{"INDONESIA",  0x8},
216
	{"IRELAND",    0xC},
217
	{"ISRAEL",     0xC},
218
	{"ITALY",      0xC},
219
	{"JAPAN",      0x8},
220
	{"JORDAN",     0x8},
221
	{"KAZAKHSTAN", 0x8},
222
	{"KUWAIT",     0x8},
223
	{"LATVIA",     0xC},
224
	{"LEBANON",    0xC},
225
	{"LUXEMBOURG", 0xC},
226
	{"MACAO",      0x8},
227
	{"MALAYSIA",   0x8},
228
	{"MALTA",      0xC},
229
	{"MEXICO",     0x8},
230
	{"MOROCCO",    0xC},
231
	{"NETHERLANDS",0xC},
232
	{"NEWZEALAND", 0xF},
233
	{"NIGERIA",    0xC},
234
	{"NORWAY",     0xC},
235
	{"OMAN",       0x8},
236
	{"PAKISTAN",   0x8},
237
	{"PERU",       0x8},
238
	{"PHILIPPINES",0x8},
239
	{"POLAND",     0x8},
240
	{"PORTUGAL",   0xC},
241
	{"ROMANIA",    0x8},
242
	{"RUSSIA",     0x8},
243
	{"SAUDIARABIA",0x8},
244
	{"SINGAPORE",  0x8},
245
	{"SLOVAKIA",   0xE},
246
	{"SLOVENIA",   0xE},
247
	{"SOUTHAFRICA",0xE},
248
	{"SOUTHKOREA", 0x8},
249
	{"SPAIN",      0xC},
250
	{"SWEDEN",     0xC},
251
	{"SWITZERLAND",0xC},
252
	{"SYRIA",      0x8},
253
	{"TAIWAN",     0x8},
254
	{"THAILAND",   0x8},
255
	{"UAE",        0x8},
256
	{"UK",         0xC},
257
	{"USA",        0x8},
258
	{"YEMEN",      0x8}
259
};
260
261
#define INOUT 2
262
263
/* Allocate enough memory for two zt chunks, receive and transmit.  Each sample uses
264
   32 bits.  Allocate an extra set just for control too */
265
#define VT_PCIDMA_BLOCKSIZE (DAHDI_MAX_CHUNKSIZE * INOUT * MAX_PORTS * 2 * 2)
266
#define VT_PCIDMA_MIDDLE    (DAHDI_MAX_CHUNKSIZE * MAX_PORTS - 4)
267
#define VT_PCIDMA_END       (DAHDI_MAX_CHUNKSIZE * MAX_PORTS * 2 - 4)
268
269
#define ID_DATA_MAXSIZE         30
270
271
#define NUM_CAL_REGS 12
272
#define NUM_FXO_REGS 60
273
274
#define TREG(addr)      (wc->ioaddr + addr)
275
276
#define TJ_CNTL         TREG(0x00)
277
#define TJ_OPER         TREG(0x01)
278
#define TJ_AUXC         TREG(0x02)
279
#define TJ_AUXD         TREG(0x03)
280
#define TJ_MASK0        TREG(0x04)
281
#define TJ_MASK1        TREG(0x05)
282
#define TJ_INTSTAT      TREG(0x06)
283
#define TJ_AUXR         TREG(0x07)
284
285
#define TJ_DMAWS        TREG(0x08)
286
#define TJ_DMAWI        TREG(0x0c)
287
#define TJ_DMAWE        TREG(0x10)
288
#define TJ_DMAWC        TREG(0x14)
289
#define TJ_DMARS        TREG(0x18)
290
#define TJ_DMARI        TREG(0x1c)
291
#define TJ_DMARE        TREG(0x20)
292
#define TJ_DMARC        TREG(0x24)
293
294
#define TJ_AUXINTPOL    TREG(0x2A)
295
296
#define TJ_AUXFUNC      TREG(0x2b)
297
#define TJ_SFDELAY      TREG(0x2c)
298
#define TJ_SERCTL       TREG(0x2d)
299
#define TJ_SFLC         TREG(0x2e)
300
#define TJ_FSCDELAY     TREG(0x2f)
301
302
#define TJ_REGBASE      TREG(0xc0)
303
304
#define PIB(addr)       (TJ_REGBASE + addr * 4)
305
306
#define HTXF_READY      (inb(PIB(0)) & 0x10)
307
#define HRXF_READY      (inb(PIB(0)) & 0x20)
308
309
310
#define VT_PORT_EMPTY	0
311
#define VT_PORT_VDAA	1   /* Voice DAA - FXO */
312
#define VT_PORT_PROSLIC	2   /* ProSLIC - FXS */
313
314
#define VBAT 0xC7
315
316
#define HKMODE_FWDACT   1
317
#define HKMODE_FWDONACT	2
318
#define HKMODE_RINGING	4
319
320
#define HOOK_ONHOOK     0
321
#define HOOK_OFFHOOK    1
322
323
#define	DSP_CODEC_RING		12	/* RING rising edge detected		*/
324
#define	DSP_CODEC_HKOFF		22	/* station port off hook                */
325
#define	DSP_CODEC_HKON		23	/* station port on hook                 */
326
#define	DSP_RING_OFF		24	/* RING falling edge detected		*/
327
#define DSP_DROP		25
328
329
#define	DSP_CODEC_FLASH		26	/* station port hook flash              */
330
331
#define DSP_LOOP_OFFHOOK	38	/* Loop Off hook from OpenPCI           */
332
#define DSP_LOOP_ONHOOK		39	/* Loop On hook from OpenPCI            */
333
#define DSP_LOOP_POLARITY	40	/* Loop Polarity from OpenPCI           */
334
#define DSP_LOOP_NOBATT		41
335
336
#define DSP_PROSLIC_SANITY	50	/* Sanity alert from a ProSLIC port 	*/
337
#define DSP_PROSLIC_PWR_ALARM	51	/* Power Alarm from a ProSLIC port 	*/
338
#define DSP_VDAA_ISO_FRAME_E	52	/* ISO-cap frame sync lost on VDAA port*/
339
340
#if VERBOSE_TIMING
341
 #define REPORT_WAIT(n,x)						    \
342
	 cardinfo(card->cardnum, #n " wait at %d, " #x " = %d", __LINE__, x )
343
#else
344
 #define REPORT_WAIT(n,x)
345
#endif
346
347
#define BUSY_WAIT(countvar,cond,delay,iter,failret)			    \
348
	countvar=0;							    \
349
	while(cond){							    \
350
	    udelay(delay);						    \
351
	    if(++countvar > iter){					    \
352
		cardcrit(wc->boardnum, "busy wait FAILED at %d", __LINE__); \
353
		return failret;						    \
354
	    }								    \
355
	}								    \
356
	REPORT_WAIT(busy,i)
357
358
#define LOCKED_WAIT(countvar,cond,delay,iter,failret)			    \
359
	countvar=0;							    \
360
	while(cond){							    \
361
	    udelay(delay);						    \
362
	    if(++countvar > iter){					    \
363
		dbginfo(wc->boardnum,"busy wait failed at %d",__LINE__);    \
364
		spin_unlock_irqrestore(&wc->lock, flags);		    \
365
		return failret;						    \
366
	    }								    \
367
	}								    \
368
	REPORT_WAIT(locked,i)
369
370
#define HTXF_WAIT()                 BUSY_WAIT(i,HTXF_READY,5,500,RET_FAIL)
371
#define HRXF_WAIT()                 BUSY_WAIT(i,!HRXF_READY,5,70000,RET_FAIL)
372
#define HTXF_WAIT_RET(failret)      BUSY_WAIT(i,HTXF_READY,5,500,failret)
373
#define HRXF_WAIT_RET(failret)      BUSY_WAIT(i,!HRXF_READY,5,1000,failret)
374
375
#define HTXF_WAIT_LOCKED()	    LOCKED_WAIT(i,HTXF_READY,5,500,RET_FAIL)
376
#define HRXF_WAIT_LOCKED()	    LOCKED_WAIT(i,!HRXF_READY,5,1000,RET_FAIL)
377
#define HTXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,HTXF_READY,5,500,failret)
378
#define HRXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,!HRXF_READY,5,1000,failret)
379
380
381
struct openpci {
382
	struct pci_dev *dev;
383
	char *variety;
384
	int boardnum;
385
	int portcount;
386
	int porttype[MAX_PORTS];
387
388
        int firmware;
389
        char serial[ID_DATA_MAXSIZE];
390
391
	spinlock_t lock;
392
393
	//XXX Replace these with proper try_module_get locking in the dahdi driver.
394
	//int usecount;	//XXX
395
	//int dead;	//XXX
396
	union {
397
		struct {
398
			int offhook;
399
		} fxo;
400
		struct {
401
			int ohttimer;
402
			int idletxhookstate;  /* IDLE changing hook state */
403
			int lasttxhook;
404
		} fxs;
405
	} mod[MAX_PORTS];
406
407
	unsigned long		ioaddr;
408
	dma_addr_t		readdma;
409
	dma_addr_t		writedma;
410
	volatile unsigned int  *writechunk;  /* Double-word aligned write memory */
411
	volatile unsigned int  *readchunk;   /* Double-word aligned read memory */
412
413
	struct dahdi_chan _chans[MAX_PORTS];
414
	struct dahdi_chan *chans[MAX_PORTS];
415
	struct dahdi_span span;
416
} *cards[MAX_CARDS];
417
418
// You must hold this lock anytime you access or modify the cards[] array.
419
DEFINE_MUTEX(cards_mutex);
420
421
static unsigned char fxo_port_lookup[8] = { 0x0, 0x8, 0x4, 0xc, 0x10, 0x18, 0x14, 0x1c};
422
static unsigned char fxs_port_lookup[8] = { 0x0, 0x1, 0x2, 0x3, 0x10, 0x11, 0x12, 0x13};
423
static char wcopenpci[] = "Voicetronix OpenPCI";
424
425
static char *country = DEFAULT_COUNTRY;
426
static int reversepolarity;  // = 0
427
static int debug;            // = 0
428
429
module_param(country, charp, 0444);
430
module_param(debug, int, 0600);
431
module_param(reversepolarity, int, 0600);
432
MODULE_PARM_DESC(country, "Set the default country name");
433
MODULE_PARM_DESC(debug, "Enable verbose logging");
434
435
//#define DEBUG_LOOP_VOLTAGE 1
436
#ifdef DEBUG_LOOP_VOLTAGE
437
 // This param is a 32 bit bitfield where bit 1 << cardnum * 8 << portnum
438
 // will enable voltage monitoring on that port (fxo only presently)
439
 static int voltmeter;        // = 0
440
 module_param(voltmeter, int, 0600);
441
 MODULE_PARM_DESC(voltmeter, "Enable loop voltage metering");
442
#endif
443
444
445
/* boolean return values */
446
#define RET_OK   1
447
#define RET_FAIL 0
448
449
/* Convenience macros for logging */
450
#define info(format,...) printk(KERN_INFO NAME ": " format "\n" , ## __VA_ARGS__)
451
#define warn(format,...) printk(KERN_WARNING NAME ": " format "\n" , ## __VA_ARGS__)
452
#define crit(format,...) printk(KERN_CRIT NAME ": " format "\n" , ## __VA_ARGS__)
453
#define cardinfo(cardnum,format,...) info("[%02d] " format, cardnum , ## __VA_ARGS__)
454
#define cardwarn(cardnum,format,...) warn("[%02d] " format, cardnum , ## __VA_ARGS__)
455
#define cardcrit(cardnum,format,...) crit("[%02d] " format, cardnum , ## __VA_ARGS__)
456
#define dbginfo(cardnum,format,...) if(debug) info("[%02d] " format, cardnum , ## __VA_ARGS__)
457
458
459
static inline const char *porttype(struct openpci *wc, int port)
460
{ //{{{
461
	switch( wc->porttype[port] ) {
462
	    case VT_PORT_VDAA:    return "VDAA";
463
	    case VT_PORT_PROSLIC: return "ProSLIC";
464
	    case VT_PORT_EMPTY:   return "empty port";
465
	    default:              return "unknown type";
466
	}
467
} //}}}
468
469
470
static int __read_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
471
{ //{{{
472
	unsigned char portadr = fxo_port_lookup[port];
473
	int i;
474
475
	if (HRXF_READY) *value = inb(PIB(1));
476
477
	outb(0x11, PIB(1));    HTXF_WAIT();
478
	outb(0x2, PIB(1));     HTXF_WAIT();
479
	outb(portadr, PIB(1)); HTXF_WAIT();
480
	outb(reg, PIB(1));     HTXF_WAIT();
481
	HRXF_WAIT(); *value = inb(PIB(1));
482
483
	return RET_OK;
484
} //}}}
485
486
static int read_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
487
{ //{{{
488
	unsigned long flags;
489
490
	spin_lock_irqsave(&wc->lock, flags);
491
	if( __read_reg_fxo(wc, port, reg, value) ){
492
		spin_unlock_irqrestore(&wc->lock, flags);
493
		return RET_OK;
494
	}
495
	spin_unlock_irqrestore(&wc->lock, flags);
496
	cardcrit(wc->boardnum, "FXO port %d, reg %d, read failed!", port, reg);
497
	return RET_FAIL;
498
} //}}}
499
500
static int __read_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
501
{ //{{{
502
	unsigned char portadr = fxs_port_lookup[port];
503
	int i;
504
505
	if (HRXF_READY) *value = inb(PIB(1));
506
507
	outb(0x13, PIB(1));    HTXF_WAIT();
508
	outb(0x2, PIB(1));     HTXF_WAIT();
509
	outb(portadr, PIB(1)); HTXF_WAIT();
510
	outb(reg, PIB(1));     HTXF_WAIT();
511
	HRXF_WAIT(); *value = inb(PIB(1));
512
513
	return RET_OK;
514
} //}}}
515
516
static int read_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
517
{ //{{{
518
	unsigned long flags;
519
520
	spin_lock_irqsave(&wc->lock, flags);
521
	if( __read_reg_fxs(wc, port, reg, value) ) {
522
		spin_unlock_irqrestore(&wc->lock, flags);
523
		return RET_OK;
524
	}
525
	spin_unlock_irqrestore(&wc->lock, flags);
526
	cardcrit(wc->boardnum, "FXS port %d, reg %d, read failed!", port, reg);
527
	return RET_FAIL;
528
} //}}}
529
530
static int __write_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char value)
531
{ //{{{
532
	unsigned char portadr = fxo_port_lookup[port];
533
	int i;
534
535
        outb(0x10, PIB(1) );   HTXF_WAIT();
536
        outb(0x3, PIB(1));     HTXF_WAIT();
537
        outb(portadr, PIB(1)); HTXF_WAIT();
538
        outb(reg, PIB(1));     HTXF_WAIT();
539
        outb(value, PIB(1));   HTXF_WAIT();
540
541
	return RET_OK;
542
} //}}}
543
544
static int write_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char value)
545
{ //{{{
546
	unsigned long flags;
547
548
	spin_lock_irqsave(&wc->lock, flags);
549
	if( __write_reg_fxo(wc, port, reg, value) ){
550
		spin_unlock_irqrestore(&wc->lock, flags);
551
		return RET_OK;
552
	}
553
	spin_unlock_irqrestore(&wc->lock, flags);
554
	cardcrit(wc->boardnum, "FXO port %d, reg %d, write(%d) failed!", port, reg, value);
555
	return RET_FAIL;
556
} //}}}
557
558
static int __write_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char value)
559
{ //{{{
560
	unsigned char portadr = fxs_port_lookup[port];
561
	int i;
562
563
        outb(0x12, PIB(1) );   HTXF_WAIT();
564
        outb(0x3, PIB(1));     HTXF_WAIT();
565
        outb(portadr, PIB(1)); HTXF_WAIT();
566
        outb(reg, PIB(1));     HTXF_WAIT();
567
        outb(value, PIB(1));   HTXF_WAIT();
568
569
	return RET_OK;
570
} //}}}
571
572
static int write_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char value)
573
{ //{{{
574
	unsigned long flags;
575
576
	spin_lock_irqsave(&wc->lock, flags);
577
	if( __write_reg_fxs(wc, port, reg, value) ){
578
		spin_unlock_irqrestore(&wc->lock, flags);
579
		return RET_OK;
580
	}
581
	spin_unlock_irqrestore(&wc->lock, flags);
582
	cardcrit(wc->boardnum, "FXS port %d, reg %d, write(%d) failed!", port, reg, value);
583
	return RET_FAIL;
584
} //}}}
585
586
static int __wait_indreg_fxs(struct openpci *wc, int port)
587
{ //{{{
588
	unsigned char value;
589
	int count = 100;
590
591
	while (--count)
592
	{
593
		if( __read_reg_fxs(wc, port, I_STATUS, &value) ){
594
			if( value == 0 )
595
				return RET_OK;
596
		} else {
597
			cardcrit(wc->boardnum,
598
				 "failed to read port %d PS_IND_ADDR_ST, retrying...",
599
				 port);
600
		}
601
		udelay(5);
602
	}
603
	cardcrit(wc->boardnum, "Failed to wait for indirect reg write to port %d", port);
604
	return RET_FAIL;
605
} //}}}
606
607
static int write_indreg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned short value)
608
{ //{{{
609
	unsigned long flags;
610
611
	spin_lock_irqsave(&wc->lock, flags);
612
	if( __wait_indreg_fxs(wc, port)
613
	 && __write_reg_fxs(wc, port, IDA_LO, value & 0xff)
614
	 && __write_reg_fxs(wc, port, IDA_HI, (value & 0xff00)>>8)
615
	 && __write_reg_fxs(wc, port, IAA, reg)
616
	 && __wait_indreg_fxs(wc, port) )
617
	{
618
		spin_unlock_irqrestore(&wc->lock, flags);
619
		return RET_OK;
620
	}
621
	spin_unlock_irqrestore(&wc->lock, flags);
622
	cardcrit(wc->boardnum, "FXS indreg %d write failed on port %d", reg, port);
623
	return RET_FAIL;
624
} //}}}
625
626
static int read_indreg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned short *value)
627
{ //{{{
628
	unsigned long flags;
629
	unsigned char lo, hi;
630
631
	spin_lock_irqsave(&wc->lock, flags);
632
	if( __wait_indreg_fxs(wc, port)
633
	 && __write_reg_fxs(wc, port, IAA, reg)
634
	 && __wait_indreg_fxs(wc, port)
635
	 && __read_reg_fxs(wc, port, IDA_LO, &lo)
636
	 && __read_reg_fxs(wc, port, IDA_HI, &hi) )
637
	{
638
		*value = lo | hi << 8;
639
		spin_unlock_irqrestore(&wc->lock, flags);
640
		return RET_OK;
641
	}
642
	spin_unlock_irqrestore(&wc->lock, flags);
643
	return RET_FAIL;
644
} //}}}
645
646
static void start_dma(struct openpci *wc)
647
{ //{{{
648
	outb(0x0f, TJ_CNTL);
649
	set_current_state(TASK_INTERRUPTIBLE);
650
	schedule_timeout(1);
651
	outb(0x01, TJ_CNTL);
652
	outb(0x01, TJ_OPER);
653
} //}}}
654
655
static void restart_dma(struct openpci *wc)
656
{ //{{{
657
	/* Reset Master and TDM */
658
	outb(0x01, TJ_CNTL);
659
	outb(0x01, TJ_OPER);
660
} //}}}
661
662
/* You must hold the card spinlock to call this function */
663
static int __ping_arm(struct openpci *wc)
664
{ //{{{
665
	int i;
666
	int pong=0;
667
668
	while(pong != 0x02){
669
		outb(0x02, PIB(1)); HTXF_WAIT();
670
		HRXF_WAIT(); pong = inb(PIB(1));
671
		dbginfo(wc->boardnum, "ping_arm returned %x", pong);
672
	}
673
	while(pong == 0x02){
674
		// Poke no-ops into the arm while it is still returning data,
675
		// if 500 usec elapses with no further response from it then
676
		// the message queue is should be completely cleared.
677
		outb(0x00, PIB(1)); HTXF_WAIT();
678
		i = 100;
679
		while( !HRXF_READY && --i ) udelay(5);
680
		if( i == 0 ) break;
681
		pong = inb(PIB(1));
682
		dbginfo(wc->boardnum, "ping_arm returned %x.", pong);
683
	}
684
	return RET_OK;
685
} //}}}
686
687
static void arm_event(struct openpci *wc, char *msg)
688
{ //{{{
689
	int port = msg[0];
690
691
	switch(msg[1]){
692
		case DSP_LOOP_OFFHOOK:
693
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
694
			dbginfo(wc->boardnum, "Port %d Loop OffHook", port);
695
			break;
696
697
		case DSP_LOOP_ONHOOK:
698
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
699
			dbginfo(wc->boardnum, "Port %d Loop OnHook", port);
700
			break;
701
702
		case DSP_LOOP_POLARITY:
703
			dahdi_qevent_lock(wc->chans[port], DAHDI_EVENT_POLARITY);
704
			dbginfo(wc->boardnum, "Port %d Loop Polarity", port);
705
			break;
706
707
		case DSP_CODEC_RING:
708
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_RING);
709
			dbginfo(wc->boardnum, "Port %d Ring On", port);
710
			break;
711
712
		case DSP_RING_OFF:
713
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
714
			dbginfo(wc->boardnum, "Port %d Ring Off", port);
715
			break;
716
717
		case DSP_CODEC_HKOFF:
718
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
719
			dbginfo(wc->boardnum, "Port %d Station OffHook", port);
720
			if (reversepolarity)
721
				wc->mod[port].fxs.idletxhookstate = 5;
722
			else
723
				wc->mod[port].fxs.idletxhookstate = 1;
724
			break;
725
726
		case DSP_CODEC_HKON:
727
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
728
			dbginfo(wc->boardnum, "Port %d Station OnHook", port);
729
			if (reversepolarity)
730
				wc->mod[port].fxs.idletxhookstate = 6;
731
			else
732
				wc->mod[port].fxs.idletxhookstate = 2;
733
			break;
734
735
		case DSP_CODEC_FLASH:
736
			dahdi_qevent_lock(wc->chans[port], DAHDI_EVENT_WINKFLASH);
737
			dbginfo(wc->boardnum, "Port %d Station Flash", port);
738
			break;
739
740
		case DSP_DROP:
741
		case DSP_LOOP_NOBATT:
742
			break;
743
744
			//XXX What to do to recover from these?
745
		case DSP_PROSLIC_SANITY:
746
			dbginfo(wc->boardnum, "Port %d ProSlic has gone insane!", port);
747
			break;
748
749
		case DSP_PROSLIC_PWR_ALARM:
750
		{
751
			char errbuf[32] = " Unknown", *p = errbuf;
752
			int i = 49;
753
754
			msg[2] >>= 2;
755
			for(; i < 55; ++i, msg[2] >>= 1 )
756
			    if(msg[2] & 1){ *(++p)='Q'; *(++p)=i; *(++p)=','; }
757
			if( p != errbuf ) *p = '\0';
758
			cardcrit(wc->boardnum,"%d: ProSlic power ALARM:%s",msg[0],errbuf);
759
			//write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook );
760
			return;
761
		}
762
763
		case DSP_VDAA_ISO_FRAME_E:
764
			dbginfo(wc->boardnum, "Port %d VDAA has lost ISO-Cap frame lock", port);
765
			break;
766
767
		default:
768
			cardwarn(wc->boardnum, "Unknown message from Arm[%d] for port %d",
769
						msg[1], port);
770
			break;
771
	}
772
} //}}}
773
774
/* You must hold the card spinlock to call this function */
775
static inline int __read_arm_byte( struct openpci *wc, unsigned char *msg )
776
{ //{{{
777
	int i;
778
779
	HRXF_WAIT(); *msg = inb(PIB(1));
780
	return RET_OK;
781
} //}}}
782
783
static inline int read_arm_msg( struct openpci *wc, unsigned char *msg )
784
{ //{{{
785
	unsigned long flags;
786
	int i, d, count;
787
	int ret = RET_OK;
788
789
	spin_lock_irqsave(&wc->lock, flags);
790
	outb(0x08, PIB(1)); HTXF_WAIT_LOCKED();
791
	//XXX Do we need to clear the interrupt flag even if this fails?
792
	HRXF_WAIT_LOCKED(); count = inb(PIB(1));
793
	if( count == 0 ){
794
		ret = RET_FAIL;
795
	} else if( count < 3 || count > 4 ){
796
		cardcrit(wc->boardnum, "BOGUS arm message size %d, flushing queue", count);
797
		// NB: This may take a while (up to 500usec or more) to complete
798
		//     and we are in the isr at present when this is called, so
799
		//     we may miss an interrupt or two while this is done in the
800
		//     bottom half, but we are already in trouble, so...
801
		d = debug; debug = 5; __ping_arm( wc ); debug = d;
802
		ret = RET_FAIL;
803
	} else while( --count ){
804
		if( ! __read_arm_byte(wc, msg) ){
805
			cardcrit(wc->boardnum,
806
				 "Failed to read arm message %d more bytes expected",
807
				 count);
808
			ret = RET_FAIL;
809
			break;
810
		}
811
		++msg;
812
	}
813
	outb(0x09, PIB(1)); HTXF_WAIT_LOCKED();
814
	spin_unlock_irqrestore(&wc->lock, flags);
815
	return ret;
816
} //}}}
817
818
static void openpci_arm_work( void *cardptr )
819
{ //{{{
820
	struct openpci *wc = (struct openpci*)cardptr;
821
	unsigned char armmsg[4];
822
823
	if( read_arm_msg(wc, armmsg) ) arm_event(wc, armmsg);
824
} //}}}
825
826
827
static inline void openpci_write(struct openpci *wc, unsigned char flags)
828
{ //{{{
829
	int x,y;
830
	volatile unsigned int *writechunk;
831
832
	if (flags & 0x01)
833
		writechunk = wc->writechunk;
834
	else if (flags & 0x02)
835
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE*2;
836
	else {
837
		cardcrit(wc->boardnum, "bad write interrupt flags %x, at %x",
838
					flags, inb(TJ_DMAWC) );
839
		return;
840
	}
841
	/* get data */
842
	dahdi_transmit(&wc->span);
843
	for (y=0,x=0;x<DAHDI_CHUNKSIZE;++x) {
844
		/* Send a sample, as a 32-bit word */
845
#ifdef __BIG_ENDIAN
846
#error No big endian support (yet)
847
#else
848
		/* transmit second 4 ports */
849
		writechunk[y]=0;
850
		if (wc->porttype[4])
851
			writechunk[y] |= (wc->chans[4]->writechunk[x] << 24);
852
		else
853
			writechunk[y] |= (0x01 << 24);
854
		if (wc->porttype[5])
855
			writechunk[y] |= (wc->chans[5]->writechunk[x] << 16);
856
		if (wc->porttype[6])
857
			writechunk[y] |= (wc->chans[6]->writechunk[x] << 8);
858
		if (wc->porttype[7])
859
			writechunk[y] |= (wc->chans[7]->writechunk[x]);
860
		++y;
861
862
		/* transmit first 4 ports */
863
		writechunk[y]=0x01000000;
864
		/* Make sure first port doesnt equal 0x00 */
865
		if (wc->porttype[0]){
866
			if (wc->chans[0]->writechunk[x] == 0)
867
				writechunk[y] |= (0x01 << 24);
868
			else
869
				writechunk[y] |= (wc->chans[0]->writechunk[x] << 24);
870
		}
871
		//else writechunk[y] |= (0x00 << 24);
872
		if (wc->porttype[1])
873
			writechunk[y] |= (wc->chans[1]->writechunk[x] << 16);
874
		if (wc->porttype[2])
875
			writechunk[y] |= (wc->chans[2]->writechunk[x] << 8);
876
		if (wc->porttype[3])
877
			writechunk[y] |= (wc->chans[3]->writechunk[x]);
878
		++y;
879
#endif
880
	}
881
} //}}}
882
883
static inline void openpci_read(struct openpci *wc, unsigned char flags)
884
{ //{{{
885
	int x,y;
886
	volatile unsigned int *readchunk;
887
888
	if (flags & 0x08)
889
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE*2;
890
	else if (flags & 0x04)
891
		readchunk = wc->readchunk;
892
	else {
893
		cardcrit(wc->boardnum, "bad read interrupt flags %x, at %x",
894
					flags, inb(TJ_DMARC));
895
		return;
896
	}
897
898
	for (y=0,x=0;x<DAHDI_CHUNKSIZE;++x) {
899
#ifdef __BIG_ENDIAN
900
#error No big endian support (yet)
901
#else
902
		/* Receive first 4 ports */
903
904
		if (wc->porttype[0])
905
			wc->chans[0]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
906
		if (wc->porttype[1])
907
			wc->chans[1]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
908
		if (wc->porttype[2])
909
			wc->chans[2]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
910
		if (wc->porttype[3])
911
			wc->chans[3]->readchunk[x] = (readchunk[y]) & 0xff;
912
		++y;
913
		/* Receive second 4 ports */
914
		if (wc->porttype[4])
915
			wc->chans[4]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
916
		if (wc->porttype[5])
917
			wc->chans[5]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
918
		if (wc->porttype[6])
919
			wc->chans[6]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
920
		if (wc->porttype[7])
921
			wc->chans[7]->readchunk[x] = (readchunk[y]) & 0xff;
922
		++y;
923
#endif
924
	}
925
	/* XXX We're wasting 8 taps.  We should get closer :( */
926
	for (x = 0; x < MAX_PORTS; x++) {
927
		if (wc->porttype[x])
928
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
929
	}
930
	dahdi_receive(&wc->span);
931
} //}}}
932
933
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
934
static irqreturn_t openpci_isr(int irq, void *dev_id, struct pt_regs *regs)
935
#else
936
static irqreturn_t openpci_isr(int irq, void *dev_id)
937
#endif
938
{ //{{{
939
	struct openpci *wc = dev_id;
940
	unsigned long flags;
941
	unsigned char status;
942
943
	spin_lock_irqsave(&wc->lock, flags);
944
	status = inb(TJ_INTSTAT);
945
	outb(status, TJ_INTSTAT);
946
947
	if (!status) {
948
		if(inb(TJ_AUXR) & 0x02) {
949
			spin_unlock_irqrestore(&wc->lock, flags);
950
			return IRQ_NONE;
951
		}
952
		spin_unlock_irqrestore(&wc->lock, flags);
953
		openpci_arm_work(wc);
954
		return IRQ_HANDLED;
955
	}
956
	if (status & 0x10){
957
		/* PCI Master abort */
958
		cardcrit(wc->boardnum, "PCI Master Abort.");
959
		/* Stop DMA, wait for watchdog */
960
		outb(0x00, TJ_OPER);
961
		spin_unlock_irqrestore(&wc->lock, flags);
962
		return IRQ_HANDLED;
963
	}
964
	spin_unlock_irqrestore(&wc->lock, flags);
965
966
	if (status & 0x20){
967
		/* PCI Target abort */
968
		cardcrit(wc->boardnum, "PCI Target Abort.");
969
		return IRQ_HANDLED;
970
	}
971
	if (status & 0x03){
972
		openpci_write(wc, status);
973
	}
974
	if (status & 0x0c){
975
	    #ifdef DEBUG_LOOP_VOLTAGE
976
	    //{{{
977
		static int counter[MAX_CARDS];
978
		int card = wc->boardnum;
979
		int port = ++counter[card] & 0x07;
980
		int ignore = counter[card] & 0xf0;
981
982
		if( ! ignore && (voltmeter & ((1 << (card * 8)) << port)) ) {
983
			unsigned char lv;
984
			if( wc->porttype[port] == VT_PORT_VDAA && read_reg_fxo(wc, port, 29, &lv) )
985
				cardinfo(wc->boardnum, "Port %d loop voltage %d",
986
							port, lv < 128 ? lv : lv - 256);
987
		}
988
	    //}}}
989
	    #endif
990
		openpci_read(wc, status);
991
	}
992
993
	return IRQ_HANDLED;
994
} //}}}
995
996
static int openpci_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
997
{ //{{{
998
	struct wctdm_stats stats;
999
	struct wctdm_regs regs;
1000
	struct wctdm_regop regop;
1001
	struct wctdm_echo_coefs echoregs;
1002
	struct openpci *wc = chan->pvt;
1003
	int port = chan->chanpos - 1;
1004
	int x;
1005
1006
	switch (cmd) {
1007
	case DAHDI_ONHOOKTRANSFER:
1008
		if (wc->porttype[port] != VT_PORT_PROSLIC)
1009
			return -EINVAL;
1010
		if (get_user(x, (int *)data))
1011
			return -EFAULT;
1012
		wc->mod[port].fxs.ohttimer = x << 3;
1013
		if (reversepolarity)
1014
			wc->mod[port].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
1015
		else
1016
			wc->mod[port].fxs.idletxhookstate = 0x2;
1017
		switch(wc->mod[port].fxs.lasttxhook) {
1018
		    case 0x1:
1019
		    case 0x5:
1020
			if (reversepolarity)
1021
				wc->mod[port].fxs.lasttxhook = 0x6;
1022
			else
1023
				wc->mod[port].fxs.lasttxhook = 0x2;
1024
			if( ! write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook) )
1025
				return -EIO;
1026
		}
1027
		break;
1028
	case DAHDI_SETPOLARITY:
1029
		if (get_user(x, (int *)data))
1030
			return -EFAULT;
1031
		if (wc->porttype[port] != VT_PORT_PROSLIC)
1032
			return -EINVAL;
1033
		/* Can't change polarity while ringing or when open */
1034
		if ((wc->mod[port].fxs.lasttxhook == 0x04) ||
1035
		    (wc->mod[port].fxs.lasttxhook == 0x00))
1036
			return -EINVAL;
1037
1038
		if ((x && !reversepolarity) || (!x && reversepolarity))
1039
			wc->mod[port].fxs.lasttxhook |= 0x04;
1040
		else
1041
			wc->mod[port].fxs.lasttxhook &= ~0x04;
1042
		if( ! write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook) )
1043
			return -EIO;
1044
		break;
1045
	case WCTDM_GET_STATS:
1046
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
1047
			unsigned char	linevolt;
1048
			if( read_reg_fxs(wc, port, 80, &linevolt) )
1049
				stats.tipvolt = linevolt * -376;
1050
			else
1051
				return -EIO;
1052
			if( read_reg_fxs(wc, port, 81, &linevolt) )
1053
				stats.ringvolt = linevolt * -376;
1054
			else
1055
				return -EIO;
1056
			if( read_reg_fxs(wc, port, 82, &linevolt) )
1057
				stats.batvolt = linevolt * -376;
1058
			else
1059
				return -EIO;
1060
		} else if (wc->porttype[port] == VT_PORT_VDAA) {
1061
			unsigned char	linevolt;
1062
			if( read_reg_fxo(wc, port, 29, &linevolt) )
1063
				stats.tipvolt = stats.ringvolt = stats.batvolt = linevolt * 1000;
1064
			else
1065
				return -EIO;
1066
		} else
1067
			return -EINVAL;
1068
		if (copy_to_user((struct wctdm_stats *)data, &stats, sizeof(stats)))
1069
			return -EFAULT;
1070
		break;
1071
	case WCTDM_GET_REGS:
1072
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
1073
			for (x=0;x<NUM_INDIRECT_REGS;x++)
1074
				if( ! read_indreg_fxs(wc, port, x, &regs.indirect[x]) )
1075
					return -EIO;
1076
			for (x=0;x<NUM_REGS;x++)
1077
				if( ! read_reg_fxs(wc, port, x, &regs.direct[x]) )
1078
					return -EIO;
1079
		} else {
1080
			memset(&regs, 0, sizeof(regs));
1081
			for (x=0;x<NUM_FXO_REGS;x++){
1082
				if( ! read_reg_fxo(wc, port, x, &regs.direct[x]) )
1083
					return -EIO;
1084
			}
1085
		}
1086
		if (copy_to_user((struct wctdm_regs *)data, &regs, sizeof(regs)))
1087
			return -EFAULT;
1088
		break;
1089
	case WCTDM_SET_REG:
1090
		if (copy_from_user(&regop, (struct wctdm_regop *)data, sizeof(regop)))
1091
			return -EFAULT;
1092
		if (regop.indirect) {
1093
			if (wc->porttype[port] != VT_PORT_PROSLIC)
1094
				return -EINVAL;
1095
			printk("Setting indirect %d to 0x%04x on %d\n",
1096
				regop.reg, regop.val, chan->chanpos);
1097
			if( ! write_indreg_fxs(wc, port, regop.reg, regop.val) )
1098
				return -EIO;
1099
		} else {
1100
			regop.val &= 0xff;
1101
			printk("Setting direct %d to %04x on %d\n",
1102
				regop.reg, regop.val, chan->chanpos);
1103
			if (wc->porttype[port] == VT_PORT_PROSLIC) {
1104
				if( ! write_reg_fxs(wc, port, regop.reg, regop.val) )
1105
					return -EIO;
1106
			} else {
1107
				if( ! write_reg_fxo(wc, port, regop.reg, regop.val) )
1108
					return -EIO;
1109
			}
1110
		}
1111
		break;
1112
	case WCTDM_SET_ECHOTUNE:
1113
		cardinfo(wc->boardnum, "Setting echo registers");
1114
		if (copy_from_user(&echoregs, (struct wctdm_echo_coefs*)data, sizeof(echoregs)))
1115
			return -EFAULT;
1116
1117
		if (wc->porttype[port] == VT_PORT_VDAA) {
1118
			/* Set the ACIM and digital echo canceller registers */
1119
			if( ! write_reg_fxo(wc, port, 30, echoregs.acim)
1120
			 || ! write_reg_fxo(wc, port, 45, echoregs.coef1)
1121
			 || ! write_reg_fxo(wc, port, 46, echoregs.coef2)
1122
			 || ! write_reg_fxo(wc, port, 47, echoregs.coef3)
1123
			 || ! write_reg_fxo(wc, port, 48, echoregs.coef4)
1124
			 || ! write_reg_fxo(wc, port, 49, echoregs.coef5)
1125
			 || ! write_reg_fxo(wc, port, 50, echoregs.coef6)
1126
			 || ! write_reg_fxo(wc, port, 51, echoregs.coef7)
1127
			 || ! write_reg_fxo(wc, port, 52, echoregs.coef8) )
1128
			{
1129
				cardcrit(wc->boardnum, "Failed to set echo registers");
1130
				return -EIO;
1131
			}
1132
			break;
1133
		} else {
1134
			return -EINVAL;
1135
		}
1136
		break;
1137
	default:
1138
		return -ENOTTY;
1139
	}
1140
	return 0;
1141
} //}}}
1142
1143
static int openpci_open(struct dahdi_chan *chan)
1144
{
1145
	struct openpci *wc = chan->pvt;
1146
	if( ! wc->porttype[chan->chanpos-1] )
1147
		return -ENODEV;
1148
1149
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1150
	//    as the owner of the span that holds the pointer to this function,
1151
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1152
	//    fatal call to an invalid pointer is made.
1153
	//if( wc->dead ) return -ENODEV;
1154
	//wc->usecount++;
1155
	try_module_get(THIS_MODULE);  //XXX
1156
1157
	return 0;
1158
}
1159
1160
static int openpci_watchdog(struct dahdi_span *span, int event)
1161
{
1162
	info("TDM: Restarting DMA");
1163
	restart_dma(span->pvt);
1164
	return 0;
1165
}
1166
1167
static int openpci_close(struct dahdi_chan *chan)
1168
{
1169
	struct openpci *wc = chan->pvt;
1170
	int port = chan->chanpos - 1;
1171
1172
	//XXX wc->usecount--;
1173
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1174
	//    as the owner of the span that holds the pointer to this function,
1175
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1176
	//    fatal call to an invalid pointer is made.
1177
	module_put(THIS_MODULE);
1178
	if (wc->porttype[port] == VT_PORT_PROSLIC) {
1179
		if (reversepolarity)
1180
			wc->mod[port].fxs.idletxhookstate = 5;
1181
		else
1182
			wc->mod[port].fxs.idletxhookstate = 1;
1183
	}
1184
	/* If we're dead, release us now */
1185
	//XXX if (!wc->usecount && wc->dead) openpci_release(wc);
1186
1187
	return 0;
1188
}
1189
1190
static int openpci_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
1191
{ //{{{
1192
	struct openpci *wc = chan->pvt;
1193
	int port = chan->chanpos - 1;
1194
	int new_hk_state;
1195
1196
	dbginfo(wc->boardnum, "Setting %s port %d hook state %s",
1197
		 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1198
		 port,
1199
		 txsig == 0 ? "ONHOOK" :
1200
		 txsig == 1 ? "OFFHOOK" :
1201
		 txsig == 2 ? "START" :
1202
		 txsig == 3 ? "KEWL" : "UNKNOWN" );
1203
1204
	switch(wc->porttype[port]) {
1205
	    case VT_PORT_VDAA:
1206
		switch(txsig) {
1207
		    case DAHDI_TXSIG_START:
1208
		    case DAHDI_TXSIG_OFFHOOK:
1209
			if( write_reg_fxo(wc, port, 5, 0x9)
1210
			 && write_reg_fxo(wc, port, 0x20, 0x0) )
1211
				wc->mod[port].fxo.offhook = 1;
1212
			else
1213
				cardcrit(wc->boardnum, "Failed set fxo off-hook");
1214
			break;
1215
1216
		    case DAHDI_TXSIG_ONHOOK:
1217
			if( write_reg_fxo(wc, port, 5, 0x8)
1218
			 && write_reg_fxo(wc, port, 0x20, 0x3) )
1219
				wc->mod[port].fxo.offhook = 0;
1220
			else
1221
				cardcrit(wc->boardnum, "Failed set fxo on-hook");
1222
			break;
1223
1224
		    default:
1225
			cardcrit(wc->boardnum,
1226
				 "Can't set FXO port %d tx state to %d",
1227
				 port, txsig);
1228
		}
1229
		break;
1230
1231
	    case VT_PORT_PROSLIC:
1232
		new_hk_state = wc->mod[port].fxs.lasttxhook;
1233
		switch(txsig) {
1234
		    case DAHDI_TXSIG_ONHOOK:
1235
			switch(chan->sig) {
1236
			case DAHDI_SIG_EM:
1237
			case DAHDI_SIG_FXOKS:
1238
			case DAHDI_SIG_FXOLS:
1239
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1240
				break;
1241
			case DAHDI_SIG_FXOGS:
1242
				new_hk_state = 3;
1243
				break;
1244
			}
1245
			break;
1246
1247
		    case DAHDI_TXSIG_OFFHOOK:
1248
			switch(chan->sig) {
1249
			case DAHDI_SIG_EM:
1250
				new_hk_state = 5;
1251
				break;
1252
			default:
1253
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1254
				break;
1255
			}
1256
			break;
1257
1258
		    case DAHDI_TXSIG_START:
1259
			new_hk_state = 4;
1260
			break;
1261
1262
		    case DAHDI_TXSIG_KEWL:
1263
			new_hk_state = 0;
1264
			break;
1265
1266
		    default:
1267
			cardinfo(wc->boardnum,
1268
				 "Can't set FXS port %d tx state to %d",
1269
				 port, txsig);
1270
		}
1271
		dbginfo(wc->boardnum, "%s port %d hook state old %d, new %d",
1272
			 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1273
			 port, wc->mod[port].fxs.lasttxhook, new_hk_state );
1274
1275
		if (new_hk_state != wc->mod[port].fxs.lasttxhook){
1276
			if( write_reg_fxs(wc, port, 64, new_hk_state) )
1277
				wc->mod[port].fxs.lasttxhook = new_hk_state;
1278
			else
1279
				cardcrit(wc->boardnum,
1280
					 "Failed to set port %d fxs hookstate from %d to %d",
1281
					 port, wc->mod[port].fxs.lasttxhook, new_hk_state);
1282
		}
1283
		break;
1284
1285
	    default:
1286
		cardcrit(wc->boardnum,
1287
			 "Unknown module type %d in openpci_hooksig",
1288
			 wc->porttype[port] );
1289
	}
1290
	return 0;
1291
} //}}}
1292
1293
static int span_initialize(struct openpci *wc)
1294
{ //{{{
1295
	int x;
1296
1297
	//XXX Set a THIS_MODULE as the owner of the span...
1298
	/* Zapata stuff */
1299
	sprintf(wc->span.name, "WCTDM/%d", wc->boardnum);
1300
	sprintf(wc->span.desc, "%s Board %d", wc->variety, wc->boardnum + 1);
1301
	for (x = 0; x < MAX_PORTS; x++) {
1302
		struct dahdi_chan *chan = &wc->_chans[x];
1303
		wc->chans[x] = chan;
1304
		sprintf(chan->name, "WCTDM/%d/%d", wc->boardnum, x);
1305
		chan->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS
1306
				    | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
1307
		chan->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
1308
		chan->chanpos = x+1;
1309
		chan->pvt = wc;
1310
	}
1311
	wc->span.deflaw = DAHDI_LAW_MULAW;
1312
	wc->span.chans = wc->chans;
1313
	wc->span.channels = MAX_PORTS;
1314
	wc->span.hooksig = openpci_hooksig;
1315
	wc->span.open = openpci_open;
1316
	wc->span.close = openpci_close;
1317
	wc->span.flags = DAHDI_FLAG_RBS;
1318
	wc->span.ioctl = openpci_ioctl;
1319
	wc->span.watchdog = openpci_watchdog;
1320
	init_waitqueue_head(&wc->span.maintq);
1321
1322
	wc->span.pvt = wc;
1323
	if (dahdi_register(&wc->span, 0)) {
1324
		cardcrit(wc->boardnum, "Unable to register span with dahdi");
1325
		return RET_FAIL;
1326
	}
1327
	return RET_OK;
1328
} //}}}
1329
1330
static int get_port_type(struct openpci *wc, int port)
1331
{ //{{{
1332
	int i, type;
1333
	unsigned long flags;
1334
1335
	spin_lock_irqsave(&wc->lock, flags);
1336
	outb(0x20, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1337
	outb(port, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1338
	HRXF_WAIT_LOCKED_RET(VT_PORT_EMPTY); type = inb(PIB(1));
1339
	spin_unlock_irqrestore(&wc->lock, flags);
1340
1341
	return type;
1342
} //}}}
1343
1344
static int check_ports(struct openpci *wc)
1345
{ //{{{
1346
	int i = 0;
1347
1348
	wc->portcount = 0;
1349
	for(; i < MAX_PORTS; ++i ){
1350
		wc->porttype[i] = get_port_type(wc, i);
1351
		dbginfo(wc->boardnum,"%d: %s", i, porttype(wc,i));
1352
1353
		switch( wc->porttype[i] ) {
1354
		    case VT_PORT_PROSLIC:
1355
			/* By default, don't send on hook */
1356
			if (reversepolarity)
1357
				wc->mod[i].fxs.idletxhookstate = 5;
1358
			else
1359
				wc->mod[i].fxs.idletxhookstate = 1;
1360
1361
		    case VT_PORT_VDAA:
1362
			++wc->portcount;
1363
		}
1364
	}
1365
	// we 'succeed' if any ports were discovered.
1366
	return wc->portcount ? RET_OK : RET_FAIL;
1367
} //}}}
1368
1369
static int configure_vdaa_country(struct openpci *wc, int port, char *name)
1370
{ //{{{
1371
	unsigned char value;
1372
	int i;
1373
1374
	for (i=0; i < sizeof(fxo_modes)/sizeof(struct fxo_mode); ++i){
1375
		if(!strcmp(fxo_modes[i].name, name)){
1376
			dbginfo(wc->boardnum, "%d: Setting country to %s", port, name);
1377
			goto part2;
1378
		}
1379
	}
1380
	i = 3;
1381
	cardinfo(wc->boardnum, "Using default country %s", fxo_modes[i].name);
1382
1383
    part2:
1384
	value  = (fxo_modes[i].ohs << 6);
1385
	value |= (fxo_modes[i].rz << 1);
1386
	value |= (fxo_modes[i].rt << 0);
1387
	if( ! write_reg_fxo(wc, port, 16, value) ) goto hell;
1388
1389
	/* DC Termination Control - Register 26 */
1390
	value  = (fxo_modes[i].dcv << 6);
1391
	value |= (fxo_modes[i].mini << 4);
1392
	value |= (fxo_modes[i].ilim << 1);
1393
	if( ! write_reg_fxo(wc, port, 26, value) ) goto hell;
1394
1395
	/* AC Termination Control - Register 30 */
1396
	value = (fxo_modes[i].acim << 0);
1397
	if( ! write_reg_fxo(wc, port, 30, value) ) goto hell;
1398
1399
	/* DAA Control 5 - Register 31 */
1400
	msleep(1);
1401
	if( ! read_reg_fxo(wc, port, 31, &value) ) goto hell;
1402
1403
	value = (value & 0xf7) | (fxo_modes[i].ohs2 << 3);
1404
	value = value | 0x02;
1405
	if( ! write_reg_fxo(wc, port, 31, value) ) goto hell;
1406
1407
	return RET_OK;
1408
1409
    hell:
1410
	cardcrit(wc->boardnum, "port %d failed configure vdaa country", port);
1411
	return RET_FAIL;
1412
} //}}}
1413
1414
// Do not call this from an interrupt context, it may sleep.
1415
static void configure_vdaa_port(struct openpci *wc, int port)
1416
{ //{{{
1417
	/* Set Country - default to Australia */
1418
	if( configure_vdaa_country(wc, port, country) )
1419
		++wc->portcount;
1420
	else {
1421
		cardcrit(wc->boardnum, "FAILED to configure vdaa port %d.  Disabled.", port);
1422
		wc->porttype[port] = VT_PORT_EMPTY;
1423
	}
1424
} //}}}
1425
1426
static int configure_proslic_country(struct openpci *wc, int port, const char *name)
1427
{ //{{{
1428
	int i;
1429
1430
	for(i=0; i < sizeof(ps_country_regs)/sizeof(struct ps_country_reg); ++i) {
1431
		if(!strcmp(ps_country_regs[i].country, name)){
1432
			dbginfo(wc->boardnum, "%d: Setting country to %s", port, name);
1433
			goto part2;
1434
		}
1435
	}
1436
	return -EINVAL;
1437
1438
    part2:
1439
1440
	if( ! write_reg_fxs(wc, port, 10, ps_country_regs[i].value) ){
1441
		cardcrit(wc->boardnum,"%d: failed to write PS_IMPEDANCE", port);
1442
		return -EIO;
1443
	}
1444
	return 0;
1445
} //}}}
1446
1447
// Do not call this from an interrupt context, it may sleep.
1448
static void configure_proslic_port(struct openpci *wc, int port)
1449
{ //{{{
1450
	/* Set Country - default to Australia */
1451
	switch( configure_proslic_country(wc, port, country) ){
1452
	    case 0:
1453
		break;
1454
1455
	    case -EINVAL:
1456
		cardwarn(wc->boardnum,"%d: Country '%s' unknown, using default", port, country);
1457
		if( configure_proslic_country(wc, port, DEFAULT_COUNTRY) == 0 )
1458
			goto hell;
1459
1460
	    default:
1461
		goto hell;
1462
	}
1463
1464
	++wc->portcount;
1465
	return;
1466
1467
    hell:
1468
	cardcrit(wc->boardnum, "FAILED to configure proslic port %d.  Disabled.", port);
1469
	wc->porttype[port] = VT_PORT_EMPTY;
1470
} //}}}
1471
1472
// Do not call this from an interrupt context, it may (indirectly) sleep.
1473
static int configure_ports(struct openpci *wc)
1474
{ //{{{
1475
	unsigned long flags;
1476
	int i;
1477
1478
	wc->portcount = 0;
1479
	for(i=0; i < MAX_PORTS; ++i){
1480
		switch (wc->porttype[i]){
1481
		    case VT_PORT_VDAA:    configure_vdaa_port(wc,i);    break;
1482
		    case VT_PORT_PROSLIC: configure_proslic_port(wc,i); break;
1483
		}
1484
	}
1485
1486
	spin_lock_irqsave(&wc->lock, flags);
1487
	outb(0x2c, PIB(1)); HTXF_WAIT_LOCKED();
1488
	outb(0xff, PIB(1)); HTXF_WAIT_LOCKED();
1489
	spin_unlock_irqrestore(&wc->lock, flags);
1490
1491
	// otherwise we 'succeed' if any ports were configured successfully.
1492
	return wc->portcount ? RET_OK : RET_FAIL;
1493
} //}}}
1494
1495
static int __get_arm_id(struct openpci *wc, int field, char *value)
1496
{ //{{{
1497
	int i;
1498
	int x=0;
1499
	int count=0;
1500
1501
	outb(0x01, PIB(1));  HTXF_WAIT();
1502
	outb(field, PIB(1)); HTXF_WAIT();
1503
	HRXF_WAIT(); count = inb(PIB(1));
1504
	if (count > ID_DATA_MAXSIZE){
1505
		cardcrit(wc->boardnum, "Too many bytes of id(%d) data %d/%d",
1506
					 field, count, ID_DATA_MAXSIZE);
1507
		return RET_FAIL;
1508
	}
1509
	//cardinfo(wc->boardnum, "get_arm_id(%d): byte count %d",field,count);
1510
	for(; x < count; ++x){
1511
		HRXF_WAIT(); *value = inb(PIB(1));
1512
		//cardinfo(wc->boardnum, "get_arm_id(%d): byte %d => 0x%02x",field,x,tmp);
1513
		++value;
1514
	}
1515
	return RET_OK;
1516
} //}}}
1517
1518
static void enable_interrupts(struct openpci *wc)
1519
{ //{{{
1520
	outb(0x3f, TJ_MASK0);
1521
	outb(0x02, TJ_MASK1);
1522
} //}}}
1523
1524
static void disable_interrupts(struct openpci *wc)
1525
{ //{{{
1526
	outb(0x00, TJ_MASK0);
1527
	outb(0x00, TJ_MASK1);
1528
} //}}}
1529
1530
// Do not call this from an interrupt context, it may sleep.
1531
static int check_arm(struct openpci *wc)
1532
{ //{{{
1533
	char model[ID_DATA_MAXSIZE+1] = { 0 };
1534
	char date[ID_DATA_MAXSIZE+1]  = { 0 };
1535
	unsigned long flags;
1536
	int i=0;
1537
	int tmp=0;
1538
1539
	spin_lock_irqsave(&wc->lock, flags);
1540
	while ((tmp != 0x88)&&(++i<100)){
1541
		outb(0x88, PIB(0));
1542
		msleep(1);
1543
		tmp = inb(PIB(1));
1544
	}
1545
	if (i>=1000) goto limbo;
1546
	dbginfo(wc->boardnum, "Arm responded on attempt %d",i);
1547
1548
	// Flush out the queue if we sent several pings before a response.
1549
	if(i>1)	__ping_arm(wc);
1550
1551
	if( ! __get_arm_id(wc, 0, model) )  goto hell;
1552
	sscanf(model, "OpenPCI8.%02d", &(wc->firmware));
1553
	cardinfo(wc->boardnum, "  model: %s", model);
1554
1555
	if( ! __get_arm_id(wc, 1, date) )   goto hell;
1556
	cardinfo(wc->boardnum, "  date: %s", date);
1557
1558
	if( ! __get_arm_id(wc, 2, wc->serial) ) goto hell;
1559
	cardinfo(wc->boardnum, "  serial: %s", wc->serial);
1560
1561
	spin_unlock_irqrestore(&wc->lock, flags);
1562
	return RET_OK;
1563
1564
    hell:
1565
	spin_unlock_irqrestore(&wc->lock, flags);
1566
        cardwarn(wc->boardnum, "Found ARM processor, dumb firmware.");
1567
	return RET_OK;
1568
1569
    limbo:
1570
	spin_unlock_irqrestore(&wc->lock, flags);
1571
	return RET_FAIL;
1572
} //}}}
1573
1574
static int arm_monitor(struct openpci *wc, int on)
1575
{ //{{{
1576
	int i;
1577
	outb( on ? 0x06 : 0x07, PIB(1) ); HTXF_WAIT();
1578
	return RET_OK;
1579
} //}}}
1580
1581
static int __devinit openpci_probe_board(struct pci_dev *pdev, const struct pci_device_id *ent)
1582
{ //{{{
1583
	struct openpci *wc;
1584
	int boardnum = 0;
1585
	int failret = -ENOMEM;
1586
	int tmp = 0;
1587
	int i;
1588
	unsigned long flags;
1589
1590
	if( ent->driver_data != (kernel_ulong_t)&wcopenpci )
1591
	{
1592
	    info("Probe of non-OpenPCI card, ignoring.");
1593
	    return -EINVAL;
1594
	}
1595
	wc = kzalloc(sizeof(struct openpci), GFP_KERNEL);
1596
	if (!wc){
1597
		return -ENOMEM;
1598
	}
1599
1600
	mutex_lock(&cards_mutex);
1601
	for (; boardnum < MAX_CARDS && cards[boardnum]; ++boardnum);
1602
	if (boardnum >= MAX_CARDS){
1603
		crit("Too many OpenPCI cards(%d), max is %d.", boardnum, MAX_CARDS);
1604
		mutex_unlock(&cards_mutex);
1605
		goto hell;
1606
	}
1607
	cards[boardnum] = wc;
1608
	mutex_unlock(&cards_mutex);
1609
1610
	spin_lock_init(&wc->lock);
1611
	pci_set_drvdata(pdev, wc);
1612
1613
	wc->boardnum = boardnum;
1614
	wc->dev      = pdev;
1615
	wc->variety  = wcopenpci;
1616
1617
	cardinfo(boardnum, "Initialising card");
1618
	if (pci_enable_device(pdev)) {
1619
		failret = -EIO;
1620
		goto hell_2;
1621
	}
1622
	wc->ioaddr = pci_resource_start(pdev, 0);
1623
	if( ! request_region(wc->ioaddr, 0xff, NAME) ){
1624
                cardcrit(boardnum, "Failed to lock IO region, another driver already using it");
1625
		failret = -EBUSY;
1626
		goto hell_2;
1627
	}
1628
1629
	spin_lock_irqsave(&wc->lock, flags);
1630
	outb(0xff, TJ_AUXD);            /* Set up TJ to access the ARM */
1631
	outb(0x78, TJ_AUXC);            /* Set up for Jtag */
1632
	outb(0x00, TJ_CNTL);            /* pull ERST low */
1633
	spin_unlock_irqrestore(&wc->lock, flags);
1634
	msleep(1);	                /* Wait a bit */
1635
1636
	dbginfo(boardnum,"Starting ARM");
1637
	spin_lock_irqsave(&wc->lock, flags);
1638
	outb(0x01, TJ_CNTL);            /* pull ERST high again */
1639
	spin_unlock_irqrestore(&wc->lock, flags);
1640
	msleep(100);                    /* Give it all a chance to boot */
1641
1642
	if( ! check_arm(wc) ){
1643
		cardcrit(boardnum, "Couldnt find ARM processor");
1644
		failret = -EIO;
1645
		goto hell_3;
1646
	}
1647
	if( wc->firmware < 11 ){
1648
		cardcrit(boardnum,
1649
			 "Firmware version %d not supported by this driver",
1650
			 wc->firmware);
1651
		cardcrit(boardnum, " contact Voicetronix to have it updated");
1652
		failret = -ENODEV;
1653
		goto hell_3;
1654
	}
1655
	if( ! check_ports(wc) ){
1656
		cardcrit(boardnum, "Couldnt find ports!");
1657
		failret = -EIO;
1658
		goto hell_3;
1659
	}
1660
1661
	wc->writechunk = pci_alloc_consistent(pdev, VT_PCIDMA_BLOCKSIZE, &wc->writedma);
1662
	if (!wc->writechunk) {
1663
		cardcrit(boardnum, "Couldnt get DMA memory.");
1664
		goto hell_3;
1665
	}
1666
	wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE * (MAX_PORTS*2 / sizeof(int));
1667
	wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_PORTS*2);
1668
1669
	memset((void*)wc->writechunk,0,VT_PCIDMA_BLOCKSIZE);
1670
1671
	spin_lock_irqsave(&wc->lock, flags);
1672
	outb(0xc1, TJ_SERCTL);
1673
	outb(0x0, TJ_FSCDELAY);
1674
1675
	outl(wc->writedma,                    TJ_DMAWS);
1676
	outl(wc->writedma + VT_PCIDMA_MIDDLE, TJ_DMAWI);
1677
	outl(wc->writedma + VT_PCIDMA_END,    TJ_DMAWE);
1678
	outl(wc->readdma,                     TJ_DMARS);
1679
	outl(wc->readdma + VT_PCIDMA_MIDDLE,  TJ_DMARI);
1680
	outl(wc->readdma + VT_PCIDMA_END,     TJ_DMARE);
1681
1682
	/* Clear interrupts */
1683
	outb(0xff, TJ_INTSTAT);
1684
	spin_unlock_irqrestore(&wc->lock, flags);
1685
1686
	if( ! arm_monitor(wc, 1) ){
1687
		cardcrit(boardnum, "failed to start arm monitoring");
1688
		failret = -EIO;
1689
		goto hell_4;
1690
	}
1691
	msleep(1000);
1692
1693
	i = 0;
1694
	while(tmp != 0x88 && ++i < 1000) {
1695
		outb(0x88, PIB(0));
1696
		msleep(250);
1697
		tmp = inb(PIB(1));
1698
	}
1699
	if(i>=1000) {
1700
		cardcrit(boardnum, "FAILED to initialise board");
1701
		goto hell_4;
1702
	}
1703
1704
	if( ! check_ports(wc) ) {
1705
		cardcrit(boardnum, "FAILED to initialise ports");
1706
		failret = -EIO;
1707
		goto hell_4;
1708
	}
1709
	if( ! configure_ports(wc) ){
1710
		cardcrit(boardnum, "Failed to configure ports.");
1711
		failret = -EIO;
1712
		goto hell_4;
1713
	}
1714
	cardinfo(wc->boardnum, "have %d configured ports", wc->portcount);
1715
1716
	if( ! span_initialize(wc) ) {
1717
		cardcrit(boardnum, "Failed to register with dahdi driver");
1718
		failret = -EFAULT;
1719
		goto hell_4;
1720
	}
1721
1722
	/* Finalize signalling  */
1723
	for (i=0; i < MAX_PORTS; ++i) {
1724
		if (wc->porttype[i] == VT_PORT_VDAA)
1725
		    wc->chans[i]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS
1726
					| DAHDI_SIG_CLEAR | DAHDI_SIG_SF;
1727
		else if (wc->porttype[i] == VT_PORT_PROSLIC)
1728
		    wc->chans[i]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS
1729
					| DAHDI_SIG_FXOGS | DAHDI_SIG_SF
1730
					| DAHDI_SIG_CLEAR | DAHDI_SIG_EM;
1731
		else if (wc->porttype[i])
1732
		    cardcrit(wc->boardnum, "Port %d has unknown type (%d)",
1733
					   i, wc->porttype[i]);
1734
	}
1735
1736
	/* Enable bus mastering */
1737
	pci_set_master(pdev);
1738
1739
	if (request_irq(pdev->irq, openpci_isr, DAHDI_IRQ_SHARED, NAME, wc)) {
1740
		cardcrit(boardnum, "Cant get IRQ!");
1741
		failret = -EIO;
1742
		goto hell_5;
1743
	}
1744
	cardinfo(boardnum, "Got IRQ %d", pdev->irq);
1745
1746
	enable_interrupts(wc);
1747
	start_dma(wc);
1748
1749
	cardinfo(boardnum,"Initialised card.");
1750
	return 0;
1751
1752
    hell_5:
1753
	dahdi_unregister(&wc->span);
1754
    hell_4:
1755
	if (wc->writechunk){
1756
		pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1757
				    (void*)wc->writechunk, wc->writedma);
1758
	}
1759
    hell_3:
1760
	outb(0x00, TJ_CNTL);
1761
	release_region(wc->ioaddr, 0xff);
1762
    hell_2:
1763
	cards[boardnum] = NULL;
1764
    hell:
1765
	kfree(wc);
1766
	return failret;
1767
} //}}}
1768
1769
static void __devexit openpci_remove_board(struct pci_dev *pdev)
1770
{ //{{{
1771
	struct openpci *wc = pci_get_drvdata(pdev);
1772
1773
	if(!wc) return;
1774
1775
	arm_monitor(wc,0);
1776
1777
	/* Stop DMA */
1778
	outb(0x00, TJ_OPER);
1779
	disable_interrupts(wc);
1780
1781
	//XXX Replace this usecount business...
1782
	//    and do this BEFORE we invalidate everything above...
1783
	//    check that we wont try to write to it in the meantime.
1784
	/* Release span, possibly delayed */
1785
	//XXX if (!wc->usecount) openpci_release(wc); else wc->dead = 1;
1786
1787
	dahdi_unregister(&wc->span);
1788
	outb(0x00, TJ_CNTL);
1789
1790
	pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE, (void *)wc->writechunk, wc->writedma);
1791
	free_irq(pdev->irq, wc);
1792
1793
	release_region(wc->ioaddr, 0xff);
1794
1795
	mutex_lock(&cards_mutex);
1796
	cards[wc->boardnum] = NULL;
1797
	mutex_unlock(&cards_mutex);
1798
1799
	kfree(wc);
1800
	cardinfo(wc->boardnum, "Removed OpenPCI card.");
1801
} //}}}
1802
1803
static struct pci_device_id openpci_pci_tbl[] = {
1804
	{ 0xe159, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t) &wcopenpci },
1805
	{ 0 }
1806
};
1807
1808
MODULE_DEVICE_TABLE(pci, openpci_pci_tbl);
1809
1810
static struct pci_driver openpci_driver = {
1811
	name: 	  NAME,
1812
	probe: 	  openpci_probe_board,
1813
	remove:	  __devexit_p(openpci_remove_board),
1814
	suspend:  NULL,
1815
	resume:	  NULL,
1816
	id_table: openpci_pci_tbl,
1817
};
1818
1819
static int __init openpci_init(void)
1820
{
1821
	if( dahdi_pci_module(&openpci_driver) )
1822
		return -ENODEV;
1823
1824
	info("Module loaded %s", debug ? "with debug enabled" : "");
1825
	return 0;
1826
}
1827
1828
static void __exit openpci_cleanup(void)
1829
{
1830
	pci_unregister_driver(&openpci_driver);
1831
	info("Module exit");
1832
}
1833
1834
module_init(openpci_init);
1835
module_exit(openpci_cleanup);
1836
1837
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
1838
MODULE_AUTHOR(DRIVER_AUTHOR);
1839
MODULE_VERSION(DAHDI_VERSION);
1840
MODULE_LICENSE("GPL");
1841
(-)dahdi-linux-2.2.0.2/drivers/dahdi/zaphfc/base.c (+1705 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/proc_fs.h>
36
#include <linux/if_arp.h>
37
38
#include <dahdi/kernel.h>
39
40
#include "zaphfc.h"
41
#include "fifo.h"
42
43
#if CONFIG_PCI
44
45
#define DAHDI_B1 0
46
#define DAHDI_B2 1
47
#define DAHDI_D 2
48
49
#define D 0
50
#define B1 1
51
#define B2 2
52
53
/*
54
 * Mode Te for all
55
 */
56
static int modes;
57
static int nt_modes[hfc_MAX_BOARDS];
58
static int nt_modes_count;
59
static int force_l1_up;
60
static struct proc_dir_entry *hfc_proc_zaphfc_dir;
61
62
#ifdef DEBUG
63
int debug_level;
64
#endif
65
66
#ifndef FALSE
67
#define FALSE 0
68
#endif
69
#ifndef TRUE
70
#define TRUE (!FALSE)
71
#endif
72
73
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
74
#define	SET_PROC_DIRENTRY_OWNER(p)	do { (p)->owner = THIS_MODULE; } while(0);
75
#else
76
#define	SET_PROC_DIRENTRY_OWNER(p)	do { } while(0);
77
#endif
78
79
static struct pci_device_id hfc_pci_ids[] = {
80
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0,
81
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
82
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000,
83
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
84
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006,
85
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
86
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007,
87
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
88
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008,
89
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
90
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009,
91
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
92
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A,
93
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
94
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B,
95
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
96
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C,
97
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
98
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100,
99
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
100
	{PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1,
101
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
102
	{PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675,
103
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
104
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT,
105
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
106
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T,
107
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
108
	{PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575,
109
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
110
	{PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0,
111
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
112
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,
113
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
114
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,
115
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
116
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,
117
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
118
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,
119
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
120
	{PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_3069,
121
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
122
	{0,}
123
};
124
125
MODULE_DEVICE_TABLE(pci, hfc_pci_ids);
126
127
static int __devinit hfc_probe(struct pci_dev *dev
128
			, const struct pci_device_id *ent);
129
static void __devexit hfc_remove(struct pci_dev *dev);
130
131
static struct pci_driver hfc_driver = {
132
	.name     = hfc_DRIVER_NAME,
133
	.id_table = hfc_pci_ids,
134
	.probe    = hfc_probe,
135
	.remove   = hfc_remove,
136
};
137
138
/******************************************
139
 * HW routines
140
 ******************************************/
141
142
static void hfc_softreset(struct hfc_card *card)
143
{
144
	printk(KERN_INFO hfc_DRIVER_PREFIX
145
		"card %d: "
146
		"resetting\n",
147
		card->cardnum);
148
149
/*
150
 * Softreset procedure. Put it on, wait and off again
151
 */
152
	hfc_outb(card, hfc_CIRM, hfc_CIRM_RESET);
153
	udelay(6);
154
	hfc_outb(card, hfc_CIRM, 0);
155
156
	set_current_state(TASK_UNINTERRUPTIBLE);
157
	schedule_timeout((hfc_RESET_DELAY * HZ) / 1000);
158
}
159
160
static void hfc_resetCard(struct hfc_card *card)
161
{
162
	card->regs.m1 = 0;
163
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
164
165
	card->regs.m2 = 0;
166
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
167
168
	hfc_softreset(card);
169
170
	card->regs.trm = 0;
171
	hfc_outb(card, hfc_TRM, card->regs.trm);
172
173
	/*
174
	 * Select the non-capacitive line mode for the S/T interface
175
	 */
176
	card->regs.sctrl = hfc_SCTRL_NONE_CAP;
177
178
	if (card->nt_mode) {
179
		/*
180
		 * ST-Bit delay for NT-Mode
181
		 */
182
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_NT);
183
184
		card->regs.sctrl |= hfc_SCTRL_MODE_NT;
185
	} else {
186
		/*
187
		 * ST-Bit delay for TE-Mode
188
		 */
189
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_TE);
190
191
		card->regs.sctrl |= hfc_SCTRL_MODE_TE;
192
	}
193
194
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
195
196
	/*
197
	 * S/T Auto awake
198
	 */
199
	card->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
200
	hfc_outb(card, hfc_SCTRL_E, card->regs.sctrl_e);
201
202
	/*
203
	 * No B-channel enabled at startup
204
	 */
205
	card->regs.sctrl_r = 0;
206
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
207
208
	/*
209
	 * HFC Master Mode
210
	 */
211
	hfc_outb(card, hfc_MST_MODE, hfc_MST_MODE_MASTER);
212
213
	/*
214
	 * Connect internal blocks
215
	 */
216
	card->regs.connect =
217
		hfc_CONNECT_B1_HFC_from_ST |
218
		hfc_CONNECT_B1_ST_from_HFC |
219
		hfc_CONNECT_B1_GCI_from_HFC |
220
		hfc_CONNECT_B2_HFC_from_ST |
221
		hfc_CONNECT_B2_ST_from_HFC |
222
		hfc_CONNECT_B2_GCI_from_HFC;
223
	hfc_outb(card, hfc_CONNECT, card->regs.connect);
224
225
	/*
226
	 * All bchans are HDLC by default, not useful, actually
227
	 * since mode is set during open()
228
	 */
229
	hfc_outb(card, hfc_CTMT, 0);
230
231
	/*
232
	 * bit order
233
	 */
234
	hfc_outb(card, hfc_CIRM, 0);
235
236
	/*
237
	 * Enable D-rx FIFO. At least one FIFO must be enabled (by specs)
238
	 */
239
	card->regs.fifo_en = hfc_FIFOEN_DRX;
240
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
241
242
	card->late_irqs = 0;
243
244
	/*
245
	 * Clear already pending ints
246
	 */
247
	hfc_inb(card, hfc_INT_S1);
248
	hfc_inb(card, hfc_INT_S2);
249
250
	/*
251
	 * Enable IRQ output
252
	 */
253
	card->regs.m1 = hfc_INTS_DREC | hfc_INTS_L1STATE | hfc_INTS_TIMER;
254
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
255
256
	card->regs.m2 = hfc_M2_IRQ_ENABLE;
257
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
258
259
	/*
260
	 * Unlocks the states machine
261
	 */
262
	hfc_outb(card, hfc_STATES, 0);
263
264
	/*
265
	 * There's no need to explicitly activate L1 now.
266
	 * Activation is managed inside the interrupt routine.
267
	 */
268
}
269
270
static void hfc_update_fifo_state(struct hfc_card *card)
271
{
272
	/*
273
	 * I'm not sure if irqsave is needed but there could be a race
274
	 * condition since hfc_update_fifo_state could be called from
275
	 * both the IRQ handler and the *_(open|close) functions
276
	 */
277
278
	unsigned long flags;
279
	spin_lock_irqsave(&card->chans[B1].lock, flags);
280
	if (!card->fifo_suspended &&
281
		(card->chans[B1].status == open_framed ||
282
		card->chans[B1].status == open_voice)) {
283
284
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1RX)) {
285
			card->regs.fifo_en |= hfc_FIFOEN_B1RX;
286
			hfc_clear_fifo_rx(&card->chans[B1].rx);
287
		}
288
289
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1TX)) {
290
			card->regs.fifo_en |= hfc_FIFOEN_B1TX;
291
			hfc_clear_fifo_tx(&card->chans[B1].tx);
292
		}
293
	} else {
294
		if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
295
			card->regs.fifo_en &= ~hfc_FIFOEN_B1RX;
296
		if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
297
			card->regs.fifo_en &= ~hfc_FIFOEN_B1TX;
298
	}
299
	spin_unlock_irqrestore(&card->chans[B1].lock, flags);
300
301
	spin_lock_irqsave(&card->chans[B2].lock, flags);
302
	if (!card->fifo_suspended &&
303
		(card->chans[B2].status == open_framed ||
304
		card->chans[B2].status == open_voice ||
305
		card->chans[B2].status == sniff_aux)) {
306
307
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2RX)) {
308
			card->regs.fifo_en |= hfc_FIFOEN_B2RX;
309
			hfc_clear_fifo_rx(&card->chans[B2].rx);
310
		}
311
312
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2TX)) {
313
			card->regs.fifo_en |= hfc_FIFOEN_B2TX;
314
			hfc_clear_fifo_tx(&card->chans[B2].tx);
315
		}
316
	} else {
317
		if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
318
			card->regs.fifo_en &= ~hfc_FIFOEN_B2RX;
319
		if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
320
			card->regs.fifo_en &= ~hfc_FIFOEN_B2TX;
321
	}
322
	spin_unlock_irqrestore(&card->chans[B2].lock, flags);
323
324
	spin_lock_irqsave(&card->chans[D].lock, flags);
325
	if (!card->fifo_suspended &&
326
		card->chans[D].status == open_framed) {
327
328
		if (!(card->regs.fifo_en & hfc_FIFOEN_DTX)) {
329
			card->regs.fifo_en |= hfc_FIFOEN_DTX;
330
331
			card->chans[D].tx.ugly_framebuf_size = 0;
332
			card->chans[D].tx.ugly_framebuf_off = 0;
333
		}
334
	} else {
335
		if (card->regs.fifo_en & hfc_FIFOEN_DTX)
336
			card->regs.fifo_en &= ~hfc_FIFOEN_DTX;
337
	}
338
	spin_unlock_irqrestore(&card->chans[D].lock, flags);
339
340
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
341
}
342
343
static inline void hfc_suspend_fifo(struct hfc_card *card)
344
{
345
	card->fifo_suspended = TRUE;
346
347
	hfc_update_fifo_state(card);
348
349
	/*
350
	 * When L1 goes down D rx receives garbage; it is nice to
351
	 * clear it to avoid a CRC error on reactivation
352
	 * udelay is needed because the FIFO deactivation happens
353
	 * in 250us
354
	 */
355
	udelay(250);
356
	hfc_clear_fifo_rx(&card->chans[D].rx);
357
358
#ifdef DEBUG
359
	if (debug_level >= 3) {
360
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
361
			"card %d: "
362
			"FIFOs suspended\n",
363
			card->cardnum);
364
	}
365
#endif
366
}
367
368
static inline void hfc_resume_fifo(struct hfc_card *card)
369
{
370
	card->fifo_suspended = FALSE;
371
372
	hfc_update_fifo_state(card);
373
374
#ifdef DEBUG
375
	if (debug_level >= 3) {
376
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
377
			"card %d: "
378
			"FIFOs resumed\n",
379
			card->cardnum);
380
	}
381
#endif
382
}
383
384
static void hfc_check_l1_up(struct hfc_card *card)
385
{
386
	if ((!card->nt_mode && card->l1_state != 7)
387
		|| (card->nt_mode && card->l1_state != 3)) {
388
389
		hfc_outb(card, hfc_STATES, hfc_STATES_DO_ACTION |
390
			hfc_STATES_ACTIVATE|
391
				hfc_STATES_NT_G2_G3);
392
393
	/*
394
	 * 0 because this is quite verbose when an inferface is unconnected, jaw
395
	 */
396
#if 0
397
		if (debug_level >= 1) {
398
			printk(KERN_DEBUG hfc_DRIVER_PREFIX
399
				"card %d: "
400
				"L1 is down, bringing up L1.\n",
401
				card->cardnum);
402
		}
403
#endif
404
	}
405
}
406
407
408
/*******************
409
 * Dahdi interface *
410
 *******************/
411
412
static int hfc_zap_open(struct dahdi_chan *zaptel_chan)
413
{
414
	struct hfc_chan_duplex *chan = zaptel_chan->pvt;
415
	struct hfc_card *card = chan->card;
416
417
	spin_lock(&chan->lock);
418
419
	switch (chan->number) {
420
	case D:
421
		if (chan->status != free &&
422
			chan->status != open_framed) {
423
			spin_unlock(&chan->lock);
424
			return -EBUSY;
425
		}
426
		chan->status = open_framed;
427
	break;
428
429
	case B1:
430
	case B2:
431
		if (chan->status != free) {
432
			spin_unlock(&chan->lock);
433
			return -EBUSY;
434
		}
435
		chan->status = open_voice;
436
	break;
437
	}
438
439
	chan->open_by_zaptel = TRUE;
440
	try_module_get(THIS_MODULE);
441
	spin_unlock(&chan->lock);
442
443
	switch (chan->number) {
444
	case D:
445
	break;
446
447
	case B1:
448
		card->regs.m2 |= hfc_M2_PROC_TRANS;
449
		/*
450
		 * Enable transparent mode
451
		 */
452
		card->regs.ctmt |= hfc_CTMT_TRANSB1;
453
		/*
454
		* Reversed bit order
455
		*/
456
		card->regs.cirm |= hfc_CIRM_B1_REV;
457
		/*
458
		 * Enable transmission
459
		 */
460
		card->regs.sctrl |= hfc_SCTRL_B1_ENA;
461
		/*
462
		 * Enable reception
463
		 */
464
		card->regs.sctrl_r |= hfc_SCTRL_R_B1_ENA;
465
	break;
466
467
	case B2:
468
		card->regs.m2 |= hfc_M2_PROC_TRANS;
469
		card->regs.ctmt |= hfc_CTMT_TRANSB2;
470
		card->regs.cirm |= hfc_CIRM_B2_REV;
471
		card->regs.sctrl |= hfc_SCTRL_B2_ENA;
472
		card->regs.sctrl_r |= hfc_SCTRL_R_B2_ENA;
473
	break;
474
475
	}
476
477
	/*
478
	 * If not already enabled, enable processing transition (8KHz)
479
	 * interrupt
480
	 */
481
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
482
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
483
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
484
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
485
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
486
487
	hfc_update_fifo_state(card);
488
489
	printk(KERN_INFO hfc_DRIVER_PREFIX
490
		"card %d: "
491
		"chan %s opened as %s.\n",
492
		card->cardnum,
493
		chan->name,
494
		zaptel_chan->name);
495
496
	return 0;
497
}
498
499
static int hfc_zap_close(struct dahdi_chan *zaptel_chan)
500
{
501
	struct hfc_chan_duplex *chan = zaptel_chan->pvt;
502
	struct hfc_card *card = chan->card;
503
504
	if (!card) {
505
		printk(KERN_CRIT hfc_DRIVER_PREFIX
506
			"hfc_zap_close called with NULL card\n");
507
		return -1;
508
	}
509
510
	spin_lock(&chan->lock);
511
512
	if (chan->status == free) {
513
		spin_unlock(&chan->lock);
514
		return -EINVAL;
515
	}
516
517
	chan->status = free;
518
	chan->open_by_zaptel = FALSE;
519
520
	spin_unlock(&chan->lock);
521
522
	switch (chan->number) {
523
	case D:
524
	break;
525
526
	case B1:
527
		card->regs.ctmt &= ~hfc_CTMT_TRANSB1;
528
		card->regs.cirm &= ~hfc_CIRM_B1_REV;
529
		card->regs.sctrl &= ~hfc_SCTRL_B1_ENA;
530
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B1_ENA;
531
	break;
532
533
	case B2:
534
		card->regs.ctmt &= ~hfc_CTMT_TRANSB2;
535
		card->regs.cirm &= ~hfc_CIRM_B2_REV;
536
		card->regs.sctrl &= ~hfc_SCTRL_B2_ENA;
537
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B2_ENA;
538
	break;
539
	}
540
541
	if (card->chans[B1].status == free &&
542
		card->chans[B2].status == free)
543
		card->regs.m2 &= ~hfc_M2_PROC_TRANS;
544
545
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
546
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
547
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
548
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
549
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
550
551
	hfc_update_fifo_state(card);
552
553
	module_put(THIS_MODULE);
554
555
	printk(KERN_INFO hfc_DRIVER_PREFIX
556
		"card %d: "
557
		"chan %s closed as %s.\n",
558
		card->cardnum,
559
		chan->name,
560
		zaptel_chan->name);
561
562
	return 0;
563
}
564
565
static int hfc_zap_rbsbits(struct dahdi_chan *chan, int bits)
566
{
567
	return 0;
568
}
569
570
static int hfc_zap_ioctl(struct dahdi_chan *chan,
571
		unsigned int cmd, unsigned long data)
572
{
573
	switch (cmd) {
574
575
	default:
576
		return -ENOTTY;
577
	}
578
579
	return 0;
580
}
581
582
static void hfc_hdlc_hard_xmit(struct dahdi_chan *d_chan)
583
{
584
	struct hfc_chan_duplex *chan = d_chan->pvt;
585
	struct hfc_card *card = chan->card;
586
	struct dahdi_hfc *hfccard = card->ztdev;
587
588
	atomic_inc(&hfccard->hdlc_pending);
589
590
}
591
592
static int hfc_zap_startup(struct dahdi_span *span)
593
{
594
    struct dahdi_hfc *zthfc = span->pvt;
595
    struct hfc_card *hfctmp = zthfc->card;
596
    int alreadyrunning;
597
598
	if (!hfctmp) {
599
		printk(KERN_INFO hfc_DRIVER_PREFIX
600
			"card %d: "
601
			"no card for span at startup!\n",
602
			hfctmp->cardnum);
603
	}
604
605
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
606
607
	if (!alreadyrunning)
608
		span->flags |= DAHDI_FLAG_RUNNING;
609
610
	return 0;
611
}
612
613
static int hfc_zap_shutdown(struct dahdi_span *span)
614
{
615
	return 0;
616
}
617
618
static int hfc_zap_maint(struct dahdi_span *span, int cmd)
619
{
620
	return 0;
621
}
622
623
static int hfc_zap_chanconfig(struct dahdi_chan *d_chan, int sigtype)
624
{
625
	struct hfc_chan_duplex *chan = d_chan->pvt;
626
	struct hfc_card *card = chan->card;
627
	struct dahdi_hfc *hfccard = card->ztdev;
628
629
	if ((sigtype == DAHDI_SIG_HARDHDLC) && (hfccard->sigchan == d_chan)) {
630
		hfccard->sigactive = 0;
631
		atomic_set(&hfccard->hdlc_pending, 0);
632
	}
633
634
	return 0;
635
}
636
637
static int hfc_zap_spanconfig(struct dahdi_span *span,
638
		struct dahdi_lineconfig *lc)
639
{
640
	span->lineconfig = lc->lineconfig;
641
642
	return 0;
643
}
644
645
static int hfc_zap_initialize(struct dahdi_hfc *hfccard)
646
{
647
	 struct hfc_card *hfctmp = hfccard->card;
648
	int i;
649
650
	memset(&hfccard->span, 0x0, sizeof(struct dahdi_span));
651
	sprintf(hfccard->span.name, "ZTHFC%d", hfctmp->cardnum + 1);
652
	sprintf(hfccard->span.desc,
653
			"HFC-S PCI A ISDN card %d [%s] ",
654
			hfctmp->cardnum,
655
			hfctmp->nt_mode ? "NT" : "TE");
656
	hfccard->span.spantype = hfctmp->nt_mode ? "NT" : "TE";
657
	hfccard->span.manufacturer = "Cologne Chips";
658
	hfccard->span.spanconfig = hfc_zap_spanconfig;
659
	hfccard->span.chanconfig = hfc_zap_chanconfig;
660
	hfccard->span.startup = hfc_zap_startup;
661
	hfccard->span.shutdown = hfc_zap_shutdown;
662
	hfccard->span.maint = hfc_zap_maint;
663
	hfccard->span.rbsbits = hfc_zap_rbsbits;
664
	hfccard->span.open = hfc_zap_open;
665
	hfccard->span.close = hfc_zap_close;
666
	hfccard->span.ioctl = hfc_zap_ioctl;
667
	hfccard->span.hdlc_hard_xmit = hfc_hdlc_hard_xmit;
668
	hfccard->span.flags = 0;
669
	hfccard->span.irq = hfctmp->pcidev->irq;
670
	dahdi_copy_string(hfccard->span.devicetype, "HFC-S PCI-A ISDN",
671
			sizeof(hfccard->span.devicetype));
672
	sprintf(hfccard->span.location, "PCI Bus %02d Slot %02d",
673
			hfctmp->pcidev->bus->number,
674
			PCI_SLOT(hfctmp->pcidev->devfn) + 1);
675
	hfccard->span.chans = hfccard->_chans;
676
	hfccard->span.channels = 3;
677
	for (i = 0; i < hfccard->span.channels; i++)
678
		hfccard->_chans[i] = &hfccard->chans[i];
679
	hfccard->span.deflaw = DAHDI_LAW_ALAW;
680
	hfccard->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS;
681
	hfccard->span.offset = 0;
682
	init_waitqueue_head(&hfccard->span.maintq);
683
	hfccard->span.pvt = hfccard;
684
685
	for (i = 0; i < hfccard->span.channels; i++) {
686
		memset(&hfccard->chans[i], 0x0, sizeof(struct dahdi_chan));
687
688
		sprintf(hfccard->chans[i].name,
689
				"ZTHFC%d/%d/%d",
690
				hfctmp->cardnum + 1, 0, i + 1);
691
692
		printk(KERN_INFO hfc_DRIVER_PREFIX
693
			"card %d: "
694
			"registered %s\n",
695
			hfctmp->cardnum,
696
			hfccard->chans[i].name);
697
698
		if (i == hfccard->span.channels - 1) {
699
			hfccard->chans[i].sigcap = DAHDI_SIG_HARDHDLC;
700
			hfccard->sigchan = &hfccard->chans[D];
701
			hfccard->sigactive = 0;
702
			atomic_set(&hfccard->hdlc_pending, 0);
703
		} else {
704
			hfccard->chans[i].sigcap =
705
				DAHDI_SIG_CLEAR | DAHDI_SIG_DACS;
706
		}
707
708
		hfccard->chans[i].chanpos = i + 1;
709
	}
710
711
	hfccard->chans[DAHDI_D].readchunk  =
712
		hfctmp->chans[D].rx.zaptel_buffer;
713
714
	hfccard->chans[DAHDI_D].writechunk =
715
		hfctmp->chans[D].tx.zaptel_buffer;
716
717
	hfccard->chans[DAHDI_D].pvt = &hfctmp->chans[D];
718
719
	hfccard->chans[DAHDI_B1].readchunk  =
720
		hfctmp->chans[B1].rx.zaptel_buffer;
721
722
	hfccard->chans[DAHDI_B1].writechunk =
723
		hfctmp->chans[B1].tx.zaptel_buffer;
724
725
	hfccard->chans[DAHDI_B1].pvt = &hfctmp->chans[B1];
726
727
	hfccard->chans[DAHDI_B2].readchunk  =
728
		hfctmp->chans[B2].rx.zaptel_buffer;
729
730
	hfccard->chans[DAHDI_B2].writechunk =
731
		hfctmp->chans[B2].tx.zaptel_buffer;
732
733
	hfccard->chans[DAHDI_B2].pvt = &hfctmp->chans[B2];
734
735
	if (dahdi_register(&hfccard->span, 0)) {
736
		printk(KERN_CRIT "unable to register zaptel device!\n");
737
		return -1;
738
	}
739
740
	return 0;
741
}
742
743
static void hfc_zap_transmit(struct hfc_chan_simplex *chan)
744
{
745
	hfc_fifo_put(chan, chan->zaptel_buffer, DAHDI_CHUNKSIZE);
746
}
747
748
static void hfc_zap_receive(struct hfc_chan_simplex *chan)
749
{
750
	hfc_fifo_get(chan, chan->zaptel_buffer, DAHDI_CHUNKSIZE);
751
}
752
753
/******************************************
754
 * Interrupt Handler
755
 ******************************************/
756
757
static void hfc_handle_timer_interrupt(struct hfc_card *card);
758
static void hfc_handle_state_interrupt(struct hfc_card *card);
759
static void hfc_handle_processing_interrupt(struct hfc_card *card);
760
static void hfc_frame_arrived(struct hfc_chan_duplex *chan);
761
static void hfc_handle_voice(struct hfc_card *card);
762
763
#if (KERNEL_VERSION(2, 6, 24) < LINUX_VERSION_CODE)
764
static irqreturn_t hfc_interrupt(int irq, void *dev_id)
765
#else
766
static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
767
#endif
768
{
769
	struct hfc_card *card = dev_id;
770
	unsigned long flags;
771
	u8 status, s1, s2;
772
773
	if (!card) {
774
		printk(KERN_CRIT hfc_DRIVER_PREFIX
775
			"spurious interrupt (IRQ %d)\n",
776
			irq);
777
		return IRQ_NONE;
778
	}
779
780
	spin_lock_irqsave(&card->lock, flags);
781
	status = hfc_inb(card, hfc_STATUS);
782
	if (!(status & hfc_STATUS_ANYINT)) {
783
		/*
784
		 * maybe we are sharing the irq
785
		 */
786
		spin_unlock_irqrestore(&card->lock, flags);
787
		return IRQ_NONE;
788
	}
789
790
	/* We used to ingore the IRQ when the card was in processing
791
	 * state but apparently there is no restriction to access the
792
	 * card in such state:
793
	 *
794
	 * Joerg Ciesielski wrote:
795
	 * > There is no restriction for the IRQ handler to access
796
	 * > HFC-S PCI during processing phase. A IRQ latency of 375 us
797
	 * > is also no problem since there are no interrupt sources in
798
	 * > HFC-S PCI which must be handled very fast.
799
	 * > Due to its deep fifos the IRQ latency can be several ms with
800
	 * > out the risk of loosing data. Even the S/T state interrupts
801
	 * > must not be handled with a latency less than <5ms.
802
	 * >
803
	 * > The processing phase only indicates that HFC-S PCI is
804
	 * > processing the Fifos as PCI master so that data is read and
805
	 * > written in the 32k memory window. But there is no restriction
806
	 * > to access data in the memory window during this time.
807
	 *
808
	 * // if (status & hfc_STATUS_PCI_PROC) {
809
	 * // return IRQ_HANDLED;
810
	 * // }
811
	 */
812
813
	s1 = hfc_inb(card, hfc_INT_S1);
814
	s2 = hfc_inb(card, hfc_INT_S2);
815
816
	if (s1 != 0) {
817
		if (s1 & hfc_INTS_TIMER) {
818
			/*
819
			 * timer (bit 7)
820
			 */
821
			hfc_handle_timer_interrupt(card);
822
		}
823
824
		if (s1 & hfc_INTS_L1STATE) {
825
			/*
826
			 * state machine (bit 6)
827
			 */
828
			hfc_handle_state_interrupt(card);
829
		}
830
831
		if (s1 & hfc_INTS_DREC) {
832
			/*
833
			 * D chan RX (bit 5)
834
			 */
835
			hfc_frame_arrived(&card->chans[D]);
836
		}
837
838
		if (s1 & hfc_INTS_B1REC) {
839
			/*
840
			 * B1 chan RX (bit 3)
841
			 */
842
			hfc_frame_arrived(&card->chans[B1]);
843
		}
844
845
		if (s1 & hfc_INTS_B2REC) {
846
			/*
847
			 * B2 chan RX (bit 4)
848
			 */
849
			hfc_frame_arrived(&card->chans[B2]);
850
		}
851
852
		if (s1 & hfc_INTS_DTRANS) {
853
			/*
854
			 * D chan TX (bit 2)
855
			 */
856
		}
857
858
		if (s1 & hfc_INTS_B1TRANS) {
859
			/*
860
			 * B1 chan TX (bit 0)
861
			 */
862
		}
863
864
		if (s1 & hfc_INTS_B2TRANS) {
865
			/*
866
			 * B2 chan TX (bit 1)
867
			 */
868
		}
869
870
	}
871
872
	if (s2 != 0) {
873
		if (s2 & hfc_M2_PMESEL) {
874
			/*
875
			 * kaboom irq (bit 7)
876
			 *
877
			 * CologneChip says:
878
			 *
879
			 * the meaning of this fatal error bit is that HFC-S
880
			 * PCI as PCI master could not access the PCI bus
881
			 * within 125us to finish its data processing. If this
882
			 * happens only very seldom it does not cause big
883
			 * problems but of course some B-channel or D-channel
884
			 * data will be corrupted due to this event.
885
			 *
886
			 * Unfortunately this bit is only set once after the
887
			 * problem occurs and can only be reseted by a
888
			 * software reset. That means it is not easily
889
			 * possible to check how often this fatal error
890
			 * happens.
891
			 *
892
			 */
893
894
			if (!card->sync_loss_reported) {
895
				printk(KERN_CRIT hfc_DRIVER_PREFIX
896
					"card %d: "
897
					"sync lost, pci performance too low!\n",
898
					card->cardnum);
899
900
				card->sync_loss_reported = TRUE;
901
			}
902
		}
903
904
		if (s2 & hfc_M2_GCI_MON_REC) {
905
			/*
906
			 * RxR monitor channel (bit 2)
907
			 */
908
		}
909
910
		if (s2 & hfc_M2_GCI_I_CHG) {
911
			/*
912
			 * GCI I-change  (bit 1)
913
			 */
914
		}
915
916
		if (s2 & hfc_M2_PROC_TRANS) {
917
			/*
918
			 * processing/non-processing transition  (bit 0)
919
			 */
920
			hfc_handle_processing_interrupt(card);
921
		}
922
923
	}
924
925
	spin_unlock_irqrestore(&card->lock, flags);
926
927
	return IRQ_HANDLED;
928
}
929
930
static void hfc_handle_timer_interrupt(struct hfc_card *card)
931
{
932
	if (card->ignore_first_timer_interrupt) {
933
		card->ignore_first_timer_interrupt = FALSE;
934
		return;
935
	}
936
937
	if ((card->nt_mode && card->l1_state == 3) ||
938
		(!card->nt_mode && card->l1_state == 7)) {
939
940
		card->regs.ctmt &= ~hfc_CTMT_TIMER_MASK;
941
		hfc_outb(card, hfc_CTMT, card->regs.ctmt);
942
943
		hfc_resume_fifo(card);
944
	}
945
}
946
947
static void hfc_handle_state_interrupt(struct hfc_card *card)
948
{
949
	u8 new_state = hfc_inb(card, hfc_STATES)  & hfc_STATES_STATE_MASK;
950
951
#ifdef DEBUG
952
	if (debug_level >= 1) {
953
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
954
			"card %d: "
955
			"layer 1 state = %c%d\n",
956
			card->cardnum,
957
			card->nt_mode ? 'G' : 'F',
958
			new_state);
959
	}
960
#endif
961
962
	if (card->nt_mode) {
963
		/*
964
		 * NT mode
965
		 */
966
967
		if (new_state == 3) {
968
			/*
969
			 * fix to G3 state (see specs)
970
			 */
971
			hfc_outb(card, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
972
		}
973
974
		if (new_state == 3 && card->l1_state != 3)
975
			hfc_resume_fifo(card);
976
977
		if (new_state != 3 && card->l1_state == 3)
978
			hfc_suspend_fifo(card);
979
980
	} else {
981
		if (new_state == 3) {
982
			/*
983
			 * Keep L1 up... zaptel & libpri expects
984
			 * a always up L1...
985
			 * Enable only  when using an unpatched libpri
986
			 */
987
988
			if (force_l1_up) {
989
				hfc_outb(card, hfc_STATES,
990
					hfc_STATES_DO_ACTION |
991
					hfc_STATES_ACTIVATE|
992
					hfc_STATES_NT_G2_G3);
993
			}
994
		}
995
996
		if (new_state == 7 && card->l1_state != 7) {
997
			/*
998
			 * TE is now active, schedule FIFO activation after
999
			 * some time, otherwise the first frames are lost
1000
			 */
1001
1002
			card->regs.ctmt |= hfc_CTMT_TIMER_50 |
1003
				hfc_CTMT_TIMER_CLEAR;
1004
			hfc_outb(card, hfc_CTMT, card->regs.ctmt);
1005
1006
			/*
1007
			 * Activating the timer firest an
1008
			 * interrupt immediately, we
1009
			 * obviously need to ignore it
1010
			 */
1011
			card->ignore_first_timer_interrupt = TRUE;
1012
		}
1013
1014
		if (new_state != 7 && card->l1_state == 7) {
1015
			/*
1016
			 * TE has become inactive, disable FIFO
1017
			 */
1018
			hfc_suspend_fifo(card);
1019
		}
1020
	}
1021
1022
	card->l1_state = new_state;
1023
}
1024
1025
static void hfc_handle_processing_interrupt(struct hfc_card *card)
1026
{
1027
	int available_bytes = 0;
1028
1029
	/*
1030
	 * Synchronize with the first enabled channel
1031
	 */
1032
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1033
		available_bytes = hfc_fifo_used_rx(&card->chans[B1].rx);
1034
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1035
		available_bytes = hfc_fifo_used_rx(&card->chans[B2].rx);
1036
	else
1037
		available_bytes = -1;
1038
1039
	if ((available_bytes == -1 && card->ticks == 8) ||
1040
		available_bytes >= DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD) {
1041
		card->ticks = 0;
1042
1043
		if (available_bytes > DAHDI_CHUNKSIZE*2 + hfc_RX_FIFO_PRELOAD) {
1044
			card->late_irqs++;
1045
			/*
1046
			 * we are out of sync, clear fifos, jaw
1047
			 */
1048
			hfc_clear_fifo_rx(&card->chans[B1].rx);
1049
			hfc_clear_fifo_tx(&card->chans[B1].tx);
1050
			hfc_clear_fifo_rx(&card->chans[B2].rx);
1051
			hfc_clear_fifo_tx(&card->chans[B2].tx);
1052
1053
#ifdef DEBUG
1054
			if (debug_level >= 4) {
1055
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1056
					"card %d: "
1057
					"late IRQ, %d bytes late\n",
1058
					card->cardnum,
1059
					available_bytes -
1060
						(DAHDI_CHUNKSIZE +
1061
						 hfc_RX_FIFO_PRELOAD));
1062
			}
1063
#endif
1064
		} else {
1065
			hfc_handle_voice(card);
1066
		}
1067
	}
1068
1069
	card->ticks++;
1070
}
1071
1072
1073
static void hfc_handle_voice(struct hfc_card *card)
1074
{
1075
	struct dahdi_hfc *hfccard = card->ztdev;
1076
	int frame_left, res;
1077
	unsigned char buf[hfc_HDLC_BUF_LEN];
1078
	unsigned int size = sizeof(buf) / sizeof(buf[0]);
1079
1080
1081
	if (card->chans[B1].status != open_voice &&
1082
		card->chans[B2].status != open_voice)
1083
		return;
1084
1085
	dahdi_transmit(&hfccard->span);
1086
1087
	if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
1088
		hfc_zap_transmit(&card->chans[B1].tx);
1089
	if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
1090
		hfc_zap_transmit(&card->chans[B2].tx);
1091
1092
	/*
1093
	 * dahdi hdlc frame tx
1094
	 */
1095
1096
	if (atomic_read(&hfccard->hdlc_pending)) {
1097
		hfc_check_l1_up(card);
1098
		res = dahdi_hdlc_getbuf(hfccard->sigchan, buf, &size);
1099
			if (size > 0) {
1100
				hfccard->sigactive = 1;
1101
				memcpy(card->chans[D].tx.ugly_framebuf +
1102
				card->chans[D].tx.ugly_framebuf_size,
1103
				buf, size);
1104
				card->chans[D].tx.ugly_framebuf_size += size;
1105
			if (res != 0) {
1106
					hfc_fifo_put_frame(&card->chans[D].tx,
1107
					card->chans[D].tx.ugly_framebuf,
1108
					card->chans[D].tx.ugly_framebuf_size);
1109
					++hfccard->frames_out;
1110
					hfccard->sigactive = 0;
1111
					card->chans[D].tx.ugly_framebuf_size
1112
						= 0;
1113
					atomic_dec(&hfccard->hdlc_pending);
1114
				}
1115
			}
1116
	}
1117
	/*
1118
	 * dahdi hdlc frame tx done
1119
	 */
1120
1121
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1122
		hfc_zap_receive(&card->chans[B1].rx);
1123
	else
1124
		memset(&card->chans[B1].rx.zaptel_buffer, 0x7f,
1125
			sizeof(card->chans[B1].rx.zaptel_buffer));
1126
1127
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1128
		hfc_zap_receive(&card->chans[B2].rx);
1129
	else
1130
		memset(&card->chans[B2].rx.zaptel_buffer, 0x7f,
1131
			sizeof(card->chans[B1].rx.zaptel_buffer));
1132
1133
	/*
1134
	 * Echo cancellation
1135
	 */
1136
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B1],
1137
			card->chans[B1].rx.zaptel_buffer,
1138
			card->chans[B1].tx.zaptel_buffer);
1139
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B2],
1140
			card->chans[B2].rx.zaptel_buffer,
1141
			card->chans[B2].tx.zaptel_buffer);
1142
1143
	/*
1144
	 * dahdi hdlc frame rx
1145
	 */
1146
	if (hfc_fifo_has_frames(&card->chans[D].rx))
1147
		hfc_frame_arrived(&card->chans[D]);
1148
1149
	if (card->chans[D].rx.ugly_framebuf_size) {
1150
		frame_left = card->chans[D].rx.ugly_framebuf_size -
1151
			card->chans[D].rx.ugly_framebuf_off ;
1152
		if (frame_left > hfc_HDLC_BUF_LEN) {
1153
			dahdi_hdlc_putbuf(hfccard->sigchan,
1154
					card->chans[D].rx.ugly_framebuf +
1155
					card->chans[D].rx.ugly_framebuf_off,
1156
					hfc_HDLC_BUF_LEN);
1157
			card->chans[D].rx.ugly_framebuf_off +=
1158
				hfc_HDLC_BUF_LEN;
1159
		} else {
1160
			dahdi_hdlc_putbuf(hfccard->sigchan,
1161
					card->chans[D].rx.ugly_framebuf +
1162
					card->chans[D].rx.ugly_framebuf_off,
1163
					frame_left);
1164
			dahdi_hdlc_finish(hfccard->sigchan);
1165
			card->chans[D].rx.ugly_framebuf_size = 0;
1166
			card->chans[D].rx.ugly_framebuf_off = 0;
1167
		}
1168
	}
1169
	/*
1170
	 * dahdi hdlc frame rx done
1171
	 */
1172
1173
	if (hfccard->span.flags & DAHDI_FLAG_RUNNING)
1174
		dahdi_receive(&hfccard->span);
1175
1176
}
1177
1178
static void hfc_frame_arrived(struct hfc_chan_duplex *chan)
1179
{
1180
	struct hfc_card *card = chan->card;
1181
	int antiloop = 16;
1182
	struct sk_buff *skb;
1183
1184
	while (hfc_fifo_has_frames(&chan->rx) && --antiloop) {
1185
		int frame_size = hfc_fifo_get_frame_size(&chan->rx);
1186
1187
		if (frame_size < 3) {
1188
#ifdef DEBUG
1189
			if (debug_level >= 2)
1190
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1191
					"card %d: "
1192
					"chan %s: "
1193
					"invalid frame received, "
1194
					"just %d bytes\n",
1195
					card->cardnum,
1196
					chan->name,
1197
					frame_size);
1198
#endif
1199
1200
			hfc_fifo_drop_frame(&chan->rx);
1201
1202
1203
			continue;
1204
		} else if (frame_size == 3) {
1205
#ifdef DEBUG
1206
			if (debug_level >= 2)
1207
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1208
					"card %d: "
1209
					"chan %s: "
1210
					"empty frame received\n",
1211
					card->cardnum,
1212
					chan->name);
1213
#endif
1214
1215
			hfc_fifo_drop_frame(&chan->rx);
1216
1217
1218
			continue;
1219
		}
1220
1221
		if (chan->open_by_zaptel &&
1222
			card->chans[D].rx.ugly_framebuf_size) {
1223
1224
				/*
1225
				 * We have to wait for Dahdi to transmit the
1226
				 * frame... wait for next time
1227
				 */
1228
1229
				 break;
1230
		}
1231
1232
		skb = dev_alloc_skb(frame_size - 3);
1233
1234
		if (!skb) {
1235
			printk(KERN_ERR hfc_DRIVER_PREFIX
1236
				"card %d: "
1237
				"chan %s: "
1238
				"cannot allocate skb: frame dropped\n",
1239
				card->cardnum,
1240
				chan->name);
1241
1242
			hfc_fifo_drop_frame(&chan->rx);
1243
1244
1245
			continue;
1246
		}
1247
1248
1249
		/*
1250
		* HFC does the checksum
1251
		*/
1252
#ifndef CHECKSUM_HW
1253
		skb->ip_summed = CHECKSUM_COMPLETE;
1254
#else
1255
		skb->ip_summed = CHECKSUM_HW;
1256
#endif
1257
1258
		if (chan->open_by_zaptel) {
1259
			card->chans[D].rx.ugly_framebuf_size = frame_size - 1;
1260
1261
			if (hfc_fifo_get_frame(&card->chans[D].rx,
1262
				card->chans[D].rx.ugly_framebuf,
1263
				frame_size - 1) == -1) {
1264
				dev_kfree_skb(skb);
1265
				continue;
1266
			}
1267
1268
			memcpy(skb_put(skb, frame_size - 3),
1269
				card->chans[D].rx.ugly_framebuf,
1270
				frame_size - 3);
1271
		} else {
1272
			if (hfc_fifo_get_frame(&chan->rx,
1273
				skb_put(skb, frame_size - 3),
1274
				frame_size - 3) == -1) {
1275
				dev_kfree_skb(skb);
1276
				continue;
1277
			}
1278
		}
1279
	}
1280
1281
	if (!antiloop)
1282
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1283
			"card %d: "
1284
			"Infinite loop detected\n",
1285
			card->cardnum);
1286
}
1287
1288
/******************************************
1289
 * Module initialization and cleanup
1290
 ******************************************/
1291
1292
static int __devinit hfc_probe(struct pci_dev *pci_dev,
1293
	const struct pci_device_id *ent)
1294
{
1295
	static int cardnum;
1296
	int err;
1297
	int i;
1298
1299
	struct hfc_card *card = NULL;
1300
	struct dahdi_hfc *zthfc = NULL;
1301
	card = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
1302
	if (!card) {
1303
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1304
			"unable to kmalloc!\n");
1305
		err = -ENOMEM;
1306
		goto err_alloc_hfccard;
1307
	}
1308
1309
	memset(card, 0x00, sizeof(struct hfc_card));
1310
	card->cardnum = cardnum;
1311
	card->pcidev = pci_dev;
1312
	spin_lock_init(&card->lock);
1313
1314
	pci_set_drvdata(pci_dev, card);
1315
1316
	err = pci_enable_device(pci_dev);
1317
	if (err)
1318
		goto err_pci_enable_device;
1319
1320
	err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT);
1321
	if (err) {
1322
		printk(KERN_ERR hfc_DRIVER_PREFIX
1323
			"card %d: "
1324
			"No suitable DMA configuration available.\n",
1325
			card->cardnum);
1326
		goto err_pci_set_dma_mask;
1327
	}
1328
1329
	pci_write_config_word(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
1330
	err = pci_request_regions(pci_dev, hfc_DRIVER_NAME);
1331
	if (err) {
1332
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1333
			"card %d: "
1334
			"cannot request I/O memory region\n",
1335
			card->cardnum);
1336
		goto err_pci_request_regions;
1337
	}
1338
1339
	pci_set_master(pci_dev);
1340
1341
	if (!pci_dev->irq) {
1342
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1343
			"card %d: "
1344
			"no irq!\n",
1345
			card->cardnum);
1346
		err = -ENODEV;
1347
		goto err_noirq;
1348
	}
1349
1350
	card->io_bus_mem = pci_resource_start(pci_dev, 1);
1351
	if (!card->io_bus_mem) {
1352
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1353
			"card %d: "
1354
			"no iomem!\n",
1355
			card->cardnum);
1356
		err = -ENODEV;
1357
		goto err_noiobase;
1358
	}
1359
1360
	card->io_mem = ioremap(card->io_bus_mem, hfc_PCI_MEM_SIZE);
1361
	if (!(card->io_mem)) {
1362
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1363
			"card %d: "
1364
			"cannot ioremap I/O memory\n",
1365
			card->cardnum);
1366
		err = -ENODEV;
1367
		goto err_ioremap;
1368
	}
1369
1370
	/*
1371
	 * pci_alloc_consistent guarantees alignment
1372
	 * (Documentation/DMA-mapping.txt)
1373
	 */
1374
	card->fifo_mem = pci_alloc_consistent(pci_dev,
1375
			hfc_FIFO_SIZE, &card->fifo_bus_mem);
1376
	if (!card->fifo_mem) {
1377
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1378
			"card %d: "
1379
			"unable to allocate FIFO DMA memory!\n",
1380
			card->cardnum);
1381
		err = -ENOMEM;
1382
		goto err_alloc_fifo;
1383
	}
1384
1385
	memset(card->fifo_mem, 0x00, hfc_FIFO_SIZE);
1386
1387
	card->fifos = card->fifo_mem;
1388
1389
	pci_write_config_dword(card->pcidev, hfc_PCI_MWBA, card->fifo_bus_mem);
1390
1391
	err = request_irq(card->pcidev->irq, &hfc_interrupt,
1392
1393
#if (KERNEL_VERSION(2, 6, 23) < LINUX_VERSION_CODE)
1394
		IRQF_SHARED, hfc_DRIVER_NAME, card);
1395
#else
1396
		SA_SHIRQ, hfc_DRIVER_NAME, card);
1397
#endif
1398
1399
	if (err) {
1400
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1401
			"card %d: "
1402
			"unable to register irq\n",
1403
			card->cardnum);
1404
		goto err_request_irq;
1405
	}
1406
1407
	card->nt_mode = FALSE;
1408
1409
	if (modes & (1 << card->cardnum))
1410
		card->nt_mode = TRUE;
1411
1412
	for (i = 0; i < nt_modes_count; i++) {
1413
		if (nt_modes[i] == card->cardnum)
1414
			card->nt_mode = TRUE;
1415
	}
1416
1417
	/*
1418
	 * D Channel
1419
	 */
1420
	card->chans[D].card = card;
1421
	card->chans[D].name = "D";
1422
	card->chans[D].status = free;
1423
	card->chans[D].number = D;
1424
	spin_lock_init(&card->chans[D].lock);
1425
1426
	card->chans[D].rx.chan      = &card->chans[D];
1427
	card->chans[D].rx.fifo_base = card->fifos + 0x4000;
1428
	card->chans[D].rx.z_base    = card->fifos + 0x4000;
1429
	card->chans[D].rx.z1_base   = card->fifos + 0x6080;
1430
	card->chans[D].rx.z2_base   = card->fifos + 0x6082;
1431
	card->chans[D].rx.z_min     = 0x0000;
1432
	card->chans[D].rx.z_max     = 0x01FF;
1433
	card->chans[D].rx.f_min     = 0x10;
1434
	card->chans[D].rx.f_max     = 0x1F;
1435
	card->chans[D].rx.f1        = card->fifos + 0x60a0;
1436
	card->chans[D].rx.f2        = card->fifos + 0x60a1;
1437
	card->chans[D].rx.fifo_size = card->chans[D].rx.z_max
1438
		- card->chans[D].rx.z_min + 1;
1439
	card->chans[D].rx.f_num     = card->chans[D].rx.f_max
1440
		- card->chans[D].rx.f_min + 1;
1441
1442
	card->chans[D].tx.chan      = &card->chans[D];
1443
	card->chans[D].tx.fifo_base = card->fifos + 0x0000;
1444
	card->chans[D].tx.z_base    = card->fifos + 0x0000;
1445
	card->chans[D].tx.z1_base   = card->fifos + 0x2080;
1446
	card->chans[D].tx.z2_base   = card->fifos + 0x2082;
1447
	card->chans[D].tx.z_min     = 0x0000;
1448
	card->chans[D].tx.z_max     = 0x01FF;
1449
	card->chans[D].tx.f_min     = 0x10;
1450
	card->chans[D].tx.f_max     = 0x1F;
1451
	card->chans[D].tx.f1        = card->fifos + 0x20a0;
1452
	card->chans[D].tx.f2        = card->fifos + 0x20a1;
1453
	card->chans[D].tx.fifo_size = card->chans[D].tx.z_max -
1454
		card->chans[D].tx.z_min + 1;
1455
	card->chans[D].tx.f_num     = card->chans[D].tx.f_max -
1456
		card->chans[D].tx.f_min + 1;
1457
1458
	/*
1459
	 * B1 Channel
1460
	 */
1461
	card->chans[B1].card = card;
1462
	card->chans[B1].name = "B1";
1463
	card->chans[B1].status = free;
1464
	card->chans[B1].number = B1;
1465
	card->chans[B1].protocol = 0;
1466
	spin_lock_init(&card->chans[B1].lock);
1467
1468
	card->chans[B1].rx.chan      = &card->chans[B1];
1469
	card->chans[B1].rx.fifo_base = card->fifos + 0x4200;
1470
	card->chans[B1].rx.z_base    = card->fifos + 0x4000;
1471
	card->chans[B1].rx.z1_base   = card->fifos + 0x6000;
1472
	card->chans[B1].rx.z2_base   = card->fifos + 0x6002;
1473
	card->chans[B1].rx.z_min     = 0x0200;
1474
	card->chans[B1].rx.z_max     = 0x1FFF;
1475
	card->chans[B1].rx.f_min     = 0x00;
1476
	card->chans[B1].rx.f_max     = 0x1F;
1477
	card->chans[B1].rx.f1        = card->fifos + 0x6080;
1478
	card->chans[B1].rx.f2        = card->fifos + 0x6081;
1479
	card->chans[B1].rx.fifo_size = card->chans[B1].rx.z_max -
1480
		card->chans[B1].rx.z_min + 1;
1481
	card->chans[B1].rx.f_num     = card->chans[B1].rx.f_max -
1482
		card->chans[B1].rx.f_min + 1;
1483
1484
	card->chans[B1].tx.chan      = &card->chans[B1];
1485
	card->chans[B1].tx.fifo_base = card->fifos + 0x0200;
1486
	card->chans[B1].tx.z_base    = card->fifos + 0x0000;
1487
	card->chans[B1].tx.z1_base   = card->fifos + 0x2000;
1488
	card->chans[B1].tx.z2_base   = card->fifos + 0x2002;
1489
	card->chans[B1].tx.z_min     = 0x0200;
1490
	card->chans[B1].tx.z_max     = 0x1FFF;
1491
	card->chans[B1].tx.f_min     = 0x00;
1492
	card->chans[B1].tx.f_max     = 0x1F;
1493
	card->chans[B1].tx.f1        = card->fifos + 0x2080;
1494
	card->chans[B1].tx.f2        = card->fifos + 0x2081;
1495
	card->chans[B1].tx.fifo_size = card->chans[B1].tx.z_max -
1496
		card->chans[B1].tx.z_min + 1;
1497
	card->chans[B1].tx.f_num     = card->chans[B1].tx.f_max -
1498
		card->chans[B1].tx.f_min + 1;
1499
1500
	/*
1501
	 * B2 Channel
1502
	 */
1503
	card->chans[B2].card = card;
1504
	card->chans[B2].name = "B2";
1505
	card->chans[B2].status = free;
1506
	card->chans[B2].number = B2;
1507
	card->chans[B2].protocol = 0;
1508
	spin_lock_init(&card->chans[B2].lock);
1509
1510
	card->chans[B2].rx.chan      = &card->chans[B2];
1511
	card->chans[B2].rx.fifo_base = card->fifos + 0x6200,
1512
	card->chans[B2].rx.z_base    = card->fifos + 0x6000;
1513
	card->chans[B2].rx.z1_base   = card->fifos + 0x6100;
1514
	card->chans[B2].rx.z2_base   = card->fifos + 0x6102;
1515
	card->chans[B2].rx.z_min     = 0x0200;
1516
	card->chans[B2].rx.z_max     = 0x1FFF;
1517
	card->chans[B2].rx.f_min     = 0x00;
1518
	card->chans[B2].rx.f_max     = 0x1F;
1519
	card->chans[B2].rx.f1        = card->fifos + 0x6180;
1520
	card->chans[B2].rx.f2        = card->fifos + 0x6181;
1521
	card->chans[B2].rx.fifo_size = card->chans[B2].rx.z_max -
1522
		card->chans[B2].rx.z_min + 1;
1523
	card->chans[B2].rx.f_num     = card->chans[B2].rx.f_max -
1524
		card->chans[B2].rx.f_min + 1;
1525
1526
	card->chans[B2].tx.chan      = &card->chans[B2];
1527
	card->chans[B2].tx.fifo_base = card->fifos + 0x2200;
1528
	card->chans[B2].tx.z_base    = card->fifos + 0x2000;
1529
	card->chans[B2].tx.z1_base   = card->fifos + 0x2100;
1530
	card->chans[B2].tx.z2_base   = card->fifos + 0x2102;
1531
	card->chans[B2].tx.z_min     = 0x0200;
1532
	card->chans[B2].tx.z_max     = 0x1FFF;
1533
	card->chans[B2].tx.f_min     = 0x00;
1534
	card->chans[B2].tx.f_max     = 0x1F;
1535
	card->chans[B2].tx.f1        = card->fifos + 0x2180;
1536
	card->chans[B2].tx.f2        = card->fifos + 0x2181;
1537
	card->chans[B2].tx.fifo_size = card->chans[B2].tx.z_max -
1538
		card->chans[B2].tx.z_min + 1;
1539
	card->chans[B2].tx.f_num     = card->chans[B2].tx.f_max -
1540
		card->chans[B2].tx.f_min + 1;
1541
1542
	/*
1543
	 * All done
1544
	 */
1545
1546
	zthfc = kmalloc(sizeof(struct dahdi_hfc), GFP_KERNEL);
1547
	if (!zthfc) {
1548
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1549
			"unable to kmalloc!\n");
1550
		goto err_request_irq;
1551
	}
1552
	memset(zthfc, 0x0, sizeof(struct dahdi_hfc));
1553
1554
	zthfc->card = card;
1555
	hfc_zap_initialize(zthfc);
1556
	card->ztdev = zthfc;
1557
1558
	snprintf(card->proc_dir_name,
1559
			sizeof(card->proc_dir_name),
1560
			"%d", card->cardnum);
1561
	card->proc_dir = proc_mkdir(card->proc_dir_name, hfc_proc_zaphfc_dir);
1562
	SET_PROC_DIRENTRY_OWNER(card->proc_dir);
1563
1564
	hfc_resetCard(card);
1565
1566
	printk(KERN_INFO hfc_DRIVER_PREFIX
1567
		"card %d configured for %s mode at mem %#lx (0x%p) IRQ %u\n",
1568
		card->cardnum,
1569
		card->nt_mode ? "NT" : "TE",
1570
		card->io_bus_mem,
1571
		card->io_mem,
1572
		card->pcidev->irq);
1573
1574
	cardnum++;
1575
1576
	return 0;
1577
1578
err_request_irq:
1579
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1580
		card->fifo_mem, card->fifo_bus_mem);
1581
err_alloc_fifo:
1582
	iounmap(card->io_mem);
1583
err_ioremap:
1584
err_noiobase:
1585
err_noirq:
1586
	pci_release_regions(pci_dev);
1587
err_pci_request_regions:
1588
err_pci_set_dma_mask:
1589
err_pci_enable_device:
1590
	kfree(card);
1591
err_alloc_hfccard:
1592
	return err;
1593
}
1594
1595
static void __devexit hfc_remove(struct pci_dev *pci_dev)
1596
{
1597
	struct hfc_card *card = pci_get_drvdata(pci_dev);
1598
1599
1600
	printk(KERN_INFO hfc_DRIVER_PREFIX
1601
		"card %d: "
1602
		"shutting down card at %p.\n",
1603
		card->cardnum,
1604
		card->io_mem);
1605
1606
	hfc_softreset(card);
1607
1608
	dahdi_unregister(&card->ztdev->span);
1609
1610
1611
	/*
1612
	 * disable memio and bustmaster
1613
	 */
1614
	pci_write_config_word(pci_dev, PCI_COMMAND, 0);
1615
1616
	remove_proc_entry("bufs", card->proc_dir);
1617
	remove_proc_entry("fifos", card->proc_dir);
1618
	remove_proc_entry("info", card->proc_dir);
1619
	remove_proc_entry(card->proc_dir_name, hfc_proc_zaphfc_dir);
1620
1621
	free_irq(pci_dev->irq, card);
1622
1623
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1624
		card->fifo_mem, card->fifo_bus_mem);
1625
1626
	iounmap(card->io_mem);
1627
1628
	pci_release_regions(pci_dev);
1629
1630
	pci_disable_device(pci_dev);
1631
1632
	kfree(card);
1633
}
1634
1635
/******************************************
1636
 * Module stuff
1637
 ******************************************/
1638
1639
static int __init hfc_init_module(void)
1640
{
1641
	int ret;
1642
1643
	printk(KERN_INFO hfc_DRIVER_PREFIX
1644
		hfc_DRIVER_STRING " loading\n");
1645
1646
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1647
	hfc_proc_zaphfc_dir = proc_mkdir(hfc_DRIVER_NAME, NULL);
1648
#else
1649
	hfc_proc_zaphfc_dir = proc_mkdir(hfc_DRIVER_NAME, proc_root_driver);
1650
#endif
1651
1652
	ret = dahdi_pci_module(&hfc_driver);
1653
	return ret;
1654
}
1655
1656
module_init(hfc_init_module);
1657
1658
static void __exit hfc_module_exit(void)
1659
{
1660
	pci_unregister_driver(&hfc_driver);
1661
1662
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1663
	remove_proc_entry(hfc_DRIVER_NAME, NULL);
1664
#else
1665
	remove_proc_entry(hfc_DRIVER_NAME, proc_root_driver);
1666
#endif
1667
1668
	printk(KERN_INFO hfc_DRIVER_PREFIX
1669
		hfc_DRIVER_STRING " unloaded\n");
1670
}
1671
1672
module_exit(hfc_module_exit);
1673
1674
#endif
1675
1676
MODULE_DESCRIPTION(hfc_DRIVER_DESCR);
1677
MODULE_AUTHOR("Jens Wilke <jw_vzaphfc@headissue.com>, "
1678
		"Daniele (Vihai) Orlandi <daniele@orlandi.com>, "
1679
		"Jose A. Deniz <odicha@hotmail.com>");
1680
MODULE_ALIAS("vzaphfc");
1681
#ifdef MODULE_LICENSE
1682
MODULE_LICENSE("GPL");
1683
#endif
1684
1685
1686
module_param(modes, int, 0444);
1687
1688
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
1689
module_param_array(nt_modes, int, &nt_modes_count, 0444);
1690
#else
1691
module_param_array(nt_modes, int, nt_modes_count, 0444);
1692
#endif
1693
1694
module_param(force_l1_up, int, 0444);
1695
#ifdef DEBUG
1696
module_param(debug_level, int, 0444);
1697
#endif
1698
1699
MODULE_PARM_DESC(modes, "[Deprecated] bit-mask to configure NT mode");
1700
MODULE_PARM_DESC(nt_modes,
1701
		"Comma-separated list of card IDs to configure in NT mode");
1702
MODULE_PARM_DESC(force_l1_up, "Don't allow L1 to go down");
1703
#ifdef DEBUG
1704
MODULE_PARM_DESC(debug_level, "Debug verbosity level");
1705
#endif
(-)dahdi-linux-2.2.0.2/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-2.2.0.2/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-2.2.0.2/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-2.2.0.2/drivers/dahdi/zaphfc/zaphfc.h (+414 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_span span;
389
    struct dahdi_chan chans[3];
390
    struct dahdi_chan *_chans[3];
391
    struct hfc_card *card;
392
393
    /* pointer to the signalling channel for this span */
394
    struct dahdi_chan *sigchan;
395
    /* nonzero means we're in the middle of sending an HDLC frame */
396
    int sigactive;
397
    /* hdlc_hard_xmit() increments, hdlc_tx_frame() decrements */
398
    atomic_t hdlc_pending;
399
    int frames_out;
400
    int frames_in;
401
402
} dahdi_hfc;
403
404
static inline u8 hfc_inb(struct hfc_card *card, int offset)
405
{
406
 return readb(card->io_mem + offset);
407
}
408
409
static inline void hfc_outb(struct hfc_card *card, int offset, u8 value)
410
{
411
 writeb(value, card->io_mem + offset);
412
}
413
414
#endif
(-)dahdi-linux-2.2.0.2/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-2.2.0.2/drivers/staging/echo/echo.h (+172 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
 * $Id: echo.h,v 1.9 2006/10/24 13:45:28 steveu Exp $
28
 */
29
30
#ifndef __ECHO_H
31
#define __ECHO_H
32
33
/*! \page echo_can_page Line echo cancellation for voice
34
35
\section echo_can_page_sec_1 What does it do?
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
\section echo_can_page_sec_2 How does it work?
40
The heart of the echo cancellor is FIR filter. This is adapted to match the
41
echo impulse response of the telephone line. It must be long enough to
42
adequately cover the duration of that impulse response. The signal transmitted
43
to the telephone line is passed through the FIR filter. Once the FIR is
44
properly adapted, the resulting output is an estimate of the echo signal
45
received from the line. This is subtracted from the received signal. The result
46
is an estimate of the signal which originated at the far end of the line, free
47
from echos of our own transmitted signal.
48
49
The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and
50
was introduced in 1960. It is the commonest form of filter adaption used in
51
things like modem line equalisers and line echo cancellers. There it works very
52
well.  However, it only works well for signals of constant amplitude. It works
53
very poorly for things like speech echo cancellation, where the signal level
54
varies widely.  This is quite easy to fix. If the signal level is normalised -
55
similar to applying AGC - LMS can work as well for a signal of varying
56
amplitude as it does for a modem signal. This normalised least mean squares
57
(NLMS) algorithm is the commonest one used for speech echo cancellation. Many
58
other algorithms exist - e.g. RLS (essentially the same as Kalman filtering),
59
FAP, etc. Some perform significantly better than NLMS.  However, factors such
60
as computational complexity and patents favour the use of NLMS.
61
62
A simple refinement to NLMS can improve its performance with speech. NLMS tends
63
to adapt best to the strongest parts of a signal. If the signal is white noise,
64
the NLMS algorithm works very well. However, speech has more low frequency than
65
high frequency content. Pre-whitening (i.e. filtering the signal to flatten its
66
spectrum) the echo signal improves the adapt rate for speech, and ensures the
67
final residual signal is not heavily biased towards high frequencies. A very
68
low complexity filter is adequate for this, so pre-whitening adds little to the
69
compute requirements of the echo canceller.
70
71
An FIR filter adapted using pre-whitened NLMS performs well, provided certain
72
conditions are met:
73
74
    - The transmitted signal has poor self-correlation.
75
    - There is no signal being generated within the environment being
76
      cancelled.
77
78
The difficulty is that neither of these can be guaranteed.
79
80
If the adaption is performed while transmitting noise (or something fairly
81
noise like, such as voice) the adaption works very well. If the adaption is
82
performed while transmitting something highly correlative (typically narrow
83
band energy such as signalling tones or DTMF), the adaption can go seriously
84
wrong. The reason is there is only one solution for the adaption on a near
85
random signal - the impulse response of the line. For a repetitive signal,
86
there are any number of solutions which converge the adaption, and nothing
87
guides the adaption to choose the generalised one. Allowing an untrained
88
canceller to converge on this kind of narrowband energy probably a good thing,
89
since at least it cancels the tones. Allowing a well converged canceller to
90
continue converging on such energy is just a way to ruin its generalised
91
adaption. A narrowband detector is needed, so adapation can be suspended at
92
appropriate times.
93
94
The adaption process is based on trying to eliminate the received signal. When
95
there is any signal from within the environment being cancelled it may upset
96
the adaption process. Similarly, if the signal we are transmitting is small,
97
noise may dominate and disturb the adaption process. If we can ensure that the
98
adaption is only performed when we are transmitting a significant signal level,
99
and the environment is not, things will be OK. Clearly, it is easy to tell when
100
we are sending a significant signal. Telling, if the environment is generating
101
a significant signal, and doing it with sufficient speed that the adaption will
102
not have diverged too much more we stop it, is a little harder.
103
104
The key problem in detecting when the environment is sourcing significant
105
energy is that we must do this very quickly. Given a reasonably long sample of
106
the received signal, there are a number of strategies which may be used to
107
assess whether that signal contains a strong far end component. However, by the
108
time that assessment is complete the far end signal will have already caused
109
major mis-convergence in the adaption process. An assessment algorithm is
110
needed which produces a fairly accurate result from a very short burst of far
111
end energy.
112
113
\section echo_can_page_sec_3 How do I use it?
114
The echo cancellor processes both the transmit and receive streams sample by
115
sample. The processing function is not declared inline. Unfortunately,
116
cancellation requires many operations per sample, so the call overhead is only
117
a minor burden.
118
*/
119
120
#include "fir.h"
121
#include "oslec.h"
122
123
/*!
124
    G.168 echo canceller descriptor. This defines the working state for a line
125
    echo canceller.
126
*/
127
struct oslec_state {
128
	int16_t tx, rx;
129
	int16_t clean;
130
	int16_t clean_nlp;
131
132
	int nonupdate_dwell;
133
	int curr_pos;
134
	int taps;
135
	int log2taps;
136
	int adaption_mode;
137
138
	int cond_met;
139
	int32_t Pstates;
140
	int16_t adapt;
141
	int32_t factor;
142
	int16_t shift;
143
144
	/* Average levels and averaging filter states */
145
	int Ltxacc, Lrxacc, Lcleanacc, Lclean_bgacc;
146
	int Ltx, Lrx;
147
	int Lclean;
148
	int Lclean_bg;
149
	int Lbgn, Lbgn_acc, Lbgn_upper, Lbgn_upper_acc;
150
151
	/* foreground and background filter states */
152
	fir16_state_t fir_state;
153
	fir16_state_t fir_state_bg;
154
	int16_t *fir_taps16[2];
155
156
	/* DC blocking filter states */
157
	int tx_1, tx_2, rx_1, rx_2;
158
159
	/* optional High Pass Filter states */
160
	int32_t xvtx[5], yvtx[5];
161
	int32_t xvrx[5], yvrx[5];
162
163
	/* Parameters for the optional Hoth noise generator */
164
	int cng_level;
165
	int cng_rndnum;
166
	int cng_filter;
167
168
	/* snapshot sample of coeffs used for development */
169
	int16_t *snapshot;
170
};
171
172
#endif /* __ECHO_H */
(-)dahdi-linux-2.2.0.2/drivers/staging/echo/fir.h (+295 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
 * $Id: fir.h,v 1.8 2006/10/24 13:45:28 steveu Exp $
26
 */
27
28
/*! \page fir_page FIR filtering
29
\section fir_page_sec_1 What does it do?
30
???.
31
32
\section fir_page_sec_2 How does it work?
33
???.
34
*/
35
36
#if !defined(_FIR_H_)
37
#define _FIR_H_
38
39
/*
40
   Blackfin NOTES & IDEAS:
41
42
   A simple dot product function is used to implement the filter.  This performs
43
   just one MAC/cycle which is inefficient but was easy to implement as a first
44
   pass.  The current Blackfin code also uses an unrolled form of the filter
45
   history to avoid 0 length hardware loop issues.  This is wasteful of
46
   memory.
47
48
   Ideas for improvement:
49
50
   1/ Rewrite filter for dual MAC inner loop.  The issue here is handling
51
   history sample offsets that are 16 bit aligned - the dual MAC needs
52
   32 bit aligmnent.  There are some good examples in libbfdsp.
53
54
   2/ Use the hardware circular buffer facility tohalve memory usage.
55
56
   3/ Consider using internal memory.
57
58
   Using less memory might also improve speed as cache misses will be
59
   reduced. A drop in MIPs and memory approaching 50% should be
60
   possible.
61
62
   The foreground and background filters currenlty use a total of
63
   about 10 MIPs/ch as measured with speedtest.c on a 256 TAP echo
64
   can.
65
*/
66
67
#if defined(USE_MMX)  ||  defined(USE_SSE2)
68
#include "mmx.h"
69
#endif
70
71
/*!
72
    16 bit integer FIR descriptor. This defines the working state for a single
73
    instance of an FIR filter using 16 bit integer coefficients.
74
*/
75
typedef struct {
76
	int taps;
77
	int curr_pos;
78
	const int16_t *coeffs;
79
	int16_t *history;
80
} fir16_state_t;
81
82
/*!
83
    32 bit integer FIR descriptor. This defines the working state for a single
84
    instance of an FIR filter using 32 bit integer coefficients, and filtering
85
    16 bit integer data.
86
*/
87
typedef struct {
88
	int taps;
89
	int curr_pos;
90
	const int32_t *coeffs;
91
	int16_t *history;
92
} fir32_state_t;
93
94
/*!
95
    Floating point FIR descriptor. This defines the working state for a single
96
    instance of an FIR filter using floating point coefficients and data.
97
*/
98
typedef struct {
99
	int taps;
100
	int curr_pos;
101
	const float *coeffs;
102
	float *history;
103
} fir_float_state_t;
104
105
static __inline__ const int16_t *fir16_create(fir16_state_t * fir,
106
					      const int16_t * coeffs, int taps)
107
{
108
	fir->taps = taps;
109
	fir->curr_pos = taps - 1;
110
	fir->coeffs = coeffs;
111
#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
112
	fir->history = kcalloc(2 * taps, sizeof(int16_t), GFP_KERNEL);
113
#else
114
	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
115
#endif
116
	return fir->history;
117
}
118
119
static __inline__ void fir16_flush(fir16_state_t * fir)
120
{
121
#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
122
	memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
123
#else
124
	memset(fir->history, 0, fir->taps * sizeof(int16_t));
125
#endif
126
}
127
128
static __inline__ void fir16_free(fir16_state_t * fir)
129
{
130
	kfree(fir->history);
131
}
132
133
#ifdef __bfin__
134
static inline int32_t dot_asm(short *x, short *y, int len)
135
{
136
	int dot;
137
138
	len--;
139
140
	__asm__("I0 = %1;\n\t"
141
		"I1 = %2;\n\t"
142
		"A0 = 0;\n\t"
143
		"R0.L = W[I0++] || R1.L = W[I1++];\n\t"
144
		"LOOP dot%= LC0 = %3;\n\t"
145
		"LOOP_BEGIN dot%=;\n\t"
146
		"A0 += R0.L * R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
147
		"LOOP_END dot%=;\n\t"
148
		"A0 += R0.L*R1.L (IS);\n\t"
149
		"R0 = A0;\n\t"
150
		"%0 = R0;\n\t"
151
		:"=&d"(dot)
152
		:"a"(x), "a"(y), "a"(len)
153
		:"I0", "I1", "A1", "A0", "R0", "R1"
154
	);
155
156
	return dot;
157
}
158
#endif
159
160
static __inline__ int16_t fir16(fir16_state_t * fir, int16_t sample)
161
{
162
	int32_t y;
163
#if defined(USE_MMX)
164
	int i;
165
	mmx_t *mmx_coeffs;
166
	mmx_t *mmx_hist;
167
168
	fir->history[fir->curr_pos] = sample;
169
	fir->history[fir->curr_pos + fir->taps] = sample;
170
171
	mmx_coeffs = (mmx_t *) fir->coeffs;
172
	mmx_hist = (mmx_t *) & fir->history[fir->curr_pos];
173
	i = fir->taps;
174
	pxor_r2r(mm4, mm4);
175
	/* 8 samples per iteration, so the filter must be a multiple of 8 long. */
176
	while (i > 0) {
177
		movq_m2r(mmx_coeffs[0], mm0);
178
		movq_m2r(mmx_coeffs[1], mm2);
179
		movq_m2r(mmx_hist[0], mm1);
180
		movq_m2r(mmx_hist[1], mm3);
181
		mmx_coeffs += 2;
182
		mmx_hist += 2;
183
		pmaddwd_r2r(mm1, mm0);
184
		pmaddwd_r2r(mm3, mm2);
185
		paddd_r2r(mm0, mm4);
186
		paddd_r2r(mm2, mm4);
187
		i -= 8;
188
	}
189
	movq_r2r(mm4, mm0);
190
	psrlq_i2r(32, mm0);
191
	paddd_r2r(mm0, mm4);
192
	movd_r2m(mm4, y);
193
	emms();
194
#elif defined(USE_SSE2)
195
	int i;
196
	xmm_t *xmm_coeffs;
197
	xmm_t *xmm_hist;
198
199
	fir->history[fir->curr_pos] = sample;
200
	fir->history[fir->curr_pos + fir->taps] = sample;
201
202
	xmm_coeffs = (xmm_t *) fir->coeffs;
203
	xmm_hist = (xmm_t *) & fir->history[fir->curr_pos];
204
	i = fir->taps;
205
	pxor_r2r(xmm4, xmm4);
206
	/* 16 samples per iteration, so the filter must be a multiple of 16 long. */
207
	while (i > 0) {
208
		movdqu_m2r(xmm_coeffs[0], xmm0);
209
		movdqu_m2r(xmm_coeffs[1], xmm2);
210
		movdqu_m2r(xmm_hist[0], xmm1);
211
		movdqu_m2r(xmm_hist[1], xmm3);
212
		xmm_coeffs += 2;
213
		xmm_hist += 2;
214
		pmaddwd_r2r(xmm1, xmm0);
215
		pmaddwd_r2r(xmm3, xmm2);
216
		paddd_r2r(xmm0, xmm4);
217
		paddd_r2r(xmm2, xmm4);
218
		i -= 16;
219
	}
220
	movdqa_r2r(xmm4, xmm0);
221
	psrldq_i2r(8, xmm0);
222
	paddd_r2r(xmm0, xmm4);
223
	movdqa_r2r(xmm4, xmm0);
224
	psrldq_i2r(4, xmm0);
225
	paddd_r2r(xmm0, xmm4);
226
	movd_r2m(xmm4, y);
227
#elif defined(__bfin__)
228
	fir->history[fir->curr_pos] = sample;
229
	fir->history[fir->curr_pos + fir->taps] = sample;
230
	y = dot_asm((int16_t *) fir->coeffs, &fir->history[fir->curr_pos],
231
		    fir->taps);
232
#else
233
	int i;
234
	int offset1;
235
	int offset2;
236
237
	fir->history[fir->curr_pos] = sample;
238
239
	offset2 = fir->curr_pos;
240
	offset1 = fir->taps - offset2;
241
	y = 0;
242
	for (i = fir->taps - 1; i >= offset1; i--)
243
		y += fir->coeffs[i] * fir->history[i - offset1];
244
	for (; i >= 0; i--)
245
		y += fir->coeffs[i] * fir->history[i + offset2];
246
#endif
247
	if (fir->curr_pos <= 0)
248
		fir->curr_pos = fir->taps;
249
	fir->curr_pos--;
250
	return (int16_t) (y >> 15);
251
}
252
253
static __inline__ const int16_t *fir32_create(fir32_state_t * fir,
254
					      const int32_t * coeffs, int taps)
255
{
256
	fir->taps = taps;
257
	fir->curr_pos = taps - 1;
258
	fir->coeffs = coeffs;
259
	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
260
	return fir->history;
261
}
262
263
static __inline__ void fir32_flush(fir32_state_t * fir)
264
{
265
	memset(fir->history, 0, fir->taps * sizeof(int16_t));
266
}
267
268
static __inline__ void fir32_free(fir32_state_t * fir)
269
{
270
	kfree(fir->history);
271
}
272
273
static __inline__ int16_t fir32(fir32_state_t * fir, int16_t sample)
274
{
275
	int i;
276
	int32_t y;
277
	int offset1;
278
	int offset2;
279
280
	fir->history[fir->curr_pos] = sample;
281
	offset2 = fir->curr_pos;
282
	offset1 = fir->taps - offset2;
283
	y = 0;
284
	for (i = fir->taps - 1; i >= offset1; i--)
285
		y += fir->coeffs[i] * fir->history[i - offset1];
286
	for (; i >= 0; i--)
287
		y += fir->coeffs[i] * fir->history[i + offset2];
288
	if (fir->curr_pos <= 0)
289
		fir->curr_pos = fir->taps;
290
	fir->curr_pos--;
291
	return (int16_t) (y >> 15);
292
}
293
294
#endif
295
/*- End of file ------------------------------------------------------------*/
(-)dahdi-linux-2.2.0.2/drivers/staging/echo/Kbuild (+6 lines)
Line 0 Link Here
1
ifdef DAHDI_USE_MMX
2
EXTRA_CFLAGSi += USE_MMX
3
endif
4
5
# An explicit 'obj-m' , unlike the Makefile
6
obj-m += echo.o
(-)dahdi-linux-2.2.0.2/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 */

Return to bug 296637