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

Collapse All | Expand All

(-)dahdi-linux-2.7.0/drivers/dahdi/ap400/ap400_drv.c (+2337 lines)
Line 0 Link Here
1
/*
2
 * AP4XX PCI Card Driver
3
 *
4
 * Written by Ronaldo Valiati <aligera@aligera.com.br>
5
 *
6
 * Based on previous works, designs, and architectures conceived and
7
 * written by Jim Dixon <jim@lambdatel.com> and Mark Spencer <markster@digium.com>.
8
 *
9
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
10
 * Copyright (C) 2001-2005, Digium, Inc.
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#include <linux/kernel.h>
31
#include <linux/errno.h>
32
#include <linux/module.h>
33
#include <linux/pci.h>
34
#include <linux/init.h>
35
#include <linux/sched.h>
36
#include <linux/interrupt.h>
37
#include <linux/time.h>
38
#include <linux/delay.h>
39
#include <linux/proc_fs.h>
40
#include <dahdi/kernel.h>
41
#include <linux/moduleparam.h>
42
43
#include "ap400.h"
44
45
//#define AP400_DEBUG
46
#ifdef AP400_DEBUG
47
#define PDEBUG(fmt, args...) { \
48
	printk(KERN_DEBUG "AP400 (%d): ",__LINE__); \
49
	printk(fmt "\n", ## args); \
50
}
51
#else
52
#define PDEBUG(fmt, args...)
53
#endif
54
55
/*
56
 * Tasklets provide better system interactive response at the cost of the
57
 * possibility of losing a frame of data at very infrequent intervals.  If
58
 * you are more concerned with the performance of your machine, enable the
59
 * tasklets.  If you are strict about absolutely no drops, then do not enable
60
 * tasklets.
61
 */
62
63
/* #define ENABLE_TASKLETS */
64
65
66
/* Work queues are a way to better distribute load on SMP systems */
67
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
68
/*
69
 * Work queues can significantly improve performance and scalability
70
 * on multi-processor machines, but requires bypassing some kernel
71
 * API's, so it's not guaranteed to be compatible with all kernels.
72
 */
73
/* #define ENABLE_WORKQUEUES */
74
#endif
75
76
/* Enable HDLC support by hardware */
77
#ifdef AP400_HDLC
78
#include "ap400_hdlc/ap400_hdlc.c"
79
#endif
80
81
//#define APEC_SUPPORT
82
#ifdef APEC_SUPPORT
83
#include "apec.h"
84
#endif
85
86
/* Workarounds */
87
#ifndef IRQF_SHARED
88
#define IRQF_SHARED		SA_SHIRQ
89
#endif
90
#ifndef IRQF_DISABLED
91
#define IRQF_DISABLED		SA_INTERRUPT
92
#endif
93
#ifndef __iomem
94
#define __iomem
95
#endif
96
97
/* Enable prefetching may help performance */
98
#define ENABLE_PREFETCH
99
100
/* Define to get more attention-grabbing but slightly more I/O using
101
   alarm status */
102
#define FANCY_ALARM
103
104
#define DEBUG_MAIN 		(1 << 0)
105
#define DEBUG_DTMF 		(1 << 1)
106
#define DEBUG_REGS 		(1 << 2)
107
#define DEBUG_TSI  		(1 << 3)
108
#define DEBUG_ECHOCAN 		(1 << 4)
109
#define DEBUG_RBS 		(1 << 5)
110
#define DEBUG_FRAMER		(1 << 6)
111
112
static int clock_source = -1;
113
static int tdm_loop = 0;
114
static int apec_enable = 1;
115
module_param(tdm_loop, int, 0600);
116
module_param(apec_enable, int, 0600);
117
118
#ifdef ENABLE_WORKQUEUES
119
#include <linux/cpumask.h>
120
121
/* XXX UGLY!!!! XXX  We have to access the direct structures of the workqueue which
122
  are only defined within workqueue.c because they don't give us a routine to allow us
123
  to nail a work to a particular thread of the CPU.  Nailing to threads gives us substantially
124
  higher scalability in multi-CPU environments though! */
125
126
/*
127
 * The per-CPU workqueue (if single thread, we always use cpu 0's).
128
 *
129
 * The sequence counters are for flush_scheduled_work().  It wants to wait
130
 * until until all currently-scheduled works are completed, but it doesn't
131
 * want to be livelocked by new, incoming ones.  So it waits until
132
 * remove_sequence is >= the insert_sequence which pertained when
133
 * flush_scheduled_work() was called.
134
 */
135
136
struct cpu_workqueue_struct {
137
138
	spinlock_t lock;
139
140
	long remove_sequence;	/* Least-recently added (next to run) */
141
	long insert_sequence;	/* Next to add */
142
143
	struct list_head worklist;
144
	wait_queue_head_t more_work;
145
	wait_queue_head_t work_done;
146
147
	struct workqueue_struct *wq;
148
	task_t *thread;
149
150
	int run_depth;		/* Detect run_workqueue() recursion depth */
151
} ____cacheline_aligned;
152
153
/*
154
 * The externally visible workqueue abstraction is an array of
155
 * per-CPU workqueues:
156
 */
157
struct workqueue_struct {
158
	struct cpu_workqueue_struct cpu_wq[NR_CPUS];
159
	const char *name;
160
	struct list_head list; 	/* Empty if single thread */
161
};
162
163
/* Preempt must be disabled. */
164
static void __ap4_queue_work(struct cpu_workqueue_struct *cwq,
165
			 struct work_struct *work)
166
{
167
	unsigned long flags;
168
169
	spin_lock_irqsave(&cwq->lock, flags);
170
	work->wq_data = cwq;
171
	list_add_tail(&work->entry, &cwq->worklist);
172
	cwq->insert_sequence++;
173
	wake_up(&cwq->more_work);
174
	spin_unlock_irqrestore(&cwq->lock, flags);
175
}
176
177
/*
178
 * Queue work on a workqueue. Return non-zero if it was successfully
179
 * added.
180
 *
181
 * We queue the work to the CPU it was submitted, but there is no
182
 * guarantee that it will be processed by that CPU.
183
 */
184
static inline int ap4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu)
185
{
186
	int ret = 0;
187
188
	if (!test_and_set_bit(0, &work->pending)) {
189
		BUG_ON(!list_empty(&work->entry));
190
		__ap4_queue_work(wq->cpu_wq + cpu, work);
191
		ret = 1;
192
	}
193
	return ret;
194
}
195
196
#endif
197
198
static int debug=0;
199
static int timingcable;
200
static int highestorder;
201
static int t1e1override = -1;
202
static int j1mode = 0;
203
static int loopback = 0;
204
static int alarmdebounce = 0;
205
206
/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
207
   can also cause PCI bus starvation, especially in combination with other
208
   aggressive cards.  Please note that burst mode has no effect on CPU
209
   utilization / max number of calls / etc. */
210
static int noburst = 1;
211
static int debugslips = 0;
212
static int polling = 0;
213
214
#ifdef FANCY_ALARM
215
static int altab[] = {
216
0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0,
217
};
218
#endif
219
220
#define FLAG_STARTED (1 << 0)
221
#define FLAG_NMF (1 << 1)
222
#define FLAG_SENDINGYELLOW (1 << 2)
223
224
#define	TYPE_T1	1		/* is a T1 card */
225
#define	TYPE_E1	2		/* is an E1 card */
226
#define TYPE_J1 3		/* is a running J1 */
227
228
struct devtype {
229
	char *desc;
230
	unsigned int flags;
231
};
232
233
static struct devtype ap401  = { "Aligera AP401", 0 };
234
static struct devtype ap402  = { "Aligera AP402", 0 };
235
static struct devtype ap404  = { "Aligera AP404", 0 };
236
static struct devtype ape401  = { "Aligera APE401", 0 };
237
static struct devtype ape402  = { "Aligera APE402", 0 };
238
static struct devtype ape404  = { "Aligera APE404", 0 };
239
240
struct ap4;
241
242
struct ap4_span {
243
	struct ap4 *owner;
244
	unsigned int *writechunk;					/* Double-word aligned write memory */
245
	unsigned int *readchunk;					/* Double-word aligned read memory */
246
	int spantype;		/* card type, T1 or E1 or J1 */
247
	int sync;
248
	int psync;
249
	int alarmtimer;
250
	int redalarms;
251
	int notclear;
252
	int alarmcount;
253
	int spanflags;
254
	int syncpos;
255
	int e1check;			/* E1 check */
256
	int reload_cas;
257
	unsigned char casbuf[15];
258
	unsigned int slipcount;
259
	struct dahdi_span span;
260
	unsigned char txsigs[16];	/* Transmit sigs */
261
	int loopupcnt;
262
	int loopdowncnt;
263
	unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
264
	unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
265
	int irqmisses;
266
#ifdef ENABLE_WORKQUEUES
267
	struct work_struct swork;
268
#endif
269
	struct dahdi_chan *chans[32];		/* Individual channels */
270
};
271
272
struct ap4_regs {
273
	volatile u32 card_id;		// 00h R0
274
	volatile u16 fpga_ver;		// 04h R1
275
	volatile u16 span_num;		// 06h R1
276
	u32 __unused;			// 08h R2
277
	volatile u32 liu_config;	// 0Ch R3
278
	volatile u32 e1_config;		// 10h R4
279
	volatile u32 e1_status;		// 14h R5
280
	volatile u32 leds;		// 18h R6
281
	volatile u32 clock_source;	// 1Ch R7
282
	u32 __unused3[8];		// 20h - 3Ch R8 - R15
283
	volatile u32 echo_ctrl;		// 40h R16
284
	volatile u32 echo_data;		// 44h R17
285
	volatile u32 t1_status;		// 48h R18
286
	volatile u32 t1_config;		// 4Ch R19
287
};
288
289
struct ap4 {
290
	/* This structure exists one per card */
291
	struct pci_dev *dev;		/* Pointer to PCI device */
292
	struct dahdi_device *ddev;
293
	struct ap4_regs *hw_regs;
294
	unsigned int intcount;
295
	int flag_1st_irq;
296
	int num;			/* Which card we are */
297
	int fpgaver;		/* version of FPGA */
298
	int hwid;			/* hardware ID */
299
	int globalconfig;	/* Whether global setup has been done */
300
	int syncsrc;			/* active sync source */
301
	struct ap4_span *tspans[4];	/* Individual spans */
302
	int numspans;			/* Number of spans on the card */
303
	int blinktimer[4];
304
#ifdef FANCY_ALARM
305
	int alarmpos[4];
306
#endif
307
	int irq;			/* IRQ used by device */
308
	int order;			/* Order */
309
	int flags;			/* Device flags */
310
	int ledreg;				/* LED Register */
311
	int e1recover;			/* E1 recovery timer */
312
	unsigned long memaddr;		/* Base address of card */
313
	unsigned long memlen;
314
	volatile unsigned int *membase;	/* Base address of card */
315
	int spansstarted;		/* number of spans started */
316
	/* spinlock_t lock; */		/* lock context */
317
	spinlock_t reglock;		/* lock register access */
318
	volatile unsigned int *writechunk;	/* Double-word aligned write memory */
319
	volatile unsigned int *readchunk;	/* Double-word aligned read memory */
320
#ifdef ENABLE_WORKQUEUES
321
	atomic_t worklist;
322
	struct workqueue_struct *workq;
323
#else
324
#ifdef ENABLE_TASKLETS
325
	int taskletrun;
326
	int taskletsched;
327
	int taskletpending;
328
	int taskletexec;
329
	int txerrors;
330
	struct tasklet_struct ap4_tlet;
331
#endif
332
#endif
333
	unsigned int passno;	/* number of interrupt passes */
334
	struct devtype *dt;
335
	char *variety;
336
	int last0;		/* for detecting double-missed IRQ */
337
	int checktiming;	/* Set >0 to cause the timing source to be checked */
338
#ifdef AP400_HDLC
339
	struct card_s *hdlc_card;
340
#endif
341
#ifdef APEC_SUPPORT
342
	int apec_enable;
343
	struct apec_s *apec;
344
#endif
345
};
346
347
348
static void __set_clear(struct ap4 *wc, int span);
349
static int ap4_startup(struct file *file, struct dahdi_span *span);
350
static int ap4_shutdown(struct dahdi_span *span);
351
static int ap4_rbsbits(struct dahdi_chan *chan, int bits);
352
static int ap4_maint(struct dahdi_span *span, int cmd);
353
static int ap4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
354
static void __ap4_set_timing_source(struct ap4 *wc, int unit);
355
static void __ap4_check_alarms(struct ap4 *wc, int span);
356
static void __ap4_check_sigbits(struct ap4 *wc, int span);
357
358
359
#define AP_ACTIVATE	(1 << 12)
360
361
#define AP_OFF	(0)
362
#define AP_ON	(1)
363
364
#define MAX_AP4_CARDS 64
365
366
#ifdef ENABLE_TASKLETS
367
static void ap4_tasklet(unsigned long data);
368
#endif
369
370
static struct ap4 *cards[MAX_AP4_CARDS];
371
372
//#define ap_debugk(fmt,args...) printk("ap400 -> %s: "fmt, __PRETTY_FUNCTION__, ##args)
373
#define ap_debugk(fmt,args...)
374
375
//#define TIMER_DEBUG	1
376
377
#ifdef TIMER_DEBUG
378
struct timer_list ap4xx_opt_timer;
379
unsigned int delay = 1000;
380
module_param(delay, uint, S_IRUGO);
381
#endif
382
383
#define PCI_DEVICE_ID_AP4XX		0x1004
384
385
static inline void __ap4_set_led(struct ap4 *wc, int span, int color)
386
{
387
	wc->ledreg &= ~(AP_ON << span);
388
	wc->ledreg |= (color << span);
389
	*(wc->membase+AP_LEDS_REG) &= ~0x0000000F;
390
	*(wc->membase+AP_LEDS_REG) |= ((wc->ledreg)&0x0F);
391
}
392
393
static inline void ap4_activate(struct ap4 *wc)
394
{
395
	wc->ledreg |= AP_ACTIVATE;
396
}
397
398
static void __set_clear(struct ap4 *wc, int span)
399
{
400
	int i,j;
401
	int oldnotclear;
402
	unsigned short val=0;
403
	struct ap4_span *ts = wc->tspans[span];
404
405
	oldnotclear = ts->notclear;
406
	if (ts->spantype == TYPE_T1) {
407
		for (i=0;i<24;i++) {
408
			j = (i/8);
409
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
410
				val |= 1 << (7 - (i % 8));
411
				ts->notclear &= ~(1 << i);
412
			} else
413
				ts->notclear |= (1 << i);
414
			if ((i % 8)==7) {
415
				val = 0;
416
			}
417
		}
418
	} else {
419
		for (i=0;i<31;i++) {
420
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
421
				ts->notclear &= ~(1 << i);
422
			else
423
				ts->notclear |= (1 << i);
424
		}
425
	}
426
}
427
428
#ifdef APEC_SUPPORT
429
430
#define APEC_CTRL_RESET		0x80000000
431
#define APEC_CTRL_DDR_NCKE	0x40000000
432
#define APEC_CTRL_EC_DISABLE	0x20000000
433
#define APEC_CTRL_DAS		0x00080000
434
#define APEC_CTRL_RD		0x00040000
435
#define APEC_CTRL_REQ		0x00020000
436
#define APEC_CTRL_READY		0x00010000
437
438
#define APEC_ACCESS_TIMEOUT	1000
439
440
static inline u16 oct_raw_read (struct ap4_regs *regs, unsigned short addr)
441
{
442
	unsigned short data;
443
	// Poll ready bit
444
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
445
	// Write control bits and address
446
	regs->echo_ctrl = APEC_CTRL_RD | APEC_CTRL_REQ | (addr & 0xFFFF);
447
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
448
	data = regs->echo_data & 0xFFFF;
449
	//PDEBUG("Raw Read 0x%04hX @ 0x%08X", data, addr);
450
	return data;
451
}
452
453
static inline void oct_raw_write (struct ap4_regs *regs, unsigned short addr,
454
							unsigned short data)
455
{
456
	// Poll ready bit
457
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
458
	// Write data, then control bits and address
459
	regs->echo_data = data & 0xFFFF;
460
	regs->echo_ctrl = APEC_CTRL_REQ | (addr & 0xFFFF);
461
	// Poll ready bit
462
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
463
	//PDEBUG("Raw Write 0x%04hX @ 0x%08X", data, addr);
464
	//oct_raw_read(regs, addr);
465
}
466
467
static inline int oct_ext_wait (struct ap4_regs *regs)
468
{
469
	int i = APEC_ACCESS_TIMEOUT;
470
	while ((oct_raw_read(regs, 0x0) & 0x100) && (i-- > 0));
471
	if (i == -1) {
472
		printk(KERN_WARNING "Wait access_req timeout\n");
473
		return -1;
474
	}
475
	return 0;
476
}
477
478
static inline u16 oct_ind_read (struct ap4_regs *regs, unsigned int addr)
479
{
480
	// Poll access_req bit
481
	if (oct_ext_wait(regs))
482
		return 0;
483
	// Write extended indirect registers
484
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
485
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
486
	oct_raw_write(regs, 0x0, ((addr & 0xE) << 8) | 0x101);
487
	// Poll access_req bit
488
	if (oct_ext_wait(regs))
489
		return 0;
490
	// Return data
491
	return oct_raw_read(regs, 0x4);
492
}
493
494
static inline void oct_ind_write (struct ap4_regs *regs, unsigned int addr,
495
							unsigned short data)
496
{
497
	// Poll access_req bit
498
	if (oct_ext_wait(regs))
499
		return;
500
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
501
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
502
	oct_raw_write(regs, 0x4, data);
503
	oct_raw_write(regs, 0x0, ((addr & 0xE) << 8) | 0x3101);
504
	// Poll access_req bit
505
	if (oct_ext_wait(regs))
506
		return;
507
}
508
509
static inline u16 oct_dir_read (struct ap4_regs *regs, unsigned int addr)
510
{
511
	// Poll access_req bit
512
	if (oct_ext_wait(regs))
513
		return 0;
514
	// Write extended direct registers
515
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
516
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
517
	oct_raw_write(regs, 0x0, 0x1);
518
	regs->echo_ctrl = APEC_CTRL_DAS | APEC_CTRL_RD | APEC_CTRL_REQ | (addr & 0xFFFF);
519
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
520
	// Return data
521
	return regs->echo_data;
522
}
523
524
static inline void oct_dir_write (struct ap4_regs *regs, unsigned int addr,
525
							unsigned short data)
526
{
527
	// Poll access_req bit
528
	if (oct_ext_wait(regs))
529
		return;
530
	// Write extended direct registers
531
	oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
532
	oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
533
	oct_raw_write(regs, 0x0, 0x3001);
534
	regs->echo_data = data & 0xFFFF;
535
	regs->echo_ctrl = APEC_CTRL_DAS | APEC_CTRL_REQ | (addr & 0xFFFF);
536
	while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
537
}
538
539
540
unsigned int oct_read (void *card, unsigned int addr)
541
{
542
	struct ap4 *wc = card;
543
	int flags;
544
	unsigned short data;
545
	spin_lock_irqsave(&wc->reglock, flags);
546
	data = oct_ind_read(wc->hw_regs, addr);
547
	spin_unlock_irqrestore(&wc->reglock, flags);
548
	PDEBUG("Read 0x%04hX @ 0x%08X", data, addr);
549
	return data;
550
}
551
552
void oct_write (void *card, unsigned int addr, unsigned int data)
553
{
554
	struct ap4 *wc = card;
555
	int flags;
556
	spin_lock_irqsave(&wc->reglock, flags);
557
	oct_ind_write(wc->hw_regs, addr, data);
558
	spin_unlock_irqrestore(&wc->reglock, flags);
559
	PDEBUG("Write 0x%04hX @ 0x%08X", data, addr);
560
}
561
562
static int ap4_apec_init(struct ap4 *wc)
563
{
564
	int laws[4];
565
	int i;
566
	unsigned int apec_capacity;
567
	struct firmware embedded_firmware;
568
	const struct firmware *firmware = &embedded_firmware;
569
#if !defined(HOTPLUG_FIRMWARE)
570
	extern void _binary_OCT6104E_64D_ima_size;
571
	extern u8 _binary_OCT6104E_64D_ima_start[];
572
	extern void _binary_OCT6104E_128D_ima_size;
573
	extern u8 _binary_OCT6104E_128D_ima_start[];
574
#else
575
	static const char oct64_firmware[] = "OCT6104E-64D.ima";
576
	static const char oct128_firmware[] = "OCT6104E-128D.ima";
577
#endif
578
579
	// Enable DDR and Reset Octasic
580
	wc->hw_regs->echo_ctrl |= APEC_CTRL_RESET;
581
	wc->hw_regs->echo_ctrl |= APEC_CTRL_DDR_NCKE;
582
	udelay(500);
583
	wc->hw_regs->echo_ctrl &= APEC_CTRL_RESET;
584
	wc->hw_regs->echo_ctrl &= APEC_CTRL_DDR_NCKE;
585
	wc->hw_regs->echo_ctrl &= APEC_CTRL_EC_DISABLE;
586
587
	/* Setup alaw vs ulaw rules */
588
	for (i = 0; i < wc->numspans; i++) {
589
		if (wc->tspans[i]->span.channels > 24)
590
			laws[i] = 1;	// E1: alaw
591
		else
592
			laws[i] = 0;	// T1: ulaw
593
	}
594
595
	switch ((apec_capacity = apec_capacity_get(wc))) {
596
	case 64:
597
#if defined(HOTPLUG_FIRMWARE)
598
		if ((request_firmware(&firmware, oct64_firmware, &wc->dev->dev) != 0) ||
599
		    !firmware) {
600
			printk("%s: firmware %s not available from userspace\n",
601
					wc->variety, oct64_firmware);
602
			return -1;
603
		}
604
#else
605
		embedded_firmware.data = _binary_OCT6104E_64D_ima_start;
606
		/* Yes... this is weird. objcopy gives us a symbol containing
607
		   the size of the firmware, not a pointer to a variable containing
608
		   the size. The only way we can get the value of the symbol
609
		   is to take its address, so we define it as a pointer and
610
		   then cast that value to the proper type.
611
		*/
612
		embedded_firmware.size = (size_t) &_binary_OCT6104E_64D_ima_size;
613
#endif
614
		break;
615
	case 128:
616
#if defined(HOTPLUG_FIRMWARE)
617
		if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
618
		    !firmware) {
619
			printk("%s: firmware %s not available from userspace\n",
620
					wc->variety, oct128_firmware);
621
			return -1;
622
		}
623
#else
624
		embedded_firmware.data = _binary_OCT6104E_128D_ima_start;
625
		/* Yes... this is weird. objcopy gives us a symbol containing
626
		   the size of the firmware, not a pointer to a variable containing
627
		   the size. The only way we can get the value of the symbol
628
		   is to take its address, so we define it as a pointer and
629
		   then cast that value to the proper type.
630
		*/
631
		embedded_firmware.size = (size_t) &_binary_OCT6104E_128D_ima_size;
632
#endif
633
		break;
634
	default:
635
		printk(KERN_INFO "Unsupported channel capacity found on"
636
				"echo cancellation module (%d).\n", apec_capacity);
637
		return -1;
638
	}
639
640
	if (!(wc->apec = apec_init(wc, laws, wc->numspans, firmware))) {
641
		printk(KERN_WARNING "APEC: Failed to initialize\n");
642
		if (firmware != &embedded_firmware)
643
			release_firmware(firmware);
644
		return -1;
645
	}
646
647
	if (firmware != &embedded_firmware)
648
		release_firmware(firmware);
649
650
	printk(KERN_INFO "APEC: Present and operational servicing %d span(s)\n", wc->numspans);
651
	return 0;
652
}
653
654
void ap4_apec_release(struct ap4 *wc)
655
{
656
	// Disabel DDR and reset Octasic
657
	wc->hw_regs->echo_ctrl |= APEC_CTRL_RESET;
658
	wc->hw_regs->echo_ctrl |= APEC_CTRL_DDR_NCKE;
659
	wc->hw_regs->echo_ctrl |= APEC_CTRL_EC_DISABLE;
660
	if (wc->apec)
661
		apec_release(wc->apec);
662
}
663
664
665
static int ap4_echocan(struct dahdi_chan *chan, int eclen)
666
{
667
	struct ap4 *wc = chan->pvt;
668
	int channel;
669
670
	if (!wc->apec)
671
		return -ENODEV;
672
	if (debug)
673
		printk(KERN_DEBUG "AP400: ap4_echocan @ Span %d Channel %d Length: %d\n",
674
				chan->span->offset, chan->chanpos, eclen);
675
	channel = (chan->chanpos << 2) | chan->span->offset;
676
	apec_setec(wc->apec, channel, eclen);
677
	return 0;
678
}
679
680
#endif // APEC_SUPPORT
681
682
683
static int ap4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
684
{
685
	struct ap4 *wc = chan->pvt;
686
	int span = 0;
687
	int alarms = 0;
688
	unsigned char c, e1_cfg;
689
690
	switch(cmd) {
691
		case AP4_GET_ALARMS:
692
			if (copy_from_user(&span, (int *)data, sizeof(int)))
693
				return -EFAULT;
694
			// span starts in zero
695
			span--;
696
		if (wc->tspans[span]->spantype == TYPE_E1) {
697
		        /* le status e configuracao do E1 */
698
		        c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
699
		        e1_cfg = ((*(wc->membase+AP_E1_CONFIG_REG))>>(8*span));
700
			if( c & AP_E1_LOS_STATUS) {
701
				alarms = 0x01;
702
			} else if( c & AP_E1_AIS_STATUS) {
703
				alarms = 0x02;
704
			} else if(!(c & AP_E1_BFAE_STATUS)) {
705
				alarms = 0x04;
706
				if (c & AP_E1_RAI_STATUS)
707
					alarms |= 0x08;
708
				// Erro de MFA: 00 - MFA desabilitado, 01 - erro de MFA, 10 - MFA OK
709
				if ( (c & AP_E1_MFAE_STATUS) && (e1_cfg & AP_E1_CRCEN_CONFIG) )
710
					alarms |= 0x10;
711
				else if ( (!(c & AP_E1_MFAE_STATUS)) && (e1_cfg & AP_E1_CRCEN_CONFIG) )
712
					alarms |= 0x20;
713
				// Erro de CAS: 00 - desabilitado, 01 - erro de CAS, 10 - CAS OK
714
				if ( (!(c & AP_E1_CAS_STATUS)) && (e1_cfg & AP_E1_PCM30_CONFIG))
715
					alarms |= 0x40;
716
				else if ( (c & AP_E1_CAS_STATUS) && (e1_cfg & AP_E1_PCM30_CONFIG))
717
					alarms |= 0x80;
718
			}
719
		} else {
720
			/* le status e configuracao do E1 */
721
		        c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
722
		        if( c & AP_E1_LOS_STATUS)
723
				alarms = 0x01;
724
			else {
725
			        c = wc->hw_regs->t1_status >> (8*span);
726
			        if (!(c & AP4_T1_FRAME_SYNC))
727
			        	alarms = 0x04;
728
		        }
729
		}
730
			if(debug) printk("AP4_GET_ALARMS: span = %d, alarms = 0x%02x\n", span+1, alarms);
731
			if (copy_to_user((int *)data, &alarms, sizeof(int)))
732
				return -EFAULT;
733
			break;
734
735
		case AP4_GET_SLIPS:
736
			if (copy_from_user(&span, (int *)data, sizeof(int)))
737
				return -EFAULT;
738
			// span starts in zero
739
			span--;
740
			if((span < wc->numspans) && (span >=0))
741
				alarms = wc->tspans[span]->slipcount;
742
			if(debug) printk("AP4_GET_SLIPS: span = %d, slips = 0x%02x\n", span+1, alarms);
743
			if (copy_to_user((int *)data, &alarms, sizeof(int)))
744
				return -EFAULT;
745
			break;
746
747
		default:
748
			PDEBUG("%s: Unknown IOCTL CODE!", wc->variety);
749
			return -ENOTTY;
750
	}
751
	return 0;
752
}
753
754
static inline struct ap4_span* ap4_span_from_span(struct dahdi_span *span) {
755
	return container_of(span, struct ap4_span, span);
756
}
757
758
static int ap4_maint(struct dahdi_span *span, int cmd)
759
{
760
	struct ap4_span *ts = ap4_span_from_span(span);
761
	struct ap4 *wc = ts->owner;
762
763
764
	if (ts->spantype == TYPE_E1) {
765
		switch(cmd) {
766
		case DAHDI_MAINT_NONE:
767
			printk("XXX Turn off local and remote loops E1 XXX\n");
768
			*(wc->membase+AP_E1_CONFIG_REG) &= ~(AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
769
			break;
770
		case DAHDI_MAINT_LOCALLOOP:
771
			printk("XXX Turn on local loopback E1 XXX\n");
772
			break;
773
		case DAHDI_MAINT_REMOTELOOP:
774
			printk("XXX Turn on remote loopback E1 XXX\n");
775
			break;
776
		case DAHDI_MAINT_LOOPUP:
777
			printk("XXX Turn on local loopback on E1 #%d instead of send loopup code XXX\n", span->spanno);
778
			*(wc->membase+AP_E1_CONFIG_REG) |= (AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
779
			break;
780
		case DAHDI_MAINT_LOOPDOWN:
781
			printk("XXX Turn on local loopback on E1 #%d instead of send loopdown code XXX\n", span->spanno);
782
			*(wc->membase+AP_E1_CONFIG_REG) |= (AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
783
			break;
784
		default:
785
			printk("%s: Unknown E1 maint command: %d\n", wc->variety, cmd);
786
			break;
787
		}
788
	} else {
789
		switch(cmd) {
790
	    case DAHDI_MAINT_NONE:
791
			printk("XXX Turn off local and remote loops T1 XXX\n");
792
			break;
793
	    case DAHDI_MAINT_LOCALLOOP:
794
			printk("XXX Turn on local loop and no remote loop XXX\n");
795
			break;
796
	    case DAHDI_MAINT_REMOTELOOP:
797
			printk("XXX Turn on remote loopup XXX\n");
798
			break;
799
	    case DAHDI_MAINT_LOOPUP:
800
			break;
801
	    case DAHDI_MAINT_LOOPDOWN:
802
			break;
803
	    default:
804
			printk("%s: Unknown T1 maint command: %d\n", wc->variety, cmd);
805
			break;
806
	   }
807
    }
808
	return 0;
809
}
810
811
static int ap4_rbsbits(struct dahdi_chan *chan, int bits)
812
{
813
	u_char m,c;
814
	int k,n,b;
815
	struct ap4 *wc = chan->pvt;
816
	struct ap4_span *ts = wc->tspans[chan->span->offset];
817
	unsigned long flags;
818
	volatile unsigned int *writecas = (wc->membase+AP_CAS_BASE);
819
	unsigned int allspansbits;
820
821
	//ap_debugk("chan->channo = %d, int bits = 0x%08x\n", chan->channo, bits);
822
	if(debug & DEBUG_RBS) printk("Setting bits to %d on channel %s\n", bits, chan->name);
823
	spin_lock_irqsave(&wc->reglock, flags);
824
	k = chan->span->offset;
825
	if (ts->spantype == TYPE_E1) { /* do it E1 way */
826
		if (chan->chanpos == 16) {
827
			spin_unlock_irqrestore(&wc->reglock, flags);
828
			return 0;
829
		}
830
		n = chan->chanpos - 1;
831
		if (chan->chanpos > 15) n--;
832
		b = (n % 15);
833
		c = ts->txsigs[b];
834
		m = (n / 15) << 2; /* nibble selector */
835
		c &= (0xf << m); /* keep the other nibble */
836
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
837
		ts->txsigs[b] = c;
838
		/* monta a word de 32 bits com informacao de todos os spans */
839
		allspansbits =  wc->tspans[0]->txsigs[b];
840
		if (wc->numspans > 1) {
841
			allspansbits |=	(wc->tspans[1]->txsigs[b] << 8);
842
		}
843
		if (wc->numspans == 4) {
844
			allspansbits |=	(wc->tspans[2]->txsigs[b] << 16) |
845
							(wc->tspans[3]->txsigs[b] << 24);
846
		}
847
		/* output them to the chip */
848
		writecas[b] = allspansbits;
849
		ap_debugk("escrito 0x%08x para ser transmitido pelo CAS (b = %d)\n", allspansbits, b);
850
#if 0
851
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
852
		n = chan->chanpos - 1;
853
		b = (n/4);
854
		c = ts->txsigs[b];
855
		m = ((3 - (n % 4)) << 1); /* nibble selector */
856
		c &= ~(0x3 << m); /* keep the other nibble */
857
		c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
858
		ts->txsigs[b] = c;
859
		  /* output them to the chip */
860
		//__ap4_out( ... );
861
	} else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
862
#endif
863
	} else {
864
		n = chan->chanpos - 1;
865
		b = (n/2);
866
		c = ts->txsigs[b];
867
		m = ((n % 2) << 2); /* nibble selector */
868
		c &= (0xf << m); /* keep the other nibble */
869
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
870
		ts->txsigs[b] = c;
871
		  /* output them to the chip */
872
		/* monta a word de 32 bits com informacao de todos os spans */
873
		allspansbits =  wc->tspans[0]->txsigs[b];
874
		if (wc->numspans > 1) {
875
			allspansbits |=	(wc->tspans[1]->txsigs[b] << 8);
876
		}
877
		if (wc->numspans == 4) {
878
			allspansbits |=	(wc->tspans[2]->txsigs[b] << 16) |
879
							(wc->tspans[3]->txsigs[b] << 24);
880
		}
881
		/* output them to the chip */
882
		writecas[b] = allspansbits;
883
		ap_debugk("escrito 0x%08x para ser transmitido pelo CAS (b = %d)\n", allspansbits, b);
884
	}
885
	spin_unlock_irqrestore(&wc->reglock, flags);
886
	if (debug & DEBUG_RBS)
887
		printk("Finished setting RBS bits\n");
888
	return 0;
889
}
890
891
static int ap4_shutdown(struct dahdi_span *span)
892
{
893
	int tspan;
894
	int wasrunning;
895
	unsigned long flags;
896
	struct ap4_span *ts = ap4_span_from_span(span);
897
	struct ap4 *wc = ts->owner;
898
899
	tspan = span->offset + 1;
900
	if (tspan < 0) {
901
		printk("%s: '%d' isn't us?\n", wc->variety, span->spanno);
902
		return -1;
903
	}
904
905
	spin_lock_irqsave(&wc->reglock, flags);
906
	wasrunning = span->flags & DAHDI_FLAG_RUNNING;
907
908
	span->flags &= ~DAHDI_FLAG_RUNNING;
909
	if (wasrunning)
910
		wc->spansstarted--;
911
	__ap4_set_led(wc, span->offset, AP_OFF);
912
	if (((wc->numspans == 4) &&
913
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)) &&
914
	    (!(wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)) &&
915
	    (!(wc->tspans[2]->span.flags & DAHDI_FLAG_RUNNING)) &&
916
	    (!(wc->tspans[3]->span.flags & DAHDI_FLAG_RUNNING)))
917
	    			||
918
	    ((wc->numspans == 2) &&
919
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)) &&
920
	    (!(wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)))
921
	    			||
922
	    ((wc->numspans == 1) &&
923
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)))) {
924
		/* No longer in use, disable interrupts */
925
		printk("%s: Disabling interrupts since there are no active spans\n",
926
				wc->variety);
927
	} else wc->checktiming = 1;
928
	spin_unlock_irqrestore(&wc->reglock, flags);
929
	if (debug & DEBUG_MAIN)
930
		printk("Span %d (%s) shutdown\n", span->spanno, span->name);
931
	return 0;
932
}
933
934
static int ap4_spanconfig(struct file *file, struct dahdi_span *span,
935
		struct dahdi_lineconfig *lc)
936
{
937
	int i;
938
	struct ap4_span *ts = ap4_span_from_span(span);
939
	struct ap4 *wc = ts->owner;
940
	unsigned int val;
941
942
	printk("About to enter spanconfig!\n");
943
	if (debug & DEBUG_MAIN)
944
		printk("%s: Configuring span %d\n", wc->variety, span->spanno);
945
	/* XXX We assume lineconfig is okay and shouldn't XXX */
946
	span->lineconfig = lc->lineconfig;
947
	span->txlevel = lc->lbo;
948
	span->rxlevel = 0;
949
	if (lc->sync < 0)
950
		lc->sync = 0;
951
	if (lc->sync > 4)
952
		lc->sync = 0;
953
954
	/* remove this span number from the current sync sources, if there */
955
	for(i = 0; i < wc->numspans; i++) {
956
		if (wc->tspans[i]->sync == span->spanno) {
957
			wc->tspans[i]->sync = 0;
958
			wc->tspans[i]->psync = 0;
959
		}
960
	}
961
	wc->tspans[span->offset]->syncpos = lc->sync;
962
	/* if a sync src, put it in proper place */
963
	if (lc->sync) {
964
		wc->tspans[lc->sync - 1]->sync = span->spanno;
965
		wc->tspans[lc->sync - 1]->psync = span->offset + 1;
966
	}
967
	wc->checktiming = 1;
968
	/* If we're already running, then go ahead and apply the changes */
969
	if (span->flags & DAHDI_FLAG_RUNNING)
970
		return ap4_startup(file, span);
971
972
	// Limpa contadores de slips, crc e bpv
973
	val = (*(wc->membase + AP_CNT_SLIP_REG));
974
	val = (*(wc->membase + AP_CNT_CRC_REG));
975
	val = (*(wc->membase + AP_CNT_CV_REG));
976
977
	ap_debugk("habilitando interrupcao!\n");
978
	// Nao considera as primeiras interrupcoes na soma das IRQs perdidas
979
	wc->flag_1st_irq = 16;
980
	// Enable interrupt
981
	*(wc->membase + AP_INT_CONTROL_REG) |= AP_INT_CTL_ENABLE;
982
	// Limpa interrupcao da FPGA para forcar borda de subida na proxima
983
	val = *(wc->membase + AP_CLEAR_IRQ_REG);
984
985
	printk("Done with spanconfig!\n");
986
	return 0;
987
}
988
989
static int ap4_chanconfig(struct file *file, struct dahdi_chan *chan,
990
		int sigtype)
991
{
992
	int alreadyrunning;
993
	unsigned long flags;
994
	struct ap4 *wc = chan->pvt;
995
996
	alreadyrunning = wc->tspans[chan->span->offset]->span.flags & DAHDI_FLAG_RUNNING;
997
	if (debug & DEBUG_MAIN) {
998
		if (alreadyrunning)
999
			printk("%s: Reconfigured channel %d (%s) sigtype %d\n",
1000
					wc->variety, chan->channo, chan->name, sigtype);
1001
		else
1002
			printk("%s: Configured channel %d (%s) sigtype %d\n",
1003
					wc->variety, chan->channo, chan->name, sigtype);
1004
	}
1005
	spin_lock_irqsave(&wc->reglock, flags);
1006
	if (alreadyrunning)
1007
		__set_clear(wc, chan->span->offset);
1008
	spin_unlock_irqrestore(&wc->reglock, flags);
1009
	return 0;
1010
}
1011
1012
static int ap4_open(struct dahdi_chan *chan)
1013
{
1014
	try_module_get(THIS_MODULE);
1015
	return 0;
1016
}
1017
1018
static int ap4_close(struct dahdi_chan *chan)
1019
{
1020
	module_put(THIS_MODULE);
1021
	return 0;
1022
}
1023
1024
static const struct dahdi_span_ops ap4_span_ops = {
1025
	.owner = THIS_MODULE,
1026
	.spanconfig = ap4_spanconfig,
1027
	.chanconfig = ap4_chanconfig,
1028
	.startup = ap4_startup,
1029
	.shutdown = ap4_shutdown,
1030
	.rbsbits = ap4_rbsbits,
1031
	.maint = ap4_maint,
1032
	.open = ap4_open,
1033
	.close  = ap4_close,
1034
#ifdef APEC_SUPPORT
1035
	.echocan = ap4_echocan,
1036
#endif
1037
	.ioctl = ap4_ioctl
1038
};
1039
1040
static void init_spans(struct ap4 *wc)
1041
{
1042
	int x,y;
1043
	struct ap4_span *ts;
1044
1045
	for (x=0;x<wc->numspans;x++) {
1046
		ts = wc->tspans[x];
1047
		sprintf(ts->span.name, "AP4%d%d/%d/%d", 0, wc->numspans, wc->num, x + 1);
1048
		snprintf(ts->span.desc, sizeof(ts->span.desc) - 1, "AP4%d%d Card %d Span %d", 0, wc->numspans, wc->num+1, x+1);
1049
		ts->span.ops = &ap4_span_ops;
1050
		if (ts->spantype == TYPE_E1) {
1051
			ts->span.channels = 31;
1052
			ts->span.spantype = SPANTYPE_DIGITAL_E1;
1053
			ts->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
1054
			ts->span.deflaw = DAHDI_LAW_ALAW;
1055
		} else {
1056
			ts->span.channels = 24;
1057
			ts->span.spantype = SPANTYPE_DIGITAL_T1;
1058
			ts->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
1059
			ts->span.deflaw = DAHDI_LAW_MULAW;
1060
		}
1061
		ts->span.chans = ts->chans;
1062
		ts->span.flags = DAHDI_FLAG_RBS;
1063
		ts->owner = wc;
1064
		ts->span.offset = x;
1065
		ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
1066
		ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
1067
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
1068
			struct dahdi_chan *mychans = ts->chans[y];
1069
			sprintf(mychans->name, "AP4%d%d/%d/%d/%d", 0, wc->numspans, wc->num, x + 1, y + 1);
1070
			mychans->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS |
1071
									 DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_EM_E1 | DAHDI_SIG_DACS_RBS;
1072
			mychans->pvt = wc;
1073
			mychans->chanpos = y + 1;
1074
		}
1075
	}
1076
	printk("%s: Spans initialized\n", wc->variety);
1077
}
1078
1079
1080
1081
static void __ap4_set_timing_source(struct ap4 *wc, int unit)
1082
{
1083
	unsigned int timing;
1084
	int x;
1085
1086
	if (unit != wc->syncsrc) {
1087
		if ((unit > -1) && (unit < 4)) {
1088
			/* define fonte de clock para interface escolhida */
1089
			timing = *(wc->membase+AP_CLKSRC_REG);
1090
			timing &= ~AP_CLKSRC_MASK;
1091
			timing |= unit+1;
1092
			*(wc->membase+AP_CLKSRC_REG) = timing;
1093
		} else {
1094
			/* define clock para interno */
1095
			timing = *(wc->membase+AP_CLKSRC_REG);
1096
			timing &= ~AP_CLKSRC_MASK;
1097
			*(wc->membase+AP_CLKSRC_REG) = timing;
1098
		}
1099
		wc->syncsrc = unit;
1100
		if ((unit < 0) || (unit > 3))
1101
			unit = 0;
1102
		else
1103
			unit++;
1104
		for (x=0;x<wc->numspans;x++)
1105
			wc->tspans[x]->span.syncsrc = unit;
1106
	} else {
1107
		if (debug & DEBUG_MAIN)
1108
			printk("%s: Timing source already set to %d\n",
1109
					wc->variety, unit);
1110
	}
1111
	printk("%s: Timing source set to %d (clksrc_reg = 0x%08x)\n",
1112
			wc->variety, unit, *(wc->membase+AP_CLKSRC_REG));
1113
}
1114
1115
static void __ap4_set_timing_source_auto(struct ap4 *wc)
1116
{
1117
	int x;
1118
1119
	wc->checktiming = 0;
1120
	for (x=0;x<wc->numspans;x++) {
1121
		if (wc->tspans[x]->sync) {
1122
			if ((wc->tspans[wc->tspans[x]->psync - 1]->span.flags & DAHDI_FLAG_RUNNING) &&
1123
				!(wc->tspans[wc->tspans[x]->psync - 1]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE) )) {
1124
					/* Valid timing source */
1125
					__ap4_set_timing_source(wc, wc->tspans[x]->psync - 1);
1126
					return;
1127
			}
1128
		}
1129
	}
1130
	__ap4_set_timing_source(wc, 4);
1131
}
1132
1133
static void __ap4_configure_t1(struct ap4 *wc, int unit, int lineconfig, int txlevel)
1134
{
1135
	char *framing, *line;
1136
	unsigned int config = 0;
1137
	unsigned int param = 0;
1138
	unsigned int linecode = 0;
1139
1140
	wc->tspans[unit]->spantype = TYPE_T1;
1141
	wc->tspans[unit]->span.channels = 24;
1142
	wc->tspans[unit]->span.deflaw = DAHDI_LAW_MULAW;
1143
1144
	/* Configure line code */
1145
	if (unit < 2)
1146
		linecode = AP_LIU1_LINECODE;
1147
	else
1148
		linecode = AP_LIU2_LINECODE;
1149
	if (lineconfig & DAHDI_CONFIG_AMI) {
1150
		*(wc->membase+AP_LEDS_REG) |= linecode;
1151
		line = "AMI";
1152
	} else {
1153
		*(wc->membase+AP_LEDS_REG) &= ~linecode;
1154
		line = "B8ZS";
1155
	}
1156
1157
	/* loopback test*/
1158
	//wc->hw_regs->e1_config |= (AP_E1_LOOP_CONFIG  << (8 * unit));
1159
	//printk("E1 config = 0x%08x\n", wc->hw_regs->e1_config);
1160
1161
	/* Configure T1 */
1162
	config = wc->hw_regs->liu_config;
1163
	config &= ~(0x000000ff << (8 * unit));
1164
	config |= (AP_PULS_DSX1_0FT << (8 * unit));
1165
	wc->hw_regs->liu_config = config;
1166
1167
	param = AP4_T1_NE1_SEL | AP4_T1_CAS_ENABLE;
1168
	if (lineconfig & DAHDI_CONFIG_D4) {
1169
		framing = "D4";
1170
	} else {
1171
		framing = "ESF";
1172
		param |= AP4_T1_ESF_NSF;
1173
	}
1174
	config = wc->hw_regs->t1_config;
1175
	config &= ~(0x000000ff << (8 * unit));
1176
	config |= (param << (8 * unit));
1177
	wc->hw_regs->t1_config = config;
1178
1179
	printk("T1 Status: 0x%08x\tT1 Config: 0x%08x\tPARAM: 0x%08x\n",
1180
			wc->hw_regs->t1_status, wc->hw_regs->t1_config, param);
1181
1182
	if (!polling) {
1183
		__ap4_check_alarms(wc, unit);
1184
		__ap4_check_sigbits(wc, unit);
1185
	}
1186
	printk("%s: Span %d configured for %s/%s\n", wc->variety, unit + 1, framing, line);
1187
}
1188
1189
static void __ap4_configure_e1(struct ap4 *wc, int unit, int lineconfig)
1190
{
1191
	char *crc4 = "";
1192
	char *framing, *line;
1193
	unsigned int e1s_cfg, config = 0;
1194
	unsigned int linecode = 0;
1195
1196
	wc->tspans[unit]->spantype = TYPE_E1;
1197
	wc->tspans[unit]->span.channels = 31;
1198
	wc->tspans[unit]->span.deflaw = DAHDI_LAW_ALAW;
1199
1200
	if (loopback) {
1201
	}
1202
1203
	if (lineconfig & DAHDI_CONFIG_CRC4) {
1204
		crc4 = "/CRC4";
1205
		config |= AP_E1_CRCEN_CONFIG;
1206
	}
1207
1208
	if(unit < 2)
1209
		linecode = AP_LIU1_LINECODE;
1210
	else
1211
		linecode = AP_LIU2_LINECODE;
1212
	/* Configure line interface */
1213
	if (lineconfig & DAHDI_CONFIG_AMI) {
1214
		*(wc->membase+AP_LEDS_REG) |= linecode;
1215
		line = "AMI";
1216
	} else {
1217
		*(wc->membase+AP_LEDS_REG) &= ~linecode;
1218
		line = "HDB3";
1219
	}
1220
1221
	if (lineconfig & DAHDI_CONFIG_CCS) {
1222
		framing = "CCS";
1223
	} else {
1224
		framing = "CAS";
1225
		config |= (AP_E1_CASEN_CONFIG | AP_E1_PCM30_CONFIG);
1226
	}
1227
1228
	e1s_cfg = *(wc->membase+AP_E1_CONFIG_REG);
1229
	e1s_cfg &= ~(0x000000ff<<(8*unit));
1230
	e1s_cfg |= (config<<(8*unit));
1231
	*(wc->membase+AP_E1_CONFIG_REG) = e1s_cfg;
1232
1233
	/* Disable T1 framer */
1234
	config = wc->hw_regs->t1_config;
1235
	config &= ~(0x000000ff << (8 * unit));
1236
	wc->hw_regs->t1_config = config;
1237
1238
	/* Configure LIU Signalling */
1239
	e1s_cfg = *(wc->membase+AP_T1E1_CONFIG_REG);
1240
	e1s_cfg &= ~(0x000000ff<<(8*unit));
1241
	e1s_cfg |= (AP_PULS_E1_120<<(8*unit));
1242
	*(wc->membase+AP_T1E1_CONFIG_REG) = e1s_cfg;
1243
1244
	if (!polling) {
1245
		__ap4_check_alarms(wc, unit);
1246
		__ap4_check_sigbits(wc, unit);
1247
	}
1248
	printk("%s: Span %d configured for %s/%s%s\n",
1249
 			wc->variety, unit + 1, framing, line, crc4);
1250
}
1251
1252
static int ap4_startup(struct file *file, struct dahdi_span *span)
1253
{
1254
	int i;
1255
	int tspan;
1256
	unsigned long flags;
1257
	int alreadyrunning;
1258
	struct ap4_span *ts = ap4_span_from_span(span);
1259
	struct ap4 *wc = ts->owner;
1260
1261
	printk("About to enter startup!\n");
1262
	tspan = span->offset + 1;
1263
	if (tspan < 0) {
1264
		printk("%s: Span '%d' isn't us?\n", wc->variety, span->spanno);
1265
		return -1;
1266
	}
1267
1268
	spin_lock_irqsave(&wc->reglock, flags);
1269
1270
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
1271
1272
	/* initialize the start value for the entire chunk of last ec buffer */
1273
	for(i = 0; i < span->channels; i++)
1274
	{
1275
		memset(ts->ec_chunk1[i],
1276
			DAHDI_LIN2X(0, span->chans[i]),DAHDI_CHUNKSIZE);
1277
		memset(ts->ec_chunk2[i],
1278
			DAHDI_LIN2X(0, span->chans[i]),DAHDI_CHUNKSIZE);
1279
	}
1280
1281
	/* Force re-evaluation fo timing source */
1282
//	if (timingcable)
1283
		wc->syncsrc = -1;
1284
1285
	if ((span->lineconfig & DAHDI_CONFIG_D4) || (span->lineconfig & DAHDI_CONFIG_ESF)) {
1286
		/* is a T1 card */
1287
		__ap4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
1288
	} else { /* is a E1 card */
1289
		__ap4_configure_e1(wc, span->offset, span->lineconfig);
1290
	}
1291
1292
	/* Note clear channel status */
1293
	wc->tspans[span->offset]->notclear = 0;
1294
	__set_clear(wc, span->offset);
1295
1296
	if (!alreadyrunning) {
1297
		span->flags |= DAHDI_FLAG_RUNNING;
1298
		wc->spansstarted++;
1299
		/* enable interrupts */
1300
1301
		if (!polling) {
1302
			__ap4_check_alarms(wc, span->offset);
1303
			__ap4_check_sigbits(wc, span->offset);
1304
		}
1305
	}
1306
	spin_unlock_irqrestore(&wc->reglock, flags);
1307
1308
	if (wc->tspans[0]->sync == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno);
1309
	if (wc->numspans > 1) {
1310
		if (wc->tspans[1]->sync == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
1311
	}
1312
	if (wc->numspans == 4) {
1313
		if (wc->tspans[2]->sync == span->spanno) printk("SPAN %d: Tertiary Sync Source\n",span->spanno);
1314
		if (wc->tspans[3]->sync == span->spanno) printk("SPAN %d: Quaternary Sync Source\n",span->spanno);
1315
	}
1316
1317
#ifdef APEC_SUPPORT
1318
	if (!apec_enable || !wc->apec_enable)
1319
		wc->hw_regs->echo_ctrl = 0xe0000000;
1320
	else if (!alreadyrunning && !wc->apec)
1321
			if (ap4_apec_init(wc))
1322
				ap4_apec_release(wc);
1323
#else
1324
	wc->hw_regs->echo_ctrl = 0xe0000000;
1325
#endif
1326
1327
	printk("Completed startup!\n");
1328
	return 0;
1329
}
1330
1331
1332
static void ap4_receiveprep(struct ap4 *wc)
1333
{
1334
	volatile unsigned int *readchunk;
1335
	unsigned int buffer[32];
1336
	unsigned char *byte = (unsigned char *) buffer;
1337
	int i, j, k;
1338
1339
	readchunk = (wc->membase + (AP_DATA_BASE));
1340
	for (i = 0; i < DAHDI_CHUNKSIZE; i++) {
1341
		/* Prefetch Card data */
1342
		for (j = 0; j < 32; ++j) {
1343
			buffer[j] = readchunk[j];
1344
		}
1345
		for (j = 0; j < wc->numspans; j++) {
1346
			/* Set first timeslot for first channel */
1347
			if (wc->tspans[j]->spantype == TYPE_E1) {
1348
				for (k = 0; k < 31; ++k) {
1349
					/* Skip first timeslot from E1 */
1350
					wc->tspans[j]->span.chans[k]->readchunk[i] =
1351
							byte[4*(k+1)+j];
1352
				}
1353
			}
1354
			else {
1355
				for (k = 0; k < 24; ++k) {
1356
					wc->tspans[j]->span.chans[k]->readchunk[i] =
1357
							byte[4*k+j];
1358
				}
1359
			}
1360
		}
1361
		readchunk += 32;
1362
	}
1363
1364
	for (i = 0; i < wc->numspans; i++) {
1365
		if (wc->tspans[i]->span.flags & DAHDI_FLAG_RUNNING) {
1366
			for (j = 0; j < wc->tspans[i]->span.channels; j++) {
1367
				/* Echo cancel double buffered data */
1368
				dahdi_ec_chunk(wc->tspans[i]->span.chans[j],
1369
				    wc->tspans[i]->span.chans[j]->readchunk,
1370
					wc->tspans[i]->ec_chunk2[j]);
1371
				memcpy(wc->tspans[i]->ec_chunk2[j],wc->tspans[i]->ec_chunk1[j],
1372
					DAHDI_CHUNKSIZE);
1373
				memcpy(wc->tspans[i]->ec_chunk1[j],
1374
					wc->tspans[i]->span.chans[j]->writechunk,
1375
						DAHDI_CHUNKSIZE);
1376
			}
1377
			dahdi_receive(&wc->tspans[i]->span);
1378
		}
1379
	}
1380
}
1381
1382
#if (DAHDI_CHUNKSIZE != 8)
1383
#error Sorry, AP400 driver does not support chunksize != 8
1384
#endif
1385
1386
#ifdef ENABLE_WORKQUEUES
1387
static void workq_handlespan(void *data)
1388
{
1389
	struct ap4_span *ts = data;
1390
	struct ap4 *wc = ts->owner;
1391
1392
//	__receive_span(ts);
1393
//	__transmit_span(ts);
1394
	atomic_dec(&wc->worklist);
1395
	atomic_read(&wc->worklist);
1396
1397
}
1398
#endif
1399
1400
static void ap4_transmitprep(struct ap4 *wc)
1401
{
1402
	volatile unsigned int *writechunk;
1403
	int x,y,z;
1404
	unsigned int tmp;
1405
1406
	for (y=0;y<wc->numspans;y++) {
1407
		if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING)
1408
			dahdi_transmit(&wc->tspans[y]->span);
1409
	}
1410
1411
	writechunk = (wc->membase+(AP_DATA_BASE));
1412
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
1413
		// Once per chunk
1414
		for (z=0;z<32;z++) {
1415
			// All channels
1416
			tmp = 0;
1417
			for (y = 0; y < wc->numspans; ++y) {
1418
				if (wc->tspans[y]->spantype == TYPE_T1 && z < 24)
1419
					tmp |= (wc->tspans[y]->span.chans[z]->writechunk[x]
1420
					                           << (8*y));
1421
				else /* Span Type is E1 */
1422
					if (z > 0) /* Skip first timeslot */
1423
						tmp |= (wc->tspans[y]->span.chans[z-1]->writechunk[x]
1424
									<< (8*y));
1425
			}
1426
			writechunk[z] = tmp;
1427
		}
1428
		// Advance pointer by 4 TDM frame lengths
1429
		writechunk += 32;
1430
	}
1431
1432
}
1433
1434
static void ap4_tdm_loop(struct ap4 *wc)
1435
{
1436
	volatile unsigned int *buf_ptr;
1437
	int x,z;
1438
	unsigned int tmp;
1439
1440
	buf_ptr = (wc->membase+AP_DATA_BASE);
1441
1442
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
1443
		// Once per chunk
1444
		for (z=0;z<32;z++) {
1445
			tmp = buf_ptr[z];
1446
			buf_ptr[z] = tmp;
1447
		}
1448
		buf_ptr += 32;
1449
	}
1450
}
1451
1452
static void __ap4_check_sigbits(struct ap4 *wc, int span)
1453
{
1454
	int a,i,rxs;
1455
	struct ap4_span *ts = wc->tspans[span];
1456
	volatile unsigned int *readcas = (wc->membase+AP_CAS_BASE);
1457
1458
//	if (debug & DEBUG_RBS)
1459
//		printk("Checking sigbits on span %d\n", span + 1);
1460
1461
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
1462
		return;
1463
	// se span estiver com alarme RED ou BLUE...
1464
	if( (ts->span.alarms & DAHDI_ALARM_RED) || (ts->span.alarms & DAHDI_ALARM_BLUE) ) {
1465
		ts->reload_cas = 4;
1466
	} else if(ts->reload_cas > 0) {
1467
		// da mais um tempo para framer recuperar e enviar bits de CAS validos
1468
		ts->reload_cas--;
1469
	}
1470
1471
	if (ts->spantype == TYPE_E1) {
1472
		for (i = 0; i < 15; i++) {
1473
1474
			// Se estamos em alarme ou recuperando de um entao mascara os bits para "1101" (bloqueado)
1475
			if(ts->reload_cas) {
1476
				a = 0xdd;
1477
			} else {
1478
				a = (int) ts->casbuf[i];
1479
			}
1480
			ts->casbuf[i] = (unsigned char) (readcas[i] >> (8*span))&0xff;
1481
1482
			/* Get high channel in low bits */
1483
			rxs = (a & 0xf);
1484
			if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
1485
				if (ts->span.chans[i+16]->rxsig != rxs) {
1486
					ap_debugk("CAS no canal %d mudou de 0x%02x para 0x%02x\n", i+16, ts->span.chans[i+16]->rxsig, rxs);
1487
					dahdi_rbsbits(ts->span.chans[i+16], rxs);
1488
				}
1489
			}
1490
			rxs = (a >> 4) & 0xf;
1491
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
1492
				if (ts->span.chans[i]->rxsig != rxs) {
1493
					ap_debugk("CAS no canal %d mudou de 0x%02x para 0x%02x\n", i, ts->span.chans[i]->rxsig, rxs);
1494
					dahdi_rbsbits(ts->span.chans[i], rxs);
1495
				}
1496
			}
1497
		}
1498
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
1499
		for (i = 0; i < 12; i++) {
1500
			a = (unsigned char) (readcas[i] >> (8*span)) & 0xcc;
1501
			rxs = a & 0xc;
1502
			//rxs = (a & 0xc) >> 2;
1503
			if (!(ts->span.chans[2*i]->sig & DAHDI_SIG_CLEAR)) {
1504
				if (ts->span.chans[2*i]->rxsig != rxs)
1505
					dahdi_rbsbits(ts->span.chans[2*i], rxs);
1506
			}
1507
			rxs = (a >> 4) & 0xc;
1508
			//rxs = ((a >> 4) & 0xc) >> 2;
1509
			if (!(ts->span.chans[2*i+1]->sig & DAHDI_SIG_CLEAR)) {
1510
				if (ts->span.chans[2*i+1]->rxsig != rxs)
1511
					dahdi_rbsbits(ts->span.chans[2*i+1], rxs);
1512
			}
1513
		}
1514
	} else { // ESF
1515
		for (i = 0; i < 12; i++) {
1516
			a = (unsigned char) (readcas[i] >> (8*span)) & 0xff;
1517
			rxs = (a & 0xf);
1518
			if (!(ts->span.chans[2*i+1]->sig & DAHDI_SIG_CLEAR)) {
1519
				/* XXX Not really reset on every trans! XXX */
1520
				if (ts->span.chans[2*i+1]->rxsig != rxs) {
1521
					dahdi_rbsbits(ts->span.chans[2*i+1], rxs);
1522
				}
1523
			}
1524
			rxs = (a >> 4) & 0xf;
1525
			if (!(ts->span.chans[2*i]->sig & DAHDI_SIG_CLEAR)) {
1526
				/* XXX Not really reset on every trans! XXX */
1527
				if (ts->span.chans[2*i]->rxsig != rxs) {
1528
					dahdi_rbsbits(ts->span.chans[2*i], rxs);
1529
				}
1530
			}
1531
		}
1532
	}
1533
}
1534
1535
static void __ap4_check_alarms(struct ap4 *wc, int span)
1536
{
1537
	unsigned char c;
1538
	int alarms;
1539
	int x,j;
1540
	struct ap4_span *ts = wc->tspans[span];
1541
	unsigned int e1_cfg;
1542
1543
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
1544
		return;
1545
1546
	/* Assume no alarms */
1547
	alarms = DAHDI_ALARM_NONE;
1548
1549
	/* And consider only carrier alarms */
1550
	ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
1551
1552
	if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
1553
		for (x=0,j=0;x < ts->span.channels;x++)
1554
			if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
1555
#ifdef CONFIG_DAHDI_NET
1556
					||
1557
			    (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
1558
#endif
1559
			    )
1560
				j++;
1561
		if (!j)
1562
			alarms |= DAHDI_ALARM_NOTOPEN;
1563
	}
1564
1565
/* le status e configuracao do E1 */
1566
	if (wc->tspans[span]->spantype == TYPE_E1) {
1567
		c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
1568
		e1_cfg = ((*(wc->membase+AP_E1_CONFIG_REG))>>(8*span));
1569
1570
		if ((c & AP_E1_LOS_STATUS)||(c & AP_E1_BFAE_STATUS)||(c & AP_E1_AIS_STATUS)) {
1571
			if (ts->alarmcount >= alarmdebounce)
1572
				alarms |= DAHDI_ALARM_RED;
1573
			else
1574
				ts->alarmcount++;
1575
		} else
1576
			ts->alarmcount = 0;
1577
1578
		if ( c & AP_E1_MFAE_STATUS )
1579
			alarms |= DAHDI_ALARM_BLUE;
1580
1581
		if ( (!(c & AP_E1_CAS_STATUS)) && (e1_cfg & AP_E1_PCM30_CONFIG))
1582
			alarms |= DAHDI_ALARM_BLUE;
1583
	} else {
1584
		c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
1585
		if (c & AP_E1_LOS_STATUS) {
1586
			if (ts->alarmcount >= alarmdebounce)
1587
				alarms |= DAHDI_ALARM_RED;
1588
			else
1589
				ts->alarmcount++;
1590
		} else
1591
			ts->alarmcount = 0;
1592
		c = wc->hw_regs->t1_status >> (8 * span);
1593
		if (!(c & AP4_T1_FRAME_SYNC))
1594
			alarms |= DAHDI_ALARM_RED;
1595
	}
1596
1597
	if (((!ts->span.alarms) && alarms) ||
1598
	    (ts->span.alarms && (!alarms)))
1599
		wc->checktiming = 1;
1600
1601
	/* Keep track of recovering */
1602
	if ((!alarms) && ts->span.alarms)
1603
		ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
1604
	if (ts->alarmtimer)
1605
		alarms |= DAHDI_ALARM_RECOVER;
1606
1607
1608
	// If receiving alarms, go into Yellow alarm state
1609
	if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
1610
		printk("Setting yellow alarm on span %d\n", span + 1);
1611
		e1_cfg = *(wc->membase+AP_E1_CONFIG_REG);
1612
		e1_cfg |= (AP_E1_RAI_CONFIG<<(8*span));
1613
		*(wc->membase+AP_E1_CONFIG_REG) = e1_cfg;
1614
		ts->spanflags |= FLAG_SENDINGYELLOW;
1615
	} else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
1616
		printk("Clearing yellow alarm on span %d\n", span + 1);
1617
		e1_cfg = *(wc->membase+AP_E1_CONFIG_REG);
1618
		e1_cfg &= ~(AP_E1_RAI_CONFIG<<(8*span));
1619
		*(wc->membase+AP_E1_CONFIG_REG) = e1_cfg;
1620
		ts->spanflags &= ~FLAG_SENDINGYELLOW;
1621
	}
1622
1623
	// Re-check the timing source when we enter/leave alarm, not withstanding yellow alarm
1624
	if (c & AP_E1_RAI_STATUS)
1625
		alarms |= DAHDI_ALARM_YELLOW;
1626
1627
	if (ts->span.mainttimer || ts->span.maintstat)
1628
		alarms |= DAHDI_ALARM_LOOPBACK;
1629
1630
	ts->span.alarms = alarms;
1631
	dahdi_alarm_notify(&ts->span);
1632
}
1633
1634
static void __ap4_do_counters(struct ap4 *wc)
1635
{
1636
	int span;
1637
1638
	for (span=0;span<wc->numspans;span++) {
1639
		struct ap4_span *ts = wc->tspans[span];
1640
		int docheck=0;
1641
		if (ts->loopupcnt || ts->loopdowncnt)
1642
			docheck++;
1643
		if (ts->alarmtimer) {
1644
			if (!--ts->alarmtimer) {
1645
				docheck++;
1646
				ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
1647
			}
1648
		}
1649
		if (docheck) {
1650
			if (!polling)
1651
				__ap4_check_alarms(wc, span);
1652
			dahdi_alarm_notify(&ts->span);
1653
		}
1654
	}
1655
}
1656
1657
static inline void __handle_leds(struct ap4 *wc)
1658
{
1659
	int x, span_status;
1660
	#define MAX_BLINKTIMER	0x14
1661
1662
	for (x=0;x<wc->numspans;x++) {
1663
		struct ap4_span *ts = wc->tspans[x];
1664
		/* le status do E1 (para avaliar LOS) */
1665
		span_status = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*x));
1666
		if (ts->span.flags & DAHDI_FLAG_RUNNING) {
1667
			if(span_status&AP_E1_LOS_STATUS) {
1668
				if (wc->blinktimer[x] >= (altab[wc->alarmpos[x]] /*>> 1*/)) {
1669
					__ap4_set_led(wc, x, AP_ON);
1670
				}
1671
				if (wc->blinktimer[x] >= (MAX_BLINKTIMER-1)) {
1672
					__ap4_set_led(wc, x, AP_OFF);
1673
				}
1674
				wc->blinktimer[x] += 1;
1675
			} else if (ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) {
1676
				if (wc->blinktimer[x] >= (altab[wc->alarmpos[x]] /*>> 1*/)) {
1677
					__ap4_set_led(wc, x, AP_ON);
1678
				}
1679
				if (wc->blinktimer[x] >= (MAX_BLINKTIMER-2)) {
1680
					__ap4_set_led(wc, x, AP_OFF);
1681
				}
1682
				wc->blinktimer[x] += 3;
1683
			} /*else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
1684
				// Yellow Alarm
1685
				__ap4_set_led(wc, x, AP_ON);
1686
			} else if (ts->span.mainttimer || ts->span.maintstat) {
1687
1688
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
1689
					__ap4_set_led(wc, x, AP_GREEN);
1690
				}
1691
				if (wc->blinktimer == 0xf) {
1692
					__ap4_set_led(wc, x, AP_OFF);
1693
				}
1694
1695
			} */else {
1696
				/* No Alarm */
1697
				__ap4_set_led(wc, x, AP_ON);
1698
			}
1699
		}	else
1700
				__ap4_set_led(wc, x, AP_OFF);
1701
1702
		if (wc->blinktimer[x] > MAX_BLINKTIMER) {
1703
			wc->blinktimer[x] = 0;
1704
			wc->alarmpos[x]++;
1705
			if (wc->alarmpos[x] >= (sizeof(altab) / sizeof(altab[0])))
1706
				wc->alarmpos[x] = 0;
1707
		}
1708
1709
	}
1710
}
1711
1712
1713
DAHDI_IRQ_HANDLER(ap4_interrupt)
1714
{
1715
	struct ap4 *wc = dev_id;
1716
	unsigned long flags;
1717
	int x;
1718
	static unsigned int val, cfg;
1719
	unsigned int cnt_irq_misses;
1720
	static unsigned int cnt_tmp;
1721
	int ret = 0;
1722
1723
	/* retorna se interrupcao nao foi habilitada ou nao esta ativa */
1724
	cfg = *(wc->membase + AP_INT_CONTROL_REG);
1725
	if((cfg & AP_INT_CTL_ENABLE) == 0 || (cfg & AP_INT_CTL_ACTIVE) == 0) {
1726
		ret = 0;
1727
		goto out;
1728
	}
1729
	/* se chegamos aqui eh porque a interrupcao esta habilitada
1730
	 * e esta ativa, ou seja, foi gerada pelo nosso cartao.
1731
	 * Agora damos o ack da interrupcao */
1732
	val = *(wc->membase + AP_CLEAR_IRQ_REG);
1733
1734
	/* conta interrupcoes perdidas */
1735
	if (wc->flag_1st_irq > 0) {
1736
		// nao considera as primeiras passagens pela rotina
1737
		cnt_irq_misses = (*(wc->membase+AP_CNT_IRQ_REG));
1738
		// so considera int. para o cartao
1739
		if(cnt_irq_misses) {
1740
			wc->flag_1st_irq--;
1741
			*(wc->membase+AP_CNT_IRQ_REG)=0;
1742
		}
1743
		// zera erro de CRC
1744
		cnt_tmp = (*(wc->membase + AP_CNT_CRC_REG));
1745
	} else {
1746
		// neste registro da FPGA temos o numero de interrupcoes que aconteceram
1747
		// desde o ultimo reset do contador de interrupcoes. O normal eh ler 1.
1748
		cnt_irq_misses = (*(wc->membase+AP_CNT_IRQ_REG));
1749
		// Se for zero significa que a interrupcao nao foi gerada pelo nosso cartao
1750
		if(cnt_irq_misses == 0) {
1751
			if(debug) printk("Interrupcao gerada mas nao pela FPGA?!\n");
1752
			ret = 0;
1753
			goto out;
1754
		}
1755
		// reseta o contador
1756
		*(wc->membase+AP_CNT_IRQ_REG)=0;
1757
		for(x=0;x<(wc->numspans);x++)
1758
			wc->ddev->irqmisses += (cnt_irq_misses-1);
1759
	}
1760
1761
	if (!wc->spansstarted) {
1762
		/* Not prepped yet! */
1763
		ret = 0;
1764
		goto out;
1765
	}
1766
1767
	wc->intcount++;
1768
1769
#ifdef ENABLE_WORKQUEUES
1770
	int cpus = num_online_cpus();
1771
	atomic_set(&wc->worklist, wc->numspans);
1772
	if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
1773
		ap4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
1774
	else
1775
		atomic_dec(&wc->worklist);
1776
	if (wc->numspans > 1) {
1777
		if (wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)
1778
			ap4_queue_work(wc->workq, &wc->tspans[1]->swork, 1 % cpus);
1779
		else
1780
			atomic_dec(&wc->worklist);
1781
	}
1782
	if (wc->numspans == 4) {
1783
		if (wc->tspans[2]->span.flags & DAHDI_FLAG_RUNNING)
1784
			ap4_queue_work(wc->workq, &wc->tspans[2]->swork, 2 % cpus);
1785
		else
1786
			atomic_dec(&wc->worklist);
1787
		if (wc->tspans[3]->span.flags & DAHDI_FLAG_RUNNING)
1788
			ap4_queue_work(wc->workq, &wc->tspans[3]->swork, 3 % cpus);
1789
		else
1790
			atomic_dec(&wc->worklist);
1791
	}
1792
#else
1793
	if (tdm_loop == 1)
1794
		ap4_tdm_loop(wc);
1795
	else {
1796
		ap4_receiveprep(wc);
1797
		ap4_transmitprep(wc);
1798
	}
1799
#endif
1800
1801
	// Estatisticas a cada 128ms
1802
	if(!(wc->intcount&0x7f)){
1803
		clock_source = wc->hw_regs->clock_source;
1804
		cnt_tmp = (*(wc->membase + AP_CNT_CV_REG));
1805
		for(x=0;x<(wc->numspans);x++)
1806
			wc->tspans[x]->span.count.bpv += (cnt_tmp>>(8*x))&0xff;
1807
		cnt_tmp = (*(wc->membase + AP_CNT_CRC_REG));
1808
		for(x=0;x<(wc->numspans);x++)
1809
			wc->tspans[x]->span.count.crc4 += (cnt_tmp>>(8*x))&0xff;
1810
		cnt_tmp = (*(wc->membase + AP_CNT_SLIP_REG));
1811
		for(x=0;x<(wc->numspans);x++) {
1812
			if (((cnt_tmp>>(8*x))&0xff) && (!(wc->tspans[x]->span.alarms & DAHDI_ALARM_RED)) ){
1813
				wc->tspans[x]->slipcount++;
1814
				if(debug) printk("Slip detected on span %d: slipcount = %d\n", x+1, wc->tspans[x]->slipcount);
1815
			}
1816
		}
1817
	}
1818
1819
	spin_lock_irqsave(&wc->reglock, flags);
1820
1821
	__handle_leds(wc);
1822
1823
	__ap4_do_counters(wc);
1824
1825
	//x = wc->intcount & 15;
1826
	x = wc->intcount & 7;
1827
	switch(x) {
1828
	case 0:
1829
	case 1:
1830
	case 2:
1831
	case 3:
1832
		__ap4_check_alarms(wc, x);
1833
		break;
1834
	case 4:
1835
	case 5:
1836
	case 6:
1837
	case 7:
1838
		__ap4_check_sigbits(wc, x - 4);
1839
		break;
1840
	}
1841
1842
	if (wc->checktiming > 0)
1843
		__ap4_set_timing_source_auto(wc);
1844
	spin_unlock_irqrestore(&wc->reglock, flags);
1845
	/* IRQ was treated */
1846
	ret = 1;
1847
out:
1848
#ifdef AP400_HDLC
1849
	/* Call AP400_HDLC_CARD IRQ handler before leave */
1850
	ret |= ap400_intr_handler(irq, wc->hdlc_card);
1851
#endif
1852
1853
	return IRQ_RETVAL(ret);
1854
}
1855
1856
1857
static int __devinit ap4_launch(struct ap4 *wc)
1858
{
1859
	int x;
1860
	unsigned long flags;
1861
1862
	if (wc->tspans[0]->span.flags & DAHDI_FLAG_REGISTERED)
1863
		return 0;
1864
	printk("%s: Launching card: %d\n", wc->variety, wc->order);
1865
1866
	/* Setup serial parameters and system interface */
1867
	for (x=0;x<4;x++) {
1868
		//ap4_serial_setup(wc, x);
1869
		wc->globalconfig = 1;
1870
	}
1871
1872
	for (x=0; x<wc->numspans; x++)
1873
		list_add_tail(&wc->tspans[x]->span.device_node,
1874
				&wc->ddev->spans);
1875
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
1876
		printk(KERN_ERR "Unable to register span %s\n", wc->tspans[0]->span.name);
1877
		return -1; /* FIXME: proper error handling */
1878
	}
1879
	wc->checktiming = 1;
1880
	spin_lock_irqsave(&wc->reglock, flags);
1881
//	__ap4_set_timing_source(wc,4);
1882
	spin_unlock_irqrestore(&wc->reglock, flags);
1883
#ifdef ENABLE_TASKLETS
1884
	tasklet_init(&wc->ap4_tlet, ap4_tasklet, (unsigned long)wc);
1885
#endif
1886
	return 0;
1887
}
1888
1889
1890
static int ap4xx_liu_reset(struct ap4 *wc)
1891
{
1892
 	unsigned int jiffies_hold = jiffies;
1893
	*(wc->membase+AP_LEDS_REG) |= AP_LIU_RESET_BIT;
1894
	while(jiffies<=(jiffies_hold+2));
1895
	*(wc->membase+AP_LEDS_REG) &= ~AP_LIU_RESET_BIT;
1896
	return 0;
1897
}
1898
1899
1900
static int ap4xx_bus_test(struct ap4 *wc)
1901
{
1902
	int tst_result = 0;
1903
	unsigned int val;
1904
1905
	*(wc->membase+AP_E1_CONFIG_REG) = 0xAAAAAAAA;
1906
	*wc->membase = 0; // flush
1907
	val = *(wc->membase+AP_E1_CONFIG_REG);
1908
	if(val != 0xAAAAAAAA) {
1909
		printk("Escrito 0xAAAAAAAA, lido 0x%08X!\n", val);
1910
		tst_result++;
1911
	}
1912
	*(wc->membase+AP_E1_CONFIG_REG) = 0x55555555;
1913
	*wc->membase = 0; // flush
1914
	val = *(wc->membase+AP_E1_CONFIG_REG);
1915
	if(val != 0x55555555) {
1916
		printk("Escrito 0x55555555, lido 0x%08X!\n", val);
1917
		tst_result++;
1918
	}
1919
	*(wc->membase+AP_E1_CONFIG_REG) = 0xFFFFFFFF;
1920
	*wc->membase = 0; // flush
1921
	val = *(wc->membase+AP_E1_CONFIG_REG);
1922
	if(val != 0xFFFFFFFF) {
1923
		printk("Escrito 0xFFFFFFFF, lido 0x%08X!\n", val);
1924
		tst_result++;
1925
	}
1926
	*(wc->membase+AP_E1_CONFIG_REG) = 0x00000000;
1927
	*wc->membase = 0xFFFFFFFF; // flush
1928
	val = *(wc->membase+AP_E1_CONFIG_REG);
1929
	if(val != 0x00000000) {
1930
		printk("Escrito 0x00000000, lido 0x%08X!\n", val);
1931
		tst_result++;
1932
	}
1933
	return tst_result;
1934
}
1935
1936
#ifdef TIMER_DEBUG
1937
void ap4xx_opt_timeout(unsigned long arg)
1938
{
1939
	struct pci_dev *dev = (struct pci_dev *)arg;
1940
	struct ap4 *wc = pci_get_drvdata(dev);
1941
1942
//	ap_debugk("wc->tspans[0]->span.chans[1].readchunk[1] = 0x%02x\n", wc->tspans[0]->span.chans[0].readchunk[1]);
1943
//	ap_debugk("e1s_cfg = 0x%08x\n", *(wc->membase+AP_E1_CONFIG_REG));
1944
//	ap_debugk("e1_status = 0x%08x\n", *(wc->membase + AP_E1_STATUS_REG));
1945
//	ap_debugk("clk_cfg = 0x%08x\n", *(wc->membase+0x07));
1946
//	ap_debugk("e1_data = 0x%08x\n", *(wc->membase + (AP_DATA_BASE + 1)));
1947
//	ap_debugk("cas_data = 0x%08x\n", *(wc->membase + AP_CAS_BASE));
1948
1949
	// dispara timer novamente
1950
	init_timer(&ap4xx_opt_timer);
1951
	ap4xx_opt_timer.function = ap4xx_opt_timeout;
1952
	ap4xx_opt_timer.data = arg;
1953
	ap4xx_opt_timer.expires = jiffies + (delay/4);
1954
	add_timer(&ap4xx_opt_timer);
1955
1956
}
1957
#endif
1958
1959
static inline int ap4_card_detect (struct ap4 *wc) {
1960
	int i;
1961
	if ((wc->hw_regs->card_id != AP4XX_CARD_ID) &&
1962
			(wc->hw_regs->card_id != APE4XX_CARD_ID)) {
1963
		printk("AP400: Unknown card ID(0x%08X)! Aborting...\n", wc->hw_regs->card_id);
1964
		return -EPERM;
1965
	}
1966
	// Test bus integrity
1967
	for (i=0; i < 1000; i++) {
1968
		if (ap4xx_bus_test(wc)) {
1969
			printk("AP400: Bus integrity test failed! Aborting...\n");
1970
			return -EIO;
1971
		}
1972
	}
1973
	printk("AP400: Bus integrity OK!\n");
1974
1975
	wc->fpgaver = wc->hw_regs->fpga_ver;
1976
	wc->numspans = wc->hw_regs->span_num;
1977
	wc->hwid = ((*(wc->membase+AP_HWCONFIG_REG))&AP_HWID_MASK)>>4;
1978
1979
	if ((wc->hwid == AP_HWID_1E1_RJ && wc->numspans != 1) ||
1980
			(wc->hwid == AP_HWID_2E1_RJ && wc->numspans != 2) ||
1981
			(wc->hwid == AP_HWID_4E1_RJ && wc->numspans != 4)) {
1982
		printk("AP400: Incompatible Hardware ID(0x%02x)! Aborting...\n", wc->hwid);
1983
		return -EIO;
1984
	}
1985
1986
	if (wc->hw_regs->card_id == AP4XX_CARD_ID)
1987
		switch (wc->numspans) {
1988
		case 1:
1989
			wc->dt = (struct devtype *) &ap401;
1990
			break;
1991
		case 2:
1992
			wc->dt = (struct devtype *) &ap402;
1993
			break;
1994
		case 4:
1995
			wc->dt = (struct devtype *) &ap404;
1996
			break;
1997
		default:
1998
			printk("AP400: Unsupported spans number(%d)! Aborting...\n",
1999
					wc->numspans);
2000
			return -EPERM;
2001
		}
2002
	else
2003
		switch (wc->numspans) {
2004
		case 1:
2005
			wc->dt = (struct devtype *) &ape401;
2006
			break;
2007
		case 2:
2008
			wc->dt = (struct devtype *) &ape402;
2009
			break;
2010
		case 4:
2011
			wc->dt = (struct devtype *) &ape404;
2012
			break;
2013
		default:
2014
			printk("APE400: Unsupported spans number(%d)! Aborting...\n",
2015
					wc->numspans);
2016
			return -EPERM;
2017
	}
2018
2019
	wc->variety = wc->dt->desc;
2020
	printk("Found a %s (firmware version %d.%d) at base address %08lx, remapped to %p\n",
2021
			wc->variety, wc->fpgaver >> 8, wc->fpgaver & 0xFF,
2022
			wc->memaddr, wc->membase);
2023
2024
	return 0;
2025
}
2026
2027
static void __devexit ap4_remove_one(struct pci_dev *pdev);
2028
2029
static int __devinit ap4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2030
{
2031
	int res;
2032
	struct ap4 *wc;
2033
	int x,f;
2034
	int basesize;
2035
	static int initd_ifaces=0;
2036
	// Initialize pointer struct
2037
	if(!initd_ifaces){
2038
		memset((void *)cards,0,(sizeof(struct ap4 *))*MAX_AP4_CARDS);
2039
		initd_ifaces=1;
2040
	}
2041
2042
	if ((res = pci_enable_device(pdev)) != 0) {
2043
		goto out;
2044
	}
2045
	// Allocate card struct
2046
	wc = kmalloc(sizeof(struct ap4), GFP_KERNEL);
2047
	if (wc == NULL) {
2048
		res = -ENOMEM;
2049
		goto out;
2050
	}
2051
2052
	memset(wc, 0x0, sizeof(struct ap4));
2053
	spin_lock_init(&wc->reglock);
2054
2055
	basesize = DAHDI_MAX_CHUNKSIZE * 32 * 2 * 4;
2056
2057
	// Request PCI regions
2058
	if ((res = pci_request_regions(pdev, "ap400")) != 0) {
2059
		printk("AP400: Unable to request regions!\n");
2060
		goto out;
2061
	}
2062
2063
	// Remap PCI address
2064
	wc->memaddr = pci_resource_start(pdev, 2);
2065
	wc->memlen = pci_resource_len(pdev, 2);
2066
	wc->membase = ioremap_nocache(wc->memaddr, wc->memlen);
2067
	if(wc->membase == NULL) {
2068
		printk("AP400: ioremap failed!\n");
2069
		res = -EIO;
2070
		goto out;
2071
	}
2072
	wc->hw_regs = (struct ap4_regs *) wc->membase;
2073
2074
	// Detect Card model
2075
	if ((res = ap4_card_detect(wc)) != 0)
2076
		goto out;
2077
2078
	ap4xx_liu_reset(wc);
2079
2080
	// This rids of the Double missed interrupt message after loading
2081
	wc->last0 = 1;
2082
2083
	wc->dev = pdev;
2084
2085
	// 32 channels, Double-buffer, Read/Write, 4 spans
2086
	wc->writechunk = kmalloc(basesize * 2, GFP_KERNEL);
2087
	if (!wc->writechunk) {
2088
		printk("%s: Unable to allocate memory!\n", wc->variety);
2089
		res = -ENOMEM;
2090
		goto out;
2091
	}
2092
2093
	// Read is after the whole write piece (in words)
2094
	wc->readchunk = wc->writechunk + basesize / 4;
2095
2096
2097
	// Initialize Write/Buffers to all blank data
2098
	memset((void *) wc->writechunk, 0x00, basesize);
2099
	memset((void *) wc->readchunk, 0xff, basesize);
2100
2101
	/* Keep track of which device we are */
2102
	pci_set_drvdata(pdev, wc);
2103
2104
	/* inicializa contador de interrupcao */
2105
	wc->intcount = 0;
2106
2107
	for(x = 0; x < MAX_AP4_CARDS; x++) {
2108
		if (!cards[x]) break;
2109
	}
2110
2111
	if (x >= MAX_AP4_CARDS) {
2112
		printk("No cards[] slot available!!\n");
2113
		res = -ENOMEM;
2114
		goto out;
2115
	}
2116
2117
	wc->num = x;
2118
	cards[x] = wc;
2119
2120
	/* Allocate pieces we need here, consider 31 channels for E1*/
2121
	for (x=0;x<4;x++) {
2122
		wc->tspans[x] = kmalloc(sizeof(struct ap4_span), GFP_KERNEL);
2123
		if (wc->tspans[x]) {
2124
			memset(wc->tspans[x], 0, sizeof(struct ap4_span));
2125
			wc->tspans[x]->spantype = TYPE_E1;
2126
		} else {
2127
			res = -ENOMEM;
2128
			goto out;
2129
		}
2130
		for (f = 0; f < 31; f++) {
2131
			if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
2132
				res = -ENOMEM;
2133
				goto out;
2134
			}
2135
			memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
2136
		}
2137
#ifdef ENABLE_WORKQUEUES
2138
		INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
2139
#endif
2140
		wc->tspans[x]->spanflags |= wc->dt->flags;
2141
	}
2142
2143
	if (request_irq(pdev->irq, ap4_interrupt, IRQF_DISABLED | IRQF_SHARED, "ap400", wc))
2144
	{
2145
		printk("%s: Unable to request IRQ %d\n", wc->variety, pdev->irq);
2146
		res = -EIO;
2147
		goto out;
2148
	}
2149
2150
	wc->ddev = dahdi_create_device();
2151
	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
2152
			wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
2153
	if (!wc->ddev->location)
2154
		return -ENOMEM; /* FIXME: proper error handling */
2155
	wc->ddev->manufacturer = "Aligera";
2156
	wc->ddev->devicetype = wc->variety;
2157
	wc->ddev->irqmisses = 0;
2158
	init_spans(wc);
2159
2160
	/* Launch cards as appropriate */
2161
	x = 0;
2162
	for(;;) {
2163
		/* Find a card to activate */
2164
		f = 0;
2165
		for (x=0;cards[x];x++) {
2166
			if (cards[x]->order <= highestorder) {
2167
				ap4_launch(cards[x]);
2168
				if (cards[x]->order == highestorder)
2169
					f = 1;
2170
			}
2171
		}
2172
		/* If we found at least one, increment the highest order and search again, otherwise stop */
2173
		if (f)
2174
			highestorder++;
2175
		else
2176
			break;
2177
	}
2178
2179
#ifdef APEC_SUPPORT
2180
	if (wc->fpgaver >= 0x0400)
2181
		wc->apec_enable = 1;
2182
#endif
2183
2184
#ifdef TIMER_DEBUG
2185
	// dispara timer de debug
2186
	init_timer(&ap4xx_opt_timer);
2187
	ap4xx_opt_timer.function = ap4xx_opt_timeout;
2188
	ap4xx_opt_timer.data = (unsigned long) pdev;
2189
	ap4xx_opt_timer.expires = jiffies + 100;
2190
	add_timer(&ap4xx_opt_timer);
2191
#endif
2192
2193
	/* Initialize HDLC_CARD */
2194
#ifdef AP400_HDLC
2195
	u8 __iomem *base_addr[3];
2196
	unsigned int bar_size[3];
2197
	int i;
2198
	base_addr[2] = (void *) wc->membase;
2199
	bar_size[2] = wc->memlen;
2200
	for (i = 0; i < 2; i++) {
2201
		bar_size[i] = (u32) pci_resource_len(pdev, i);
2202
		base_addr[i] = ioremap_nocache(pci_resource_start(pdev, i),
2203
								bar_size[i]);
2204
		if (base_addr[i] == NULL) {
2205
			printk(KERN_ERR "Memory map failed\n");
2206
			res = -ENODEV;
2207
			goto out;
2208
		}
2209
	}
2210
	ap400_card_init(&wc->hdlc_card, base_addr, bar_size);
2211
	ap400_intr_enable(wc->hdlc_card);
2212
#endif
2213
2214
	res = 0;
2215
out:
2216
	if (res != 0) {
2217
		ap4_remove_one(pdev);
2218
	}
2219
	return res;
2220
}
2221
2222
static void __devexit ap4_remove_one(struct pci_dev *pdev)
2223
{
2224
	struct ap4 *wc = pci_get_drvdata(pdev);
2225
	int x;
2226
2227
	if (wc) {
2228
		ap_debugk("desabilita interrupcao!\n");
2229
		// desabilita interrupcao
2230
		*(wc->membase + AP_INT_CONTROL_REG) &= ~AP_INT_CTL_ENABLE;
2231
2232
#ifdef APEC_SUPPORT
2233
		// Stop echo cancellation module
2234
		ap4_apec_release(wc);
2235
#endif
2236
		/* Unregister spans */
2237
		dahdi_unregister_device(wc->ddev);
2238
		kfree(wc->ddev->location);
2239
		dahdi_free_device(wc->ddev);
2240
#ifdef ENABLE_WORKQUEUES
2241
		if (wc->workq) {
2242
			flush_workqueue(wc->workq);
2243
			destroy_workqueue(wc->workq);
2244
		}
2245
#endif
2246
2247
#ifdef TIMER_DEBUG
2248
		del_timer(&ap4xx_opt_timer);
2249
#endif
2250
2251
		wc->hw_regs = NULL;
2252
		if(wc->membase)
2253
			iounmap((void *)wc->membase);
2254
2255
		/* Immediately free resources */
2256
		kfree((void *) wc->writechunk);
2257
2258
#ifdef AP400_HDLC
2259
		/* Remove HDLC Card */
2260
		ap400_card_remove(wc->hdlc_card);
2261
		if (wc->hdlc_card->cfg_base_addr)
2262
			iounmap(wc->hdlc_card->cfg_base_addr);
2263
		if (wc->hdlc_card->buf_base_addr)
2264
			iounmap(wc->hdlc_card->buf_base_addr);
2265
		kfree(wc->hdlc_card);
2266
#endif
2267
		free_irq(pdev->irq, wc);
2268
2269
		cards[wc->num] = NULL;
2270
		for (x=0;x<wc->numspans;x++) {
2271
			if (wc->tspans[x])
2272
				kfree(wc->tspans[x]);
2273
		}
2274
		kfree(wc);
2275
	}
2276
	pci_release_regions(pdev);
2277
	pci_disable_device(pdev);
2278
	pci_set_drvdata(pdev, NULL);
2279
	printk(KERN_INFO "AP400 driver removed\n");
2280
}
2281
2282
2283
static struct pci_device_id ap4_pci_tbl[] __devinitdata =
2284
{
2285
	{ PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_AP4XX), },
2286
	{ 0, }
2287
};
2288
2289
2290
static struct pci_driver ap4_driver = {
2291
	.name = 	"Unified ap4xx driver",
2292
	.probe = 	ap4_init_one,
2293
#ifdef LINUX26
2294
	.remove =	__devexit_p(ap4_remove_one),
2295
#else
2296
	.remove =	ap4_remove_one,
2297
#endif
2298
	.id_table = ap4_pci_tbl,
2299
};
2300
2301
static int __init ap4_init(void)
2302
{
2303
	int res;
2304
	printk("Unified AP4XX PCI Card Driver\n");
2305
	res = dahdi_pci_module(&ap4_driver);
2306
	if (res) {
2307
		return -ENODEV;
2308
	}
2309
	return 0;
2310
}
2311
2312
static void __exit ap4_cleanup(void)
2313
{
2314
	printk("Unified AP4XX PCI Card Driver Cleanup\n");
2315
	pci_unregister_driver(&ap4_driver);
2316
}
2317
2318
2319
MODULE_AUTHOR("Aligera (aligera@aligera.com.br)");
2320
MODULE_DESCRIPTION("Unified AP4XX PCI Card Driver");
2321
#ifdef MODULE_LICENSE
2322
MODULE_LICENSE("GPL");
2323
#endif
2324
module_param(debug, int, 0600);
2325
module_param(loopback, int, 0600);
2326
module_param(noburst, int, 0600);
2327
module_param(debugslips, int, 0600);
2328
module_param(polling, int, 0600);
2329
module_param(timingcable, int, 0600);
2330
module_param(t1e1override, int, 0600);
2331
module_param(alarmdebounce, int, 0600);
2332
module_param(j1mode, int, 0600);
2333
2334
MODULE_DEVICE_TABLE(pci, ap4_pci_tbl);
2335
2336
module_init(ap4_init);
2337
module_exit(ap4_cleanup);
(-)dahdi-linux-2.7.0/drivers/dahdi/ap400/ap400.h (+107 lines)
Line 0 Link Here
1
/*
2
 * AP4XX  T1/E1 PCI Driver
3
 *
4
 * Written by Ronaldo Valiati <aligera@aligera.com.br>
5
 *
6
 * Based on previous works, designs, and archetectures conceived and
7
 * written by Jim Dixon <jim@lambdatel.com> and Mark Spencer <markster@digium.com>.
8
 *
9
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
10
 * Copyright (C) 2001-2005, Digium, Inc.
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#include <linux/ioctl.h>
31
32
33
#define AP4_GET_ALARMS  _IOW (DAHDI_CODE, 60, int)
34
#define AP4_GET_SLIPS	_IOW (DAHDI_CODE, 61, int)
35
36
#define AP4XX_CARD_ID		0x41434532		// "ACE2"
37
#define APE4XX_CARD_ID		0x41504534		// "APE4"
38
39
#define AP_CAS_BASE		0x0080
40
#define AP_DATA_BASE		0x0100
41
42
#define AP_CARD_TYPE_REG	0x0001
43
#define AP_T1E1_CONFIG_REG	0x0003
44
#define AP_E1_CONFIG_REG	0x0004
45
#define AP_E1_STATUS_REG	0x0005
46
#define AP_LEDS_REG		0x0006
47
#define AP_CLKSRC_REG		0x0007
48
#define AP_HWCONFIG_REG		0x0008
49
#define AP_INT_CONTROL_REG	0x0009
50
#define AP_CNT_IRQ_REG		0x000B
51
#define AP_CNT_CV_REG		0x000C
52
#define AP_CNT_CRC_REG		0x000D
53
#define AP_CLEAR_IRQ_REG	0x000E
54
#define AP_CNT_SLIP_REG		0x000F
55
56
#define AP_HWID_MASK		0x00F0
57
58
#define AP_CLKSRC_MASK		0x07
59
60
#define AP_LIU1_LINECODE	0x0080
61
#define AP_LIU2_LINECODE	0x0100
62
#define AP_LIU_RESET_BIT	0x0200
63
64
#define AP_E1_AIS_STATUS	0x01
65
#define AP_E1_BFAE_STATUS	0x02
66
#define AP_E1_MFAE_STATUS	0x04
67
#define AP_E1_SYNC_STATUS	0x08
68
#define AP_E1_CAS_STATUS	0x10
69
#define AP_E1_LOS_STATUS	0x20
70
#define AP_E1_RAI_STATUS	0x40
71
72
#define AP_E1_RAI_CONFIG	0x01
73
#define AP_E1_LOOP_CONFIG	0x10
74
#define AP_E1_CASEN_CONFIG	0x20
75
#define AP_E1_PCM30_CONFIG	0x40
76
#define AP_E1_CRCEN_CONFIG	0x80
77
78
#define AP_INT_CTL_ENABLE	0x01
79
#define AP_INT_CTL_ACTIVE	0x02
80
81
#define AP_HWID_1E1_RJ		0x01
82
#define AP_HWID_2E1_RJ		0x00
83
#define AP_HWID_4E1_RJ		0x02
84
#define AP_HWID_T1		0x04
85
86
#define AP4_T1_NE1_SEL		0x04
87
#define AP4_T1_ESF_NSF		0x02
88
#define AP4_T1_CAS_ENABLE	0x01
89
90
#define AP4_T1_FRAME_SYNC	0x01
91
92
93
typedef enum {
94
	AP_PULS_E1_75 = 0,
95
	AP_PULS_E1_120,
96
	AP_PULS_DSX1_0FT,
97
	AP_PULS_DSX1_133FT,
98
	AP_PULS_DSX1_266FT,
99
	AP_PULS_DSX1_399FT,
100
	AP_PULS_DSX1_533FT,
101
	AP_PULS_J1_110,
102
	AP_PULS_DS1_0DB,
103
	AP_PULS_DS1_M075DB,
104
	AP_PULS_DS1_M150DB,
105
	AP_PULS_DS1_M225DB
106
} liu_mode;
107
(-)dahdi-linux-2.7.0/drivers/dahdi/ap400/apec.c (+390 lines)
Line 0 Link Here
1
/*
2
 * AP400 Echo Cancelation Hardware support
3
 *
4
 * Written by Wagner Gegler <aligera@aligera.com.br>
5
 *
6
 * Based on previous work written by Mark Spencer <markster@digium.com>
7
 *
8
 * Copyright (C) 2005-2006 Digium, Inc.
9
 *
10
 * Mark Spencer <markster@digium.com>
11
 *
12
 * All Rights Reserved
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#include <linux/slab.h>
31
#include <linux/vmalloc.h>
32
#include <linux/string.h>
33
#include <linux/time.h>
34
#include <linux/version.h>
35
#include <linux/delay.h>
36
37
#include "apec.h"
38
#include "oct6100api/oct6100_api.h"
39
40
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
41
#include <linux/config.h>
42
#else
43
#include <linux/autoconf.h>
44
#endif
45
46
/* API for Octasic access */
47
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
48
{
49
	/* Why couldn't they just take a timeval like everyone else? */
50
	struct timeval tv;
51
	unsigned long long total_usecs;
52
	unsigned int mask = ~0;
53
54
	do_gettimeofday(&tv);
55
	total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
56
				  (((unsigned long long)(tv.tv_usec)));
57
	f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
58
	f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
59
	return cOCT6100_ERR_OK;
60
}
61
62
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
63
{
64
	memset(f_pAddress, f_ulPattern, f_ulLength);
65
	return cOCT6100_ERR_OK;
66
}
67
68
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
69
{
70
	memcpy(f_pDestination, f_pSource, f_ulLength);
71
	return cOCT6100_ERR_OK;
72
}
73
74
UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
75
{
76
	return cOCT6100_ERR_OK;
77
}
78
79
UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
80
{
81
#ifdef OCTASIC_DEBUG
82
	printk("I should never be called! (destroy serialize object)\n");
83
#endif
84
	return cOCT6100_ERR_OK;
85
}
86
87
UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
88
{
89
	/* Not needed */
90
	return cOCT6100_ERR_OK;
91
}
92
93
UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
94
{
95
	/* Not needed */
96
	return cOCT6100_ERR_OK;
97
}
98
99
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
100
{
101
	oct_write(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
102
	return cOCT6100_ERR_OK;
103
}
104
105
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
106
{
107
	unsigned int x;
108
	for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
109
		oct_write(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
110
	}
111
	return cOCT6100_ERR_OK;
112
}
113
114
UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
115
{
116
	unsigned int x;
117
	for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
118
		oct_write(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
119
	}
120
	return cOCT6100_ERR_OK;
121
}
122
123
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
124
{
125
	*(f_pReadParams->pusReadData) = oct_read(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
126
	return cOCT6100_ERR_OK;
127
}
128
129
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
130
{
131
	unsigned int x;
132
	for (x=0;x<f_pBurstParams->ulReadLength;x++) {
133
		f_pBurstParams->pusReadData[x] = oct_read(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
134
	}
135
	return cOCT6100_ERR_OK;
136
}
137
138
#if 0
139
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
140
#else
141
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
142
#endif
143
144
struct apec_s {
145
	tPOCT6100_INSTANCE_API pApiInstance;
146
	UINT32 aulEchoChanHndl[128];
147
	int chanflags[128];
148
	int ecmode[128];
149
	int numchans;
150
};
151
152
#define FLAG_DTMF	 (1 << 0)
153
#define FLAG_MUTE	 (1 << 1)
154
#define FLAG_ECHO	 (1 << 2)
155
156
static void apec_setecmode(struct apec_s *apec, int channel, int mode)
157
{
158
	tOCT6100_CHANNEL_MODIFY *modify;
159
	UINT32 ulResult;
160
161
	if (apec->ecmode[channel] == mode)
162
		return;
163
	modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
164
	if (!modify) {
165
		printk("APEC: Unable to allocate memory for setec!\n");
166
		return;
167
	}
168
	Oct6100ChannelModifyDef(modify);
169
	modify->ulEchoOperationMode = mode;
170
	modify->ulChannelHndl = apec->aulEchoChanHndl[channel];
171
	ulResult = Oct6100ChannelModify(apec->pApiInstance, modify);
172
	if (ulResult != GENERIC_OK) {
173
		printk("Failed to apply echo can changes on channel %d!\n", channel);
174
	} else {
175
#ifdef OCTASIC_DEBUG
176
		printk("Echo can on channel %d set to %d\n", channel, mode);
177
#endif
178
		apec->ecmode[channel] = mode;
179
	}
180
	kfree(modify);
181
}
182
183
void apec_setec(struct apec_s *apec, int channel, int eclen)
184
{
185
	if (eclen) {
186
		apec->chanflags[channel] |= FLAG_ECHO;
187
		apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
188
		apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
189
	} else {
190
		apec->chanflags[channel] &= ~FLAG_ECHO;
191
		if (apec->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
192
			apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
193
			apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
194
		} else
195
			apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
196
	}
197
	printk("APEC: Setting EC on channel %d to %d\n", channel, eclen);
198
}
199
200
int apec_checkirq(struct apec_s *apec)
201
{
202
	tOCT6100_INTERRUPT_FLAGS InterruptFlags;
203
204
	Oct6100InterruptServiceRoutineDef(&InterruptFlags);
205
	Oct6100InterruptServiceRoutine(apec->pApiInstance, &InterruptFlags);
206
207
	return InterruptFlags.fToneEventsPending ? 1 : 0;
208
}
209
210
unsigned int apec_capacity_get(void *wc)
211
{
212
	UINT32 ulResult;
213
214
	tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
215
216
	Oct6100ApiGetCapacityPinsDef(&CapacityPins);
217
	CapacityPins.pProcessContext = wc;
218
	CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
219
	CapacityPins.fEnableMemClkOut = TRUE;
220
	CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
221
222
	ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
223
	if (ulResult != cOCT6100_ERR_OK) {
224
		printk("Failed to get chip capacity, code %08x!\n", ulResult);
225
		return 0;
226
	}
227
	return CapacityPins.ulCapacityValue;
228
}
229
230
struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
231
{
232
	tOCT6100_CHIP_OPEN *ChipOpen;
233
	tOCT6100_GET_INSTANCE_SIZE InstanceSize;
234
	tOCT6100_CHANNEL_OPEN *ChannelOpen;
235
	UINT32 ulResult;
236
	struct apec_s *apec;
237
	int x, law;
238
#ifdef CONFIG_4KSTACKS
239
	unsigned long flags;
240
#endif
241
242
	if (!(apec = kmalloc(sizeof(struct apec_s), GFP_KERNEL)))
243
		return NULL;
244
245
	memset(apec, 0, sizeof(struct apec_s));
246
247
	if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
248
		kfree(apec);
249
		return NULL;
250
	}
251
252
	memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
253
254
	if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
255
		kfree(apec);
256
		kfree(ChipOpen);
257
		return NULL;
258
	}
259
260
	memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
261
262
	for (x=0;x<128;x++)
263
		apec->ecmode[x] = -1;
264
265
	apec->numchans = numspans * 32;
266
	printk("APEC: echo cancellation for %d channels\n", apec->numchans);
267
268
	Oct6100ChipOpenDef(ChipOpen);
269
270
	/* Setup Chip Open Parameters */
271
	ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
272
	Oct6100GetInstanceSizeDef(&InstanceSize);
273
274
	ChipOpen->pProcessContext = wc;
275
276
	ChipOpen->pbyImageFile = firmware->data;
277
	ChipOpen->ulImageSize = firmware->size;
278
279
	ChipOpen->fEnableMemClkOut = TRUE;
280
	ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
281
	ChipOpen->ulMaxChannels = apec->numchans;
282
	ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
283
	ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
284
	ChipOpen->ulNumMemoryChips = 1;
285
	ChipOpen->ulMaxTdmStreams = 4;
286
	ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
287
	ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
288
#if 0
289
	ChipOpen->fEnableAcousticEcho = TRUE;
290
#endif
291
292
	ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
293
	if (ulResult != cOCT6100_ERR_OK) {
294
		printk("Failed to get instance size, code %08x!\n", ulResult);
295
		kfree(apec);
296
		return NULL;
297
	}
298
299
300
	apec->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
301
	if (!apec->pApiInstance) {
302
		printk("Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
303
		kfree(apec);
304
		kfree(ChipOpen);
305
		kfree(ChannelOpen);
306
		return NULL;
307
	}
308
309
	/* I don't know what to curse more in this comment, the problems caused by
310
	 * the 4K kernel stack limit change or the octasic API for being so darn
311
	 * stack unfriendly.  Stupid, stupid, stupid.  So we disable IRQs so we
312
	 * don't run the risk of overflowing the stack while we initialize the
313
	 * octasic. */
314
#ifdef CONFIG_4KSTACKS
315
	local_irq_save(flags);
316
#endif
317
	ulResult = Oct6100ChipOpen(apec->pApiInstance, ChipOpen);
318
	if (ulResult != cOCT6100_ERR_OK) {
319
		printk("Failed to open chip, code %08x!\n", ulResult);
320
#ifdef CONFIG_4KSTACKS
321
		local_irq_restore(flags);
322
#endif
323
		kfree(apec);
324
		kfree(ChipOpen);
325
		kfree(ChannelOpen);
326
		return NULL;
327
	}
328
	for (x=0; x < 128; x++) {
329
		/* execute this loop always on 4 span cards but
330
		*  on 2 span cards only execute for the channels related to our spans */
331
		if ((x & 0x3) < numspans) {
332
			/* span timeslots are interleaved 12341234...
333
		 	*  therefore, the lower 2 bits tell us which span this
334
			*  timeslot/channel
335
		 	*/
336
			if (isalaw[x & 0x03])
337
				law = cOCT6100_PCM_A_LAW;
338
			else
339
				law = cOCT6100_PCM_U_LAW;
340
			Oct6100ChannelOpenDef(ChannelOpen);
341
			ChannelOpen->pulChannelHndl = &apec->aulEchoChanHndl[x];
342
			ChannelOpen->ulUserChanId = x;
343
			ChannelOpen->TdmConfig.ulRinPcmLaw = law;
344
			ChannelOpen->TdmConfig.ulRinStream = 0;
345
			ChannelOpen->TdmConfig.ulRinTimeslot = x;
346
			ChannelOpen->TdmConfig.ulSinPcmLaw = law;
347
			ChannelOpen->TdmConfig.ulSinStream = 1;
348
			ChannelOpen->TdmConfig.ulSinTimeslot = x;
349
			ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
350
			ChannelOpen->TdmConfig.ulSoutStream = 2;
351
			ChannelOpen->TdmConfig.ulSoutTimeslot = x;
352
			ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
353
			ChannelOpen->TdmConfig.ulRoutStream = 3;
354
			ChannelOpen->TdmConfig.ulRoutTimeslot = x;
355
			ChannelOpen->VqeConfig.fEnableNlp = TRUE;
356
			ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
357
			ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
358
359
			ChannelOpen->fEnableToneDisabler = TRUE;
360
			ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
361
362
			ulResult = Oct6100ChannelOpen(apec->pApiInstance, ChannelOpen);
363
			if (ulResult != GENERIC_OK) {
364
				printk("Failed to open channel %d!\n", x);
365
			}
366
		}
367
	}
368
369
#ifdef CONFIG_4KSTACKS
370
	local_irq_restore(flags);
371
#endif
372
	kfree(ChipOpen);
373
	kfree(ChannelOpen);
374
	return apec;
375
}
376
377
void apec_release(struct apec_s *apec)
378
{
379
	UINT32 ulResult;
380
	tOCT6100_CHIP_CLOSE ChipClose;
381
382
	Oct6100ChipCloseDef(&ChipClose);
383
	ulResult = Oct6100ChipClose(apec->pApiInstance, &ChipClose);
384
	if (ulResult != cOCT6100_ERR_OK) {
385
		printk("Failed to close chip, code %08x!\n", ulResult);
386
	}
387
	vfree(apec->pApiInstance);
388
	kfree(apec);
389
	printk(KERN_INFO "APEC: Releasing...\n");
390
}
(-)dahdi-linux-2.7.0/drivers/dahdi/ap400/apec.h (+48 lines)
Line 0 Link Here
1
/*
2
 * AP400 Echo Cancelation Hardware support
3
 *
4
 * Written by Wagner Gegler <aligera@aligera.com.br>
5
 * 
6
 * Based on previous work written by Mark Spencer <markster@digium.com>
7
 * 
8
 * Copyright (C) 2005-2006 Digium, Inc.
9
 *
10
 * Mark Spencer <markster@digium.com>
11
 *
12
 * All Rights Reserved
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
#ifndef _APEC_H_
31
#define _APEC_H_
32
33
#include <linux/firmware.h>
34
35
struct apec_s;
36
37
/* From AP400 */
38
unsigned int oct_read(void *card, unsigned int addr);
39
void oct_write(void *card, unsigned int addr, unsigned int data);
40
41
/* From APEC */
42
struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
43
unsigned int apec_capacity_get(void *wc);
44
void apec_setec(struct apec_s *instance, int channel, int eclen);
45
int apec_checkirq(struct apec_s *apec);
46
void apec_release(struct apec_s *instance);
47
48
#endif /*_APEC_H_*/
(-)dahdi-linux-2.7.0/drivers/dahdi/ap400/Kbuild (+26 lines)
Line 0 Link Here
1
obj-m += ap400.o
2
3
EXTRA_CFLAGS := -I$(src)/.. 
4
5
ap400-objs := ap400_drv.o
6
7
# APEC_SUPPORT
8
ECHO_FIRMWARE := $(wildcard $(src)/OCT61*.ima)
9
ifneq ($(strip $(ECHO_FIRMWARE)),)
10
	EXTRA_CFLAGS+=-DAPEC_SUPPORT $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
11
	ap400-objs += apec.o $(shell $(src)/../oct612x/octasic-helper objects ../oct612x) firmware_oct6104e-64d.o firmware_oct6104e-128d.o
12
endif
13
14
$(obj)/apec.o: $(src)/apec.h $(src)/../oct612x/include/oct6100api/oct6100_api.h
15
16
$(obj)/firmware_oct6104e-64d.o: $(src)/OCT6104E-64D.ima $(obj)/ap400_drv.o $(src)/../firmware/make_firmware_object
17
	@echo Making firmware object file for $(notdir $<)
18
	@cd $(src) && ../firmware/make_firmware_object $(notdir $<) $@ $(obj)/ap400_drv.o
19
20
$(obj)/firmware_oct6104e-128d.o: $(src)/OCT6104E-128D.ima $(obj)/ap400_drv.o $(src)/../firmware/make_firmware_object
21
	@echo Making firmware object file for $(notdir $<)
22
	@cd $(src) && ../firmware/make_firmware_object $(notdir $<) $@ $(obj)/ap400_drv.o
23
24
$(src)/../firmware/make_firmware_object:
25
	make -C $(src)/../firmware make_firmware_object
26
(-)dahdi-linux-2.7.0/drivers/dahdi/Kbuild (+8 lines)
Lines 39-44 Link Here
39
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
39
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
40
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
40
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
41
41
42
ifdef CONFIG_PCI
43
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_AP400)		+= ap400/
44
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200)		+= opvxa1200/
45
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115)		+= opvxd115/
46
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCOPENPCI)		+= wcopenpci.o
47
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ZAPHFC)		+= zaphfc/
48
endif
49
42
obj-m += $(DAHDI_MODULES_EXTRA)
50
obj-m += $(DAHDI_MODULES_EXTRA)
43
51
44
# If you want to build OSLEC, include the code in the standard location:
52
# If you want to build OSLEC, include the code in the standard location:
(-)dahdi-linux-2.7.0/drivers/dahdi/Kconfig (+86 lines)
Lines 292-294 Link Here
292
	  If unsure, say Y.
292
	  If unsure, say Y.
293
293
294
source "drivers/dahdi/xpp/Kconfig"
294
source "drivers/dahdi/xpp/Kconfig"
295
296
config DAHDI_AP4XX
297
	tristate "Aligera AP4XX PCI Card Driver"
298
	depends on DAHDI && PCI
299
	default DAHDI
300
	---help---
301
	  This driver provides support for the Aligera AP400 quad-span
302
	  E1/T1 DAHDI cards:
303
304
	  To compile this driver as a module, choose M here: the
305
	  module will be called ap4xx.
306
307
	  If unsure, say Y.
308
309
config DAHDI_OPVXA1200
310
	tristate "OpenVox 8/12 ports analog card Support"
311
	depends on DAHDI && PCI
312
	default DAHDI
313
	---help---
314
	  This driver provides support for the following OpenVox
315
	  Wildcard products:
316
317
	  * A1200P (PCI)
318
	  * A1200E (PCI-E)
319
	  * A800P (PCI)
320
	  * A800E (PCI-E)
321
322
	  To compile this driver as a module, choose M here: the
323
	  module will be called opvxa1200.
324
325
	  If unsure, say Y.
326
327
config DAHDI_OPVXD115
328
	tristate "OpenVox Single-T1/E1/J1 Support"
329
	depends on DAHDI && PCI
330
	default DAHDI
331
	---help---
332
	  This driver provides support for the following OpenVox
333
	  Wildcard products:
334
335
	  * D115P/DE115P/D130P/DE130P (PCI)
336
	  * D115E/DE115E/D130E/DE130E (PCI-E)
337
338
	  To compile this driver as a module, choose M here: the
339
	  module will be called opvxd115.
340
341
	  If unsure, say Y.
342
343
344
config DAHDI_WCOPENPCI
345
	tristate "Voicetronix OpenPCI Interface DAHDI driver"
346
	depends on DAHDI && PCI
347
	default DAHDI
348
	---help---
349
	  This driver provides support for the Voicetronix OpenPCI Interface.
350
351
	  To compile this driver as a module, choose M here: the
352
	  module will be called wcopenpci.
353
354
	  If unsure, say Y.
355
356
config DAHDI_ZAPHFC
357
	tristate "HFC-S DAHDI Driver"
358
	depends on DAHDI && PCI
359
	default DAHDI
360
	---help---
361
	  This driver provides DAHDI support for various HFC-S single-port
362
          ISDN (BRI) cards.
363
364
	  To compile this driver as a module, choose M here: the
365
	  module will be called zaphfc.
366
367
	  If unsure, say Y.
368
369
config ECHO
370
	tristate "Line Echo Canceller support"
371
	default DAHDI
372
	--help--
373
	  This driver provides line echo cancelling support for mISDN and
374
	  DAHDI drivers.
375
376
	  To compile this driver as a module, choose M here: the
377
	  module will be called echo.
378
379
	  If unsure, say Y.
380
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/base.c (+3065 lines)
Line 0 Link Here
1
/*
2
 * OpenVox A1200P FXS/FXO Interface Driver for DAHDI Telephony interface
3
 *
4
 * Written by MiaoLin<miaolin@openvox.cn>
5
 *
6
 * Copyright (C) 2005-2010 OpenVox Communication Co. Ltd,
7
 *
8
 * All rights reserved.
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 * 
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 * 
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
23
 *
24
 */
25
26
/* Rev histroy
27
 *
28
 * Rev 0.10 initial version	
29
 * Rev 0.11 
30
 * 	fixed the led light on/off bug.
31
 * 	modify some wctdm print to opvxa1200
32
 * 	support firmware version 1.2, faster i/o operation, and better LED control.
33
 * 
34
 * Rev 0.12 patched to support new pci id 0x8519
35
 * Rev 0.13 patched to remove the warning during compile under kernel 2.6.22 
36
 * Rev 0.14 patched to remove the bug for ZAP_IRQ_SHARED , 3/9/2007 
37
 * Rev 0.15 patched to support new pci ID 0X9532 by james.zhu, 23/10/2007
38
 * Rev 0.16 support new pci id 0x9559 by Miao Lin 21/3/2008
39
 * Rev 0.17 
40
 *	patched a few bugs, 
41
 *	add hwgain support.
42
 *	fixed A800P version check
43
 * Rev 1.4.9.2 
44
 *		Only generate 8 channels for A800P
45
 * 		Version number synced to zaptel distribution.
46
 * Rev 1.4.9.2.a
47
 *		Fixed freeregion.
48
 * 		
49
 * Rev 1.4.9.2.b
50
 *    Add cid before first ring support.
51
 *    New Paremeters:
52
 *          	cidbeforering : set to 1 will cause the card enable cidbeforering function. default 0
53
 * 		cidbuflen : length of cid buffer, in msec, default 3000 msec.
54
 *              cidtimeout : time out of a ring, default 6000msec
55
 *   	User must set cidstart=polarity in zapata.conf to use with this feature
56
 * 		cidsignalling = signalling format send before 1st ring. most likely dtmf.
57
 * 
58
 * Rev 1.4.9.2.c
59
 * 	add driver parameter cidtimeout.
60
 * 
61
 * Rev 1.4.9.2.d 
62
 *  	add debug stuff to test fxs power alarm
63
 *  
64
 * Rev 1.4.11
65
 *  	Support enhanced full scale tx/rx for FXO required by europe standard (Register 30, acim) (module parm fxofullscale)
66
 *  
67
 * Rev 1.4.12 2008/10/17
68
 *      Fixed bug cause FXS module report fake power alarm.
69
 *      Power alarm debug stuff removed.
70
 * 
71
 * Rev 2.0 DAHDI 2008/10/17
72
 *
73
 * Rev 2.0.1 add new pci id 0x9599
74
 * Re 2.0.2 12/01/2009  
75
       add fixedtimepolarity: set time(ms) when send polarity after 1st ring happen. 
76
 *				Sometimes the dtmf cid is sent just after first ring off, and the system do not have 
77
 *				enough time to start detect 1st dtmf.
78
 *				0 means send polarity at the end of 1st ring.
79
 *				x means send ploarity after x ms of 1st ring begin.
80
 * 
81
 * Rev 2.0.3 12/01/2009 
82
 *        Add touch_softlockup_watchdog() in wctdm_hardware_init, to avoid cpu softlockup system message for FXS.
83
 *
84
 *
85
 * Rev 1.4.12.4  17/04/2009 James.zhu
86
 *       Changed wctdm_voicedaa_check_hook() to detect FXO battery and solved the problem with dial(dahdi/go/XXXXXXXXXX)
87
 *       add alarm detection for FXO
88
 *
89
 * Rev 1.4.12.5 01/10/2009 james.zhu
90
 *       Add jiffies for 5 second in wctdm_hardware_init
91
 *
92
 *
93
 */ 
94
95
#include <linux/kernel.h>
96
#include <linux/errno.h>
97
#include <linux/module.h>
98
#include <linux/init.h>
99
#include <linux/errno.h>
100
#include <linux/pci.h>
101
#include <linux/interrupt.h>
102
#include <linux/moduleparam.h>
103
#include <asm/io.h>
104
#include <linux/sched.h>
105
#include "proslic.h"
106
   
107
/* MiaoLin debug start */
108
#include <linux/string.h>
109
#include <asm/uaccess.h> 	/* get_fs(), set_fs(), KERNEL_DS */
110
#include <linux/file.h> 	/* fput() */
111
/* MiaoLin debug end */
112
  
113
114
/*
115
 *  Define for audio vs. register based ring detection
116
 *  
117
 */
118
/* #define AUDIO_RINGCHECK  */
119
120
/*
121
  Experimental max loop current limit for the proslic
122
  Loop current limit is from 20 mA to 41 mA in steps of 3
123
  (according to datasheet)
124
  So set the value below to:
125
  0x00 : 20mA (default)
126
  0x01 : 23mA
127
  0x02 : 26mA
128
  0x03 : 29mA
129
  0x04 : 32mA
130
  0x05 : 35mA
131
  0x06 : 37mA
132
  0x07 : 41mA
133
*/
134
static int loopcurrent = 20;
135
136
static int reversepolarity = 0;
137
138
static alpha  indirect_regs[] =
139
{
140
{0,255,"DTMF_ROW_0_PEAK",0x55C2},
141
{1,255,"DTMF_ROW_1_PEAK",0x51E6},
142
{2,255,"DTMF_ROW2_PEAK",0x4B85},
143
{3,255,"DTMF_ROW3_PEAK",0x4937},
144
{4,255,"DTMF_COL1_PEAK",0x3333},
145
{5,255,"DTMF_FWD_TWIST",0x0202},
146
{6,255,"DTMF_RVS_TWIST",0x0202},
147
{7,255,"DTMF_ROW_RATIO_TRES",0x0198},
148
{8,255,"DTMF_COL_RATIO_TRES",0x0198},
149
{9,255,"DTMF_ROW_2ND_ARM",0x0611},
150
{10,255,"DTMF_COL_2ND_ARM",0x0202},
151
{11,255,"DTMF_PWR_MIN_TRES",0x00E5},
152
{12,255,"DTMF_OT_LIM_TRES",0x0A1C},
153
{13,0,"OSC1_COEF",0x7B30},
154
{14,1,"OSC1X",0x0063},
155
{15,2,"OSC1Y",0x0000},
156
{16,3,"OSC2_COEF",0x7870},
157
{17,4,"OSC2X",0x007D},
158
{18,5,"OSC2Y",0x0000},
159
{19,6,"RING_V_OFF",0x0000},
160
{20,7,"RING_OSC",0x7EF0},
161
{21,8,"RING_X",0x0160},
162
{22,9,"RING_Y",0x0000},
163
{23,255,"PULSE_ENVEL",0x2000},
164
{24,255,"PULSE_X",0x2000},
165
{25,255,"PULSE_Y",0x0000},
166
//{26,13,"RECV_DIGITAL_GAIN",0x4000},	// playback volume set lower
167
{26,13,"RECV_DIGITAL_GAIN",0x2000},	// playback volume set lower
168
{27,14,"XMIT_DIGITAL_GAIN",0x4000},
169
//{27,14,"XMIT_DIGITAL_GAIN",0x2000},
170
{28,15,"LOOP_CLOSE_TRES",0x1000},
171
{29,16,"RING_TRIP_TRES",0x3600},
172
{30,17,"COMMON_MIN_TRES",0x1000},
173
{31,18,"COMMON_MAX_TRES",0x0200},
174
{32,19,"PWR_ALARM_Q1Q2",0x07C0},
175
{33,20,"PWR_ALARM_Q3Q4",0x2600},
176
{34,21,"PWR_ALARM_Q5Q6",0x1B80},
177
{35,22,"LOOP_CLOSURE_FILTER",0x8000},
178
{36,23,"RING_TRIP_FILTER",0x0320},
179
{37,24,"TERM_LP_POLE_Q1Q2",0x008C},
180
{38,25,"TERM_LP_POLE_Q3Q4",0x0100},
181
{39,26,"TERM_LP_POLE_Q5Q6",0x0010},
182
{40,27,"CM_BIAS_RINGING",0x0C00},
183
{41,64,"DCDC_MIN_V",0x0C00},
184
{42,255,"DCDC_XTRA",0x1000},
185
{43,66,"LOOP_CLOSE_TRES_LOW",0x1000},
186
};
187
188
189
#include <dahdi/kernel.h>
190
#include <dahdi/wctdm_user.h>
191
192
#include "fxo_modes.h"
193
194
#define NUM_FXO_REGS 60
195
196
#define WC_MAX_IFACES 128
197
198
#define WC_OFFSET	4	/* Offset between transmit and receive, in bytes. */
199
#define WC_SYNCFLAG	0xca1ef1ac
200
201
#define WC_CNTL    	0x00
202
#define WC_OPER		0x01
203
#define WC_AUXC    	0x02
204
#define WC_AUXD    	0x03
205
#define WC_MASK0   	0x04
206
#define WC_MASK1   	0x05
207
#define WC_INTSTAT 	0x06
208
#define WC_AUXR		0x07
209
210
#define WC_DMAWS	0x08
211
#define WC_DMAWI	0x0c
212
#define WC_DMAWE	0x10
213
#define WC_DMARS	0x18
214
#define WC_DMARI	0x1c
215
#define WC_DMARE	0x20
216
217
#define WC_AUXFUNC	0x2b
218
#define WC_SERCTL	0x2d
219
#define WC_FSCDELAY	0x2f
220
221
#define WC_REGBASE	0xc0
222
223
#define WC_VER		0x0
224
#define WC_CS		0x1
225
#define WC_SPICTRL	0x2
226
#define WC_SPIDATA	0x3
227
228
#define BIT_SPI_BYHW 	(1 << 0)
229
#define BIT_SPI_BUSY    (1 << 1)	// 0=can read/write spi, 1=spi working.
230
#define BIT_SPI_START	(1 << 2)
231
232
233
#define BIT_LED_CLK     (1 << 0)	// MiaoLin add to control the led. 
234
#define BIT_LED_DATA    (1 << 1)	// MiaoLin add to control the led.
235
236
#define BIT_CS		(1 << 2)
237
#define BIT_SCLK	(1 << 3)
238
#define BIT_SDI		(1 << 4)
239
#define BIT_SDO		(1 << 5)
240
241
#define FLAG_EMPTY	0
242
#define FLAG_WRITE	1
243
#define FLAG_READ	2
244
#define DEFAULT_RING_DEBOUNCE		64		/* Ringer Debounce (64 ms) */
245
#define POLARITY_DEBOUNCE 	64  	/* Polarity debounce (64 ms) */
246
#define OHT_TIMER		6000	/* How long after RING to retain OHT */
247
248
#define FLAG_3215	(1 << 0)
249
#define FLAG_A800	(1 << 7)
250
251
#define MAX_NUM_CARDS 12
252
#define NUM_CARDS 12
253
#define NUM_FLAG  4	/* number of flag channels. */
254
255
256
enum cid_hook_state {
257
	CID_STATE_IDLE = 0,
258
	CID_STATE_RING_ON,
259
	CID_STATE_RING_OFF,
260
	CID_STATE_WAIT_RING_FINISH
261
};
262
263
/* if you want to record the last 8 sec voice before the driver unload, uncomment it and rebuild. */
264
/* #define TEST_LOG_INCOME_VOICE */
265
#define voc_buffer_size (8000*8)
266
267
268
#define MAX_ALARMS 10
269
270
#define MOD_TYPE_FXS	0
271
#define MOD_TYPE_FXO	1
272
273
#define MINPEGTIME	10 * 8		/* 30 ms peak to peak gets us no more than 100 Hz */
274
#define PEGTIME		50 * 8		/* 50ms peak to peak gets us rings of 10 Hz or more */
275
#define PEGCOUNT	5		/* 5 cycles of pegging means RING */
276
277
#define NUM_CAL_REGS 12
278
279
struct calregs {
280
	unsigned char vals[NUM_CAL_REGS];
281
};
282
283
enum proslic_power_warn {
284
	PROSLIC_POWER_UNKNOWN = 0,
285
	PROSLIC_POWER_ON,
286
	PROSLIC_POWER_WARNED,
287
};
288
289
enum battery_state {
290
	BATTERY_UNKNOWN = 0,
291
	BATTERY_PRESENT,
292
	BATTERY_LOST,
293
};
294
struct wctdm {
295
	struct pci_dev *dev;
296
	char *variety;
297
	struct dahdi_span span;
298
	struct dahdi_device *ddev;
299
	unsigned char ios;
300
	int usecount;
301
	unsigned int intcount;
302
	int dead;
303
	int pos;
304
	int flags[MAX_NUM_CARDS];
305
	int freeregion;
306
	int alt;
307
	int curcard;
308
	int cardflag;		/* Bit-map of present cards */
309
	enum proslic_power_warn proslic_power;
310
	spinlock_t lock;
311
312
	union {
313
		struct fxo {
314
#ifdef AUDIO_RINGCHECK
315
			unsigned int pegtimer;
316
			int pegcount;
317
			int peg;
318
			int ring;
319
#else			
320
			int wasringing;
321
			int lastrdtx;
322
#endif			
323
			int ringdebounce;
324
			int offhook;
325
		    unsigned int battdebounce;
326
			unsigned int battalarm;
327
			enum battery_state battery;
328
		        int lastpol;
329
		        int polarity;
330
		        int polaritydebounce;
331
		} fxo;
332
		struct fxs {
333
			int oldrxhook;
334
			int debouncehook;
335
			int lastrxhook;
336
			int debounce;
337
			int ohttimer;
338
			int idletxhookstate;		/* IDLE changing hook state */
339
			int lasttxhook;
340
			int palarms;
341
			struct calregs calregs;
342
		} fxs;
343
	} mod[MAX_NUM_CARDS];
344
345
	/* Receive hook state and debouncing */
346
	int modtype[MAX_NUM_CARDS];
347
	unsigned char reg0shadow[MAX_NUM_CARDS];
348
	unsigned char reg1shadow[MAX_NUM_CARDS];
349
350
	unsigned long ioaddr;
351
	unsigned long mem_region;	/* 32 bit Region allocated to tiger320 */
352
	unsigned long mem_len;		/* Length of 32 bit region */
353
	volatile unsigned long mem32;	/* Virtual representation of 32 bit memory area */
354
	
355
	dma_addr_t 	readdma;
356
	dma_addr_t	writedma;
357
	volatile unsigned char *writechunk;					/* Double-word aligned write memory */
358
	volatile unsigned char *readchunk;					/* Double-word aligned read memory */
359
	/*struct dahdi_chan chans[MAX_NUM_CARDS];*/
360
	struct dahdi_chan _chans[NUM_CARDS];
361
	struct dahdi_chan *chans[NUM_CARDS];
362
363
364
#ifdef TEST_LOG_INCOME_VOICE	
365
	char * voc_buf[MAX_NUM_CARDS + NUM_FLAG];
366
	int voc_ptr[MAX_NUM_CARDS + NUM_FLAG];
367
#endif
368
	int lastchan;
369
	unsigned short ledstate;
370
	unsigned char fwversion;
371
	int max_cards;
372
	char *card_name;
373
	
374
	char *cid_history_buf[MAX_NUM_CARDS];
375
	int	 cid_history_ptr[MAX_NUM_CARDS];
376
	int  cid_history_clone_cnt[MAX_NUM_CARDS];
377
	enum cid_hook_state cid_state[MAX_NUM_CARDS];
378
   int 	cid_ring_on_time[MAX_NUM_CARDS];
379
};
380
381
static char* A1200P_Name = "A1200P";
382
static char* A800P_Name  = "A800P";
383
384
struct wctdm_desc {
385
	char *name;
386
	int flags;
387
};
388
389
static struct wctdm_desc wctdme = { "OpenVox A1200P/A800P", 0 };
390
static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 };
391
392
static struct wctdm *ifaces[WC_MAX_IFACES];
393
394
static void wctdm_release(struct wctdm *wc);
395
396
static unsigned int battdebounce;
397
static unsigned int battalarm;
398
static unsigned int battthresh;
399
static int ringdebounce = DEFAULT_RING_DEBOUNCE;
400
/* times 4, because must be a multiple of 4ms: */
401
static int dialdebounce = 8 * 8;
402
static int fwringdetect = 0;
403
static int debug = 0;
404
static int robust = 0;
405
static int timingonly = 0;
406
static int lowpower = 0;
407
static int boostringer = 0;
408
static int fastringer = 0;
409
static int _opermode = 0;
410
static char *opermode = "FCC";
411
static int fxshonormode = 0;
412
static int alawoverride = 0;
413
static int fastpickup = 0;
414
static int fxotxgain = 0;
415
static int fxorxgain = 0;
416
static int fxstxgain = 0;
417
static int fxsrxgain = 0;
418
/* special h/w control command */
419
static int spibyhw = 1;
420
static int usememio = 1;
421
static int cidbeforering = 0;
422
static int cidbuflen = 3000;	/* in msec, default 3000 */
423
static int cidtimeout = 6*1000;	/* in msec, default 6000 */
424
static int fxofullscale = 0;	/* fxo full scale tx/rx, register 30, acim */
425
static int fixedtimepolarity=0;	/* time delay in ms when send polarity after rise edge of 1st ring.*/
426
427
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
428
429
static void wctdm_set_led(struct wctdm* wc, int card, int onoff)
430
{
431
	int i;
432
	unsigned char c;
433
	
434
	wc->ledstate &= ~(0x01<<card);
435
	wc->ledstate |= (onoff<<card);
436
	c = (inb(wc->ioaddr + WC_AUXD)&~BIT_LED_CLK)|BIT_LED_DATA;
437
	outb( c,  wc->ioaddr + WC_AUXD);
438
	for(i=MAX_NUM_CARDS-1; i>=0; i--)
439
	{
440
		if(wc->ledstate & (0x0001<<i))
441
			if(wc->fwversion == 0x11)
442
				c &= ~BIT_LED_DATA;
443
			else
444
				c |= BIT_LED_DATA;
445
		else
446
			if(wc->fwversion == 0x11)
447
				c |= BIT_LED_DATA;
448
			else
449
				c &= ~BIT_LED_DATA;
450
			
451
		outb( c,  wc->ioaddr + WC_AUXD);
452
		outb( c|BIT_LED_CLK,  wc->ioaddr + WC_AUXD);
453
		outb( (c&~BIT_LED_CLK)|BIT_LED_DATA,  wc->ioaddr + WC_AUXD);
454
	}	
455
}
456
 
457
458
static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char ints)
459
{
460
	int x, y, chan_offset, pos;
461
	volatile unsigned char *txbuf;
462
	
463
	if (ints & /*0x01*/ 0x04) 
464
		/* Write is at interrupt address.  Start writing from normal offset */
465
		txbuf = wc->writechunk;
466
	else 
467
		txbuf = wc->writechunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
468
		
469
	/* Calculate Transmission */
470
	dahdi_transmit(&wc->span);
471
	
472
	if(wc->lastchan == -1)	// not in sync.
473
		return;
474
	
475
	chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
476
477
	for (y=0;y<DAHDI_CHUNKSIZE;y++) {
478
#ifdef __BIG_ENDIAN
479
	// operation pending...
480
#else
481
		for (x=0;x<(MAX_NUM_CARDS+NUM_FLAG);x++) {
482
			pos = y * (MAX_NUM_CARDS+NUM_FLAG) + ((x + chan_offset + MAX_NUM_CARDS+NUM_FLAG - WC_OFFSET)&0x0f);
483
			if(x<wc->max_cards/*MAX_NUM_CARDS*/)
484
				txbuf[pos] = wc->chans[x]->writechunk[y]; 
485
			else
486
				txbuf[pos] = 0; 
487
		}
488
#endif
489
	}
490
}
491
492
493
#ifdef AUDIO_RINGCHECK
494
static inline void ring_check(struct wctdm *wc, int card)
495
{
496
	int x;
497
	short sample;
498
	if (wc->modtype[card] != MOD_TYPE_FXO)
499
		return;
500
	wc->mod[card].fxo.pegtimer += DAHDI_CHUNKSIZE;
501
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
502
		/* Look for pegging to indicate ringing */
503
		sample = DAHDI_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card])));
504
		if ((sample > 10000) && (wc->mod[card].fxo.peg != 1)) {
505
			if (debug > 1) printk(KERN_DEBUG "High peg!\n");
506
			if ((wc->mod[card].fxo.pegtimer < PEGTIME) && (wc->mod[card].fxo.pegtimer > MINPEGTIME))
507
				wc->mod[card].fxo.pegcount++;
508
			wc->mod[card].fxo.pegtimer = 0;
509
			wc->mod[card].fxo.peg = 1;
510
		} else if ((sample < -10000) && (wc->mod[card].fxo.peg != -1)) {
511
			if (debug > 1) printk(KERN_DEBUG "Low peg!\n");
512
			if ((wc->mod[card].fxo.pegtimer < (PEGTIME >> 2)) && (wc->mod[card].fxo.pegtimer > (MINPEGTIME >> 2)))
513
				wc->mod[card].fxo.pegcount++;
514
			wc->mod[card].fxo.pegtimer = 0;
515
			wc->mod[card].fxo.peg = -1;
516
		}
517
	}
518
	if (wc->mod[card].fxo.pegtimer > PEGTIME) {
519
		/* Reset pegcount if our timer expires */
520
		wc->mod[card].fxo.pegcount = 0;
521
	}
522
	/* Decrement debouncer if appropriate */
523
	if (wc->mod[card].fxo.ringdebounce)
524
		wc->mod[card].fxo.ringdebounce--;
525
	if (!wc->mod[card].fxo.offhook && !wc->mod[card].fxo.ringdebounce) {
526
		if (!wc->mod[card].fxo.ring && (wc->mod[card].fxo.pegcount > PEGCOUNT)) {
527
			/* It's ringing */
528
			if (debug)
529
				printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
530
			if (!wc->mod[card].fxo.offhook)
531
				dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_RING);
532
			wc->mod[card].fxo.ring = 1;
533
		}
534
		if (wc->mod[card].fxo.ring && !wc->mod[card].fxo.pegcount) {
535
			/* No more ring */
536
			if (debug)
537
				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
538
			dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
539
			wc->mod[card].fxo.ring = 0;
540
		}
541
	}
542
}
543
#endif
544
545
546
static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char ints)
547
{
548
	volatile unsigned char *rxbuf;
549
	int x, y, chan_offset;
550
551
552
	if (ints & 0x08/*0x04*/)
553
		/* Read is at interrupt address.  Valid data is available at normal offset */
554
		rxbuf = wc->readchunk;
555
	else
556
		rxbuf = wc->readchunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
557
558
	for(x=0; x<4; x++)
559
		if(  *(int*)(rxbuf+x*4) == WC_SYNCFLAG)
560
			break;
561
	if(x==4)
562
	{
563
		printk("buffer sync misseed!\n");
564
		wc->lastchan = -1;
565
		return;
566
	}
567
	else if(wc->lastchan != x)
568
	{
569
		printk("buffer re-sync occur from %d to %d\n", wc->lastchan, x);
570
		wc->lastchan = x;
571
	}
572
	chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
573
574
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
575
#ifdef __BIG_ENDIAN
576
	// operation pending...
577
#else
578
		for (y=0;y<wc->max_cards/*MAX_NUM_CARDS*/;y++) { 
579
			if (wc->cardflag & (1 << y))
580
				wc->chans[y]->readchunk[x] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset ) & 0x0f)];
581
#ifdef TEST_LOG_INCOME_VOICE
582
			wc->voc_buf[y][wc->voc_ptr[y]] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset) & 0x0f)];
583
			wc->voc_ptr[y]++;
584
			if(wc->voc_ptr[y] >= voc_buffer_size)
585
				wc->voc_ptr[y] = 0;
586
#endif		
587
		}
588
#endif
589
	}
590
	
591
	if(cidbeforering)
592
	{
593
		for(x=0; x<wc->max_cards; x++)
594
		{
595
			if (wc->modtype[wc->chans[x]->chanpos - 1] == MOD_TYPE_FXO)
596
				if(wc->mod[wc->chans[x]->chanpos - 1].fxo.offhook == 0)
597
				{
598
					/*unsigned int *p_readchunk, *p_cid_history;
599
					
600
					p_readchunk = (unsigned int*)wc->chans[x].readchunk;
601
					p_cid_history = (unsigned int*)(wc->cid_history_buf[x] + wc->cid_history_ptr[x]);*/
602
					
603
					if(wc->cid_state[x] == CID_STATE_IDLE)	/* we need copy data to the cid voice buffer */
604
					{
605
						memcpy(wc->cid_history_buf[x] + wc->cid_history_ptr[x], wc->chans[x]->readchunk, DAHDI_CHUNKSIZE);
606
						wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
607
					}
608
					else if (wc->cid_state[x] == CID_STATE_RING_ON)
609
						wc->cid_history_clone_cnt[x] = cidbuflen;
610
					else if (wc->cid_state[x] == CID_STATE_RING_OFF)
611
					{ 
612
						if(wc->cid_history_clone_cnt[x])
613
						{	
614
							memcpy(wc->chans[x]->readchunk, wc->cid_history_buf[x] + wc->cid_history_ptr[x], DAHDI_MAX_CHUNKSIZE);
615
							wc->cid_history_clone_cnt[x]--;
616
							wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_MAX_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
617
						}
618
						else
619
						{
620
							wc->cid_state[x] = CID_STATE_WAIT_RING_FINISH;
621
							wc->cid_history_clone_cnt[x] = cidtimeout; /* wait 6 sec, if no ring, return to idle */
622
						}
623
					}
624
					else if(wc->cid_state[x] == CID_STATE_WAIT_RING_FINISH)
625
					{
626
						if(wc->cid_history_clone_cnt[x] > 0)
627
							wc->cid_history_clone_cnt[x]--;
628
						else
629
						{
630
							wc->cid_state[x] = CID_STATE_IDLE;
631
							wc->cid_history_ptr[x] = 0;
632
							wc->cid_history_clone_cnt[x] = 0;
633
						}
634
					}
635
				}
636
		}		
637
	}
638
	
639
#ifdef AUDIO_RINGCHECK
640
	for (x=0;x<wc->max_cards;x++)
641
		ring_check(wc, x);
642
#endif		
643
	/* XXX We're wasting 8 taps.  We should get closer :( */
644
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
645
		if (wc->cardflag & (1 << x))
646
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
647
	}
648
	dahdi_receive(&wc->span);
649
}
650
651
static void wctdm_stop_dma(struct wctdm *wc);
652
static void wctdm_reset_tdm(struct wctdm *wc);
653
static void wctdm_restart_dma(struct wctdm *wc);
654
655
656
static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg);
657
static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val);
658
659
660
static inline void __write_8bits(struct wctdm *wc, unsigned char bits)
661
{
662
	if(spibyhw == 0)
663
	{
664
		int x;
665
		/* Drop chip select */
666
		wc->ios |= BIT_SCLK;
667
		outb(wc->ios, wc->ioaddr + WC_AUXD);
668
		wc->ios &= ~BIT_CS;
669
		outb(wc->ios, wc->ioaddr + WC_AUXD);
670
		for (x=0;x<8;x++) {
671
			/* Send out each bit, MSB first, drop SCLK as we do so */
672
			if (bits & 0x80)
673
				wc->ios |= BIT_SDI;
674
			else
675
				wc->ios &= ~BIT_SDI;
676
			wc->ios &= ~BIT_SCLK;
677
			outb(wc->ios, wc->ioaddr + WC_AUXD);
678
			/* Now raise SCLK high again and repeat */
679
			wc->ios |= BIT_SCLK;
680
			outb(wc->ios, wc->ioaddr + WC_AUXD);
681
			bits <<= 1;
682
		}
683
		/* Finally raise CS back high again */
684
		wc->ios |= BIT_CS;
685
		outb(wc->ios, wc->ioaddr + WC_AUXD);
686
	}
687
	else
688
	{
689
		__wctdm_setcreg(wc, WC_SPIDATA, bits);
690
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
691
		while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
692
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
693
	}
694
}
695
696
697
static inline void __reset_spi(struct wctdm *wc)
698
{
699
	__wctdm_setcreg(wc, WC_SPICTRL, 0);
700
	
701
	/* Drop chip select and clock once and raise and clock once */
702
	wc->ios |= BIT_SCLK;
703
	outb(wc->ios, wc->ioaddr + WC_AUXD);
704
	wc->ios &= ~BIT_CS;
705
	outb(wc->ios, wc->ioaddr + WC_AUXD);
706
	wc->ios |= BIT_SDI;
707
	wc->ios &= ~BIT_SCLK;
708
	outb(wc->ios, wc->ioaddr + WC_AUXD);
709
	/* Now raise SCLK high again and repeat */
710
	wc->ios |= BIT_SCLK;
711
	outb(wc->ios, wc->ioaddr + WC_AUXD);
712
	/* Finally raise CS back high again */
713
	wc->ios |= BIT_CS;
714
	outb(wc->ios, wc->ioaddr + WC_AUXD);
715
	/* Clock again */
716
	wc->ios &= ~BIT_SCLK;
717
	outb(wc->ios, wc->ioaddr + WC_AUXD);
718
	/* Now raise SCLK high again and repeat */
719
	wc->ios |= BIT_SCLK;
720
	outb(wc->ios, wc->ioaddr + WC_AUXD);
721
	
722
	__wctdm_setcreg(wc, WC_SPICTRL, spibyhw);
723
724
}
725
726
static inline unsigned char __read_8bits(struct wctdm *wc)
727
{
728
	unsigned char res=0, c;
729
	int x;
730
	if(spibyhw == 0)
731
	{
732
		wc->ios &= ~BIT_CS;
733
		outb(wc->ios, wc->ioaddr + WC_AUXD);
734
		/* Drop chip select */
735
		wc->ios &= ~BIT_CS;
736
		outb(wc->ios, wc->ioaddr + WC_AUXD);
737
		for (x=0;x<8;x++) {
738
			res <<= 1;
739
			/* Get SCLK */
740
			wc->ios &= ~BIT_SCLK;
741
			outb(wc->ios, wc->ioaddr + WC_AUXD);
742
			/* Read back the value */
743
			c = inb(wc->ioaddr + WC_AUXR);
744
			if (c & BIT_SDO)
745
				res |= 1;
746
			/* Now raise SCLK high again */
747
			wc->ios |= BIT_SCLK;
748
			outb(wc->ios, wc->ioaddr + WC_AUXD);
749
		}
750
		/* Finally raise CS back high again */
751
		wc->ios |= BIT_CS;
752
		outb(wc->ios, wc->ioaddr + WC_AUXD);
753
		wc->ios &= ~BIT_SCLK;
754
		outb(wc->ios, wc->ioaddr + WC_AUXD);
755
	}
756
	else
757
	{
758
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
759
		while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
760
		res = __wctdm_getcreg(wc, WC_SPIDATA);
761
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
762
	}
763
	
764
	/* And return our result */
765
	return res;
766
}
767
768
static void __wctdm_setcreg_mem(struct wctdm *wc, unsigned char reg, unsigned char val)
769
{
770
	unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
771
	*p = val;
772
}
773
774
static unsigned char __wctdm_getcreg_mem(struct wctdm *wc, unsigned char reg)
775
{
776
	unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
777
	return (*p)&0x00ff;
778
}
779
780
781
static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val)
782
{
783
	if(usememio)
784
		__wctdm_setcreg_mem(wc, reg, val);
785
	else
786
		outb(val, wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
787
}
788
789
static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg)
790
{
791
	if(usememio)
792
		return __wctdm_getcreg_mem(wc, reg);
793
	else
794
		return inb(wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
795
}
796
797
static inline void __wctdm_setcard(struct wctdm *wc, int card)
798
{
799
	if (wc->curcard != card) {
800
		__wctdm_setcreg(wc, WC_CS, card);
801
		wc->curcard = card;
802
		//printk("Select card %d\n", card);
803
	}
804
}
805
806
static void __wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
807
{
808
	__wctdm_setcard(wc, card);
809
	if (wc->modtype[card] == MOD_TYPE_FXO) {
810
		__write_8bits(wc, 0x20);
811
		__write_8bits(wc, reg & 0x7f);
812
	} else {
813
		__write_8bits(wc, reg & 0x7f);
814
	}
815
	__write_8bits(wc, value);
816
}
817
818
static void wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
819
{
820
	unsigned long flags;
821
	spin_lock_irqsave(&wc->lock, flags);
822
	__wctdm_setreg(wc, card, reg, value);
823
	spin_unlock_irqrestore(&wc->lock, flags);
824
}
825
826
static unsigned char __wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
827
{
828
	__wctdm_setcard(wc, card);
829
	if (wc->modtype[card] == MOD_TYPE_FXO) {
830
		__write_8bits(wc, 0x60);
831
		__write_8bits(wc, reg & 0x7f);
832
	} else {
833
		__write_8bits(wc, reg | 0x80);
834
	}
835
	return __read_8bits(wc);
836
}
837
838
static inline void reset_spi(struct wctdm *wc, int card)
839
{
840
	unsigned long flags;
841
	spin_lock_irqsave(&wc->lock, flags);
842
	__wctdm_setcard(wc, card);
843
	__reset_spi(wc);
844
	__reset_spi(wc);
845
	spin_unlock_irqrestore(&wc->lock, flags);
846
}
847
848
static unsigned char wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
849
{
850
	unsigned long flags;
851
	unsigned char res;
852
	spin_lock_irqsave(&wc->lock, flags);
853
	res = __wctdm_getreg(wc, card, reg);
854
	spin_unlock_irqrestore(&wc->lock, flags);
855
	return res;
856
}
857
858
static int __wait_access(struct wctdm *wc, int card)
859
{
860
    unsigned char data = 0;
861
    long origjiffies;
862
    int count = 0;
863
864
    #define MAX 6000 /* attempts */
865
866
867
    origjiffies = jiffies;
868
    /* Wait for indirect access */
869
    while (count++ < MAX)
870
	 {
871
		data = __wctdm_getreg(wc, card, I_STATUS);
872
873
		if (!data)
874
			return 0;
875
876
	 }
877
878
    if(count > (MAX-1)) printk(KERN_NOTICE " ##### Loop error (%02x) #####\n", data);
879
880
	return 0;
881
}
882
883
static unsigned char translate_3215(unsigned char address)
884
{
885
	int x;
886
	for (x=0;x<sizeof(indirect_regs)/sizeof(indirect_regs[0]);x++) {
887
		if (indirect_regs[x].address == address) {
888
			address = indirect_regs[x].altaddr;
889
			break;
890
		}
891
	}
892
	return address;
893
}
894
895
static int wctdm_proslic_setreg_indirect(struct wctdm *wc, int card, unsigned char address, unsigned short data)
896
{
897
	unsigned long flags;
898
	int res = -1;
899
	/* Translate 3215 addresses */
900
	if (wc->flags[card] & FLAG_3215) {
901
		address = translate_3215(address);
902
		if (address == 255)
903
			return 0;
904
	}
905
	spin_lock_irqsave(&wc->lock, flags);
906
	if(!__wait_access(wc, card)) {
907
		__wctdm_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF));
908
		__wctdm_setreg(wc, card, IDA_HI,(unsigned char)((data & 0xFF00)>>8));
909
		__wctdm_setreg(wc, card, IAA,address);
910
		res = 0;
911
	};
912
	spin_unlock_irqrestore(&wc->lock, flags);
913
	return res;
914
}
915
916
static int wctdm_proslic_getreg_indirect(struct wctdm *wc, int card, unsigned char address)
917
{ 
918
	unsigned long flags;
919
	int res = -1;
920
	char *p=NULL;
921
	/* Translate 3215 addresses */
922
	if (wc->flags[card] & FLAG_3215) {
923
		address = translate_3215(address);
924
		if (address == 255)
925
			return 0;
926
	}
927
	spin_lock_irqsave(&wc->lock, flags);
928
	if (!__wait_access(wc, card)) {
929
		__wctdm_setreg(wc, card, IAA, address);
930
		if (!__wait_access(wc, card)) {
931
			unsigned char data1, data2;
932
			data1 = __wctdm_getreg(wc, card, IDA_LO);
933
			data2 = __wctdm_getreg(wc, card, IDA_HI);
934
			res = data1 | (data2 << 8);
935
		} else
936
			p = "Failed to wait inside\n";
937
	} else
938
		p = "failed to wait\n";
939
	spin_unlock_irqrestore(&wc->lock, flags);
940
	if (p)
941
		printk(KERN_NOTICE "%s", p);
942
	return res;
943
}
944
945
static int wctdm_proslic_init_indirect_regs(struct wctdm *wc, int card)
946
{
947
	unsigned char i;
948
949
	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
950
	{
951
		if(wctdm_proslic_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))
952
			return -1;
953
	}
954
955
	return 0;
956
}
957
958
static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card)
959
{ 
960
	int passed = 1;
961
	unsigned short i, initial;
962
	int j;
963
964
	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++) 
965
	{
966
		if((j = wctdm_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
967
			printk(KERN_NOTICE "Failed to read indirect register %d\n", i);
968
			return -1;
969
		}
970
		initial= indirect_regs[i].initial;
971
972
		if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255)))
973
		{
974
			 printk(KERN_NOTICE "!!!!!!! %s  iREG %X = %X  should be %X\n",
975
				indirect_regs[i].name,indirect_regs[i].address,j,initial );
976
			 passed = 0;
977
		}	
978
	}
979
980
    if (passed) {
981
		if (debug)
982
			printk(KERN_DEBUG "Init Indirect Registers completed successfully.\n");
983
    } else {
984
		printk(KERN_NOTICE " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
985
		return -1;
986
    }
987
    return 0;
988
}
989
990
static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card)
991
{
992
	int res;
993
	/* Check loopback */
994
	res = wc->reg1shadow[card];
995
	
996
	if (!res && (res != wc->mod[card].fxs.lasttxhook))     // read real state from register   By wx
997
		res=wctdm_getreg(wc, card, 64);
998
	
999
	if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
1000
		res = wctdm_getreg(wc, card, 8);
1001
		if (res) {
1002
			printk(KERN_NOTICE "Ouch, part reset, quickly restoring reality (%d)\n", card);
1003
			wctdm_init_proslic(wc, card, 1, 0, 1);
1004
		} else {
1005
			if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
1006
				printk(KERN_NOTICE "Power alarm on module %d, resetting!\n", card + 1);
1007
				if (wc->mod[card].fxs.lasttxhook == 4)
1008
					wc->mod[card].fxs.lasttxhook = 1;
1009
				wctdm_setreg(wc, card, 64, wc->mod[card].fxs.lasttxhook);
1010
			} else {
1011
				if (wc->mod[card].fxs.palarms == MAX_ALARMS)
1012
					printk(KERN_NOTICE "Too many power alarms on card %d, NOT resetting!\n", card + 1);
1013
			}
1014
		}
1015
	}
1016
}
1017
static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
1018
{
1019
#define MS_PER_CHECK_HOOK 16
1020
1021
#ifndef AUDIO_RINGCHECK
1022
	unsigned char res;
1023
#endif	
1024
	signed char b;
1025
	int errors = 0;
1026
	struct fxo *fxo = &wc->mod[card].fxo;
1027
1028
	/* Try to track issues that plague slot one FXO's */
1029
	b = wc->reg0shadow[card];
1030
	if ((b & 0x2) || !(b & 0x8)) {
1031
		/* Not good -- don't look at anything else */
1032
		if (debug)
1033
			printk(KERN_DEBUG "Error (%02x) on card %d!\n", b, card + 1); 
1034
		errors++;
1035
	}
1036
	b &= 0x9b;
1037
	if (fxo->offhook) {
1038
		if (b != 0x9)
1039
			wctdm_setreg(wc, card, 5, 0x9);
1040
	} else {
1041
		if (b != 0x8)
1042
			wctdm_setreg(wc, card, 5, 0x8);
1043
	}
1044
	if (errors)
1045
		return;
1046
	if (!fxo->offhook) {
1047
 if(fixedtimepolarity) {
1048
			if ( wc->cid_state[card] == CID_STATE_RING_ON && wc->cid_ring_on_time[card]>0)
1049
			{
1050
 	if(wc->cid_ring_on_time[card]>=fixedtimepolarity )
1051
			{
1052
			dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1053
			wc->cid_ring_on_time[card] = -1;	/* the polarity already sent */	
1054
			}
1055
			else
1056
		wc->cid_ring_on_time[card] += 16;
1057
    }
1058
}
1059
		if (fwringdetect) {
1060
			res = wc->reg0shadow[card] & 0x60;
1061
			if (fxo->ringdebounce) {
1062
				--fxo->ringdebounce;
1063
				if (res && (res != fxo->lastrdtx) &&
1064
				    (fxo->battery == BATTERY_PRESENT)) {
1065
					if (!fxo->wasringing) {
1066
						fxo->wasringing = 1;
1067
						if (debug)
1068
          printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
1069
	if(cidbeforering)
1070
						{
1071
							if(wc->cid_state[card] == CID_STATE_IDLE)
1072
							{
1073
								wc->cid_state[card] = CID_STATE_RING_ON;
1074
								wc->cid_ring_on_time[card] = 16;	/* check every 16ms */
1075
							}
1076
							else
1077
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1078
						}
1079
						else 							
1080
        dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1081
					}
1082
					fxo->lastrdtx = res;
1083
					fxo->ringdebounce = 10;
1084
				} else if (!res) {
1085
					if ((fxo->ringdebounce == 0) && fxo->wasringing) {
1086
				fxo->wasringing = 0;
1087
				if (debug)
1088
				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
1089
	if(cidbeforering)
1090
						{
1091
							if(wc->cid_state[card] == CID_STATE_RING_ON)
1092
							{
1093
								if(fixedtimepolarity==0)
1094
									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1095
								wc->cid_state[card] = CID_STATE_RING_OFF;
1096
							}
1097
							else 
1098
							{
1099
								if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
1100
									wc->cid_history_clone_cnt[card] = cidtimeout;
1101
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1102
							}
1103
						}
1104
						else
1105
1106
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1107
				}
1108
				}
1109
			} else if (res && (fxo->battery == BATTERY_PRESENT)) {
1110
				fxo->lastrdtx = res;
1111
				fxo->ringdebounce = 10;
1112
			}
1113
		} else {
1114
			res = wc->reg0shadow[card];
1115
			if ((res & 0x60) && (fxo->battery == BATTERY_PRESENT)) {
1116
				fxo->ringdebounce += (DAHDI_CHUNKSIZE * 16);
1117
				if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
1118
					if (!fxo->wasringing) {
1119
						fxo->wasringing = 1;
1120
 if(cidbeforering)
1121
						{
1122
							if(wc->cid_state[card] == CID_STATE_IDLE)
1123
							{	
1124
								wc->cid_state[card] = CID_STATE_RING_ON;
1125
								wc->cid_ring_on_time[card] = 16;		/* check every 16ms */
1126
							}
1127
							else
1128
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1129
						}
1130
						else      
1131
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
1132
						if (debug)
1133
							printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
1134
					}
1135
					fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
1136
				}
1137
			} else {
1138
				fxo->ringdebounce -= DAHDI_CHUNKSIZE * 4;
1139
				if (fxo->ringdebounce <= 0) {
1140
					if (fxo->wasringing) {
1141
						fxo->wasringing = 0;
1142
	if(cidbeforering)
1143
						{
1144
							if(wc->cid_state[card] == CID_STATE_RING_ON)
1145
							{
1146
								if(fixedtimepolarity==0)
1147
									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1148
								wc->cid_state[card] = CID_STATE_RING_OFF;
1149
							}
1150
							else 
1151
							{
1152
								if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
1153
									wc->cid_history_clone_cnt[card] = cidtimeout;
1154
								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1155
							}
1156
						}
1157
						else
1158
						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1159
						if (debug)
1160
							printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
1161
					}
1162
					fxo->ringdebounce = 0;
1163
				}
1164
			}
1165
		}
1166
	}
1167
1168
	b = wc->reg1shadow[card];
1169
	if (abs(b) < battthresh) {
1170
		/* possible existing states:
1171
		   battery lost, no debounce timer
1172
		   battery lost, debounce timer (going to battery present)
1173
		   battery present or unknown, no debounce timer
1174
		   battery present or unknown, debounce timer (going to battery lost)
1175
		*/
1176
1177
		if (fxo->battery == BATTERY_LOST) {
1178
			if (fxo->battdebounce) {
1179
				/* we were going to BATTERY_PRESENT, but battery was lost again,
1180
				   so clear the debounce timer */
1181
				fxo->battdebounce = 0;
1182
			}
1183
		} else {
1184
			if (fxo->battdebounce) {
1185
				/* going to BATTERY_LOST, see if we are there yet */
1186
				if (--fxo->battdebounce == 0) {
1187
					fxo->battery = BATTERY_LOST;
1188
					if (debug)
1189
						printk(KERN_DEBUG "NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);
1190
#ifdef	JAPAN
1191
					if (!wc->ohdebounce && wc->offhook) {
1192
						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_ONHOOK);
1193
						if (debug)
1194
							printk(KERN_DEBUG "Signalled On Hook\n");
1195
#ifdef	ZERO_BATT_RING
1196
						wc->onhook++;
1197
#endif
1198
					}
1199
#else
1200
					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
1201
					/* set the alarm timer, taking into account that part of its time
1202
					   period has already passed while debouncing occurred */
1203
					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
1204
#endif
1205
				}
1206
			} else {
1207
				/* start the debounce timer to verify that battery has been lost */
1208
				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
1209
			}
1210
		}
1211
	} else {
1212
		/* possible existing states:
1213
		   battery lost or unknown, no debounce timer
1214
		   battery lost or unknown, debounce timer (going to battery present)
1215
		   battery present, no debounce timer
1216
		   battery present, debounce timer (going to battery lost)
1217
		*/
1218
1219
		if (fxo->battery == BATTERY_PRESENT) {
1220
			if (fxo->battdebounce) {
1221
				/* we were going to BATTERY_LOST, but battery appeared again,
1222
				   so clear the debounce timer */
1223
				fxo->battdebounce = 0;
1224
			}
1225
		} else {
1226
			if (fxo->battdebounce) {
1227
				/* going to BATTERY_PRESENT, see if we are there yet */
1228
				if (--fxo->battdebounce == 0) {
1229
					fxo->battery = BATTERY_PRESENT;
1230
					if (debug)
1231
						printk(KERN_DEBUG "BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1, 
1232
						       (b < 0) ? "-" : "+");			    
1233
#ifdef	ZERO_BATT_RING
1234
					if (wc->onhook) {
1235
						wc->onhook = 0;
1236
						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1237
						if (debug)
1238
							printk(KERN_DEBUG "Signalled Off Hook\n");
1239
					}
1240
#else
1241
					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1242
#endif
1243
					/* set the alarm timer, taking into account that part of its time
1244
					   period has already passed while debouncing occurred */
1245
					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
1246
				}
1247
			} else {
1248
				/* start the debounce timer to verify that battery has appeared */
1249
				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
1250
			}
1251
		}
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
	if (fxo->lastpol <= 0) {
1261
		if (b > 0) {
1262
			fxo->lastpol = 1;
1263
			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
1264
		}
1265
	}
1266
1267
	if (fxo->battalarm) {
1268
		if (--fxo->battalarm == 0) {
1269
			/* the alarm timer has expired, so update the battery alarm state
1270
			   for this channel */
1271
			dahdi_alarm_channel(wc->chans[card], fxo->battery == BATTERY_LOST ? DAHDI_ALARM_RED : DAHDI_ALARM_NONE);
1272
		}
1273
	}
1274
1275
	if (fxo->polaritydebounce) {
1276
		if (--fxo->polaritydebounce == 0) {
1277
		    if (fxo->lastpol != fxo->polarity) {
1278
				if (debug)
1279
					printk(KERN_DEBUG "%lu Polarity reversed (%d -> %d)\n", jiffies, 
1280
				       fxo->polarity, 
1281
				       fxo->lastpol);
1282
				if (fxo->polarity)
1283
					dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
1284
				fxo->polarity = fxo->lastpol;
1285
		    }
1286
		}
1287
	}
1288
#undef MS_PER_CHECK_HOOK
1289
}
1290
1291
static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
1292
{
1293
	char res;
1294
	int hook;
1295
1296
	/* For some reason we have to debounce the
1297
	   hook detector.  */
1298
1299
	res = wc->reg0shadow[card];
1300
	hook = (res & 1);
1301
	if (hook != wc->mod[card].fxs.lastrxhook) {
1302
		/* Reset the debounce (must be multiple of 4ms) */
1303
		wc->mod[card].fxs.debounce = dialdebounce * 4;
1304
1305
#if 0
1306
		printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
1307
#endif
1308
	} else {
1309
		if (wc->mod[card].fxs.debounce > 0) {
1310
			wc->mod[card].fxs.debounce-= 16 * DAHDI_CHUNKSIZE;
1311
#if 0
1312
			printk(KERN_DEBUG "Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
1313
#endif
1314
			if (!wc->mod[card].fxs.debounce) {
1315
#if 0
1316
				printk(KERN_DEBUG "Counted down debounce, newhook: %d...\n", hook);
1317
#endif
1318
				wc->mod[card].fxs.debouncehook = hook;
1319
			}
1320
			if (!wc->mod[card].fxs.oldrxhook && wc->mod[card].fxs.debouncehook) {
1321
				/* Off hook */
1322
#if 1
1323
				if (debug)
1324
#endif				
1325
					printk(KERN_DEBUG "opvxa1200: Card %d Going off hook\n", card);
1326
				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
1327
				if (robust)
1328
					wctdm_init_proslic(wc, card, 1, 0, 1);
1329
				wc->mod[card].fxs.oldrxhook = 1;
1330
			
1331
			} else if (wc->mod[card].fxs.oldrxhook && !wc->mod[card].fxs.debouncehook) {
1332
				/* On hook */
1333
#if 1
1334
				if (debug)
1335
#endif				
1336
					printk(KERN_DEBUG "opvxa1200: Card %d Going on hook\n", card);
1337
				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
1338
				wc->mod[card].fxs.oldrxhook = 0;
1339
			}
1340
		}
1341
	}
1342
	wc->mod[card].fxs.lastrxhook = hook;
1343
}
1344
1345
DAHDI_IRQ_HANDLER(wctdm_interrupt)
1346
{
1347
	struct wctdm *wc = dev_id;
1348
	unsigned char ints;
1349
	int x, y, z;
1350
	int mode;
1351
1352
	ints = inb(wc->ioaddr + WC_INTSTAT);
1353
1354
	if (!ints)
1355
		return IRQ_NONE;
1356
1357
	outb(ints, wc->ioaddr + WC_INTSTAT);
1358
	
1359
	if (ints & 0x10) {
1360
		/* Stop DMA, wait for watchdog */
1361
		printk(KERN_INFO "TDM PCI Master abort\n");
1362
		wctdm_stop_dma(wc);
1363
		return IRQ_RETVAL(1);
1364
	}
1365
	
1366
	if (ints & 0x20) {
1367
		printk(KERN_INFO "PCI Target abort\n");
1368
		return IRQ_RETVAL(1);
1369
	}
1370
1371
	for (x=0;x<wc->max_cards/*4*3*/;x++) {
1372
		if (wc->cardflag & (1 << x) &&
1373
		    (wc->modtype[x] == MOD_TYPE_FXS)) {
1374
			if (wc->mod[x].fxs.lasttxhook == 0x4) {
1375
				/* RINGing, prepare for OHT */
1376
				wc->mod[x].fxs.ohttimer = OHT_TIMER << 3;
1377
				if (reversepolarity)
1378
					wc->mod[x].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
1379
				else
1380
					wc->mod[x].fxs.idletxhookstate = 0x2; 
1381
			} else {
1382
				if (wc->mod[x].fxs.ohttimer) {
1383
					wc->mod[x].fxs.ohttimer-= DAHDI_CHUNKSIZE;
1384
					if (!wc->mod[x].fxs.ohttimer) {
1385
						if (reversepolarity)
1386
							wc->mod[x].fxs.idletxhookstate = 0x5;	/* Switch to active */
1387
						else
1388
							wc->mod[x].fxs.idletxhookstate = 0x1;
1389
						if ((wc->mod[x].fxs.lasttxhook == 0x2) || (wc->mod[x].fxs.lasttxhook == 0x6)) {
1390
							/* Apply the change if appropriate */
1391
							if (reversepolarity) 
1392
								wc->mod[x].fxs.lasttxhook = 0x5;
1393
							else
1394
								wc->mod[x].fxs.lasttxhook = 0x1;
1395
							wctdm_setreg(wc, x, 64, wc->mod[x].fxs.lasttxhook);
1396
						}
1397
					}
1398
				}
1399
			}
1400
		}
1401
	}
1402
1403
	if (ints & 0x0f) {
1404
		wc->intcount++;
1405
		z = wc->intcount & 0x3;
1406
		mode = wc->intcount & 0xc;
1407
		for(y=0; y<wc->max_cards/4/*3*/; y++)
1408
		{
1409
			x = z + y*4;
1410
			if (wc->cardflag & (1 << x ) ) 
1411
			{
1412
				switch(mode) 
1413
				{
1414
				case 0:
1415
					/* Rest */
1416
					break;
1417
				case 4:
1418
					/* Read first shadow reg */
1419
					if (wc->modtype[x] == MOD_TYPE_FXS)
1420
						wc->reg0shadow[x] = wctdm_getreg(wc, x, 68);
1421
					else if (wc->modtype[x] == MOD_TYPE_FXO)
1422
						wc->reg0shadow[x] = wctdm_getreg(wc, x, 5);
1423
					break;
1424
				case 8:
1425
					/* Read second shadow reg */
1426
					if (wc->modtype[x] == MOD_TYPE_FXS)
1427
						wc->reg1shadow[x] = wctdm_getreg(wc, x, 64);
1428
					else if (wc->modtype[x] == MOD_TYPE_FXO)
1429
						wc->reg1shadow[x] = wctdm_getreg(wc, x, 29);
1430
					break;
1431
				case 12:
1432
					/* Perform processing */
1433
					if (wc->modtype[x] == MOD_TYPE_FXS) {
1434
						wctdm_proslic_check_hook(wc, x);
1435
						if (!(wc->intcount & 0xf0))
1436
							wctdm_proslic_recheck_sanity(wc, x);
1437
					} else if (wc->modtype[x] == MOD_TYPE_FXO) {
1438
						wctdm_voicedaa_check_hook(wc, x);
1439
					}
1440
					break;
1441
				}
1442
			}
1443
		}
1444
		if (!(wc->intcount % 10000)) {
1445
			/* Accept an alarm once per 10 seconds */
1446
			for (x=0;x<wc->max_cards/*4*3*/;x++) 
1447
				if (wc->modtype[x] == MOD_TYPE_FXS) {
1448
					if (wc->mod[x].fxs.palarms)
1449
						wc->mod[x].fxs.palarms--;
1450
				}
1451
		}
1452
		wctdm_receiveprep(wc, ints);
1453
		wctdm_transmitprep(wc, ints);
1454
	}
1455
1456
	return IRQ_RETVAL(1);
1457
1458
}
1459
1460
static int wctdm_voicedaa_insane(struct wctdm *wc, int card)
1461
{
1462
	int blah;
1463
	blah = wctdm_getreg(wc, card, 2);
1464
	if (blah != 0x3)
1465
		return -2;
1466
	blah = wctdm_getreg(wc, card, 11);
1467
	if (debug)
1468
		printk(KERN_DEBUG "VoiceDAA System: %02x\n", blah & 0xf);
1469
	return 0;
1470
}
1471
1472
static int wctdm_proslic_insane(struct wctdm *wc, int card)
1473
{
1474
	int blah,insane_report;
1475
	insane_report=0;
1476
1477
	blah = wctdm_getreg(wc, card, 0);
1478
	if (debug) 
1479
		printk(KERN_DEBUG "ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));
1480
1481
#if 0
1482
	if ((blah & 0x30) >> 4) {
1483
		printk(KERN_DEBUG "ProSLIC on module %d is not a 3210.\n", card);
1484
		return -1;
1485
	}
1486
#endif
1487
	if (((blah & 0xf) == 0) || ((blah & 0xf) == 0xf)) {
1488
		/* SLIC not loaded */
1489
		return -1;
1490
	}
1491
	if ((blah & 0xf) < 2) {
1492
		printk(KERN_NOTICE "ProSLIC 3210 version %d is too old\n", blah & 0xf);
1493
		return -1;
1494
	}
1495
	if (wctdm_getreg(wc, card, 1) & 0x80)
1496
	/* ProSLIC 3215, not a 3210 */
1497
		wc->flags[card] |= FLAG_3215;
1498
	
1499
	blah = wctdm_getreg(wc, card, 8);
1500
	if (blah != 0x2) {
1501
		printk(KERN_NOTICE  "ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
1502
		return -1;
1503
	} else if ( insane_report)
1504
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);
1505
1506
	blah = wctdm_getreg(wc, card, 64);
1507
	if (blah != 0x0) {
1508
		printk(KERN_NOTICE  "ProSLIC on module %d insane (2)\n", card);
1509
		return -1;
1510
	} else if ( insane_report)
1511
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);
1512
1513
	blah = wctdm_getreg(wc, card, 11);
1514
	if (blah != 0x33) {
1515
		printk(KERN_NOTICE  "ProSLIC on module %d insane (3)\n", card);
1516
		return -1;
1517
	} else if ( insane_report)
1518
		printk(KERN_NOTICE  "ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);
1519
1520
	/* Just be sure it's setup right. */
1521
	wctdm_setreg(wc, card, 30, 0);
1522
1523
	if (debug) 
1524
		printk(KERN_DEBUG "ProSLIC on module %d seems sane.\n", card);
1525
	return 0;
1526
}
1527
1528
static int wctdm_proslic_powerleak_test(struct wctdm *wc, int card)
1529
{
1530
	unsigned long origjiffies;
1531
	unsigned char vbat;
1532
1533
	/* Turn off linefeed */
1534
	wctdm_setreg(wc, card, 64, 0);
1535
1536
	/* Power down */
1537
	wctdm_setreg(wc, card, 14, 0x10);
1538
1539
	/* Wait for one second */
1540
	origjiffies = jiffies;
1541
1542
	while((vbat = wctdm_getreg(wc, card, 82)) > 0x6) {
1543
		if ((jiffies - origjiffies) >= (HZ/2))
1544
			break;
1545
	}
1546
1547
	if (vbat < 0x06) {
1548
		printk(KERN_NOTICE "Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,
1549
		       376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ));
1550
		return -1;
1551
	} else if (debug) {
1552
		printk(KERN_NOTICE "Post-leakage voltage: %d volts\n", 376 * vbat / 1000);
1553
	}
1554
	return 0;
1555
}
1556
1557
static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast)
1558
{
1559
	unsigned char vbat;
1560
	unsigned long origjiffies;
1561
	int lim;
1562
1563
	/* Set period of DC-DC converter to 1/64 khz */
1564
	wctdm_setreg(wc, card, 92, 0xff /* was 0xff */);
1565
1566
	/* Wait for VBat to powerup */
1567
	origjiffies = jiffies;
1568
1569
	/* Disable powerdown */
1570
	wctdm_setreg(wc, card, 14, 0);
1571
1572
	/* If fast, don't bother checking anymore */
1573
	if (fast)
1574
		return 0;
1575
1576
	while((vbat = wctdm_getreg(wc, card, 82)) < 0xc0) {
1577
		/* Wait no more than 500ms */
1578
		if ((jiffies - origjiffies) > HZ/2) {
1579
			break;
1580
		}
1581
	}
1582
1583
	if (vbat < 0xc0) {
1584
		if (wc->proslic_power == PROSLIC_POWER_UNKNOWN)
1585
				 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",
1586
					card, (int)(((jiffies - origjiffies) * 1000 / HZ)),
1587
					vbat * 375);
1588
		wc->proslic_power = PROSLIC_POWER_WARNED;
1589
		return -1;
1590
	} else if (debug) {
1591
		printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
1592
		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
1593
	}
1594
	wc->proslic_power = PROSLIC_POWER_ON;
1595
1596
        /* Proslic max allowed loop current, reg 71 LOOP_I_LIMIT */
1597
        /* If out of range, just set it to the default value     */
1598
        lim = (loopcurrent - 20) / 3;
1599
        if ( loopcurrent > 41 ) {
1600
                lim = 0;
1601
                if (debug)
1602
                        printk(KERN_DEBUG "Loop current out of range! Setting to default 20mA!\n");
1603
        }
1604
        else if (debug)
1605
                        printk(KERN_DEBUG "Loop current set to %dmA!\n",(lim*3)+20);
1606
        wctdm_setreg(wc,card,LOOP_I_LIMIT,lim);
1607
1608
	/* Engage DC-DC converter */
1609
	wctdm_setreg(wc, card, 93, 0x19 /* was 0x19 */);
1610
#if 0
1611
	origjiffies = jiffies;
1612
	while(0x80 & wctdm_getreg(wc, card, 93)) {
1613
		if ((jiffies - origjiffies) > 2 * HZ) {
1614
			printk(KERN_DEBUG "Timeout waiting for DC-DC calibration on module %d\n", card);
1615
			return -1;
1616
		}
1617
	}
1618
1619
#if 0
1620
	/* Wait a full two seconds */
1621
	while((jiffies - origjiffies) < 2 * HZ);
1622
1623
	/* Just check to be sure */
1624
	vbat = wctdm_getreg(wc, card, 82);
1625
	printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
1626
		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
1627
#endif
1628
#endif
1629
	return 0;
1630
1631
}
1632
1633
static int wctdm_proslic_manual_calibrate(struct wctdm *wc, int card){
1634
	unsigned long origjiffies;
1635
	unsigned char i;
1636
1637
	wctdm_setreg(wc, card, 21, 0);//(0)  Disable all interupts in DR21
1638
	wctdm_setreg(wc, card, 22, 0);//(0)Disable all interupts in DR21
1639
	wctdm_setreg(wc, card, 23, 0);//(0)Disable all interupts in DR21
1640
	wctdm_setreg(wc, card, 64, 0);//(0)
1641
1642
	wctdm_setreg(wc, card, 97, 0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration.
1643
	wctdm_setreg(wc, card, 96, 0x47); //(0x47)	Calibrate common mode and differential DAC mode DAC + ILIM
1644
1645
	origjiffies=jiffies;
1646
	while( wctdm_getreg(wc,card,96)!=0 ){
1647
		if((jiffies-origjiffies)>80)
1648
			return -1;
1649
	}
1650
//Initialized DR 98 and 99 to get consistant results.
1651
// 98 and 99 are the results registers and the search should have same intial conditions.
1652
1653
/*******************************The following is the manual gain mismatch calibration****************************/
1654
/*******************************This is also available as a function *******************************************/
1655
	// Delay 10ms
1656
	origjiffies=jiffies; 
1657
	while((jiffies-origjiffies)<1);
1658
	wctdm_proslic_setreg_indirect(wc, card, 88,0);
1659
	wctdm_proslic_setreg_indirect(wc,card,89,0);
1660
	wctdm_proslic_setreg_indirect(wc,card,90,0);
1661
	wctdm_proslic_setreg_indirect(wc,card,91,0);
1662
	wctdm_proslic_setreg_indirect(wc,card,92,0);
1663
	wctdm_proslic_setreg_indirect(wc,card,93,0);
1664
1665
	wctdm_setreg(wc, card, 98,0x10); // This is necessary if the calibration occurs other than at reset time
1666
	wctdm_setreg(wc, card, 99,0x10);
1667
1668
	for ( i=0x1f; i>0; i--)
1669
	{
1670
		wctdm_setreg(wc, card, 98,i);
1671
		origjiffies=jiffies; 
1672
		while((jiffies-origjiffies)<4);
1673
		if((wctdm_getreg(wc,card,88)) == 0)
1674
			break;
1675
	} // for
1676
1677
	for ( i=0x1f; i>0; i--)
1678
	{
1679
		wctdm_setreg(wc, card, 99,i);
1680
		origjiffies=jiffies; 
1681
		while((jiffies-origjiffies)<4);
1682
		if((wctdm_getreg(wc,card,89)) == 0)
1683
			break;
1684
	}//for
1685
1686
/*******************************The preceding is the manual gain mismatch calibration****************************/
1687
/**********************************The following is the longitudinal Balance Cal***********************************/
1688
	wctdm_setreg(wc,card,64,1);
1689
	while((jiffies-origjiffies)<10); // Sleep 100?
1690
1691
	wctdm_setreg(wc, card, 64, 0);
1692
	wctdm_setreg(wc, card, 23, 0x4);  // enable interrupt for the balance Cal
1693
	wctdm_setreg(wc, card, 97, 0x1); // this is a singular calibration bit for longitudinal calibration
1694
	wctdm_setreg(wc, card, 96,0x40);
1695
1696
	wctdm_getreg(wc,card,96); /* Read Reg 96 just cause */
1697
1698
	wctdm_setreg(wc, card, 21, 0xFF);
1699
	wctdm_setreg(wc, card, 22, 0xFF);
1700
	wctdm_setreg(wc, card, 23, 0xFF);
1701
1702
	/**The preceding is the longitudinal Balance Cal***/
1703
	return(0);
1704
1705
}
1706
#if 1
1707
static int wctdm_proslic_calibrate(struct wctdm *wc, int card)
1708
{
1709
	unsigned long origjiffies;
1710
	int x;
1711
	/* Perform all calibrations */
1712
	wctdm_setreg(wc, card, 97, 0x1f);
1713
	
1714
	/* Begin, no speedup */
1715
	wctdm_setreg(wc, card, 96, 0x5f);
1716
1717
	/* Wait for it to finish */
1718
	origjiffies = jiffies;
1719
	while(wctdm_getreg(wc, card, 96)) {
1720
		if ((jiffies - origjiffies) > 2 * HZ) {
1721
			printk(KERN_NOTICE "Timeout waiting for calibration of module %d\n", card);
1722
			return -1;
1723
		}
1724
	}
1725
	
1726
	if (debug) {
1727
		/* Print calibration parameters */
1728
		printk(KERN_DEBUG "Calibration Vector Regs 98 - 107: \n");
1729
		for (x=98;x<108;x++) {
1730
			printk(KERN_DEBUG "%d: %02x\n", x, wctdm_getreg(wc, card, x));
1731
		}
1732
	}
1733
	return 0;
1734
}
1735
#endif
1736
1737
static void wait_just_a_bit(int foo)
1738
{
1739
	long newjiffies;
1740
	newjiffies = jiffies + foo;
1741
	while(jiffies < newjiffies);
1742
}
1743
1744
/*********************************************************************
1745
 * Set the hwgain on the analog modules
1746
 *
1747
 * card = the card position for this module (0-23)
1748
 * gain = gain in dB x10 (e.g. -3.5dB  would be gain=-35)
1749
 * tx = (0 for rx; 1 for tx)
1750
 *
1751
 *******************************************************************/
1752
static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
1753
{
1754
	if (!(wc->modtype[card] == MOD_TYPE_FXO)) {
1755
		printk(KERN_NOTICE "Cannot adjust gain.  Unsupported module type!\n");
1756
		return -1;
1757
	}
1758
	if (tx) {
1759
		if (debug)
1760
			printk(KERN_DEBUG "setting FXO tx gain for card=%d to %d\n", card, gain);
1761
		if (gain >=  -150 && gain <= 0) {
1762
			wctdm_setreg(wc, card, 38, 16 + (gain/-10));
1763
			wctdm_setreg(wc, card, 40, 16 + (-gain%10));
1764
		} else if (gain <= 120 && gain > 0) {
1765
			wctdm_setreg(wc, card, 38, gain/10);
1766
			wctdm_setreg(wc, card, 40, (gain%10));
1767
		} else {
1768
			printk(KERN_INFO "FXO tx gain is out of range (%d)\n", gain);
1769
			return -1;
1770
		}
1771
	} else { /* rx */
1772
		if (debug)
1773
			printk(KERN_DEBUG "setting FXO rx gain for card=%d to %d\n", card, gain);
1774
		if (gain >=  -150 && gain <= 0) {
1775
			wctdm_setreg(wc, card, 39, 16+ (gain/-10));
1776
			wctdm_setreg(wc, card, 41, 16 + (-gain%10));
1777
		} else if (gain <= 120 && gain > 0) {
1778
			wctdm_setreg(wc, card, 39, gain/10);
1779
			wctdm_setreg(wc, card, 41, (gain%10));
1780
		} else {
1781
			printk(KERN_INFO "FXO rx gain is out of range (%d)\n", gain);
1782
			return -1;
1783
		}
1784
	}
1785
1786
	return 0;
1787
}
1788
1789
static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane)
1790
{
1791
	unsigned char reg16=0, reg26=0, reg30=0, reg31=0;
1792
	long newjiffies;
1793
	wc->modtype[card] = MOD_TYPE_FXO;
1794
	/* Sanity check the ProSLIC */
1795
	reset_spi(wc, card);
1796
	if (!sane && wctdm_voicedaa_insane(wc, card))
1797
		return -2;
1798
1799
	/* Software reset */
1800
	wctdm_setreg(wc, card, 1, 0x80);
1801
1802
	/* Wait just a bit */
1803
	wait_just_a_bit(HZ/10);
1804
1805
	/* Enable PCM, ulaw */
1806
	if (alawoverride)
1807
		wctdm_setreg(wc, card, 33, 0x20);
1808
	else
1809
		wctdm_setreg(wc, card, 33, 0x28);
1810
1811
	/* Set On-hook speed, Ringer impedence, and ringer threshold */
1812
	reg16 |= (fxo_modes[_opermode].ohs << 6);
1813
	reg16 |= (fxo_modes[_opermode].rz << 1);
1814
	reg16 |= (fxo_modes[_opermode].rt);
1815
	wctdm_setreg(wc, card, 16, reg16);
1816
1817
	if(fwringdetect) {
1818
		/* Enable ring detector full-wave rectifier mode */
1819
		wctdm_setreg(wc, card, 18, 2);
1820
		wctdm_setreg(wc, card, 24, 0);
1821
	} else { 
1822
		/* Set to the device defaults */
1823
		wctdm_setreg(wc, card, 18, 0);
1824
		wctdm_setreg(wc, card, 24, 0x19);
1825
	}
1826
	
1827
	/* Set DC Termination:
1828
	   Tip/Ring voltage adjust, minimum operational current, current limitation */
1829
	reg26 |= (fxo_modes[_opermode].dcv << 6);
1830
	reg26 |= (fxo_modes[_opermode].mini << 4);
1831
	reg26 |= (fxo_modes[_opermode].ilim << 1);
1832
	wctdm_setreg(wc, card, 26, reg26);
1833
1834
	/* Set AC Impedence */ 
1835
	reg30 = (fxofullscale==1) ? (fxo_modes[_opermode].acim|0x10) :  (fxo_modes[_opermode].acim);
1836
	wctdm_setreg(wc, card, 30, reg30);
1837
1838
	/* Misc. DAA parameters */
1839
	if (fastpickup)
1840
		reg31 = 0xb3;
1841
	else
1842
		reg31 = 0xa3;
1843
1844
	reg31 |= (fxo_modes[_opermode].ohs2 << 3);
1845
	wctdm_setreg(wc, card, 31, reg31);
1846
1847
	/* Set Transmit/Receive timeslot */
1848
	//printk("set card %d to %d\n", card, (3-(card%4)) * 8 + (card/4) * 64);
1849
	wctdm_setreg(wc, card, 34, (3-(card%4)) * 8 + (card/4) * 64);
1850
	wctdm_setreg(wc, card, 35, 0x00);
1851
	wctdm_setreg(wc, card, 36, (3-(card%4)) * 8 + (card/4) * 64);
1852
	wctdm_setreg(wc, card, 37, 0x00);
1853
1854
	/* Enable ISO-Cap */
1855
	wctdm_setreg(wc, card, 6, 0x00);
1856
1857
	if (fastpickup)
1858
		wctdm_setreg(wc, card, 17, wctdm_getreg(wc, card, 17) | 0x20);
1859
1860
	/* Wait 1000ms for ISO-cap to come up */
1861
	newjiffies = jiffies;
1862
	newjiffies += 2 * HZ;
1863
	while((jiffies < newjiffies) && !(wctdm_getreg(wc, card, 11) & 0xf0))
1864
		wait_just_a_bit(HZ/10);
1865
1866
	if (!(wctdm_getreg(wc, card, 11) & 0xf0)) {
1867
		printk(KERN_NOTICE "VoiceDAA did not bring up ISO link properly!\n");
1868
		return -1;
1869
	}
1870
	if (debug)
1871
		printk(KERN_DEBUG "ISO-Cap is now up, line side: %02x rev %02x\n", 
1872
		       wctdm_getreg(wc, card, 11) >> 4,
1873
		       (wctdm_getreg(wc, card, 13) >> 2) & 0xf);
1874
	/* Enable on-hook line monitor */
1875
	wctdm_setreg(wc, card, 5, 0x08);
1876
1877
	/* Take values for fxotxgain and fxorxgain and apply them to module */
1878
	wctdm_set_hwgain(wc, card, fxotxgain, 1);
1879
	wctdm_set_hwgain(wc, card, fxorxgain, 0);
1880
1881
	/* NZ -- crank the tx gain up by 7 dB */
1882
	if (!strcmp(fxo_modes[_opermode].name, "NEWZEALAND")) {
1883
		printk(KERN_INFO "Adjusting gain\n");
1884
		wctdm_set_hwgain(wc, card, 7, 1);
1885
	}
1886
1887
	if(debug)
1888
		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));
1889
1890
    return 0;
1891
		
1892
}
1893
1894
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, int sane)
1895
{
1896
1897
	unsigned short tmp[5];
1898
	unsigned char r19, r9;
1899
	int x;
1900
	int fxsmode=0;
1901
1902
	/* Sanity check the ProSLIC */
1903
	if (!sane && wctdm_proslic_insane(wc, card))
1904
		return -2;
1905
1906
	/* By default, don't send on hook */
1907
	if (reversepolarity)
1908
		wc->mod[card].fxs.idletxhookstate = 5;
1909
	else
1910
		wc->mod[card].fxs.idletxhookstate = 1;
1911
		
1912
	if (sane) {
1913
		/* Make sure we turn off the DC->DC converter to prevent anything from blowing up */
1914
		wctdm_setreg(wc, card, 14, 0x10);
1915
	}
1916
1917
	if (wctdm_proslic_init_indirect_regs(wc, card)) {
1918
		printk(KERN_INFO "Indirect Registers failed to initialize on module %d.\n", card);
1919
		return -1;
1920
	}
1921
1922
	/* Clear scratch pad area */
1923
	wctdm_proslic_setreg_indirect(wc, card, 97,0);
1924
1925
	/* Clear digital loopback */
1926
	wctdm_setreg(wc, card, 8, 0);
1927
1928
	/* Revision C optimization */
1929
	wctdm_setreg(wc, card, 108, 0xeb);
1930
1931
	/* Disable automatic VBat switching for safety to prevent
1932
	   Q7 from accidently turning on and burning out. */
1933
	wctdm_setreg(wc, card, 67, 0x07);  /* Note, if pulse dialing has problems at high REN loads
1934
					      change this to 0x17 */
1935
1936
	/* Turn off Q7 */
1937
	wctdm_setreg(wc, card, 66, 1);
1938
1939
	/* Flush ProSLIC digital filters by setting to clear, while
1940
	   saving old values */
1941
	for (x=0;x<5;x++) {
1942
		tmp[x] = wctdm_proslic_getreg_indirect(wc, card, x + 35);
1943
		wctdm_proslic_setreg_indirect(wc, card, x + 35, 0x8000);
1944
	}
1945
1946
	/* Power up the DC-DC converter */
1947
	if (wctdm_powerup_proslic(wc, card, fast)) {
1948
		printk(KERN_NOTICE "Unable to do INITIAL ProSLIC powerup on module %d\n", card);
1949
		return -1;
1950
	}
1951
1952
	if (!fast) {
1953
1954
		/* Check for power leaks */
1955
		if (wctdm_proslic_powerleak_test(wc, card)) {
1956
			printk(KERN_NOTICE "ProSLIC module %d failed leakage test.  Check for short circuit\n", card);
1957
		}
1958
		/* Power up again */
1959
		if (wctdm_powerup_proslic(wc, card, fast)) {
1960
			printk(KERN_NOTICE "Unable to do FINAL ProSLIC powerup on module %d\n", card);
1961
			return -1;
1962
		}
1963
#ifndef NO_CALIBRATION
1964
		/* Perform calibration */
1965
		if(manual) {
1966
			if (wctdm_proslic_manual_calibrate(wc, card)) {
1967
				//printk(KERN_NOTICE "Proslic failed on Manual Calibration\n");
1968
				if (wctdm_proslic_manual_calibrate(wc, card)) {
1969
					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n");
1970
					return -1;
1971
				}
1972
				printk(KERN_NOTICE "Proslic Passed Manual Calibration on Second Attempt\n");
1973
			}
1974
		}
1975
		else {
1976
			if(wctdm_proslic_calibrate(wc, card))  {
1977
				//printk(KERN_NOTICE "ProSlic died on Auto Calibration.\n");
1978
				if (wctdm_proslic_calibrate(wc, card)) {
1979
					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Auto Calibrate\n");
1980
					return -1;
1981
				}
1982
				printk(KERN_NOTICE "Proslic Passed Auto Calibration on Second Attempt\n");
1983
			}
1984
		}
1985
		/* Perform DC-DC calibration */
1986
		wctdm_setreg(wc, card, 93, 0x99);
1987
		r19 = wctdm_getreg(wc, card, 107);
1988
		if ((r19 < 0x2) || (r19 > 0xd)) {
1989
			printk(KERN_NOTICE "DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19);
1990
			wctdm_setreg(wc, card, 107, 0x8);
1991
		}
1992
1993
		/* Save calibration vectors */
1994
		for (x=0;x<NUM_CAL_REGS;x++)
1995
			wc->mod[card].fxs.calregs.vals[x] = wctdm_getreg(wc, card, 96 + x);
1996
#endif
1997
1998
	} else {
1999
		/* Restore calibration registers */
2000
		for (x=0;x<NUM_CAL_REGS;x++)
2001
			wctdm_setreg(wc, card, 96 + x, wc->mod[card].fxs.calregs.vals[x]);
2002
	}
2003
	/* Calibration complete, restore original values */
2004
	for (x=0;x<5;x++) {
2005
		wctdm_proslic_setreg_indirect(wc, card, x + 35, tmp[x]);
2006
	}
2007
2008
	if (wctdm_proslic_verify_indirect_regs(wc, card)) {
2009
		printk(KERN_INFO "Indirect Registers failed verification.\n");
2010
		return -1;
2011
	}
2012
2013
2014
#if 0
2015
    /* Disable Auto Power Alarm Detect and other "features" */
2016
    wctdm_setreg(wc, card, 67, 0x0e);
2017
    blah = wctdm_getreg(wc, card, 67);
2018
#endif
2019
2020
#if 0
2021
    if (wctdm_proslic_setreg_indirect(wc, card, 97, 0x0)) { // Stanley: for the bad recording fix
2022
		 printk(KERN_INFO "ProSlic IndirectReg Died.\n");
2023
		 return -1;
2024
	}
2025
#endif
2026
2027
    if (alawoverride)
2028
    	wctdm_setreg(wc, card, 1, 0x20);
2029
    else
2030
    	wctdm_setreg(wc, card, 1, 0x28);
2031
  // U-Law 8-bit interface
2032
    wctdm_setreg(wc, card, 2, (3-(card%4)) * 8 + (card/4) * 64);    // Tx Start count low byte  0
2033
    wctdm_setreg(wc, card, 3, 0);    // Tx Start count high byte 0
2034
    wctdm_setreg(wc, card, 4, (3-(card%4)) * 8 + (card/4) * 64);    // Rx Start count low byte  0
2035
    wctdm_setreg(wc, card, 5, 0);    // Rx Start count high byte 0
2036
    wctdm_setreg(wc, card, 18, 0xff);     // clear all interrupt
2037
    wctdm_setreg(wc, card, 19, 0xff);
2038
    wctdm_setreg(wc, card, 20, 0xff);
2039
    wctdm_setreg(wc, card, 73, 0x04);
2040
	if (fxshonormode) {
2041
		fxsmode = acim2tiss[fxo_modes[_opermode].acim];
2042
		wctdm_setreg(wc, card, 10, 0x08 | fxsmode);
2043
		if (fxo_modes[_opermode].ring_osc)
2044
			wctdm_proslic_setreg_indirect(wc, card, 20, fxo_modes[_opermode].ring_osc);
2045
		if (fxo_modes[_opermode].ring_x)
2046
			wctdm_proslic_setreg_indirect(wc, card, 21, fxo_modes[_opermode].ring_x);
2047
	}
2048
    if (lowpower)
2049
    	wctdm_setreg(wc, card, 72, 0x10);
2050
2051
#if 0
2052
    wctdm_setreg(wc, card, 21, 0x00); 	// enable interrupt
2053
    wctdm_setreg(wc, card, 22, 0x02); 	// Loop detection interrupt
2054
    wctdm_setreg(wc, card, 23, 0x01); 	// DTMF detection interrupt
2055
#endif
2056
2057
#if 0
2058
    /* Enable loopback */
2059
    wctdm_setreg(wc, card, 8, 0x2);
2060
    wctdm_setreg(wc, card, 14, 0x0);
2061
    wctdm_setreg(wc, card, 64, 0x0);
2062
    wctdm_setreg(wc, card, 1, 0x08);
2063
#endif
2064
2065
	if (fastringer) {
2066
		/* Speed up Ringer */
2067
		wctdm_proslic_setreg_indirect(wc, card, 20, 0x7e6d);
2068
		wctdm_proslic_setreg_indirect(wc, card, 21, 0x01b9);
2069
		/* Beef up Ringing voltage to 89V */
2070
		if (boostringer) {
2071
			wctdm_setreg(wc, card, 74, 0x3f);
2072
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x247)) 
2073
				return -1;
2074
			printk(KERN_INFO  "Boosting fast ringer on slot %d (89V peak)\n", card + 1);
2075
		} else if (lowpower) {
2076
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x14b)) 
2077
				return -1;
2078
			printk(KERN_INFO  "Reducing fast ring power on slot %d (50V peak)\n", card + 1);
2079
		} else
2080
			printk(KERN_INFO  "Speeding up ringer on slot %d (25Hz)\n", card + 1);
2081
	} else {
2082
		/* Beef up Ringing voltage to 89V */
2083
		if (boostringer) {
2084
			wctdm_setreg(wc, card, 74, 0x3f);
2085
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x1d1)) 
2086
				return -1;
2087
			printk(KERN_INFO  "Boosting ringer on slot %d (89V peak)\n", card + 1);
2088
		} else if (lowpower) {
2089
			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x108)) 
2090
				return -1;
2091
			printk(KERN_INFO  "Reducing ring power on slot %d (50V peak)\n", card + 1);
2092
		}
2093
	}
2094
2095
	if(fxstxgain || fxsrxgain) {
2096
		r9 = wctdm_getreg(wc, card, 9);
2097
		switch (fxstxgain) {
2098
		
2099
			case 35:
2100
				r9+=8;
2101
				break;
2102
			case -35:
2103
				r9+=4;
2104
				break;
2105
			case 0: 
2106
				break;
2107
		}
2108
	
2109
		switch (fxsrxgain) {
2110
			
2111
			case 35:
2112
				r9+=2;
2113
				break;
2114
			case -35:
2115
				r9+=1;
2116
				break;
2117
			case 0:
2118
				break;
2119
		}
2120
		wctdm_setreg(wc,card,9,r9);
2121
	}
2122
2123
	if(debug)
2124
		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"));
2125
2126
	wctdm_setreg(wc, card, 64, 0x01);
2127
	return 0;
2128
}
2129
2130
2131
static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
2132
{
2133
	struct wctdm_stats stats;
2134
	struct wctdm_regs regs;
2135
	struct wctdm_regop regop;
2136
	struct wctdm_echo_coefs echoregs;
2137
	struct dahdi_hwgain hwgain;
2138
	struct wctdm *wc = chan->pvt;
2139
	int x;
2140
	switch (cmd) {
2141
	case DAHDI_ONHOOKTRANSFER:
2142
		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2143
			return -EINVAL;
2144
		if (get_user(x, (__user  int *)data))
2145
			return -EFAULT;
2146
		wc->mod[chan->chanpos - 1].fxs.ohttimer = x << 3;
2147
		if (reversepolarity)
2148
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
2149
		else
2150
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x2;
2151
		if (wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x1 || wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x5) {
2152
				/* Apply the change if appropriate */
2153
				if (reversepolarity)
2154
					wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x6;
2155
				else
2156
					wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x2;
2157
				wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
2158
		}
2159
		break;
2160
	case DAHDI_SETPOLARITY:
2161
		if (get_user(x, (__user int *)data))
2162
			return -EFAULT;
2163
		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2164
			return -EINVAL;
2165
		/* Can't change polarity while ringing or when open */
2166
		if ((wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x04) ||
2167
		    (wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x00))
2168
			return -EINVAL;
2169
2170
		if ((x && !reversepolarity) || (!x && reversepolarity))
2171
			wc->mod[chan->chanpos - 1].fxs.lasttxhook |= 0x04;
2172
		else
2173
			wc->mod[chan->chanpos - 1].fxs.lasttxhook &= ~0x04;
2174
		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
2175
		break;
2176
	case WCTDM_GET_STATS:
2177
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2178
			stats.tipvolt = wctdm_getreg(wc, chan->chanpos - 1, 80) * -376;
2179
			stats.ringvolt = wctdm_getreg(wc, chan->chanpos - 1, 81) * -376;
2180
			stats.batvolt = wctdm_getreg(wc, chan->chanpos - 1, 82) * -376;
2181
		} else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2182
			stats.tipvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2183
			stats.ringvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2184
			stats.batvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
2185
		} else 
2186
			return -EINVAL;
2187
		if (copy_to_user((__user void *)data, &stats, sizeof(stats)))
2188
			return -EFAULT;
2189
		break;
2190
	case WCTDM_GET_REGS:
2191
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2192
			for (x=0;x<NUM_INDIRECT_REGS;x++)
2193
				regs.indirect[x] = wctdm_proslic_getreg_indirect(wc, chan->chanpos -1, x);
2194
			for (x=0;x<NUM_REGS;x++)
2195
				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
2196
		} else {
2197
			memset(&regs, 0, sizeof(regs));
2198
			for (x=0;x<NUM_FXO_REGS;x++)
2199
				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
2200
		}
2201
		if (copy_to_user((__user void *)data, &regs, sizeof(regs)))
2202
			return -EFAULT;
2203
		break;
2204
	case WCTDM_SET_REG:
2205
		if (copy_from_user(&regop, (__user void *)data, sizeof(regop)))
2206
			return -EFAULT;
2207
		if (regop.indirect) {
2208
			if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
2209
				return -EINVAL;
2210
			printk(KERN_INFO  "Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos);
2211
			wctdm_proslic_setreg_indirect(wc, chan->chanpos - 1, regop.reg, regop.val);
2212
		} else {
2213
			regop.val &= 0xff;
2214
			printk(KERN_INFO  "Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos);
2215
			wctdm_setreg(wc, chan->chanpos - 1, regop.reg, regop.val);
2216
		}
2217
		break;
2218
	case WCTDM_SET_ECHOTUNE:
2219
		printk(KERN_INFO  "-- Setting echo registers: \n");
2220
		if (copy_from_user(&echoregs, (__user void *)data, sizeof(echoregs)))
2221
			return -EFAULT;
2222
2223
		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2224
			/* Set the ACIM register */
2225
			wctdm_setreg(wc, chan->chanpos - 1, 30, (fxofullscale==1) ? (echoregs.acim|0x10) : echoregs.acim);
2226
2227
			/* Set the digital echo canceller registers */
2228
			wctdm_setreg(wc, chan->chanpos - 1, 45, echoregs.coef1);
2229
			wctdm_setreg(wc, chan->chanpos - 1, 46, echoregs.coef2);
2230
			wctdm_setreg(wc, chan->chanpos - 1, 47, echoregs.coef3);
2231
			wctdm_setreg(wc, chan->chanpos - 1, 48, echoregs.coef4);
2232
			wctdm_setreg(wc, chan->chanpos - 1, 49, echoregs.coef5);
2233
			wctdm_setreg(wc, chan->chanpos - 1, 50, echoregs.coef6);
2234
			wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7);
2235
			wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8);
2236
2237
			printk(KERN_INFO  "-- Set echo registers successfully\n");
2238
2239
			break;
2240
		} else {
2241
			return -EINVAL;
2242
2243
		}
2244
		break;
2245
	case DAHDI_SET_HWGAIN:
2246
		if (copy_from_user(&hwgain, (__user void *) data, sizeof(hwgain)))
2247
			return -EFAULT;
2248
2249
		wctdm_set_hwgain(wc, chan->chanpos-1, hwgain.newgain, hwgain.tx);
2250
2251
		if (debug)
2252
			printk(KERN_DEBUG  "Setting hwgain on channel %d to %d for %s direction\n", 
2253
				chan->chanpos-1, hwgain.newgain, hwgain.tx ? "tx" : "rx");
2254
		break;
2255
	default:
2256
		return -ENOTTY;
2257
	}
2258
	return 0;
2259
2260
}
2261
2262
static int wctdm_open(struct dahdi_chan *chan)
2263
{
2264
	struct wctdm *wc = chan->pvt;
2265
	if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
2266
		return -ENODEV;
2267
	if (wc->dead)
2268
		return -ENODEV;
2269
	wc->usecount++;
2270
2271
	/*MOD_INC_USE_COUNT; */
2272
	try_module_get(THIS_MODULE);
2273
	return 0;
2274
}
2275
2276
static inline struct wctdm *wctdm_from_span(struct dahdi_span *span)
2277
{
2278
	return container_of(span, struct wctdm, span);
2279
}
2280
2281
static int wctdm_watchdog(struct dahdi_span *span, int event)
2282
{
2283
	printk(KERN_INFO "opvxa1200: Restarting DMA\n");
2284
	wctdm_restart_dma(wctdm_from_span(span));
2285
	return 0;
2286
}
2287
2288
static int wctdm_close(struct dahdi_chan *chan)
2289
{
2290
	struct wctdm *wc = chan->pvt;
2291
	wc->usecount--;
2292
2293
	/*MOD_DEC_USE_COUNT;*/
2294
	module_put(THIS_MODULE);
2295
2296
	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
2297
		if (reversepolarity)
2298
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 5;
2299
		else
2300
			wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 1;
2301
	}
2302
	/* If we're dead, release us now */
2303
	if (!wc->usecount && wc->dead) 
2304
		wctdm_release(wc);
2305
	return 0;
2306
}
2307
2308
static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
2309
{
2310
	struct wctdm *wc = chan->pvt;
2311
	int reg=0;
2312
	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
2313
		/* XXX Enable hooksig for FXO XXX */
2314
		switch(txsig) {
2315
		case DAHDI_TXSIG_START:
2316
		case DAHDI_TXSIG_OFFHOOK:
2317
			wc->mod[chan->chanpos - 1].fxo.offhook = 1;
2318
			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x9);
2319
			if(cidbeforering)
2320
			{
2321
				wc->cid_state[chan->chanpos - 1] = CID_STATE_IDLE;
2322
				wc->cid_history_clone_cnt[chan->chanpos - 1] = 0;
2323
				wc->cid_history_ptr[chan->chanpos - 1] = 0;
2324
				memset(wc->cid_history_buf[chan->chanpos - 1], DAHDI_LIN2X(0, chan), cidbuflen * DAHDI_MAX_CHUNKSIZE);
2325
			}
2326
			break;
2327
		case DAHDI_TXSIG_ONHOOK:
2328
			wc->mod[chan->chanpos - 1].fxo.offhook = 0;
2329
			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x8);
2330
			break;
2331
		default:
2332
			printk(KERN_NOTICE "wcfxo: Can't set tx state to %d\n", txsig);
2333
		}
2334
	} else {
2335
		switch(txsig) {
2336
		case DAHDI_TXSIG_ONHOOK:
2337
			switch(chan->sig) {
2338
			case DAHDI_SIG_EM:
2339
			case DAHDI_SIG_FXOKS:
2340
			case DAHDI_SIG_FXOLS:
2341
				wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
2342
				break;
2343
			case DAHDI_SIG_FXOGS:
2344
				wc->mod[chan->chanpos-1].fxs.lasttxhook = 3;
2345
				break;
2346
			}
2347
			break;
2348
		case DAHDI_TXSIG_OFFHOOK:
2349
			switch(chan->sig) {
2350
			case DAHDI_SIG_EM:
2351
				wc->mod[chan->chanpos-1].fxs.lasttxhook = 5;
2352
				break;
2353
			default:
2354
				wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
2355
				break;
2356
			}
2357
			break;
2358
		case DAHDI_TXSIG_START:
2359
			wc->mod[chan->chanpos-1].fxs.lasttxhook = 4;
2360
			break;
2361
		case DAHDI_TXSIG_KEWL:
2362
			wc->mod[chan->chanpos-1].fxs.lasttxhook = 0;
2363
			break;
2364
		default:
2365
			printk(KERN_NOTICE "opvxa1200: Can't set tx state to %d\n", txsig);
2366
		}
2367
		if (debug)
2368
			printk(KERN_DEBUG "Setting FXS hook state to %d (%02x)\n", txsig, reg);
2369
2370
#if 1
2371
		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos-1].fxs.lasttxhook);
2372
#endif
2373
	}
2374
	return 0;
2375
}
2376
2377
#ifdef DAHDI_SPAN_OPS
2378
static const struct dahdi_span_ops wctdm_span_ops = {
2379
	.owner = THIS_MODULE,
2380
	.hooksig = wctdm_hooksig,
2381
	.open = wctdm_open,
2382
	.close = wctdm_close,
2383
	.ioctl = wctdm_ioctl,
2384
	.watchdog = wctdm_watchdog,
2385
};
2386
#endif
2387
2388
static int wctdm_initialize(struct wctdm *wc)
2389
{
2390
	int x;
2391
2392
	/* Dahdi stuff */
2393
	sprintf(wc->span.name, "OPVXA1200/%d", wc->pos);
2394
	snprintf(wc->span.desc, sizeof(wc->span.desc)-1, "%s Board %d", wc->variety, wc->pos + 1);
2395
	wc->ddev->location = kasprintf(GFP_KERNEL,
2396
				      "PCI Bus %02d Slot %02d",
2397
				      wc->dev->bus->number,
2398
				      PCI_SLOT(wc->dev->devfn) + 1);
2399
	if (!wc->ddev->location) {
2400
		dahdi_free_device(wc->ddev);
2401
		wc->ddev = NULL;
2402
		return -ENOMEM;
2403
	}
2404
	wc->ddev->manufacturer = "OpenVox";
2405
	wc->ddev->devicetype = wc->variety;
2406
	if (alawoverride) {
2407
		printk(KERN_INFO "ALAW override parameter detected.  Device will be operating in ALAW\n");
2408
		wc->span.deflaw = DAHDI_LAW_ALAW;
2409
	} else
2410
		wc->span.deflaw = DAHDI_LAW_MULAW;
2411
		
2412
	x = __wctdm_getcreg(wc, WC_VER);
2413
	wc->fwversion = x;
2414
	if( x & FLAG_A800)
2415
	{
2416
		wc->card_name = A800P_Name;
2417
		wc->max_cards = 8;
2418
	}
2419
	else
2420
	{
2421
		wc->card_name = A1200P_Name;
2422
		wc->max_cards = 12;
2423
	}
2424
		
2425
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2426
		sprintf(wc->chans[x]->name, "OPVXA1200/%d/%d", wc->pos, x);
2427
		wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
2428
		wc->chans[x]->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
2429
		wc->chans[x]->chanpos = x+1;
2430
		wc->chans[x]->pvt = wc;
2431
	}
2432
2433
#ifdef DAHDI_SPAN_MODULE	
2434
		wc->span.owner = THIS_MODULE;
2435
#endif
2436
2437
#ifdef DAHDI_SPAN_OPS
2438
	wc->span.ops = &wctdm_span_ops;
2439
#else
2440
		wc->span.hooksig = wctdm_hooksig,
2441
		wc->span.watchdog = wctdm_watchdog,
2442
		wc->span.open = wctdm_open;
2443
		wc->span.close  = wctdm_close;
2444
		wc->span.ioctl = wctdm_ioctl;
2445
		wc->span.pvt = wc;
2446
#endif
2447
	wc->span.chans = wc->chans;
2448
	wc->span.channels = wc->max_cards;	/*MAX_NUM_CARDS;*/
2449
	wc->span.flags = DAHDI_FLAG_RBS;
2450
	wc->span.ops = &wctdm_span_ops;
2451
2452
	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
2453
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
2454
		printk(KERN_NOTICE "Unable to register device %s with DAHDI\n",
2455
				wc->span.name);
2456
		kfree(wc->ddev->location);
2457
		dahdi_free_device(wc->ddev);
2458
		wc->ddev = NULL;
2459
		return -1;
2460
	}
2461
	return 0;
2462
}
2463
2464
static void wctdm_post_initialize(struct wctdm *wc)
2465
{
2466
	int x;
2467
2468
	/* Finalize signalling  */
2469
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2470
		if (wc->cardflag & (1 << x)) {
2471
			if (wc->modtype[x] == MOD_TYPE_FXO)
2472
				wc->chans[x]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
2473
			else
2474
				wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
2475
		} else if (!(wc->chans[x]->sigcap & DAHDI_SIG_BROKEN)) {
2476
			wc->chans[x]->sigcap = 0;
2477
		}
2478
	}
2479
}
2480
2481
static int wctdm_hardware_init(struct wctdm *wc)
2482
{
2483
	/* Hardware stuff */
2484
	unsigned char ver;
2485
	unsigned char x,y;
2486
	int failed;
2487
	long origjiffies; //ml.
2488
	
2489
	/* Signal Reset */
2490
	printk("before raise reset\n");
2491
	outb(0x01, wc->ioaddr + WC_CNTL);
2492
2493
	/* Wait for 5 second */
2494
	
2495
	origjiffies = jiffies;
2496
2497
	while(1) 
2498
	{
2499
		if ((jiffies - origjiffies) >= (HZ*5))
2500
			break;;
2501
	}
2502
2503
	/* printk(KERN_INFO "after raise reset\n");*/
2504
2505
	/* Check OpenVox chip */
2506
	x=inb(wc->ioaddr + WC_CNTL);
2507
	ver = __wctdm_getcreg(wc, WC_VER);
2508
	wc->fwversion = ver;
2509
	/*if( ver & FLAG_A800)
2510
	{
2511
		wc->card_name = A800P_Name;
2512
		wc->max_cards = 8;
2513
	}
2514
	else
2515
	{
2516
		wc->card_name = A1200P_Name;
2517
		wc->max_cards = 12;
2518
	}*/
2519
	printk(KERN_NOTICE "OpenVox %s version: %01x.%01x\n", wc->card_name, (ver&(~FLAG_A800))>>4, ver&0x0f);
2520
	
2521
	failed = 0;
2522
	if (ver != 0x00) {
2523
		for (x=0;x<16;x++) {
2524
			/* Test registers */
2525
			__wctdm_setcreg(wc, WC_CS, x);
2526
			y = __wctdm_getcreg(wc, WC_CS) & 0x0f;
2527
			if (x != y) {
2528
				printk(KERN_INFO "%02x != %02x\n", x, y);
2529
				failed++;
2530
			}
2531
		}
2532
2533
		if (!failed) {
2534
			printk(KERN_INFO "OpenVox %s passed register test\n", wc->card_name);
2535
		} else {
2536
			printk(KERN_NOTICE "OpenVox %s failed register test\n", wc->card_name);
2537
			return -1;
2538
		}
2539
	} else {
2540
		printk(KERN_INFO "No OpenVox chip %02x\n", ver);
2541
	}
2542
2543
	if (spibyhw)
2544
		__wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);	// spi controled by hw MiaoLin;
2545
	else
2546
		__wctdm_setcreg(wc, WC_SPICTRL, 0);	
2547
		
2548
	/* Reset PCI Interface chip and registers (and serial) */
2549
	outb(0x06, wc->ioaddr + WC_CNTL);
2550
	/* Setup our proper outputs for when we switch for our "serial" port */
2551
	wc->ios = BIT_CS | BIT_SCLK | BIT_SDI;
2552
2553
	outb(wc->ios, wc->ioaddr + WC_AUXD);
2554
2555
	/* Set all to outputs except AUX 5, which is an input */
2556
	outb(0xdf, wc->ioaddr + WC_AUXC);
2557
2558
	/* Select alternate function for AUX0 */  /* Useless in OpenVox by MiaoLin. */
2559
	/* outb(0x4, wc->ioaddr + WC_AUXFUNC); */
2560
	
2561
	/* Wait 1/4 of a sec */
2562
	wait_just_a_bit(HZ/4);
2563
2564
	/* Back to normal, with automatic DMA wrap around */
2565
	outb(0x30 | 0x01, wc->ioaddr + WC_CNTL);
2566
	wc->ledstate = 0;
2567
	wctdm_set_led(wc, 0, 0);
2568
	
2569
	/* Make sure serial port and DMA are out of reset */
2570
	outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, wc->ioaddr + WC_CNTL);
2571
	
2572
	/* Configure serial port for MSB->LSB operation */
2573
	outb(0xc1, wc->ioaddr + WC_SERCTL);
2574
2575
	/* Delay FSC by 0 so it's properly aligned */
2576
	outb(0x01, wc->ioaddr + WC_FSCDELAY);  /* Modify to 1 by MiaoLin */
2577
2578
	/* Setup DMA Addresses */
2579
	outl(wc->writedma,                    wc->ioaddr + WC_DMAWS);		/* Write start */
2580
	outl(wc->writedma + DAHDI_CHUNKSIZE * 4 * 4 - 4, wc->ioaddr + WC_DMAWI);		/* Middle (interrupt) */
2581
	outl(wc->writedma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMAWE);			/* End */
2582
	
2583
	outl(wc->readdma,                    	 wc->ioaddr + WC_DMARS);	/* Read start */
2584
	outl(wc->readdma + DAHDI_CHUNKSIZE * 4 * 4 - 4, 	 wc->ioaddr + WC_DMARI);	/* Middle (interrupt) */
2585
	outl(wc->readdma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMARE);	/* End */
2586
	
2587
	/* Clear interrupts */
2588
	outb(0xff, wc->ioaddr + WC_INTSTAT);
2589
2590
	/* Wait 1/4 of a second more */
2591
	wait_just_a_bit(HZ/4);
2592
2593
	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2594
		int sane=0,ret=0,readi=0;
2595
#if 1
2596
		touch_softlockup_watchdog();  // avoid showing CPU softlock message
2597
		/* Init with Auto Calibration */
2598
		if (!(ret=wctdm_init_proslic(wc, x, 0, 0, sane))) {
2599
			wc->cardflag |= (1 << x);
2600
                        if (debug) {
2601
                                readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
2602
                                printk("Proslic module %d loop current is %dmA\n",x,
2603
                                ((readi*3)+20));
2604
                        }
2605
			printk(KERN_INFO "Module %d: Installed -- AUTO FXS/DPO\n",x);
2606
			wctdm_set_led(wc, (unsigned int)x, 1);
2607
		} else {
2608
			if(ret!=-2) {
2609
				sane=1;
2610
				
2611
				printk(KERN_INFO "Init ProSlic with Manual Calibration \n");
2612
				/* Init with Manual Calibration */
2613
				if (!wctdm_init_proslic(wc, x, 0, 1, sane)) {
2614
					wc->cardflag |= (1 << x);
2615
                                if (debug) {
2616
                                        readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
2617
                                        printk("Proslic module %d loop current is %dmA\n",x,
2618
                                        ((readi*3)+20));
2619
                                }
2620
					printk(KERN_INFO "Module %d: Installed -- MANUAL FXS\n",x);
2621
				} else {
2622
					printk(KERN_NOTICE "Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");
2623
					wc->chans[x]->sigcap = __DAHDI_SIG_FXO | DAHDI_SIG_BROKEN;
2624
				} 
2625
			} else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) {
2626
				wc->cardflag |= (1 << x);
2627
				printk(KERN_INFO "Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);
2628
				wctdm_set_led(wc, (unsigned int)x, 1);
2629
			} else
2630
				printk(KERN_NOTICE "Module %d: Not installed\n", x);
2631
		}
2632
#endif
2633
	}
2634
2635
	/* Return error if nothing initialized okay. */
2636
	if (!wc->cardflag && !timingonly)
2637
		return -1;
2638
	/*__wctdm_setcreg(wc, WC_SYNC, (wc->cardflag << 1) | 0x1); */  /* removed by MiaoLin */
2639
	return 0;
2640
}
2641
2642
static void wctdm_enable_interrupts(struct wctdm *wc)
2643
{
2644
	/* Clear interrupts */
2645
	outb(0xff, wc->ioaddr + WC_INTSTAT);
2646
2647
	/* Enable interrupts (we care about all of them) */
2648
	outb(0x3c, wc->ioaddr + WC_MASK0);
2649
	/* No external interrupts */
2650
	outb(0x00, wc->ioaddr + WC_MASK1);
2651
}
2652
2653
static void wctdm_restart_dma(struct wctdm *wc)
2654
{
2655
	/* Reset Master and TDM */
2656
	outb(0x01, wc->ioaddr + WC_CNTL);
2657
	outb(0x01, wc->ioaddr + WC_OPER);
2658
}
2659
2660
static void wctdm_start_dma(struct wctdm *wc)
2661
{
2662
	/* Reset Master and TDM */
2663
	outb(0x0f, wc->ioaddr + WC_CNTL);
2664
	set_current_state(TASK_INTERRUPTIBLE);
2665
	schedule_timeout(1);
2666
	outb(0x01, wc->ioaddr + WC_CNTL);
2667
	outb(0x01, wc->ioaddr + WC_OPER);
2668
}
2669
2670
static void wctdm_stop_dma(struct wctdm *wc)
2671
{
2672
	outb(0x00, wc->ioaddr + WC_OPER);
2673
}
2674
2675
static void wctdm_reset_tdm(struct wctdm *wc)
2676
{
2677
	/* Reset TDM */
2678
	outb(0x0f, wc->ioaddr + WC_CNTL);
2679
}
2680
2681
static void wctdm_disable_interrupts(struct wctdm *wc)	
2682
{
2683
	outb(0x00, wc->ioaddr + WC_MASK0);
2684
	outb(0x00, wc->ioaddr + WC_MASK1);
2685
}
2686
2687
static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2688
{
2689
	int res;
2690
	struct wctdm *wc;
2691
	struct wctdm_desc *d = (struct wctdm_desc *)ent->driver_data;
2692
	int x;
2693
	int y;
2694
2695
	static int initd_ifaces=0;
2696
	
2697
	if(initd_ifaces){
2698
		memset((void *)ifaces,0,(sizeof(struct wctdm *))*WC_MAX_IFACES);
2699
		initd_ifaces=1;
2700
	}
2701
	for (x=0;x<WC_MAX_IFACES;x++)
2702
		if (!ifaces[x]) break;
2703
	if (x >= WC_MAX_IFACES) {
2704
		printk(KERN_NOTICE "Too many interfaces\n");
2705
		return -EIO;
2706
	}
2707
	
2708
	if (pci_enable_device(pdev)) {
2709
		res = -EIO;
2710
	} else {
2711
		wc = kmalloc(sizeof(struct wctdm), GFP_KERNEL);
2712
		if (wc) {
2713
			int cardcount = 0;
2714
			
2715
			wc->lastchan = -1;	/* first channel offset = -1; */
2716
			wc->ledstate = 0;
2717
			
2718
			ifaces[x] = wc;
2719
			memset(wc, 0, sizeof(struct wctdm));
2720
			for (x=0; x < sizeof(wc->chans)/sizeof(wc->chans[0]); ++x) {
2721
				wc->chans[x] = &wc->_chans[x];
2722
			}
2723
2724
			spin_lock_init(&wc->lock);
2725
			wc->curcard = -1;
2726
			wc->ioaddr = pci_resource_start(pdev, 0);
2727
			wc->mem_region = pci_resource_start(pdev, 1);
2728
			wc->mem_len = pci_resource_len(pdev, 1);
2729
			wc->mem32 = (unsigned long)ioremap(wc->mem_region, wc->mem_len);
2730
			wc->dev = pdev;
2731
			wc->pos = x;
2732
			wc->variety = d->name;
2733
			for (y=0;y<MAX_NUM_CARDS;y++)
2734
				wc->flags[y] = d->flags;
2735
			/* Keep track of whether we need to free the region */
2736
			if (request_region(wc->ioaddr, 0xff, "opvxa1200")) 
2737
				wc->freeregion = 1;
2738
			else
2739
				wc->freeregion = 0;
2740
			
2741
			if (request_mem_region(wc->mem_region, wc->mem_len, "opvxa1200"))
2742
				wc->freeregion |= 0x02;
2743
2744
			/* Allocate enough memory for two zt chunks, receive and transmit.  Each sample uses
2745
			   8 bits.  */
2746
			wc->writechunk = pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, &wc->writedma);
2747
			if (!wc->writechunk) {
2748
				printk(KERN_NOTICE "opvxa1200: Unable to allocate DMA-able memory\n");
2749
				if (wc->freeregion & 0x01)
2750
					release_region(wc->ioaddr, 0xff);
2751
				if (wc->freeregion & 0x02)
2752
				{
2753
					release_mem_region(wc->mem_region, wc->mem_len);
2754
					iounmap((void *)wc->mem32);
2755
				}
2756
				return -ENOMEM;
2757
			}
2758
2759
			wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
2760
			wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
2761
			
2762
			if (wctdm_initialize(wc)) {
2763
				printk(KERN_NOTICE "opvxa1200: Unable to intialize FXS\n");
2764
				/* Set Reset Low */
2765
				x=inb(wc->ioaddr + WC_CNTL);
2766
				outb((~0x1)&x, wc->ioaddr + WC_CNTL);
2767
				/* Free Resources */
2768
				free_irq(pdev->irq, wc);
2769
				if (wc->freeregion & 0x01)
2770
					release_region(wc->ioaddr, 0xff);
2771
				if (wc->freeregion & 0x02)
2772
				{
2773
					release_mem_region(wc->mem_region, wc->mem_len);
2774
					iounmap((void *)wc->mem32);
2775
				}
2776
			}
2777
2778
			/* Enable bus mastering */
2779
			pci_set_master(pdev);
2780
2781
			/* Keep track of which device we are */
2782
			pci_set_drvdata(pdev, wc);
2783
2784
2785
			if (request_irq(pdev->irq, wctdm_interrupt, DAHDI_IRQ_SHARED, "opvxa1200", wc)) {
2786
				printk(KERN_NOTICE "opvxa1200: Unable to request IRQ %d\n", pdev->irq);
2787
				if (wc->freeregion & 0x01)
2788
					release_region(wc->ioaddr, 0xff);
2789
				if (wc->freeregion & 0x02)
2790
				{
2791
					release_mem_region(wc->mem_region, wc->mem_len);
2792
					iounmap((void *)wc->mem32);
2793
				}
2794
				pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2795
				pci_set_drvdata(pdev, NULL);
2796
				kfree(wc);
2797
				return -EIO;
2798
			}
2799
2800
			if (wctdm_hardware_init(wc)) {
2801
				unsigned char w;
2802
2803
				/* Set Reset Low */
2804
				w=inb(wc->ioaddr + WC_CNTL);
2805
				outb((~0x1)&w, wc->ioaddr + WC_CNTL);
2806
				/* Free Resources */
2807
				free_irq(pdev->irq, wc);
2808
				if (wc->freeregion & 0x01)
2809
					release_region(wc->ioaddr, 0xff);
2810
				if (wc->freeregion & 0x02)
2811
				{
2812
					release_mem_region(wc->mem_region, wc->mem_len);
2813
					iounmap((void *)wc->mem32);
2814
				}
2815
				pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2816
				pci_set_drvdata(pdev, NULL);
2817
				dahdi_unregister_device(wc->ddev);
2818
				kfree(wc->ddev->location);
2819
				dahdi_free_device(wc->ddev);
2820
				kfree(wc);
2821
				return -EIO;
2822
2823
			}
2824
2825
#ifdef TEST_LOG_INCOME_VOICE
2826
			for(x=0; x<MAX_NUM_CARDS+NUM_FLAG; x++)
2827
			{
2828
				wc->voc_buf[x] = kmalloc(voc_buffer_size, GFP_KERNEL);
2829
				wc->voc_ptr[x] = 0;
2830
			}
2831
#endif
2832
2833
			if(cidbeforering) 
2834
			{		
2835
				int len = cidbuflen * DAHDI_MAX_CHUNKSIZE;
2836
				if(debug)
2837
					printk("cidbeforering support enabled, length is %d msec\n", cidbuflen);
2838
				for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) 
2839
				{
2840
					wc->cid_history_buf[x] = kmalloc(len, GFP_KERNEL);
2841
					wc->cid_history_ptr[x] = 0;
2842
					wc->cid_history_clone_cnt[x] = 0;
2843
					wc->cid_state[x] = CID_STATE_IDLE;
2844
				}
2845
			}
2846
			
2847
			wctdm_post_initialize(wc);
2848
2849
			/* Enable interrupts */
2850
			wctdm_enable_interrupts(wc);
2851
			/* Initialize Write/Buffers to all blank data */
2852
			memset((void *)wc->writechunk,0, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2);
2853
2854
			/* Start DMA */
2855
			wctdm_start_dma(wc);
2856
2857
			for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
2858
				if (wc->cardflag & (1 << x))
2859
					cardcount++;
2860
			}
2861
2862
			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);
2863
			if(debug)
2864
				printk(KERN_DEBUG "OpenVox %s debug On\n", wc->card_name);
2865
			
2866
			res = 0;
2867
		} else
2868
			res = -ENOMEM;
2869
	}
2870
	return res;
2871
}
2872
2873
static void wctdm_release(struct wctdm *wc)
2874
{
2875
#ifdef TEST_LOG_INCOME_VOICE
2876
	struct file * f = NULL;
2877
	mm_segment_t orig_fs;
2878
	int i;
2879
	char fname[20];
2880
#endif
2881
	
2882
	dahdi_unregister_device(wc->ddev);
2883
	kfree(wc->ddev->location);
2884
	dahdi_free_device(wc->ddev);
2885
	if (wc->freeregion & 0x01)
2886
		release_region(wc->ioaddr, 0xff);
2887
	if (wc->freeregion & 0x02)
2888
	{
2889
		release_mem_region(wc->mem_region, wc->mem_len);
2890
		iounmap((void *)wc->mem32);
2891
	}
2892
	
2893
#ifdef TEST_LOG_INCOME_VOICE
2894
	for(i=0; i<MAX_NUM_CARDS + NUM_FLAG; i++)
2895
	{
2896
		sprintf(fname, "//usr//%d.pcm", i); 
2897
		f = filp_open(fname, O_RDWR|O_CREAT, 00);
2898
	
2899
		if (!f || !f->f_op || !f->f_op->read)
2900
		{
2901
			printk("WARNING: File (read) object is a null pointer!!!\n");
2902
			continue;
2903
		}
2904
	
2905
		f->f_pos = 0;
2906
		
2907
		orig_fs = get_fs();
2908
		set_fs(KERNEL_DS); 
2909
		
2910
		if(wc->voc_buf[i])
2911
		{
2912
			f->f_op->write(f, wc->voc_buf[i], voc_buffer_size, &f->f_pos);
2913
			kfree(wc->voc_buf[i]);
2914
		}
2915
		
2916
		set_fs(orig_fs); 
2917
		fput(f);
2918
	}
2919
#endif
2920
 
2921
	if(cidbeforering) 
2922
	{
2923
		int x;
2924
		for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) 
2925
			kfree(wc->cid_history_buf[x]);
2926
	}
2927
 
2928
	kfree(wc);
2929
	printk(KERN_INFO "Free an OpenVox A1200 card\n");
2930
}
2931
2932
static void __devexit wctdm_remove_one(struct pci_dev *pdev)
2933
{
2934
	struct wctdm *wc = pci_get_drvdata(pdev);
2935
	if (wc) {
2936
2937
		/* Stop any DMA */
2938
		wctdm_stop_dma(wc);
2939
		wctdm_reset_tdm(wc);
2940
2941
		/* In case hardware is still there */
2942
		wctdm_disable_interrupts(wc);
2943
		
2944
		/* Immediately free resources */
2945
		pci_free_consistent(pdev,  DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
2946
		free_irq(pdev->irq, wc);
2947
2948
		/* Reset PCI chip and registers */
2949
		if(wc->fwversion > 0x11)
2950
			outb(0x0e, wc->ioaddr + WC_CNTL);
2951
		else
2952
		{
2953
			wc->ledstate = 0;
2954
			wctdm_set_led(wc,0,0);	// power off all leds.
2955
		}
2956
2957
		/* Release span, possibly delayed */
2958
		if (!wc->usecount)
2959
			wctdm_release(wc);
2960
		else
2961
			wc->dead = 1;
2962
	}
2963
}
2964
2965
static struct pci_device_id wctdm_pci_tbl[] = {
2966
	{ 0xe159, 0x0001, 0x9100, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2967
	{ 0xe159, 0x0001, 0x9519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2968
	{ 0xe159, 0x0001, 0x95D9, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2969
	{ 0xe159, 0x0001, 0x9500, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2970
	{ 0xe159, 0x0001, 0x9532, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme }, 
2971
	{ 0xe159, 0x0001, 0x8519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2972
	{ 0xe159, 0x0001, 0x9559, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2973
	{ 0xe159, 0x0001, 0x9599, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
2974
	{ 0 }
2975
};
2976
2977
MODULE_DEVICE_TABLE(pci, wctdm_pci_tbl);
2978
2979
static struct pci_driver wctdm_driver = {
2980
	.name = "opvxa1200",
2981
	.probe =	wctdm_init_one,
2982
	.remove =	__devexit_p(wctdm_remove_one),
2983
	.suspend = NULL,
2984
	.resume =	NULL,
2985
	.id_table = wctdm_pci_tbl,
2986
};
2987
2988
static int __init wctdm_init(void)
2989
{
2990
	int res;
2991
	int x;
2992
	for (x=0;x<(sizeof(fxo_modes) / sizeof(fxo_modes[0])); x++) {
2993
		if (!strcmp(fxo_modes[x].name, opermode))
2994
			break;
2995
	}
2996
	if (x < sizeof(fxo_modes) / sizeof(fxo_modes[0])) {
2997
		_opermode = x;
2998
	} else {
2999
		printk(KERN_NOTICE "Invalid/unknown operating mode '%s' specified.  Please choose one of:\n", opermode);
3000
		for (x=0;x<sizeof(fxo_modes) / sizeof(fxo_modes[0]); x++)
3001
			printk(KERN_INFO "  %s\n", fxo_modes[x].name);
3002
		printk(KERN_INFO "Note this option is CASE SENSITIVE!\n");
3003
		return -ENODEV;
3004
	}
3005
	if (!strcmp(fxo_modes[_opermode].name, "AUSTRALIA")) {
3006
		boostringer=1;
3007
		fxshonormode=1;
3008
}
3009
	if (battdebounce == 0) {
3010
		battdebounce = fxo_modes[_opermode].battdebounce;
3011
	}
3012
	if (battalarm == 0) {
3013
		battalarm = fxo_modes[_opermode].battalarm;
3014
	}
3015
	if (battthresh == 0) {
3016
		battthresh = fxo_modes[_opermode].battthresh;
3017
	}
3018
3019
	res = dahdi_pci_module(&wctdm_driver);
3020
	if (res)
3021
		return -ENODEV;
3022
	return 0;
3023
}
3024
3025
static void __exit wctdm_cleanup(void)
3026
{
3027
	pci_unregister_driver(&wctdm_driver);
3028
}
3029
3030
module_param(debug, int, 0600);
3031
module_param(loopcurrent, int, 0600);
3032
module_param(reversepolarity, int, 0600);
3033
module_param(robust, int, 0600);
3034
module_param(opermode, charp, 0600);
3035
module_param(timingonly, int, 0600);
3036
module_param(lowpower, int, 0600);
3037
module_param(boostringer, int, 0600);
3038
module_param(fastringer, int, 0600);
3039
module_param(fxshonormode, int, 0600);
3040
module_param(battdebounce, uint, 0600);
3041
module_param(battthresh, uint, 0600);
3042
module_param(battalarm, uint, 0600);
3043
module_param(ringdebounce, int, 0600);
3044
module_param(dialdebounce, int, 0600);
3045
module_param(fwringdetect, int, 0600);
3046
module_param(alawoverride, int, 0600);
3047
module_param(fastpickup, int, 0600);
3048
module_param(fxotxgain, int, 0600);
3049
module_param(fxorxgain, int, 0600);
3050
module_param(fxstxgain, int, 0600);
3051
module_param(fxsrxgain, int, 0600);
3052
module_param(spibyhw, int, 0600);
3053
module_param(usememio, int, 0600);
3054
module_param(cidbeforering, int, 0600);
3055
module_param(cidbuflen, int, 0600);
3056
module_param(cidtimeout, int, 0600);
3057
module_param(fxofullscale, int, 0600);
3058
module_param(fixedtimepolarity, int, 0600);
3059
3060
MODULE_DESCRIPTION("OpenVox A1200 Driver");
3061
MODULE_AUTHOR("MiaoLin <miaolin@openvox.com.cn>");
3062
MODULE_LICENSE("GPL v2");
3063
3064
module_init(wctdm_init);
3065
module_exit(wctdm_cleanup);
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/Kbuild (+19 lines)
Line 0 Link Here
1
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200) += opvxa1200.o
2
3
EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
4
5
opvxa1200-objs := base.o
6
7
DAHDI_KERNEL_H_NAME:=kernel.h
8
DAHDI_KERNEL_H_PATH:=$(DAHDI_INCLUDE)/dahdi/$(DAHDI_KERNEL_H_NAME)
9
ifneq ($(DAHDI_KERNEL_H_PATH),)
10
        DAHDI_SPAN_MODULE:=$(shell if grep -C 5 "struct dahdi_span {" $(DAHDI_KERNEL_H_PATH) | grep -q "struct module \*owner"; then echo "yes"; else echo "no"; fi)
11
        DAHDI_SPAN_OPS:=$(shell if grep -q "struct dahdi_span_ops {" $(DAHDI_KERNEL_H_PATH); then echo "yes"; else echo "no"; fi)
12
        ifeq ($(DAHDI_SPAN_MODULE),yes)
13
                EXTRA_CFLAGS+=-DDAHDI_SPAN_MODULE
14
        else
15
                ifeq ($(DAHDI_SPAN_OPS),yes)
16
                        EXTRA_CFLAGS+=-DDAHDI_SPAN_OPS
17
                endif
18
        endif
19
endif
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/Makefile (+8 lines)
Line 0 Link Here
1
ifdef KBUILD_EXTMOD
2
# We only get here on kernels 2.6.0-2.6.9 .
3
# For newer kernels, Kbuild will be included directly by the kernel
4
# build system.
5
include $(src)/Kbuild
6
7
else
8
endif
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/base.c (+4908 lines)
Line 0 Link Here
1
/*
2
 * OpenVox D115P/D115E PCI/PCI-E Driver version 0.1 01/07/2011
3
 *
4
 * Written by Mark Spencer <markster@digium.com>
5
 * Modify from wct4xxp module by mark.liu@openvox.cn
6
7
 * Based on previous works, designs, and archetectures conceived and
8
 * written by Jim Dixon <jim@lambdatel.com>.
9
 *
10
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
11
 * Copyright (C) 2001-2010, Digium, Inc.
12
 *
13
 * All rights reserved.
14
 *
15
 */
16
17
/*
18
 * See http://www.asterisk.org for more information about
19
 * the Asterisk project. Please do not directly contact
20
 * any of the maintainers of this project for assistance;
21
 * the project provides a web site, mailing lists and IRC
22
 * channels for your use.
23
 *
24
 * This program is free software, distributed under the terms of
25
 * the GNU General Public License Version 2 as published by the
26
 * Free Software Foundation. See the LICENSE file included with
27
 * this program for more details.
28
 */
29
30
#include <linux/kernel.h>
31
#include <linux/errno.h>
32
#include <linux/module.h>
33
#include <linux/pci.h>
34
#include <linux/init.h>
35
#include <linux/sched.h>
36
#include <linux/interrupt.h>
37
#include <linux/spinlock.h>
38
#include <asm/io.h>
39
#include <linux/version.h>
40
#include <linux/delay.h>
41
#include <linux/moduleparam.h>
42
43
#include <dahdi/kernel.h>
44
45
#include "opvxd115.h"
46
#include "vpm450m.h"
47
48
/* Work queues are a way to better distribute load on SMP systems */
49
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
50
/*
51
 * Work queues can significantly improve performance and scalability
52
 * on multi-processor machines, but requires bypassing some kernel
53
 * API's, so it's not guaranteed to be compatible with all kernels.
54
 */
55
/* #define ENABLE_WORKQUEUES */
56
#endif
57
58
/* Enable prefetching may help performance */
59
#define ENABLE_PREFETCH
60
61
/* Support first generation cards? */
62
#define SUPPORT_GEN1 
63
64
/* Define to get more attention-grabbing but slightly more I/O using
65
   alarm status */
66
#define FANCY_ALARM
67
68
/* Define to support Digium Voice Processing Module expansion card */
69
#define VPM_SUPPORT
70
71
#define DEBUG_MAIN 		(1 << 0)
72
#define DEBUG_DTMF 		(1 << 1)
73
#define DEBUG_REGS 		(1 << 2)
74
#define DEBUG_TSI  		(1 << 3)
75
#define DEBUG_ECHOCAN 	(1 << 4)
76
#define DEBUG_RBS 		(1 << 5)
77
#define DEBUG_FRAMER		(1 << 6)
78
79
/* Maximum latency to be used with Gen 5 */
80
#define GEN5_MAX_LATENCY	127
81
82
#define T4_BASE_SIZE (DAHDI_MAX_CHUNKSIZE * 32 * 4) 
83
84
#ifdef ENABLE_WORKQUEUES
85
#include <linux/cpu.h>
86
87
/* XXX UGLY!!!! XXX  We have to access the direct structures of the workqueue which
88
  are only defined within workqueue.c because they don't give us a routine to allow us
89
  to nail a work to a particular thread of the CPU.  Nailing to threads gives us substantially
90
  higher scalability in multi-CPU environments though! */
91
92
/*
93
 * The per-CPU workqueue (if single thread, we always use cpu 0's).
94
 *
95
 * The sequence counters are for flush_scheduled_work().  It wants to wait
96
 * until until all currently-scheduled works are completed, but it doesn't
97
 * want to be livelocked by new, incoming ones.  So it waits until
98
 * remove_sequence is >= the insert_sequence which pertained when
99
 * flush_scheduled_work() was called.
100
 */
101
 
102
struct cpu_workqueue_struct {
103
104
	spinlock_t lock;
105
106
	long remove_sequence;	/* Least-recently added (next to run) */
107
	long insert_sequence;	/* Next to add */
108
109
	struct list_head worklist;
110
	wait_queue_head_t more_work;
111
	wait_queue_head_t work_done;
112
113
	struct workqueue_struct *wq;
114
	task_t *thread;
115
116
	int run_depth;		/* Detect run_workqueue() recursion depth */
117
} ____cacheline_aligned;
118
119
/*
120
 * The externally visible workqueue abstraction is an array of
121
 * per-CPU workqueues:
122
 */
123
struct workqueue_struct {
124
	/* TODO: Find out exactly where the API changed */
125
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
126
	struct cpu_workqueue_struct *cpu_wq;
127
#else
128
	struct cpu_workqueue_struct cpu_wq[NR_CPUS];
129
#endif
130
	const char *name;
131
	struct list_head list; 	/* Empty if single thread */
132
};
133
134
/* Preempt must be disabled. */
135
static void __t4_queue_work(struct cpu_workqueue_struct *cwq,
136
			 struct work_struct *work)
137
{
138
	unsigned long flags;
139
140
	spin_lock_irqsave(&cwq->lock, flags);
141
	work->wq_data = cwq;
142
	list_add_tail(&work->entry, &cwq->worklist);
143
	cwq->insert_sequence++;
144
	wake_up(&cwq->more_work);
145
	spin_unlock_irqrestore(&cwq->lock, flags);
146
}
147
148
/*
149
 * Queue work on a workqueue. Return non-zero if it was successfully
150
 * added.
151
 *
152
 * We queue the work to the CPU it was submitted, but there is no
153
 * guarantee that it will be processed by that CPU.
154
 */
155
static inline int t4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu)
156
{
157
	int ret = 0;
158
	get_cpu();
159
	if (!test_and_set_bit(0, &work->pending)) {
160
		BUG_ON(!list_empty(&work->entry));
161
		__t4_queue_work(wq->cpu_wq + cpu, work);
162
		ret = 1;
163
	}
164
	put_cpu();
165
	return ret;
166
}
167
168
#endif
169
170
/*
171
 * Define CONFIG_EXTENDED_RESET to allow the qfalc framer extra time
172
 * to reset itself upon hardware initialization. This exits for rare
173
 * cases for customers who are seeing the qfalc returning unexpected
174
 * information at initialization
175
 */
176
#undef CONFIG_EXTENDED_RESET
177
178
static int pedanticpci = 1;
179
static int debug=0;
180
static int timingcable = 0;
181
static int t1e1override = -1;  /* 0xff for E1, 0x00 for T1 */
182
static int j1mode = 0;
183
static int sigmode = FRMR_MODE_NO_ADDR_CMP;
184
static int alarmdebounce = 2500; /* LOF/LFA def to 2.5s AT&T TR54016*/
185
static int losalarmdebounce = 2500;/* LOS def to 2.5s AT&T TR54016*/
186
static int aisalarmdebounce = 2500;/* AIS(blue) def to 2.5s AT&T TR54016*/
187
static int yelalarmdebounce = 500;/* RAI(yellow) def to 0.5s AT&T devguide */
188
static int max_latency = GEN5_MAX_LATENCY;  /* Used to set a maximum latency (if you don't wish it to hard cap it at a certain value) in milliseconds */
189
#ifdef VPM_SUPPORT
190
static int vpmsupport = 1;
191
/* If set to auto, vpmdtmfsupport is enabled for VPM400M and disabled for VPM450M */
192
static int vpmdtmfsupport = -1; /* -1=auto, 0=disabled, 1=enabled*/
193
static int vpmspans = 1;
194
#define VPM_DEFAULT_DTMFTHRESHOLD 1000
195
static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
196
static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
197
#endif
198
/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
199
   can also cause PCI bus starvation, especially in combination with other
200
   aggressive cards.  Please note that burst mode has no effect on CPU
201
   utilization / max number of calls / etc. */
202
static int noburst;
203
/* For 56kbps links, set this module parameter to 0x7f */
204
static int hardhdlcmode = 0xff;
205
206
static int latency = 1;
207
208
static int ms_per_irq = 1;
209
210
#ifdef FANCY_ALARM
211
static int altab[] = {
212
0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0, 
213
};
214
#endif
215
216
#define MAX_SPANS 16
217
218
#define FLAG_STARTED (1 << 0)
219
#define FLAG_NMF (1 << 1)
220
#define FLAG_SENDINGYELLOW (1 << 2)
221
222
223
#define	TYPE_T1	1		/* is a T1 card */
224
#define	TYPE_E1	2		/* is an E1 card */
225
#define TYPE_J1 3		/* is a running J1 */
226
227
#define FLAG_2NDGEN  (1 << 3)
228
#define FLAG_2PORT   (1 << 4)
229
#define FLAG_VPM2GEN (1 << 5)
230
#define FLAG_OCTOPT  (1 << 6)
231
#define FLAG_3RDGEN  (1 << 7)
232
#define FLAG_BURST   (1 << 8)
233
#define FLAG_5THGEN  (1 << 10)
234
235
#define CANARY 0xc0de
236
237
238
#define PORTS_PER_FRAMER 4
239
240
struct devtype {
241
	char *desc;
242
	unsigned int flags;
243
};
244
245
static struct devtype opvxd115 = { "OpenVox D115P/D115E ", FLAG_2NDGEN};
246
static struct devtype opvxd130 = { "OpenVox D130P/D130E", FLAG_5THGEN | FLAG_BURST | FLAG_2NDGEN | FLAG_3RDGEN};
247
	
248
249
struct t4;
250
251
struct t4_span {
252
	struct t4 *owner;
253
	unsigned int *writechunk;					/* Double-word aligned write memory */
254
	unsigned int *readchunk;					/* Double-word aligned read memory */
255
	int spantype;		/* card type, T1 or E1 or J1 */
256
	int sync;
257
	int psync;
258
	int alarmtimer;
259
	int redalarms;
260
	int notclear;
261
	int alarmcount;
262
	int losalarmcount;
263
	int aisalarmcount;
264
	int yelalarmcount;
265
	int spanflags;
266
	int syncpos;
267
#ifdef SUPPORT_GEN1
268
	int e1check;			/* E1 check */
269
#endif
270
	struct dahdi_span span;
271
	unsigned char txsigs[16];	/* Transmit sigs */
272
	int loopupcnt;
273
	int loopdowncnt;
274
#ifdef SUPPORT_GEN1
275
	unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
276
	unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
277
#endif
278
	int irqmisses;
279
	
280
	/* HDLC controller fields */
281
	struct dahdi_chan *sigchan;
282
	unsigned char sigmode;
283
	int sigactive;
284
	int frames_out;
285
	int frames_in;
286
287
#ifdef VPM_SUPPORT
288
	unsigned long dtmfactive;
289
	unsigned long dtmfmask;
290
	unsigned long dtmfmutemask;
291
	short dtmfenergy[31];
292
	short dtmfdigit[31];
293
#endif
294
#ifdef ENABLE_WORKQUEUES
295
	struct work_struct swork;
296
#endif	
297
	struct dahdi_chan *chans[32];		/* Individual channels */
298
	struct dahdi_echocan_state *ec[32];	/* Echocan state for each channel */
299
};
300
301
struct t4 {
302
	/* This structure exists one per card */
303
	struct pci_dev *dev;		/* Pointer to PCI device */
304
	struct dahdi_device *ddev;	/* Pointer to DAHDI device */
305
	unsigned int intcount;
306
	int num;			/* Which card we are */
307
	int t1e1;			/* T1/E1 select pins */
308
	int globalconfig;	/* Whether global setup has been done */
309
	int syncsrc;			/* active sync source */
310
	struct t4_span *tspans[4];	/* Individual spans */
311
	int numspans;			/* Number of spans on the card */
312
	int blinktimer;
313
#ifdef FANCY_ALARM
314
	int alarmpos;
315
#endif
316
	int irq;			/* IRQ used by device */
317
	int order;			/* Order */
318
	int flags;                      /* Device flags */
319
	unsigned int falc31 : 1;	/* are we falc v3.1 (atomic not necessary) */
320
	int master;				/* Are we master */
321
	int ledreg;				/* LED Register */
322
	unsigned int gpio;
323
	unsigned int gpioctl;
324
	int e1recover;			/* E1 recovery timer */
325
	spinlock_t reglock;		/* lock register access */
326
	int spansstarted;		/* number of spans started */
327
	volatile unsigned int *writechunk;					/* Double-word aligned write memory */
328
	volatile unsigned int *readchunk;					/* Double-word aligned read memory */
329
	unsigned short canary;
330
#ifdef ENABLE_WORKQUEUES
331
	atomic_t worklist;
332
	struct workqueue_struct *workq;
333
#endif
334
	unsigned int passno;	/* number of interrupt passes */
335
	char *variety;
336
	int last0;		/* for detecting double-missed IRQ */
337
338
	/* DMA related fields */
339
	unsigned int dmactrl;
340
	dma_addr_t 	readdma;
341
	dma_addr_t	writedma;
342
	unsigned long memaddr;		/* Base address of card */
343
	unsigned long memlen;
344
	__iomem volatile unsigned int *membase;	/* Base address of card */
345
346
	/* Add this for our softlockup protector */
347
	unsigned int oct_rw_count;
348
349
	/* Flags for our bottom half */
350
	unsigned long checkflag;
351
	struct tasklet_struct t4_tlet;
352
	unsigned int vpm400checkstatus;
353
	/* Latency related additions */
354
	unsigned char rxident;
355
	unsigned char lastindex;
356
	int numbufs;
357
	int needed_latency;
358
	
359
#ifdef VPM_SUPPORT
360
	struct vpm450m *vpm450m;
361
	int vpm;
362
#endif	
363
364
};
365
366
#define T4_VPM_PRESENT (1 << 28)
367
368
#ifdef VPM_SUPPORT
369
static void t4_vpm400_init(struct t4 *wc);
370
static void t4_vpm450_init(struct t4 *wc);
371
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
372
373
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
374
375
static const struct dahdi_echocan_features vpm400m_ec_features = {
376
	.NLP_automatic = 1,
377
	.CED_tx_detect = 1,
378
	.CED_rx_detect = 1,
379
};
380
381
static const struct dahdi_echocan_features vpm450m_ec_features = {
382
	.NLP_automatic = 1,
383
	.CED_tx_detect = 1,
384
	.CED_rx_detect = 1,
385
};
386
387
static const struct dahdi_echocan_ops vpm400m_ec_ops = {
388
	.echocan_free = echocan_free,
389
};
390
391
static const struct dahdi_echocan_ops vpm450m_ec_ops = {
392
	.echocan_free = echocan_free,
393
};
394
#endif
395
396
static void __set_clear(struct t4 *wc, int span);
397
static int t4_startup(struct file *file, struct dahdi_span *span);
398
static int t4_shutdown(struct dahdi_span *span);
399
static int t4_rbsbits(struct dahdi_chan *chan, int bits);
400
static int t4_maint(struct dahdi_span *span, int cmd);
401
static int t4_clear_maint(struct dahdi_span *span);
402
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
403
static int t4_reset_counters(struct dahdi_span *span);
404
#endif
405
#ifdef SUPPORT_GEN1
406
static int t4_reset_dma(struct t4 *wc);
407
#endif
408
static void t4_hdlc_hard_xmit(struct dahdi_chan *chan);
409
static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
410
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan);
411
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan);
412
static void __t4_set_rclk_src(struct t4 *wc, int span);
413
static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave);
414
static void t4_check_alarms(struct t4 *wc, int span);
415
static void t4_check_sigbits(struct t4 *wc, int span);
416
417
#define WC_RDADDR	0
418
#define WC_WRADDR	1
419
#define WC_COUNT	2
420
#define WC_DMACTRL	3	
421
#define WC_INTR		4
422
/* #define WC_GPIO		5 */
423
#define WC_VERSION	6
424
#define WC_LEDS		7
425
#define WC_GPIOCTL	8
426
#define WC_GPIO		9
427
#define WC_LADDR	10
428
#define WC_LDATA		11
429
#define WC_LCS		(1 << 11)
430
#define WC_LCS2		(1 << 12)
431
#define WC_LALE			(1 << 13)
432
#define WC_LFRMR_CS	(1 << 10)	/* Framer's ChipSelect signal */
433
#define WC_ACTIVATE	(1 << 12)
434
#define WC_LREAD			(1 << 15)
435
#define WC_LWRITE		(1 << 16)
436
437
#define WC_OFF    (0)
438
#define WC_RED    (1)
439
#define WC_GREEN  (2)
440
#define WC_YELLOW (3)
441
442
#define WC_RECOVER 	0
443
#define WC_SELF 	1
444
445
#define LIM0_T 0x36 		/* Line interface mode 0 register */
446
#define LIM0_LL (1 << 1)	/* Local Loop */
447
#define LIM1_T 0x37		/* Line interface mode 1 register */
448
#define LIM1_RL (1 << 1)	/* Remote Loop */
449
450
#define FMR0 0x1C		/* Framer Mode Register 0 */
451
#define FMR0_SIM (1 << 0)	/* Alarm Simulation */
452
#define FMR1_T 0x1D		/* Framer Mode Register 1 */
453
#define FMR1_ECM (1 << 2)	/* Error Counter 1sec Interrupt Enable */
454
#define DEC_T 0x60		/* Diable Error Counter */
455
#define IERR_T 0x1B		/* Single Bit Defect Insertion Register */
456
#define IBV	0	 /* Bipolar violation */
457
#define IPE	(1 << 1) /* PRBS defect */
458
#define ICASE	(1 << 2) /* CAS defect */
459
#define ICRCE	(1 << 3) /* CRC defect */
460
#define IMFE	(1 << 4) /* Multiframe defect */
461
#define IFASE	(1 << 5) /* FAS defect */
462
#define ISR3_SEC (1 << 6)	/* Internal one-second interrupt bit mask */
463
#define ISR3_ES (1 << 7)	/* Errored Second interrupt bit mask */
464
#define ESM 0x47		/* Errored Second mask register */
465
466
#define FMR2_T 0x1E		/* Framer Mode Register 2 */
467
#define FMR2_PLB (1 << 2)	/* Framer Mode Register 2 */
468
469
#define FECL_T 0x50		/* Framing Error Counter Lower Byte */
470
#define FECH_T 0x51		/* Framing Error Counter Higher Byte */
471
#define CVCL_T 0x52		/* Code Violation Counter Lower Byte */
472
#define CVCH_T 0x53		/* Code Violation Counter Higher Byte */
473
#define CEC1L_T 0x54		/* CRC Error Counter 1 Lower Byte */
474
#define CEC1H_T 0x55		/* CRC Error Counter 1 Higher Byte */
475
#define EBCL_T 0x56		/* E-Bit Error Counter Lower Byte */
476
#define EBCH_T 0x57		/* E-Bit Error Counter Higher Byte */
477
#define BECL_T 0x58		/* Bit Error Counter Lower Byte */
478
#define BECH_T 0x59		/* Bit Error Counter Higher Byte */
479
#define COEC_T 0x5A		/* COFA Event Counter */
480
#define PRBSSTA_T 0xDA		/* PRBS Status Register */
481
482
#define LCR1_T 0x3B		/* Loop Code Register 1 */
483
#define EPRM (1 << 7)		/* Enable PRBS rx */
484
#define XPRBS (1 << 6)		/* Enable PRBS tx */
485
#define FLLB (1 << 1)		/* Framed line loop/Invert */
486
#define LLBP (1 << 0)		/* Line Loopback Pattern */
487
#define TPC0_T 0xA8		/* Test Pattern Control Register */
488
#define FRA (1 << 6)		/* Framed/Unframed Selection */
489
#define PRBS23 (3 << 4)		/* Pattern selection (23 poly) */
490
#define PRM (1 << 2)		/* Non framed mode */
491
#define FRS1_T 0x4D		/* Framer Receive Status Reg 1 */
492
#define LLBDD (1 << 4)
493
#define LLBAD (1 << 3)
494
495
#define MAX_T4_CARDS 64
496
497
static void t4_isr_bh(unsigned long data);
498
499
static struct t4 *cards[MAX_T4_CARDS];
500
501
502
#define MAX_TDM_CHAN 32
503
#define MAX_DTMF_DET 16
504
505
#define HDLC_IMR0_MASK (FRMR_IMR0_RME | FRMR_IMR0_RPF)
506
#if 0
507
#define HDLC_IMR1_MASK (FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR)
508
#else
509
#define HDLC_IMR1_MASK	(FRMR_IMR1_XDU | FRMR_IMR1_XPR)
510
#endif
511
512
static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
513
{
514
	unsigned int res = readl(&wc->membase[addr]);
515
	return res;
516
}
517
518
static inline void __t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
519
{
520
	unsigned int tmp;
521
	writel(value, &wc->membase[addr]);
522
	if (pedanticpci) {
523
		tmp = __t4_pci_in(wc, WC_VERSION);
524
		if ((tmp & 0xffff0000) != 0xc01a0000)
525
			dev_notice(&wc->dev->dev,
526
					"Version Synchronization Error!\n");
527
	}
528
#if 0
529
	tmp = __t4_pci_in(wc, addr);
530
	if ((value != tmp) && (addr != WC_LEDS) && (addr != WC_LDATA) &&
531
		(addr != WC_GPIO) && (addr != WC_INTR))
532
		dev_info(&wc->dev->dev, "Tried to load %08x into %08x, "
533
				"but got %08x instead\n", value, addr, tmp);
534
#endif		
535
}
536
537
static inline void __t4_gpio_set(struct t4 *wc, unsigned bits, unsigned int val)
538
{
539
	unsigned int newgpio;
540
	newgpio = wc->gpio & (~bits);
541
	newgpio |= val;
542
	if (newgpio != wc->gpio) {
543
		wc->gpio = newgpio;
544
		__t4_pci_out(wc, WC_GPIO, wc->gpio);
545
	}	
546
}
547
548
static inline void __t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
549
{
550
	unsigned int newgpioctl;
551
	newgpioctl = wc->gpioctl & (~bits);
552
	newgpioctl |= val;
553
	if (newgpioctl != wc->gpioctl) {
554
		wc->gpioctl = newgpioctl;
555
		__t4_pci_out(wc, WC_GPIOCTL, wc->gpioctl);
556
	}
557
}
558
559
static inline void t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
560
{
561
	unsigned long flags;
562
	spin_lock_irqsave(&wc->reglock, flags);
563
	__t4_gpio_setdir(wc, bits, val);
564
	spin_unlock_irqrestore(&wc->reglock, flags);
565
}
566
567
static inline void t4_gpio_set(struct t4 *wc, unsigned int bits, unsigned int val)
568
{
569
	unsigned long flags;
570
	spin_lock_irqsave(&wc->reglock, flags);
571
	__t4_gpio_set(wc, bits, val);
572
	spin_unlock_irqrestore(&wc->reglock, flags);
573
}
574
575
static inline void t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
576
{
577
	unsigned long flags;
578
	spin_lock_irqsave(&wc->reglock, flags);
579
	__t4_pci_out(wc, addr, value);
580
	spin_unlock_irqrestore(&wc->reglock, flags);
581
}
582
583
static inline void __t4_set_led(struct t4 *wc, int span, int color)
584
{
585
	int oldreg = wc->ledreg;
586
	wc->ledreg &= ~(0x3 << (span << 1));
587
	wc->ledreg |= (color << (span << 1));
588
	if (oldreg != wc->ledreg)
589
		__t4_pci_out(wc, WC_LEDS, wc->ledreg);
590
}
591
592
static inline void t4_activate(struct t4 *wc)
593
{
594
	wc->ledreg |= WC_ACTIVATE;
595
	t4_pci_out(wc, WC_LEDS, wc->ledreg);
596
}
597
598
static inline unsigned int t4_pci_in(struct t4 *wc, const unsigned int addr)
599
{
600
	unsigned int ret;
601
	unsigned long flags;
602
	
603
	spin_lock_irqsave(&wc->reglock, flags);
604
	ret = __t4_pci_in(wc, addr);
605
	spin_unlock_irqrestore(&wc->reglock, flags);
606
	return ret;
607
}
608
609
static inline unsigned int __t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
610
{
611
	unsigned int ret;
612
	unit &= 0x3;
613
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
614
	if (!pedanticpci)
615
		__t4_pci_in(wc, WC_VERSION);
616
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LREAD);
617
	if (!pedanticpci) {
618
		__t4_pci_in(wc, WC_VERSION);
619
	} else {
620
		__t4_pci_out(wc, WC_VERSION, 0);
621
	}
622
	ret = __t4_pci_in(wc, WC_LDATA);
623
 	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
624
625
	if (unlikely(debug & DEBUG_REGS))
626
		dev_info(&wc->dev->dev, "Reading unit %d address %02x is "
627
				"%02x\n", unit, addr, ret & 0xff);
628
629
	if (!pedanticpci)
630
		__t4_pci_in(wc, WC_VERSION);
631
632
	return ret & 0xff;
633
}
634
635
static inline unsigned int t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
636
{
637
	unsigned long flags;
638
	unsigned int ret;
639
	spin_lock_irqsave(&wc->reglock, flags);
640
	ret = __t4_framer_in(wc, unit, addr);
641
	spin_unlock_irqrestore(&wc->reglock, flags);
642
	return ret;
643
644
}
645
646
static inline void __t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
647
{
648
	unit &= 0x3;
649
	if (unlikely(debug & DEBUG_REGS))
650
		dev_info(&wc->dev->dev, "Writing %02x to address %02x of "
651
				"unit %d\n", value, addr, unit);
652
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
653
	__t4_pci_out(wc, WC_LDATA, value);
654
	if (!pedanticpci)
655
		__t4_pci_in(wc, WC_VERSION);
656
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE);
657
	if (!pedanticpci)
658
		__t4_pci_in(wc, WC_VERSION);
659
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));	
660
	if (!pedanticpci)
661
		__t4_pci_in(wc, WC_VERSION);
662
	if (unlikely(debug & DEBUG_REGS))
663
		dev_info(&wc->dev->dev, "Write complete\n");
664
#if 0
665
	if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc))
666
	{ unsigned int tmp;
667
	tmp = __t4_framer_in(wc, unit, addr);
668
	if (tmp != value) {
669
		dev_notice(&wc->dev->dev, "Expected %d from unit %d "
670
				"register %d but got %d instead\n",
671
				value, unit, addr, tmp);
672
	} }
673
#endif	
674
}
675
676
static inline void t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
677
{
678
	unsigned long flags;
679
	spin_lock_irqsave(&wc->reglock, flags);
680
	__t4_framer_out(wc, unit, addr, value);
681
	spin_unlock_irqrestore(&wc->reglock, flags);
682
}
683
684
#ifdef VPM_SUPPORT
685
686
static inline void wait_a_little(void)
687
{
688
	unsigned long newjiffies=jiffies+2;
689
	while(jiffies < newjiffies);
690
}
691
692
static inline unsigned int __t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
693
{
694
	unsigned int ret;
695
	unit &= 0x7;
696
	__t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12));
697
	__t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12) | (1 << 11) | WC_LREAD);
698
	ret = __t4_pci_in(wc, WC_LDATA);
699
	__t4_pci_out(wc, WC_LADDR, 0);
700
	return ret & 0xff;
701
}
702
703
static inline void __t4_raw_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
704
{
705
	int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
706
	if (!octopt) 
707
		__t4_gpio_set(wc, 0xff, (addr >> 8));
708
	__t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
709
	if (!octopt)
710
		__t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
711
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
712
	if (!pedanticpci)
713
		__t4_pci_in(wc, WC_VERSION);
714
	if (!octopt)
715
		__t4_gpio_set(wc, 0xff, (value >> 8));
716
	__t4_pci_out(wc, WC_LDATA, (value & 0xffff));
717
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE | WC_LCS));
718
	if (!pedanticpci)
719
		__t4_pci_in(wc, WC_VERSION);
720
	__t4_pci_out(wc, WC_LADDR, (0));
721
	if (!pedanticpci)
722
		__t4_pci_in(wc, WC_VERSION);
723
}
724
725
static inline unsigned int __t4_raw_oct_in(struct t4 *wc, const unsigned int addr)
726
{
727
	unsigned int ret;
728
	int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
729
	if (!octopt)
730
		__t4_gpio_set(wc, 0xff, (addr >> 8));
731
	__t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
732
	if (!octopt)
733
		__t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
734
	if (!pedanticpci)
735
		__t4_pci_in(wc, WC_VERSION);
736
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
737
	if (!pedanticpci)
738
		__t4_pci_in(wc, WC_VERSION);
739
#ifdef PEDANTIC_OCTASIC_CHECKING 
740
	__t4_pci_out(wc, WC_LADDR, (WC_LALE));
741
	if (!pedanticpci)
742
		__t4_pci_in(wc, WC_VERSION);
743
#endif
744
	if (!octopt) {
745
		__t4_gpio_setdir(wc, 0xff, 0x00);
746
		__t4_gpio_set(wc, 0xff, 0x00);
747
	}
748
	__t4_pci_out(wc, WC_LADDR, (WC_LREAD | WC_LALE | WC_LCS));
749
	if (!pedanticpci)
750
		__t4_pci_in(wc, WC_VERSION);
751
	if (octopt) {
752
		ret = __t4_pci_in(wc, WC_LDATA) & 0xffff;
753
	} else {
754
		ret = __t4_pci_in(wc, WC_LDATA) & 0xff;
755
		ret |= (__t4_pci_in(wc, WC_GPIO) & 0xff) << 8;
756
	}
757
	__t4_pci_out(wc, WC_LADDR, (0));
758
	if (!pedanticpci)
759
		__t4_pci_in(wc, WC_VERSION);
760
	if (!octopt)
761
		__t4_gpio_setdir(wc, 0xff, 0xff);
762
	return ret & 0xffff;
763
}
764
765
static inline unsigned int __t4_oct_in(struct t4 *wc, unsigned int addr)
766
{
767
#ifdef PEDANTIC_OCTASIC_CHECKING
768
	int count = 1000;
769
#endif
770
	__t4_raw_oct_out(wc, 0x0008, (addr >> 20));
771
	__t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
772
	__t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (1));
773
#ifdef PEDANTIC_OCTASIC_CHECKING
774
	while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
775
	if (count != 1000)
776
		dev_notice(&wc->dev->dev, "Yah, read can be slow...\n");
777
	if (!count)
778
		dev_notice(&wc->dev->dev, "Read timed out!\n");
779
#endif
780
	return __t4_raw_oct_in(wc, 0x0004);
781
}
782
783
static inline unsigned int t4_oct_in(struct t4 *wc, const unsigned int addr)
784
{
785
	unsigned long flags;
786
	unsigned int ret;
787
788
	spin_lock_irqsave(&wc->reglock, flags);
789
	ret = __t4_oct_in(wc, addr);
790
	spin_unlock_irqrestore(&wc->reglock, flags);
791
	return ret;
792
}
793
794
static inline unsigned int t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
795
{
796
	unsigned long flags;
797
	unsigned int ret;
798
	spin_lock_irqsave(&wc->reglock, flags);
799
	ret = __t4_vpm_in(wc, unit, addr);
800
	spin_unlock_irqrestore(&wc->reglock, flags);
801
	return ret;
802
}
803
804
static inline void __t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
805
{
806
	unit &= 0x7;
807
	if (debug & DEBUG_REGS)
808
		dev_notice(&wc->dev->dev, "Writing %02x to address %02x of "
809
				"ec unit %d\n", value, addr, unit);
810
	__t4_pci_out(wc, WC_LADDR, (addr & 0xff));
811
	__t4_pci_out(wc, WC_LDATA, value);
812
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
813
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11) | WC_LWRITE);
814
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
815
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff));	
816
	__t4_pci_out(wc, WC_LADDR, 0);
817
	if (debug & DEBUG_REGS)
818
		dev_notice(&wc->dev->dev, "Write complete\n");
819
820
      
821
#if 0
822
	{ unsigned int tmp;
823
	tmp = t4_vpm_in(wc, unit, addr);
824
	if (tmp != value) {
825
		dev_notice(&wc->dev->dev, "Expected %d from unit %d echo "
826
				"register %d but got %d instead\n",
827
				value, unit, addr, tmp);
828
	} }
829
#endif
830
}
831
832
static inline void __t4_oct_out(struct t4 *wc, unsigned int addr, unsigned int value)
833
{
834
#ifdef PEDANTIC_OCTASIC_CHECKING
835
	int count = 1000;
836
#endif
837
	__t4_raw_oct_out(wc, 0x0008, (addr >> 20));
838
	__t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
839
	__t4_raw_oct_out(wc, 0x0004, value);
840
	__t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (3 << 12) | 1);
841
#ifdef PEDANTIC_OCTASIC_CHECKING
842
	while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
843
	if (count != 1000)
844
		dev_notice(&wc->dev->dev, "Yah, write can be slow\n");
845
	if (!count)
846
		dev_notice(&wc->dev->dev, "Write timed out!\n");
847
#endif
848
}
849
850
static inline void t4_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
851
{
852
	unsigned long flags;
853
854
	spin_lock_irqsave(&wc->reglock, flags);
855
	__t4_oct_out(wc, addr, value);
856
	spin_unlock_irqrestore(&wc->reglock, flags);
857
}
858
859
static inline void t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
860
{
861
	unsigned long flags;
862
	spin_lock_irqsave(&wc->reglock, flags);
863
	__t4_vpm_out(wc, unit, addr, value);
864
	spin_unlock_irqrestore(&wc->reglock, flags);
865
}
866
867
static const char vpm_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#'};
868
869
static void t4_check_vpm450(struct t4 *wc)
870
{
871
	int channel, tone, start, span;
872
873
	if (vpm450m_checkirq(wc->vpm450m)) {
874
		while(vpm450m_getdtmf(wc->vpm450m, &channel, &tone, &start)) {
875
			span = channel & 0x3;
876
			channel >>= 2;
877
			if (!wc->t1e1)
878
				channel -= 5;
879
			else
880
				channel -= 1;
881
			if (unlikely(debug))
882
				dev_info(&wc->dev->dev, "Got tone %s of '%c' "
883
					"on channel %d of span %d\n",
884
					(start ? "START" : "STOP"),
885
					tone, channel, span + 1);
886
			if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) {
887
				if (start) {
888
					/* The octasic is supposed to mute us, but...  Yah, you
889
					   guessed it.  */
890
					if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) {
891
						unsigned long flags;
892
						struct dahdi_chan *chan = wc->tspans[span]->span.chans[channel];
893
						int y;
894
						spin_lock_irqsave(&chan->lock, flags);
895
						for (y=0;y<chan->numbufs;y++) {
896
							if ((chan->inreadbuf > -1) && (chan->readidx[y]))
897
								memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
898
						}
899
						spin_unlock_irqrestore(&chan->lock, flags);
900
					}
901
					set_bit(channel, &wc->tspans[span]->dtmfactive);
902
					dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFDOWN | tone));
903
				} else {
904
					clear_bit(channel, &wc->tspans[span]->dtmfactive);
905
					dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFUP | tone));
906
				}
907
			}
908
		}
909
	}
910
}
911
912
static void t4_check_vpm400(struct t4 *wc, unsigned int newio)
913
{
914
	unsigned int digit, regval = 0;
915
	unsigned int regbyte;
916
	int x, i;
917
	short energy=0;
918
	static unsigned int lastio = 0;
919
	struct t4_span *ts;
920
921
	if (debug && (newio != lastio)) 
922
		dev_notice(&wc->dev->dev, "Last was %08x, new is %08x\n",
923
				lastio, newio);
924
925
	lastio = newio;
926
 
927
	for(x = 0; x < 8; x++) {
928
		if (newio & (1 << (7 - x)))
929
			continue;
930
		ts = wc->tspans[x%4];
931
		/* Start of DTMF detection process */	
932
		regbyte = t4_vpm_in(wc, x, 0xb8);
933
		t4_vpm_out(wc, x, 0xb8, regbyte); /* Write 1 to clear */
934
		regval = regbyte << 8;
935
		regbyte = t4_vpm_in(wc, x, 0xb9);
936
		t4_vpm_out(wc, x, 0xb9, regbyte);
937
		regval |= regbyte;
938
939
		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
940
			if(regval & 0x0001) {
941
				int channel = (i << 1) + (x >> 2);
942
				int base = channel - 1;
943
944
				if (!wc->t1e1)
945
					base -= 4;
946
				regbyte = t4_vpm_in(wc, x, 0xa8 + i);
947
				digit = vpm_digits[regbyte];
948
				if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
949
					energy = t4_vpm_in(wc, x, 0x58 + channel);
950
					energy = DAHDI_XLAW(energy, ts->chans[0]);
951
					ts->dtmfenergy[base] = energy;
952
				}
953
				set_bit(base, &ts->dtmfactive);
954
				if (ts->dtmfdigit[base]) {
955
					if (ts->dtmfmask & (1 << base))
956
						dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
957
				}
958
				ts->dtmfdigit[base] = digit;
959
				if (test_bit(base, &ts->dtmfmask))
960
					dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFDOWN | digit));
961
				if (test_bit(base, &ts->dtmfmutemask)) {
962
					/* Mute active receive buffer*/
963
					unsigned long flags;
964
					struct dahdi_chan *chan = ts->span.chans[base];
965
					int y;
966
					spin_lock_irqsave(&chan->lock, flags);
967
					for (y=0;y<chan->numbufs;y++) {
968
						if ((chan->inreadbuf > -1) && (chan->readidx[y]))
969
							memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
970
					}
971
					spin_unlock_irqrestore(&chan->lock, flags);
972
				}
973
				if (debug)
974
					dev_notice(&wc->dev->dev, "Digit "
975
						"Seen: %d, Span: %d, channel:"
976
						" %d, energy: %02x, 'channel "
977
						"%d' chip %d\n", digit, x % 4,
978
						base + 1, energy, channel, x);
979
				
980
			}
981
			regval = regval >> 1;
982
		}
983
		if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN))
984
			continue;
985
986
		/* Start of DTMF off detection process */	
987
		regbyte = t4_vpm_in(wc, x, 0xbc);
988
		t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */
989
		regval = regbyte << 8;
990
		regbyte = t4_vpm_in(wc, x, 0xbd);
991
		t4_vpm_out(wc, x, 0xbd, regbyte);
992
		regval |= regbyte;
993
994
		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
995
			if(regval & 0x0001) {
996
				int channel = (i << 1) + (x >> 2);
997
				int base = channel - 1;
998
999
				if (!wc->t1e1)
1000
					base -= 4;
1001
				clear_bit(base, &ts->dtmfactive);
1002
				if (ts->dtmfdigit[base]) {
1003
					if (test_bit(base, &ts->dtmfmask))
1004
						dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
1005
				}
1006
				digit = ts->dtmfdigit[base];
1007
				ts->dtmfdigit[base] = 0;
1008
				if (debug)
1009
					dev_notice(&wc->dev->dev, "Digit "
1010
						"Gone: %d, Span: %d, channel:"
1011
						" %d, energy: %02x, 'channel "
1012
						"%d' chip %d\n", digit, x % 4,
1013
						base + 1, energy, channel, x);
1014
				
1015
			}
1016
			regval = regval >> 1;
1017
		}
1018
1019
	}
1020
}
1021
#endif
1022
1023
static void hdlc_stop(struct t4 *wc, unsigned int span)
1024
{
1025
	struct t4_span *t = wc->tspans[span];
1026
	unsigned char imr0, imr1, mode;
1027
	int i = 0;
1028
1029
	if (debug & DEBUG_FRAMER)
1030
		dev_notice(&wc->dev->dev, "Stopping HDLC controller on span "
1031
				"%d\n", span+1);
1032
	
1033
	/* Clear receive and transmit timeslots */
1034
	for (i = 0; i < 4; i++) {
1035
		t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00);
1036
		t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00);
1037
	}
1038
1039
	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
1040
	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
1041
1042
	/* Disable HDLC interrupts */
1043
	imr0 |= HDLC_IMR0_MASK;
1044
	t4_framer_out(wc, span, FRMR_IMR0, imr0);
1045
1046
	imr1 |= HDLC_IMR1_MASK;
1047
	t4_framer_out(wc, span, FRMR_IMR1, imr1);
1048
1049
	mode = t4_framer_in(wc, span, FRMR_MODE);
1050
	mode &= ~FRMR_MODE_HRAC;
1051
	t4_framer_out(wc, span, FRMR_MODE, mode);
1052
1053
	t->sigactive = 0;
1054
}
1055
1056
static inline void __t4_framer_cmd(struct t4 *wc, unsigned int span, int cmd)
1057
{
1058
	__t4_framer_out(wc, span, FRMR_CMDR, cmd);
1059
}
1060
1061
static inline void t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd)
1062
{
1063
	int sis;
1064
	int loops = 0;
1065
1066
	/* XXX could be time consuming XXX */
1067
	for (;;) {
1068
		sis = t4_framer_in(wc, span, FRMR_SIS);
1069
		if (!(sis & 0x04))
1070
			break;
1071
		if (!loops++ && (debug & DEBUG_FRAMER)) {
1072
			dev_notice(&wc->dev->dev, "!!!SIS Waiting before cmd "
1073
					"%02x\n", cmd);
1074
		}
1075
	}
1076
	if (loops && (debug & DEBUG_FRAMER))
1077
		dev_notice(&wc->dev->dev, "!!!SIS waited %d loops\n", loops);
1078
1079
	t4_framer_out(wc, span, FRMR_CMDR, cmd);
1080
}
1081
1082
static int hdlc_start(struct t4 *wc, unsigned int span, struct dahdi_chan *chan, unsigned char mode)
1083
{
1084
	struct t4_span *t = wc->tspans[span];
1085
	unsigned char imr0, imr1;
1086
	int offset = chan->chanpos;
1087
	unsigned long flags;
1088
1089
	if (debug & DEBUG_FRAMER)
1090
		dev_info(&wc->dev->dev, "Starting HDLC controller for channel "
1091
				"%d span %d\n", offset, span+1);
1092
1093
	if (mode != FRMR_MODE_NO_ADDR_CMP)
1094
		return -1;
1095
1096
	mode |= FRMR_MODE_HRAC;
1097
1098
	/* Make sure we're in the right mode */
1099
	t4_framer_out(wc, span, FRMR_MODE, mode);
1100
	t4_framer_out(wc, span, FRMR_TSEO, 0x00);
1101
	t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode);
1102
1103
	/* Set the interframe gaps, etc */
1104
	t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
1105
1106
	t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
1107
	
1108
	/* Set up the time slot that we want to tx/rx on */
1109
	t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
1110
	t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
1111
1112
	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
1113
	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
1114
1115
	/* Enable our interrupts again */
1116
	imr0 &= ~HDLC_IMR0_MASK;
1117
	t4_framer_out(wc, span, FRMR_IMR0, imr0);
1118
1119
	imr1 &= ~HDLC_IMR1_MASK;
1120
	t4_framer_out(wc, span, FRMR_IMR1, imr1);
1121
1122
	/* Reset the signaling controller */
1123
	t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
1124
1125
	spin_lock_irqsave(&wc->reglock, flags);
1126
	t->sigchan = chan;
1127
	spin_unlock_irqrestore(&wc->reglock, flags);
1128
1129
	t->sigactive = 0;
1130
1131
	return 0;
1132
}
1133
1134
static void __set_clear(struct t4 *wc, int span)
1135
{
1136
	int i,j;
1137
	int oldnotclear;
1138
	unsigned short val=0;
1139
	struct t4_span *ts = wc->tspans[span];
1140
1141
	oldnotclear = ts->notclear;
1142
	if ((ts->spantype == TYPE_T1) || (ts->spantype == TYPE_J1)) {
1143
		for (i=0;i<24;i++) {
1144
			j = (i/8);
1145
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
1146
				val |= 1 << (7 - (i % 8));
1147
				ts->notclear &= ~(1 << i);
1148
			} else
1149
				ts->notclear |= (1 << i);
1150
			if ((i % 8)==7) {
1151
				if (debug)
1152
					dev_notice(&wc->dev->dev, "Putting %d "
1153
						"in register %02x on span %d"
1154
						"\n", val, 0x2f + j, span + 1);
1155
				__t4_framer_out(wc, span, 0x2f + j, val);
1156
				val = 0;
1157
			}
1158
		}
1159
	} else {
1160
		for (i=0;i<31;i++) {
1161
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
1162
				ts->notclear &= ~(1 << i);
1163
			else 
1164
				ts->notclear |= (1 << i);
1165
		}
1166
	}
1167
	if (ts->notclear != oldnotclear) {
1168
		unsigned char reg;
1169
		reg = __t4_framer_in(wc, span, FRMR_IMR0);
1170
		if (ts->notclear)
1171
			reg &= ~0x08;
1172
		else
1173
			reg |= 0x08;
1174
		__t4_framer_out(wc, span, FRMR_IMR0, reg);
1175
	}
1176
}
1177
1178
#if 0
1179
static void set_clear(struct t4 *wc, int span)
1180
{
1181
	unsigned long flags;
1182
	spin_lock_irqsave(&wc->reglock, flags);
1183
	__set_clear(wc, span);
1184
	spin_unlock_irqrestore(&wc->reglock, flags);
1185
}
1186
#endif
1187
1188
static int t4_dacs(struct dahdi_chan *dst, struct dahdi_chan *src)
1189
{
1190
	struct t4 *wc;
1191
	struct t4_span *ts;
1192
	wc = dst->pvt;
1193
	ts = wc->tspans[dst->span->offset];
1194
	if (src && (src->pvt != dst->pvt)) {
1195
		if (ts->spanflags & FLAG_2NDGEN)
1196
			t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
1197
		wc = src->pvt;
1198
		if (ts->spanflags & FLAG_2NDGEN)
1199
			t4_tsi_unassign(wc, src->span->offset, src->chanpos);
1200
		if (debug)
1201
			dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
1202
				"default and...\n", src->span->offset,
1203
				src->chanpos);
1204
		if (debug)
1205
			dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
1206
				"default\n", dst->span->offset, dst->chanpos);
1207
		return -1;
1208
	}
1209
	if (src) {
1210
		t4_tsi_assign(wc, src->span->offset, src->chanpos, dst->span->offset, dst->chanpos);
1211
		if (debug)
1212
			dev_notice(&wc->dev->dev, "Assigning channel %d/%d -> "
1213
				"%d/%d!\n", src->span->offset, src->chanpos,
1214
				dst->span->offset, dst->chanpos);
1215
	} else {
1216
		t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
1217
		if (debug)
1218
			dev_notice(&wc->dev->dev, "Unassigning channel %d/%d!"
1219
				"\n", dst->span->offset, dst->chanpos);
1220
	}
1221
	return 0;
1222
}
1223
1224
#ifdef VPM_SUPPORT
1225
1226
void oct_set_reg(void *data, unsigned int reg, unsigned int val)
1227
{
1228
	struct t4 *wc = data;
1229
	t4_oct_out(wc, reg, val);
1230
}
1231
1232
unsigned int oct_get_reg(void *data, unsigned int reg)
1233
{
1234
	struct t4 *wc = data;
1235
	unsigned int ret;
1236
	ret = t4_oct_in(wc, reg);
1237
	return ret;
1238
}
1239
1240
static int t4_vpm_unit(int span, int channel)
1241
{
1242
	int unit = 0;
1243
	switch(vpmspans) {
1244
	case 4:
1245
		unit = span;
1246
		unit += (channel & 1) << 2;
1247
		break;
1248
	case 2:
1249
		unit = span;
1250
		unit += (channel & 0x3) << 1;
1251
		break;
1252
	case 1:
1253
		unit = span;
1254
		unit += (channel & 0x7);
1255
	}
1256
	return unit;
1257
}
1258
1259
static inline struct t4_span *t4_from_span(struct dahdi_span *span)
1260
{
1261
	return container_of(span, struct t4_span, span);
1262
}
1263
1264
static int t4_echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
1265
			  struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
1266
{
1267
	struct t4 *wc = chan->pvt;
1268
	struct t4_span *tspan = container_of(chan->span, struct t4_span, span);
1269
	int channel;
1270
	const struct dahdi_echocan_ops *ops;
1271
	const struct dahdi_echocan_features *features;
1272
1273
	if (!vpmsupport || !wc->vpm)
1274
		return -ENODEV;
1275
1276
	if (chan->span->offset >= vpmspans)
1277
		return -ENODEV;
1278
1279
	if (wc->vpm450m) {
1280
		ops = &vpm450m_ec_ops;
1281
		features = &vpm450m_ec_features;
1282
	} else {
1283
		ops = &vpm400m_ec_ops;
1284
		features = &vpm400m_ec_features;
1285
	}
1286
1287
	if (ecp->param_count > 0) {
1288
		dev_warn(&wc->dev->dev, "echo canceller does not support "
1289
				"parameters; failing request\n");
1290
		return -EINVAL;
1291
	}
1292
1293
	*ec = tspan->ec[chan->chanpos - 1];
1294
	(*ec)->ops = ops;
1295
	(*ec)->features = *features;
1296
1297
	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
1298
1299
	if (wc->vpm450m) {
1300
		channel = channel << 2;
1301
		channel |= chan->span->offset;
1302
		if (debug & DEBUG_ECHOCAN)
1303
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1304
				"Channel is %d, Span is %d, offset is %d "
1305
				"length %d\n", wc->num, chan->chanpos,
1306
				chan->span->offset, channel, ecp->tap_length);
1307
		vpm450m_setec(wc->vpm450m, channel, ecp->tap_length);
1308
	} else {
1309
		int unit = t4_vpm_unit(chan->span->offset, channel);
1310
1311
		if (debug & DEBUG_ECHOCAN)
1312
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1313
				"Channel is %d, Span is %d, unit is %d, "
1314
				"unit offset is %d length %d\n", wc->num,
1315
				chan->chanpos, chan->span->offset, unit,
1316
				channel, ecp->tap_length);
1317
		t4_vpm_out(wc, unit, channel, 0x3e);
1318
	}
1319
1320
	return 0;
1321
}
1322
1323
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
1324
{
1325
	struct t4 *wc = chan->pvt;
1326
	int channel;
1327
1328
	memset(ec, 0, sizeof(*ec));
1329
1330
	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
1331
1332
	if (wc->vpm450m) {
1333
		channel = channel << 2;
1334
		channel |= chan->span->offset;
1335
		if (debug & DEBUG_ECHOCAN)
1336
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1337
				"Channel is %d, Span is %d, offset is %d "
1338
				"length 0\n", wc->num, chan->chanpos,
1339
				chan->span->offset, channel);
1340
		vpm450m_setec(wc->vpm450m, channel, 0);
1341
	} else {
1342
		int unit = t4_vpm_unit(chan->span->offset, channel);
1343
1344
		if (debug & DEBUG_ECHOCAN)
1345
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1346
				"Channel is %d, Span is %d, unit is %d, "
1347
				"unit offset is %d length 0\n", wc->num,
1348
				chan->chanpos, chan->span->offset, unit,
1349
				channel);
1350
		t4_vpm_out(wc, unit, channel, 0x01);
1351
	}
1352
}
1353
#endif
1354
1355
static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
1356
{
1357
	struct t4_regs regs;
1358
	int x;
1359
	struct t4 *wc = chan->pvt;
1360
#ifdef VPM_SUPPORT
1361
	int j;
1362
	int channel;
1363
	struct t4_span *ts = wc->tspans[chan->span->offset];
1364
#endif
1365
1366
#ifdef VPM_SUPPORT
1367
	if (dtmfthreshold == 0)
1368
		dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
1369
	if (lastdtmfthreshold != dtmfthreshold) {
1370
		lastdtmfthreshold = dtmfthreshold;
1371
		t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
1372
	}
1373
#endif
1374
1375
	switch(cmd) {
1376
	case WCT4_GET_REGS:
1377
		for (x=0;x<NUM_PCI;x++)
1378
			regs.pci[x] = t4_pci_in(wc, x);
1379
		for (x=0;x<NUM_REGS;x++)
1380
			regs.regs[x] = t4_framer_in(wc, chan->span->offset, x);
1381
		if (copy_to_user((__user void *) data, &regs, sizeof(regs)))
1382
			return -EFAULT;
1383
		break;
1384
#ifdef VPM_SUPPORT
1385
	case DAHDI_TONEDETECT:
1386
		if (get_user(j, (__user int *) data))
1387
			return -EFAULT;
1388
		if (!wc->vpm)
1389
			return -ENOSYS;
1390
		if (j && (vpmdtmfsupport == 0))
1391
			return -ENOSYS;
1392
		if (j & DAHDI_TONEDETECT_ON)
1393
			set_bit(chan->chanpos - 1, &ts->dtmfmask);
1394
		else
1395
			clear_bit(chan->chanpos - 1, &ts->dtmfmask);
1396
		if (j & DAHDI_TONEDETECT_MUTE)
1397
			set_bit(chan->chanpos - 1, &ts->dtmfmutemask);
1398
		else
1399
			clear_bit(chan->chanpos - 1, &ts->dtmfmutemask);
1400
		if (wc->vpm450m) {
1401
			channel = (chan->chanpos) << 2;
1402
			if (!wc->t1e1)
1403
				channel += (4 << 2);
1404
			channel |= chan->span->offset;
1405
			vpm450m_setdtmf(wc->vpm450m, channel, j & DAHDI_TONEDETECT_ON, j & DAHDI_TONEDETECT_MUTE);
1406
		}
1407
		return 0;
1408
#endif
1409
	default:
1410
		return -ENOTTY;
1411
	}
1412
	return 0;
1413
}
1414
1415
static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts)
1416
{
1417
	int res, i;
1418
	unsigned int size = 32;
1419
	unsigned char buf[32];
1420
1421
	res = dahdi_hdlc_getbuf(ts->sigchan, buf, &size);
1422
	if (debug & DEBUG_FRAMER)
1423
		dev_notice(&wc->dev->dev, "Got buffer sized %d and res %d "
1424
				"for %d\n", size, res, span);
1425
	if (size > 0) {
1426
		ts->sigactive = 1;
1427
1428
		if (debug & DEBUG_FRAMER) {
1429
			dev_notice(&wc->dev->dev, "TX(");
1430
			for (i = 0; i < size; i++)
1431
				dev_notice(&wc->dev->dev, "%s%02x",
1432
						(i ? " " : ""), buf[i]);
1433
			dev_notice(&wc->dev->dev, ")\n");
1434
		}
1435
1436
		for (i = 0; i < size; i++)
1437
			t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]);
1438
1439
		if (res) /* End of message */ {
1440
			if (debug & DEBUG_FRAMER)
1441
				dev_notice(&wc->dev->dev,
1442
					"transmiting XHF|XME\n");
1443
			t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME);
1444
#if 0
1445
			ts->sigactive = (__t4_framer_in(wc, span, FRMR_SIS) & FRMR_SIS_XFW) ? 0 : 1;
1446
#endif
1447
			++ts->frames_out;
1448
			if ((debug & DEBUG_FRAMER) && !(ts->frames_out & 0x0f))
1449
				dev_notice(&wc->dev->dev, "Transmitted %d "
1450
					"frames on span %d\n", ts->frames_out,
1451
					span);
1452
		} else { /* Still more to transmit */
1453
			if (debug & DEBUG_FRAMER)
1454
				dev_notice(&wc->dev->dev, "transmiting XHF\n");
1455
			t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF);
1456
		}
1457
	}
1458
	else if (res < 0)
1459
		ts->sigactive = 0;
1460
}
1461
1462
static void t4_hdlc_hard_xmit(struct dahdi_chan *chan)
1463
{
1464
	struct t4 *wc = chan->pvt;
1465
	int span = chan->span->offset;
1466
	struct t4_span *ts = wc->tspans[span];
1467
	unsigned long flags; 
1468
1469
	spin_lock_irqsave(&wc->reglock, flags);
1470
	if (!ts->sigchan) {
1471
		dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit: Invalid (NULL) "
1472
				"signalling channel\n");
1473
		spin_unlock_irqrestore(&wc->reglock, flags);
1474
		return;
1475
	}
1476
	spin_unlock_irqrestore(&wc->reglock, flags);
1477
1478
	if (debug & DEBUG_FRAMER)
1479
		dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit on channel %s "
1480
				"(sigchan %s), sigactive=%d\n", chan->name,
1481
				ts->sigchan->name, ts->sigactive);
1482
1483
	if ((ts->sigchan == chan) && !ts->sigactive)
1484
		t4_hdlc_xmit_fifo(wc, span, ts);
1485
}
1486
1487
static int t4_maint(struct dahdi_span *span, int cmd)
1488
{
1489
	struct t4_span *ts = t4_from_span(span);
1490
	struct t4 *wc = ts->owner;
1491
	unsigned int reg;
1492
#ifdef DAHDI_SPAN_OPS
1493
	unsigned long flags;
1494
#endif
1495
1496
	if (ts->spantype == TYPE_E1) {
1497
		switch(cmd) {
1498
		case DAHDI_MAINT_NONE:
1499
			dev_info(&wc->dev->dev, "Clearing all maint modes\n");
1500
			t4_clear_maint(span);
1501
			break;
1502
		case DAHDI_MAINT_LOCALLOOP:
1503
			dev_info(&wc->dev->dev,
1504
				 "Turning on local loopback\n");
1505
			t4_clear_maint(span);
1506
			reg = t4_framer_in(wc, span->offset, LIM0_T);
1507
			t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
1508
			break;
1509
#ifdef DAHDI_SPAN_OPS
1510
		case DAHDI_MAINT_NETWORKLINELOOP:
1511
			dev_info(&wc->dev->dev,
1512
				 "Turning on network line loopback\n");
1513
			t4_clear_maint(span);
1514
			reg = t4_framer_in(wc, span->offset, LIM1_T);
1515
			t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
1516
			break;
1517
		case DAHDI_MAINT_NETWORKPAYLOADLOOP:
1518
			dev_info(&wc->dev->dev,
1519
				 "Turning on network payload loopback\n");
1520
			t4_clear_maint(span);
1521
			reg = t4_framer_in(wc, span->offset, FMR2_T);
1522
			t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
1523
			break;
1524
#endif
1525
		case DAHDI_MAINT_LOOPUP:
1526
		case DAHDI_MAINT_LOOPDOWN:
1527
			dev_info(&wc->dev->dev,
1528
				"Loopup & loopdown supported in E1 mode\n");
1529
			return -ENOSYS;
1530
#ifdef DAHDI_SPAN_OPS
1531
		case DAHDI_MAINT_FAS_DEFECT:
1532
			t4_framer_out(wc, span->offset, IERR_T, IFASE);
1533
			break;
1534
		case DAHDI_MAINT_MULTI_DEFECT:
1535
			t4_framer_out(wc, span->offset, IERR_T, IMFE);
1536
			break;
1537
		case DAHDI_MAINT_CRC_DEFECT:
1538
			t4_framer_out(wc, span->offset, IERR_T, ICRCE);
1539
			break;
1540
		case DAHDI_MAINT_CAS_DEFECT:
1541
			t4_framer_out(wc, span->offset, IERR_T, ICASE);
1542
			break;
1543
		case DAHDI_MAINT_PRBS_DEFECT:
1544
			t4_framer_out(wc, span->offset, IERR_T, IPE);
1545
			break;
1546
		case DAHDI_MAINT_BIPOLAR_DEFECT:
1547
			t4_framer_out(wc, span->offset, IERR_T, IBV);
1548
			break;
1549
		case DAHDI_RESET_COUNTERS:
1550
			t4_reset_counters(span);
1551
			break;
1552
		case DAHDI_MAINT_ALARM_SIM:
1553
			dev_info(&wc->dev->dev, "Invoking alarm state");
1554
			reg = t4_framer_in(wc, span->offset, FMR0);
1555
			t4_framer_out(wc, span->offset, FMR0, (reg|FMR0_SIM));
1556
			break;
1557
#endif
1558
		default:
1559
			dev_info(&wc->dev->dev,
1560
					"Unknown E1 maint command: %d\n", cmd);
1561
			return -ENOSYS;
1562
		}
1563
	} else {
1564
		switch(cmd) {
1565
		case DAHDI_MAINT_NONE:
1566
			dev_info(&wc->dev->dev, "Clearing all maint modes\n");
1567
			t4_clear_maint(span);
1568
			break;
1569
		case DAHDI_MAINT_LOCALLOOP:
1570
			dev_info(&wc->dev->dev,
1571
				 "Turning on local loopback\n");
1572
			t4_clear_maint(span);
1573
			reg = t4_framer_in(wc, span->offset, LIM0_T);
1574
			t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
1575
			break;
1576
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1577
		case DAHDI_MAINT_NETWORKLINELOOP:
1578
			dev_info(&wc->dev->dev,
1579
				 "Turning on network line loopback\n");
1580
			t4_clear_maint(span);
1581
			reg = t4_framer_in(wc, span->offset, LIM1_T);
1582
			t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
1583
			break;
1584
		case DAHDI_MAINT_NETWORKPAYLOADLOOP:
1585
			dev_info(&wc->dev->dev,
1586
				 "Turning on network payload loopback\n");
1587
			t4_clear_maint(span);
1588
			reg = t4_framer_in(wc, span->offset, FMR2_T);
1589
			t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
1590
			break;
1591
#endif
1592
		case DAHDI_MAINT_LOOPUP:
1593
			dev_info(&wc->dev->dev, "Transmitting loopup code\n");
1594
			t4_clear_maint(span);
1595
			t4_framer_out(wc, span->offset, 0x21, 0x50);
1596
			break;
1597
		case DAHDI_MAINT_LOOPDOWN:
1598
			dev_info(&wc->dev->dev, "Transmitting loopdown code\n");
1599
			t4_clear_maint(span);
1600
			t4_framer_out(wc, span->offset, 0x21, 0x60);
1601
			break;
1602
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1603
		case DAHDI_MAINT_FAS_DEFECT:
1604
			t4_framer_out(wc, span->offset, IERR_T, IFASE);
1605
			break;
1606
		case DAHDI_MAINT_MULTI_DEFECT:
1607
			t4_framer_out(wc, span->offset, IERR_T, IMFE);
1608
			break;
1609
		case DAHDI_MAINT_CRC_DEFECT:
1610
			t4_framer_out(wc, span->offset, IERR_T, ICRCE);
1611
			break;
1612
		case DAHDI_MAINT_CAS_DEFECT:
1613
			t4_framer_out(wc, span->offset, IERR_T, ICASE);
1614
			break;
1615
		case DAHDI_MAINT_PRBS_DEFECT:
1616
			t4_framer_out(wc, span->offset, IERR_T, IPE);
1617
			break;
1618
		case DAHDI_MAINT_BIPOLAR_DEFECT:
1619
			t4_framer_out(wc, span->offset, IERR_T, IBV);
1620
			break;
1621
		case DAHDI_MAINT_PRBS:
1622
			dev_info(&wc->dev->dev, "PRBS not supported\n");
1623
#if 0
1624
			dev_notice(&wc->dev->dev, "Enabling PRBS!\n");
1625
			span->mainttimer = 1;
1626
			/* Enable PRBS monitor */
1627
			reg = t4_framer_in(wc, span->offset, LCR1_T);
1628
			reg |= EPRM;
1629
1630
			/* Setup PRBS xmit */
1631
			t4_framer_out(wc, span->offset, TPC0_T, 0);
1632
1633
			/* Enable PRBS transmit */
1634
			reg |= XPRBS;
1635
			reg &= ~LLBP;
1636
			reg &= ~FLLB;
1637
			t4_framer_out(wc, span->offset, LCR1_T, reg);
1638
#endif
1639
			return -ENOSYS;
1640
		case DAHDI_RESET_COUNTERS:
1641
			t4_reset_counters(span);
1642
			break;
1643
#endif
1644
#ifdef DAHDI_SPAN_OPS
1645
		case DAHDI_MAINT_ALARM_SIM:
1646
			reg = t4_framer_in(wc, span->offset, FMR0);
1647
1648
			/*
1649
			 * The alarm simulation state machine requires us to
1650
			 * bring this bit up and down for at least 1 clock cycle
1651
			 */
1652
			spin_lock_irqsave(&wc->reglock, flags);
1653
			__t4_framer_out(wc, span->offset,
1654
					FMR0, (reg | FMR0_SIM));
1655
			udelay(1);
1656
			__t4_framer_out(wc, span->offset,
1657
					FMR0, (reg & ~FMR0_SIM));
1658
			udelay(1);
1659
			spin_unlock_irqrestore(&wc->reglock, flags);
1660
1661
			reg = t4_framer_in(wc, span->offset, 0x4e);
1662
			if (debug & DEBUG_MAIN) {
1663
				dev_info(&wc->dev->dev,
1664
					"FRS2(alarm state): %d\n",
1665
					((reg & 0xe0) >> 5));
1666
			}
1667
			break;
1668
#endif
1669
		default:
1670
			dev_info(&wc->dev->dev, "Unknown T1 maint command:%d\n",
1671
									cmd);
1672
			break;
1673
	   }
1674
    }
1675
	return 0;
1676
}
1677
1678
static int t4_clear_maint(struct dahdi_span *span)
1679
{
1680
	struct t4_span *ts = t4_from_span(span);
1681
	struct t4 *wc = ts->owner;
1682
	unsigned int reg;
1683
1684
	/* Clear local loop */
1685
	reg = t4_framer_in(wc, span->offset, LIM0_T);
1686
	t4_framer_out(wc, span->offset, LIM0_T, (reg & ~LIM0_LL));
1687
1688
	/* Clear Remote Loop */
1689
	reg = t4_framer_in(wc, span->offset, LIM1_T);
1690
	t4_framer_out(wc, span->offset, LIM1_T, (reg & ~LIM1_RL));
1691
1692
	/* Clear Remote Payload Loop */
1693
	reg = t4_framer_in(wc, span->offset, FMR2_T);
1694
	t4_framer_out(wc, span->offset, FMR2_T, (reg & ~FMR2_PLB));
1695
1696
	/* Clear PRBS */
1697
	reg = t4_framer_in(wc, span->offset, LCR1_T);
1698
	t4_framer_out(wc, span->offset, LCR1_T, (reg & ~(XPRBS | EPRM)));
1699
1700
	span->mainttimer = 0;
1701
1702
	return 0;
1703
}
1704
1705
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1706
static int t4_reset_counters(struct dahdi_span *span)
1707
{
1708
	struct t4_span *ts = t4_from_span(span);
1709
	memset(&ts->span.count, 0, sizeof(ts->span.count));
1710
	return 0;
1711
}
1712
#endif
1713
1714
static int t4_rbsbits(struct dahdi_chan *chan, int bits)
1715
{
1716
	u_char m,c;
1717
	int k,n,b;
1718
	struct t4 *wc = chan->pvt;
1719
	struct t4_span *ts = wc->tspans[chan->span->offset];
1720
	unsigned long flags;
1721
	
1722
	if (debug & DEBUG_RBS)
1723
		dev_notice(&wc->dev->dev, "Setting bits to %d on channel %s\n",
1724
				bits, chan->name);
1725
	spin_lock_irqsave(&wc->reglock, flags);	
1726
	k = chan->span->offset;
1727
	if (ts->spantype == TYPE_E1) { /* do it E1 way */
1728
		if (chan->chanpos == 16) {
1729
			spin_unlock_irqrestore(&wc->reglock, flags);
1730
			return 0;
1731
		}
1732
		n = chan->chanpos - 1;
1733
		if (chan->chanpos > 15) n--;
1734
		b = (n % 15);
1735
		c = ts->txsigs[b];
1736
		m = (n / 15) << 2; /* nibble selector */
1737
		c &= (0xf << m); /* keep the other nibble */
1738
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
1739
		ts->txsigs[b] = c;
1740
		  /* output them to the chip */
1741
		__t4_framer_out(wc,k,0x71 + b,c); 
1742
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
1743
		n = chan->chanpos - 1;
1744
		b = (n/4);
1745
		c = ts->txsigs[b];
1746
		m = ((3 - (n % 4)) << 1); /* nibble selector */
1747
		c &= ~(0x3 << m); /* keep the other nibble */
1748
		c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
1749
		ts->txsigs[b] = c;
1750
		  /* output them to the chip */
1751
		__t4_framer_out(wc,k,0x70 + b,c); 
1752
		__t4_framer_out(wc,k,0x70 + b + 6,c); 
1753
	} else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
1754
		n = chan->chanpos - 1;
1755
		b = (n/2);
1756
		c = ts->txsigs[b];
1757
		m = ((n % 2) << 2); /* nibble selector */
1758
		c &= (0xf << m); /* keep the other nibble */
1759
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
1760
		ts->txsigs[b] = c;
1761
		  /* output them to the chip */
1762
		__t4_framer_out(wc,k,0x70 + b,c); 
1763
	} 
1764
	spin_unlock_irqrestore(&wc->reglock, flags);
1765
	if (debug & DEBUG_RBS)
1766
		dev_notice(&wc->dev->dev, "Finished setting RBS bits\n");
1767
	return 0;
1768
}
1769
1770
static int t4_shutdown(struct dahdi_span *span)
1771
{
1772
	int tspan;
1773
	int wasrunning;
1774
	unsigned long flags;
1775
	struct t4_span *ts = t4_from_span(span);
1776
	struct t4 *wc = ts->owner;
1777
1778
	tspan = span->offset + 1;
1779
	if (tspan < 0) {
1780
		dev_notice(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
1781
				span->spanno);
1782
		return -1;
1783
	}
1784
1785
	if (debug & DEBUG_MAIN)
1786
		dev_notice(&wc->dev->dev, "Shutting down span %d (%s)\n",
1787
				span->spanno, span->name);
1788
1789
	/* Stop HDLC controller if runned */
1790
	if (ts->sigchan)
1791
		hdlc_stop(wc, span->offset);
1792
	
1793
	spin_lock_irqsave(&wc->reglock, flags);
1794
	wasrunning = span->flags & DAHDI_FLAG_RUNNING;
1795
1796
	span->flags &= ~DAHDI_FLAG_RUNNING;
1797
	__t4_set_led(wc, span->offset, WC_OFF);
1798
	if ((wc->numspans == 1) && 
1799
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING))) {
1800
		/* No longer in use, disable interrupts */
1801
		dev_info(&wc->dev->dev, "opvxd115: Disabling interrupts since "
1802
				"there are no active spans\n");
1803
		set_bit(T4_STOP_DMA, &wc->checkflag);
1804
	} else
1805
		set_bit(T4_CHECK_TIMING, &wc->checkflag);
1806
1807
	spin_unlock_irqrestore(&wc->reglock, flags);
1808
1809
	/* Wait for interrupt routine to shut itself down */
1810
	msleep(10);
1811
	if (wasrunning)
1812
		wc->spansstarted--;
1813
1814
	if (debug & DEBUG_MAIN)
1815
		dev_notice(&wc->dev->dev, "Span %d (%s) shutdown\n",
1816
				span->spanno, span->name);
1817
	return 0;
1818
}
1819
1820
static void t4_chan_set_sigcap(struct dahdi_span *span, int x)
1821
{
1822
	struct t4_span *wc = container_of(span, struct t4_span, span);
1823
	struct dahdi_chan *chan = wc->chans[x];
1824
	chan->sigcap = DAHDI_SIG_CLEAR;
1825
	/* E&M variant supported depends on span type */
1826
	if (wc->spantype == TYPE_E1) {
1827
		/* E1 sigcap setup */
1828
		if (span->lineconfig & DAHDI_CONFIG_CCS) {
1829
			/* CCS setup */
1830
			chan->sigcap |= DAHDI_SIG_MTP2 | DAHDI_SIG_SF |
1831
				DAHDI_SIG_HARDHDLC;
1832
			return;
1833
		}
1834
		/* clear out sig and sigcap for channel 16 on E1 CAS
1835
		 * lines, otherwise, set it correctly */
1836
		if (x == 15) {
1837
			/* CAS signaling channel setup */
1838
			wc->chans[15]->sigcap = 0;
1839
			wc->chans[15]->sig = 0;
1840
			return;
1841
		}
1842
		/* normal CAS setup */
1843
		chan->sigcap |= DAHDI_SIG_EM_E1 | DAHDI_SIG_FXSLS |
1844
			DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_SF |
1845
			DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS |
1846
			DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS;
1847
	} else {
1848
		/* T1 sigcap setup */
1849
		chan->sigcap |= DAHDI_SIG_EM | DAHDI_SIG_FXSLS |
1850
			DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_MTP2 |
1851
			DAHDI_SIG_SF | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS |
1852
			DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS |
1853
			DAHDI_SIG_HARDHDLC;
1854
	}
1855
}
1856
1857
static int t4_spanconfig(struct file *file, struct dahdi_span *span,
1858
		struct dahdi_lineconfig *lc)
1859
{
1860
	int i;
1861
	struct t4_span *ts = t4_from_span(span);
1862
	struct t4 *wc = ts->owner;
1863
1864
	if (debug)
1865
		dev_info(&wc->dev->dev, "About to enter spanconfig!\n");
1866
	if (debug & DEBUG_MAIN)
1867
		dev_notice(&wc->dev->dev, "opvxd115: Configuring span %d\n",
1868
				span->spanno);
1869
1870
	if (lc->sync < 0)
1871
		lc->sync = 0;
1872
	if (lc->sync > wc->numspans)
1873
		lc->sync = 0;
1874
	
1875
	/* remove this span number from the current sync sources, if there */
1876
	for(i = 0; i < wc->numspans; i++) {
1877
		if (wc->tspans[i]->sync == span->spanno) {
1878
			wc->tspans[i]->sync = 0;
1879
			wc->tspans[i]->psync = 0;
1880
		}
1881
	}
1882
	wc->tspans[span->offset]->syncpos = lc->sync;
1883
	/* if a sync src, put it in proper place */
1884
	if (lc->sync) {
1885
		wc->tspans[lc->sync - 1]->sync = span->spanno;
1886
		wc->tspans[lc->sync - 1]->psync = span->offset + 1;
1887
	}
1888
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
1889
1890
	/* Make sure this is clear in case of multiple startup and shutdown
1891
	 * iterations */
1892
	clear_bit(T4_STOP_DMA, &wc->checkflag);
1893
	
1894
	/* make sure that sigcaps gets updated if necessary */
1895
	for (i = 0; i < span->channels; i++)
1896
		t4_chan_set_sigcap(span, i);
1897
1898
	/* If we're already running, then go ahead and apply the changes */
1899
	if (span->flags & DAHDI_FLAG_RUNNING)
1900
		return t4_startup(file, span);
1901
1902
	if (debug)
1903
		dev_info(&wc->dev->dev, "Done with spanconfig!\n");
1904
	return 0;
1905
}
1906
1907
static int t4_chanconfig(struct file *file, struct dahdi_chan *chan,
1908
		int sigtype)
1909
{
1910
	int alreadyrunning;
1911
	unsigned long flags;
1912
	struct t4 *wc = chan->pvt;
1913
	struct t4_span *ts = wc->tspans[chan->span->offset];
1914
1915
	alreadyrunning = ts->span.flags & DAHDI_FLAG_RUNNING;
1916
	if (debug & DEBUG_MAIN) {
1917
		if (alreadyrunning)
1918
			dev_notice(&wc->dev->dev, "opvxd115: Reconfigured "
1919
				"channel %d (%s) sigtype %d\n",
1920
				chan->channo, chan->name, sigtype);
1921
		else
1922
			dev_notice(&wc->dev->dev, "opvxd115: Configured channel"
1923
				" %d (%s) sigtype %d\n",
1924
				chan->channo, chan->name, sigtype);
1925
	}
1926
1927
	spin_lock_irqsave(&wc->reglock, flags);	
1928
1929
	if (alreadyrunning)
1930
		__set_clear(wc, chan->span->offset);
1931
1932
	spin_unlock_irqrestore(&wc->reglock, flags);	
1933
1934
	/* (re)configure signalling channel */
1935
	if ((sigtype == DAHDI_SIG_HARDHDLC) || (ts->sigchan == chan)) {
1936
		if (debug & DEBUG_FRAMER)
1937
			dev_notice(&wc->dev->dev, "%sonfiguring hardware HDLC "
1938
				"on %s\n",
1939
				((sigtype == DAHDI_SIG_HARDHDLC) ? "C" : "Unc"),
1940
				chan->name);
1941
		if (alreadyrunning) {
1942
			if (ts->sigchan)
1943
				hdlc_stop(wc, ts->sigchan->span->offset);
1944
			if (sigtype == DAHDI_SIG_HARDHDLC) {
1945
				if (hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
1946
					dev_notice(&wc->dev->dev, "Error "
1947
						"initializing signalling "
1948
						"controller\n");
1949
					return -1;
1950
				}
1951
			} else {
1952
				spin_lock_irqsave(&wc->reglock, flags);
1953
				ts->sigchan = NULL;
1954
				spin_unlock_irqrestore(&wc->reglock, flags);
1955
			}
1956
		
1957
		}
1958
		else {
1959
			spin_lock_irqsave(&wc->reglock, flags);
1960
			ts->sigchan = (sigtype == DAHDI_SIG_HARDHDLC) ? chan : NULL;
1961
			spin_unlock_irqrestore(&wc->reglock, flags);
1962
			ts->sigactive = 0;
1963
		}
1964
	}
1965
	return 0;
1966
}
1967
1968
static int t4_open(struct dahdi_chan *chan)
1969
{
1970
	return 0;
1971
}
1972
1973
static int t4_close(struct dahdi_chan *chan)
1974
{
1975
	return 0;
1976
}
1977
1978
static void set_span_devicetype(struct t4 *wc)
1979
{
1980
	struct dahdi_device *ddev = wc->ddev;
1981
	const char *devicetype_old = ddev->devicetype;
1982
	char *extra_str = "";
1983
1984
	if (wc->vpm == T4_VPM_PRESENT)
1985
		extra_str = (!wc->vpm450m) ? " (VPM400M)" : " (VPMOCT032)",
1986
	wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s%s",
1987
			wc->variety, extra_str);
1988
1989
	/* On the off chance that we were able to allocate it previously. */
1990
	if (!wc->ddev->devicetype)
1991
		wc->ddev->devicetype = devicetype_old;
1992
	else
1993
		kfree(devicetype_old);
1994
}
1995
1996
/* The number of cards we have seen with each
1997
   possible 'order' switch setting.
1998
*/
1999
static unsigned int order_index[16];
2000
2001
static void setup_chunks(struct t4 *wc, int which)
2002
{
2003
	struct t4_span *ts;
2004
	int offset = 1;
2005
	int x, y;
2006
	int gen2;
2007
2008
	if (!wc->t1e1)
2009
		offset += 4;
2010
2011
	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
2012
2013
	for (x = 0; x < wc->numspans; x++) {
2014
		ts = wc->tspans[x];
2015
		ts->writechunk = (void *)(wc->writechunk + (x * 32 * 2) + (which * (1024 >> 2)));
2016
		ts->readchunk = (void *)(wc->readchunk + (x * 32 * 2) + (which * (1024 >> 2)));
2017
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
2018
			struct dahdi_chan *mychans = ts->chans[y];
2019
			if (gen2) {
2020
				mychans->writechunk = (void *)(wc->writechunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
2021
				mychans->readchunk = (void *)(wc->readchunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
2022
			}
2023
		}
2024
	}
2025
}
2026
2027
#ifdef DAHDI_SPAN_OPS
2028
static const struct dahdi_span_ops t4_gen1_span_ops = {
2029
	.owner = THIS_MODULE,
2030
	.spanconfig = t4_spanconfig,
2031
	.chanconfig = t4_chanconfig,
2032
	.startup = t4_startup,
2033
	.shutdown = t4_shutdown,
2034
	.rbsbits = t4_rbsbits,
2035
	.maint = t4_maint,
2036
	.open = t4_open,
2037
	.close  = t4_close,
2038
	.ioctl = t4_ioctl,
2039
	.hdlc_hard_xmit = t4_hdlc_hard_xmit,
2040
};
2041
2042
static const struct dahdi_span_ops t4_gen2_span_ops = {
2043
	.owner = THIS_MODULE,
2044
	.spanconfig = t4_spanconfig,
2045
	.chanconfig = t4_chanconfig,
2046
	.startup = t4_startup,
2047
	.shutdown = t4_shutdown,
2048
	.rbsbits = t4_rbsbits,
2049
	.maint = t4_maint,
2050
	.open = t4_open,
2051
	.close  = t4_close,
2052
	.ioctl = t4_ioctl,
2053
	.hdlc_hard_xmit = t4_hdlc_hard_xmit,
2054
	.dacs = t4_dacs,
2055
#ifdef VPM_SUPPORT
2056
	.echocan_create = t4_echocan_create,
2057
#endif
2058
};
2059
#endif
2060
2061
static void init_spans(struct t4 *wc)
2062
{
2063
	int x,y;
2064
	int gen2;
2065
	struct t4_span *ts;
2066
	unsigned int reg;
2067
2068
	wc->ddev->manufacturer = "OpenVox";
2069
	if (order_index[wc->order] == 1)
2070
		wc->ddev->location = kasprintf(GFP_KERNEL,
2071
				"Board ID Switch %d", wc->order);
2072
	else
2073
		wc->ddev->location = kasprintf(GFP_KERNEL,
2074
				"PCI Bus %02d Slot %02d",
2075
				wc->dev->bus->number,
2076
				PCI_SLOT(wc->dev->devfn) + 1);
2077
	if (!wc->ddev->location)
2078
		return; /* FIXME: Error handling */
2079
2080
	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
2081
	for (x = 0; x < wc->numspans; x++) {
2082
		ts = wc->tspans[x];
2083
		sprintf(ts->span.name, "D115/D130/%d/%d", wc->num, x + 1);
2084
		snprintf(ts->span.desc, sizeof(ts->span.desc) - 1,
2085
			 "D115/D130 (E1|T1) Card %d Span %d", wc->num, x+1);
2086
		switch (ts->spantype) {
2087
		case TYPE_T1:
2088
			ts->span.spantype = SPANTYPE_DIGITAL_T1;
2089
			break;
2090
		case TYPE_E1:
2091
			ts->span.spantype = SPANTYPE_DIGITAL_E1;
2092
			break;
2093
		case TYPE_J1:
2094
			ts->span.spantype = SPANTYPE_DIGITAL_J1;
2095
			break;
2096
		}
2097
#ifdef DAHDI_SPAN_MODULE	
2098
		ts->span.owner = THIS_MODULE;
2099
#endif
2100
#ifdef DAHDI_SPAN_OPS
2101
		if (gen2) {
2102
			ts->span.ops = &t4_gen2_span_ops;
2103
		} else {
2104
			ts->span.ops = &t4_gen1_span_ops;
2105
		}
2106
#else
2107
		ts->span.spanconfig = t4_spanconfig;
2108
		ts->span.chanconfig = t4_chanconfig;
2109
		ts->span.startup = t4_startup;
2110
		ts->span.shutdown = t4_shutdown;
2111
		ts->span.rbsbits = t4_rbsbits;
2112
		ts->span.maint = t4_maint;
2113
		ts->span.open = t4_open;
2114
		ts->span.close  = t4_close;
2115
		ts->span.ioctl = t4_ioctl;
2116
		ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
2117
		if (gen2) {
2118
#ifdef VPM_SUPPORT
2119
		if (vpmsupport)
2120
			ts->span.echocan_create = t4_echocan_create;
2121
#endif			
2122
			ts->span.dacs = t4_dacs;
2123
		}
2124
		ts->span.pvt = ts;
2125
#endif
2126
2127
		/* HDLC Specific init */
2128
		ts->sigchan = NULL;
2129
		ts->sigmode = sigmode;
2130
		ts->sigactive = 0;
2131
		
2132
		if (ts->spantype == TYPE_T1 || ts->spantype == TYPE_J1) {
2133
			ts->span.channels = 24;
2134
			ts->span.deflaw = DAHDI_LAW_MULAW;
2135
			ts->span.linecompat = DAHDI_CONFIG_AMI |
2136
				DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 |
2137
				DAHDI_CONFIG_ESF;
2138
		} else {
2139
			ts->span.channels = 31;
2140
			ts->span.deflaw = DAHDI_LAW_ALAW;
2141
			ts->span.linecompat = DAHDI_CONFIG_AMI |
2142
				DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS |
2143
				DAHDI_CONFIG_CRC4;
2144
		}
2145
		ts->span.chans = ts->chans;
2146
		ts->span.flags = DAHDI_FLAG_RBS;
2147
2148
		ts->owner = wc;
2149
		ts->span.offset = x;
2150
		ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
2151
		ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
2152
2153
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
2154
			struct dahdi_chan *mychans = ts->chans[y];
2155
			sprintf(mychans->name, "D115/D130/%d/%d/%d", wc->num, x + 1, y + 1);
2156
			t4_chan_set_sigcap(&ts->span, x);
2157
			mychans->pvt = wc;
2158
			mychans->chanpos = y + 1;
2159
		}
2160
2161
		/* Enable 1sec timer interrupt */
2162
		reg = t4_framer_in(wc, x, FMR1_T);
2163
		t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
2164
2165
		/* Enable Errored Second interrupt */
2166
		t4_framer_out(wc, x, ESM, 0);
2167
2168
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
2169
		t4_reset_counters(&ts->span);
2170
#endif
2171
	}
2172
2173
	set_span_devicetype(wc);
2174
	setup_chunks(wc, 0);
2175
	wc->lastindex = 0;
2176
}
2177
2178
static void t4_serial_setup(struct t4 *wc, int unit)
2179
{
2180
	if (!wc->globalconfig) {
2181
		wc->globalconfig = 1;
2182
		if (debug)
2183
			dev_info(&wc->dev->dev, "opvxd115: Setting up global "
2184
					"serial parameters\n");
2185
		t4_framer_out(wc, 0, 0x85, 0xe0);	/* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
2186
		t4_framer_out(wc, 0, 0x08, 0x01);	/* IPC: Interrupt push/pull active low */
2187
	
2188
		/* Global clocks (8.192 Mhz CLK) */
2189
		t4_framer_out(wc, 0, 0x92, 0x00);	
2190
		t4_framer_out(wc, 0, 0x93, 0x18);
2191
		t4_framer_out(wc, 0, 0x94, 0xfb);
2192
		t4_framer_out(wc, 0, 0x95, 0x0b);
2193
		t4_framer_out(wc, 0, 0x96, 0x00);
2194
		t4_framer_out(wc, 0, 0x97, 0x0b);
2195
		t4_framer_out(wc, 0, 0x98, 0xdb);
2196
		t4_framer_out(wc, 0, 0x99, 0xdf);
2197
	}
2198
2199
	/* Configure interrupts */	
2200
	t4_framer_out(wc, unit, FRMR_GCR, 0x00);	/* GCR: Interrupt on Activation/Deactivation of each */
2201
2202
	/* Configure system interface */
2203
	t4_framer_out(wc, unit, FRMR_SIC1, 0xc2);	/* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */
2204
	t4_framer_out(wc, unit, FRMR_SIC2, 0x20 | (unit << 1)); /* SIC2: No FFS, no center receive eliastic buffer, phase */
2205
	t4_framer_out(wc, unit, FRMR_SIC3, 0x04);	/* SIC3: Edges for capture */
2206
	t4_framer_out(wc, unit, FRMR_CMR2, 0x00);	/* CMR2: We provide sync and clock for tx and rx. */
2207
	if (!wc->t1e1) { /* T1 mode */
2208
		t4_framer_out(wc, unit, FRMR_XC0, 0x03);	/* XC0: Normal operation of Sa-bits */
2209
		t4_framer_out(wc, unit, FRMR_XC1, 0x84);	/* XC1: 0 offset */
2210
		if (wc->tspans[unit]->spantype == TYPE_J1)
2211
			t4_framer_out(wc, unit, FRMR_RC0, 0x83);	/* RC0: Just shy of 1023 */
2212
		else
2213
			t4_framer_out(wc, unit, FRMR_RC0, 0x03);	/* RC0: Just shy of 1023 */
2214
		t4_framer_out(wc, unit, FRMR_RC1, 0x84);	/* RC1: The rest of RC0 */
2215
	} else { /* E1 mode */
2216
		t4_framer_out(wc, unit, FRMR_XC0, 0x00);	/* XC0: Normal operation of Sa-bits */
2217
		t4_framer_out(wc, unit, FRMR_XC1, 0x04);	/* XC1: 0 offset */
2218
		t4_framer_out(wc, unit, FRMR_RC0, 0x04);	/* RC0: Just shy of 1023 */
2219
		t4_framer_out(wc, unit, FRMR_RC1, 0x04);	/* RC1: The rest of RC0 */
2220
	}
2221
	
2222
	/* Configure ports */
2223
	t4_framer_out(wc, unit, 0x80, 0x00);	/* PC1: SPYR/SPYX input on RPA/XPA */
2224
	if (wc->falc31) {
2225
			  t4_framer_out(wc, unit, 0x81, 0xBB);	/* PC2: RMFB/XSIG output/input on RPB/XPB */
2226
			  t4_framer_out(wc, unit, 0x82, 0xBB);	/* PC3: Some unused stuff */
2227
			  t4_framer_out(wc, unit, 0x83, 0xBB);	/* PC4: Some more unused stuff */
2228
	} else {
2229
			  t4_framer_out(wc, unit, 0x81, 0x22);	/* PC2: RMFB/XSIG output/input on RPB/XPB */
2230
			  t4_framer_out(wc, unit, 0x82, 0x65);	/* PC3: Some unused stuff */
2231
			  t4_framer_out(wc, unit, 0x83, 0x35);	/* PC4: Some more unused stuff */
2232
	}
2233
	t4_framer_out(wc, unit, 0x84, 0x01);	/* PC5: XMFS active low, SCLKR is input, RCLK is output */
2234
	if (debug & DEBUG_MAIN)
2235
		dev_notice(&wc->dev->dev, "Successfully initialized serial "
2236
				"bus for unit %d\n", unit);
2237
}
2238
2239
static int syncsrc = 0;
2240
static int syncnum = 0 /* -1 */;
2241
static int syncspan = 0;
2242
#ifdef DEFINE_SPINLOCK
2243
static DEFINE_SPINLOCK(synclock);
2244
#else
2245
static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
2246
#endif
2247
2248
static void __t4_set_rclk_src(struct t4 *wc, int span)
2249
{
2250
	int cmr1 = 0x38;	/* Clock Mode: RCLK sourced by DCO-R1
2251
				   by default, Disable Clock-Switching */
2252
2253
	cmr1 |= (span << 6);
2254
	__t4_framer_out(wc, 0, 0x44, cmr1);
2255
2256
	dev_info(&wc->dev->dev, "RCLK source set to span %d\n", span+1);
2257
}
2258
2259
static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave)
2260
{
2261
	if (slave) {
2262
		wc->dmactrl |= (1 << 25);
2263
		dev_info(&wc->dev->dev, "SCLK is slaved to timing cable\n");
2264
	} else {
2265
		wc->dmactrl &= ~(1 << 25);
2266
	}
2267
2268
	if (master) {
2269
		wc->dmactrl |= (1 << 24);
2270
		dev_info(&wc->dev->dev, "SCLK is master to timing cable\n");
2271
	} else {
2272
		wc->dmactrl &= ~(1 << 24);
2273
	}
2274
2275
	if (mode == WC_RECOVER)
2276
		wc->dmactrl |= (1 << 29); /* Recover timing from RCLK */
2277
2278
	if (mode == WC_SELF)
2279
		wc->dmactrl &= ~(1 << 29);/* Provide timing from MCLK */
2280
2281
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2282
}
2283
2284
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
2285
static ssize_t t4_timing_master_show(struct device *dev,
2286
				     struct device_attribute *attr,
2287
				     char *buf)
2288
{
2289
	struct t4 *wc = dev_get_drvdata(dev);
2290
	if (wc->dmactrl & (1 << 29))
2291
		return sprintf(buf, "%d\n", wc->syncsrc);
2292
	else
2293
		return sprintf(buf, "%d\n", -1);
2294
}
2295
2296
static DEVICE_ATTR(timing_master, 0400, t4_timing_master_show, NULL);
2297
2298
static void create_sysfs_files(struct t4 *wc)
2299
{
2300
	int ret;
2301
	ret = device_create_file(&wc->dev->dev,
2302
				 &dev_attr_timing_master);
2303
	if (ret) {
2304
		dev_info(&wc->dev->dev,
2305
			"Failed to create device attributes.\n");
2306
	}
2307
}
2308
2309
static void remove_sysfs_files(struct t4 *wc)
2310
{
2311
	device_remove_file(&wc->dev->dev,
2312
			   &dev_attr_timing_master);
2313
}
2314
2315
#else
2316
2317
static inline void create_sysfs_files(struct t4 *wc) { return; }
2318
static inline void remove_sysfs_files(struct t4 *wc) { return; }
2319
2320
#endif /* LINUX_KERNEL > 2.6.18 */
2321
2322
static inline void __t4_update_timing(struct t4 *wc)
2323
{
2324
	int i;
2325
	/* update sync src info */
2326
	if (wc->syncsrc != syncsrc) {
2327
		dev_info(&wc->dev->dev, "Swapping card %d from %d to %d\n",
2328
				wc->num, wc->syncsrc, syncsrc);
2329
		wc->syncsrc = syncsrc;
2330
		/* Update sync sources */
2331
		for (i = 0; i < wc->numspans; i++) {
2332
			wc->tspans[i]->span.syncsrc = wc->syncsrc;
2333
		}
2334
		if (syncnum == wc->num) {
2335
			__t4_set_rclk_src(wc, syncspan-1);
2336
			__t4_set_sclk_src(wc, WC_RECOVER, 1, 0);
2337
			if (debug)
2338
				dev_notice(&wc->dev->dev, "Card %d, using sync "
2339
					"span %d, master\n", wc->num, syncspan);
2340
		} else {
2341
			__t4_set_sclk_src(wc, WC_RECOVER, 0, 1);
2342
			if (debug)
2343
				dev_notice(&wc->dev->dev, "Card %d, using "
2344
					"Timing Bus, NOT master\n", wc->num);
2345
		}
2346
	}
2347
}
2348
2349
static int __t4_findsync(struct t4 *wc)
2350
{
2351
	int i;
2352
	int x;
2353
	unsigned long flags;
2354
	int p;
2355
	int nonzero;
2356
	int newsyncsrc = 0;			/* DAHDI span number */
2357
	int newsyncnum = 0;			/* opvxd115 card number */
2358
	int newsyncspan = 0;		/* span on given opvxd115 card */
2359
	spin_lock_irqsave(&synclock, flags);
2360
#if 1
2361
	if (!wc->num) {
2362
		/* If we're the first card, go through all the motions, up to 8 levels
2363
		   of sync source */
2364
		p = 1;
2365
		while (p < 8) {
2366
			nonzero = 0;
2367
			for (x=0;cards[x];x++) {
2368
				for (i = 0; i < wc->numspans; i++) {
2369
					if (cards[x]->tspans[i]->syncpos) {
2370
						nonzero = 1;
2371
						if ((cards[x]->tspans[i]->syncpos == p) &&
2372
						    !(cards[x]->tspans[i]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_LOOPBACK)) &&
2373
							(cards[x]->tspans[i]->span.flags & DAHDI_FLAG_RUNNING)) {
2374
								/* This makes a good sync source */
2375
								newsyncsrc = cards[x]->tspans[i]->span.spanno;
2376
								newsyncnum = x;
2377
								newsyncspan = i + 1;
2378
								/* Jump out */
2379
								goto found;
2380
						}
2381
					}
2382
				}		
2383
			}
2384
			if (nonzero)
2385
				p++;
2386
			else 
2387
				break;
2388
		}
2389
found:		
2390
		if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) {
2391
			if (debug)
2392
				dev_notice(&wc->dev->dev, "New syncnum: %d "
2393
					"(was %d), syncsrc: %d (was %d), "
2394
					"syncspan: %d (was %d)\n", newsyncnum,
2395
					syncnum, newsyncsrc, syncsrc,
2396
					newsyncspan, syncspan);
2397
			syncnum = newsyncnum;
2398
			syncsrc = newsyncsrc;
2399
			syncspan = newsyncspan;
2400
			for (x=0;cards[x];x++) {
2401
				__t4_update_timing(cards[x]);
2402
			}
2403
		}
2404
	}
2405
	__t4_update_timing(wc);
2406
#endif	
2407
	spin_unlock_irqrestore(&synclock, flags);
2408
	return 0;
2409
}
2410
2411
static void __t4_set_timing_source_auto(struct t4 *wc)
2412
{
2413
	int x;
2414
	int firstprio, secondprio;
2415
	firstprio = secondprio = 4;
2416
2417
	if (debug)
2418
		dev_info(&wc->dev->dev, "timing source auto\n");
2419
	clear_bit(T4_CHECK_TIMING, &wc->checkflag);
2420
	if (timingcable) {
2421
		__t4_findsync(wc);
2422
	} else {
2423
		if (debug)
2424
			dev_info(&wc->dev->dev, "Evaluating spans for timing "
2425
					"source\n");
2426
		for (x=0;x<wc->numspans;x++) {
2427
			if ((wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) &&
2428
			   !(wc->tspans[x]->span.alarms & (DAHDI_ALARM_RED |
2429
							   DAHDI_ALARM_BLUE))) {
2430
				if (debug)
2431
					dev_info(&wc->dev->dev, "span %d is "
2432
						"green : syncpos %d\n", x+1,
2433
						wc->tspans[x]->syncpos);
2434
				if (wc->tspans[x]->syncpos) {
2435
					/* Valid rsync source in recovered
2436
					   timing mode */
2437
					if (firstprio == 4)
2438
						firstprio = x;
2439
					else if (wc->tspans[x]->syncpos <
2440
						wc->tspans[firstprio]->syncpos)
2441
						firstprio = x;
2442
				} else {
2443
					/* Valid rsync source in system timing
2444
					   mode */
2445
					if (secondprio == 4)
2446
						secondprio = x;
2447
				}
2448
			}
2449
		}
2450
		if (firstprio != 4) {
2451
			wc->syncsrc = firstprio;
2452
			__t4_set_rclk_src(wc, firstprio);
2453
			__t4_set_sclk_src(wc, WC_RECOVER, 0, 0);
2454
			dev_info(&wc->dev->dev, "Recovered timing mode, "\
2455
						"RCLK set to span %d\n",
2456
						firstprio+1);
2457
		} else if (secondprio != 4) {
2458
			wc->syncsrc = -1;
2459
			__t4_set_rclk_src(wc, secondprio);
2460
			__t4_set_sclk_src(wc, WC_SELF, 0, 0);
2461
			dev_info(&wc->dev->dev, "System timing mode, "\
2462
						"RCLK set to span %d\n",
2463
						secondprio+1);
2464
		} else {
2465
			wc->syncsrc = -1;
2466
			dev_info(&wc->dev->dev, "All spans in alarm : No valid"\
2467
						"span to source RCLK from\n");
2468
			/* Default rclk to lock with span 1 */
2469
			__t4_set_rclk_src(wc, 0);
2470
			__t4_set_sclk_src(wc, WC_SELF, 0, 0);
2471
		}
2472
	}
2473
}
2474
2475
static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel)
2476
{
2477
	unsigned int fmr4, fmr2, fmr1, fmr0, lim2;
2478
	char *framing, *line;
2479
	int mytxlevel;
2480
	if ((txlevel > 7) || (txlevel < 4))
2481
		mytxlevel = 0;
2482
	else
2483
		mytxlevel = txlevel - 4;
2484
	fmr1 = 0x9c; /* FMR1: Mode 1, T1 mode, CRC on for ESF, 8.192 Mhz system data rate, no XAIS */
2485
	fmr2 = 0x20; /* FMR2: no payload loopback, don't auto yellow */
2486
	fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */
2487
	lim2 = 0x21; /* LIM2: 50% peak is a "1", Advanced Loss recovery */
2488
	lim2 |= (mytxlevel << 6);	/* LIM2: Add line buildout */
2489
	__t4_framer_out(wc, unit, 0x1d, fmr1);
2490
	__t4_framer_out(wc, unit, 0x1e, fmr2);
2491
2492
	/* Configure line interface */
2493
	if (lineconfig & DAHDI_CONFIG_AMI) {
2494
		line = "AMI";
2495
		/* workaround for errata #2 in ES v3 09-10-16 */
2496
		fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
2497
	} else {
2498
		line = "B8ZS";
2499
		fmr0 = 0xf0;
2500
	}
2501
	if (lineconfig & DAHDI_CONFIG_D4) {
2502
		framing = "D4";
2503
	} else {
2504
		framing = "ESF";
2505
		fmr4 |= 0x2;
2506
		fmr2 |= 0xc0;
2507
	}
2508
	__t4_framer_out(wc, unit, 0x1c, fmr0);
2509
	__t4_framer_out(wc, unit, 0x20, fmr4);
2510
	__t4_framer_out(wc, unit, 0x21, 0x40);	/* FMR5: Enable RBS mode */
2511
2512
	__t4_framer_out(wc, unit, 0x37, 0xf0 );	/* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
2513
	__t4_framer_out(wc, unit, 0x36, 0x08);	/* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
2514
2515
	__t4_framer_out(wc, unit, 0x02, 0x50);	/* CMDR: Reset the receiver and transmitter line interface */
2516
	__t4_framer_out(wc, unit, 0x02, 0x00);	/* CMDR: Reset the receiver and transmitter line interface */
2517
2518
	if (wc->falc31) {
2519
		if (debug)
2520
			dev_info(&wc->dev->dev, "card %d span %d: setting Rtx "
2521
					"to 0ohm for T1\n", wc->num, unit);
2522
		__t4_framer_out(wc, unit, 0x86, 0x00);	/* PC6: set Rtx to 0ohm for T1 */
2523
2524
		// Hitting the bugfix register to fix errata #3
2525
		__t4_framer_out(wc, unit, 0xbd, 0x05);
2526
	}
2527
2528
	__t4_framer_out(wc, unit, 0x3a, lim2);	/* LIM2: 50% peak amplitude is a "1" */
2529
	__t4_framer_out(wc, unit, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
2530
	__t4_framer_out(wc, unit, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
2531
	
2532
	/* Generate pulse mask for T1 */
2533
	switch(mytxlevel) {
2534
	case 3:
2535
		__t4_framer_out(wc, unit, 0x26, 0x07);	/* XPM0 */
2536
		__t4_framer_out(wc, unit, 0x27, 0x01);	/* XPM1 */
2537
		__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2538
		break;
2539
	case 2:
2540
		__t4_framer_out(wc, unit, 0x26, 0x8c);	/* XPM0 */
2541
		__t4_framer_out(wc, unit, 0x27, 0x11);	/* XPM1 */
2542
		__t4_framer_out(wc, unit, 0x28, 0x01);	/* XPM2 */
2543
		break;
2544
	case 1:
2545
		__t4_framer_out(wc, unit, 0x26, 0x8c);	/* XPM0 */
2546
		__t4_framer_out(wc, unit, 0x27, 0x01);	/* XPM1 */
2547
		__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2548
		break;
2549
	case 0:
2550
	default:
2551
		__t4_framer_out(wc, unit, 0x26, 0xd7);	/* XPM0 */
2552
		__t4_framer_out(wc, unit, 0x27, 0x22);	/* XPM1 */
2553
		__t4_framer_out(wc, unit, 0x28, 0x01);	/* XPM2 */
2554
		break;
2555
	}
2556
2557
	/* Don't mask framer interrupts if hardware HDLC is in use */
2558
	__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0));	/* IMR0: We care about CAS changes, etc */
2559
	__t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0));	/* IMR1: We care about nothing */
2560
	__t4_framer_out(wc, unit, 0x16, 0x00);	/* IMR2: All the alarm stuff! */
2561
	__t4_framer_out(wc, unit, 0x17, 0x34);	/* IMR3: AIS and friends */
2562
	__t4_framer_out(wc, unit, 0x18, 0x3f);  /* IMR4: Slips on transmit */
2563
2564
	dev_info(&wc->dev->dev, "Span %d configured for %s/%s\n", unit + 1,
2565
			framing, line);
2566
}
2567
2568
static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
2569
{
2570
	unsigned int fmr2, fmr1, fmr0;
2571
	unsigned int cas = 0;
2572
	unsigned int imr3extra=0;
2573
	char *crc4 = "";
2574
	char *framing, *line;
2575
	fmr1 = 0x44; /* FMR1: E1 mode, Automatic force resync, PCM30 mode, 8.192 Mhz backplane, no XAIS */
2576
	fmr2 = 0x03; /* FMR2: Auto transmit remote alarm, auto loss of multiframe recovery, no payload loopback */
2577
	if (lineconfig & DAHDI_CONFIG_CRC4) {
2578
		fmr1 |= 0x08;	/* CRC4 transmit */
2579
		fmr2 |= 0xc0;	/* CRC4 receive */
2580
		crc4 = "/CRC4";
2581
	}
2582
	__t4_framer_out(wc, unit, 0x1d, fmr1);
2583
	__t4_framer_out(wc, unit, 0x1e, fmr2);
2584
2585
	/* Configure line interface */
2586
	if (lineconfig & DAHDI_CONFIG_AMI) {
2587
		line = "AMI";
2588
		/* workaround for errata #2 in ES v3 09-10-16 */
2589
		fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
2590
	} else {
2591
		line = "HDB3";
2592
		fmr0 = 0xf0;
2593
	}
2594
	if (lineconfig & DAHDI_CONFIG_CCS) {
2595
		framing = "CCS";
2596
		imr3extra = 0x28;
2597
	} else {
2598
		framing = "CAS";
2599
		cas = 0x40;
2600
	}
2601
	__t4_framer_out(wc, unit, 0x1c, fmr0);
2602
2603
	__t4_framer_out(wc, unit, 0x37, 0xf0 /*| 0x6 */ );	/* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
2604
	__t4_framer_out(wc, unit, 0x36, 0x08);	/* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
2605
2606
	__t4_framer_out(wc, unit, 0x02, 0x50);	/* CMDR: Reset the receiver and transmitter line interface */
2607
	__t4_framer_out(wc, unit, 0x02, 0x00);	/* CMDR: Reset the receiver and transmitter line interface */
2608
2609
	if (wc->falc31) {
2610
		if (debug)
2611
			dev_info(&wc->dev->dev,
2612
					"setting Rtx to 7.5ohm for E1\n");
2613
		__t4_framer_out(wc, unit, 0x86, 0x40);	/* PC6: turn on 7.5ohm Rtx for E1 */
2614
	}
2615
2616
	/* Condition receive line interface for E1 after reset */
2617
	__t4_framer_out(wc, unit, 0xbb, 0x17);
2618
	__t4_framer_out(wc, unit, 0xbc, 0x55);
2619
	__t4_framer_out(wc, unit, 0xbb, 0x97);
2620
	__t4_framer_out(wc, unit, 0xbb, 0x11);
2621
	__t4_framer_out(wc, unit, 0xbc, 0xaa);
2622
	__t4_framer_out(wc, unit, 0xbb, 0x91);
2623
	__t4_framer_out(wc, unit, 0xbb, 0x12);
2624
	__t4_framer_out(wc, unit, 0xbc, 0x55);
2625
	__t4_framer_out(wc, unit, 0xbb, 0x92);
2626
	__t4_framer_out(wc, unit, 0xbb, 0x0c);
2627
	__t4_framer_out(wc, unit, 0xbb, 0x00);
2628
	__t4_framer_out(wc, unit, 0xbb, 0x8c);
2629
	
2630
	__t4_framer_out(wc, unit, 0x3a, 0x20);	/* LIM2: 50% peak amplitude is a "1" */
2631
	__t4_framer_out(wc, unit, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
2632
	__t4_framer_out(wc, unit, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
2633
	
2634
	__t4_framer_out(wc, unit, 0x20, 0x9f);	/* XSW: Spare bits all to 1 */
2635
	__t4_framer_out(wc, unit, 0x21, 0x1c|cas);	/* XSP: E-bit set when async. AXS auto, XSIF to 1 */
2636
	
2637
	
2638
	/* Generate pulse mask for E1 */
2639
	__t4_framer_out(wc, unit, 0x26, 0x54);	/* XPM0 */
2640
	__t4_framer_out(wc, unit, 0x27, 0x02);	/* XPM1 */
2641
	__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2642
2643
	/* Don't mask framer interrupts if hardware HDLC is in use */
2644
	__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0));	/* IMR0: We care about CRC errors, CAS changes, etc */
2645
	__t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0));	/* IMR1: We care about loopup / loopdown */
2646
	__t4_framer_out(wc, unit, 0x16, 0x00);	/* IMR2: We care about all the alarm stuff! */
2647
	__t4_framer_out(wc, unit, 0x17, 0x04 | imr3extra); /* IMR3: AIS */
2648
	__t4_framer_out(wc, unit, 0x18, 0x3f);  /* IMR4: We care about slips on transmit */
2649
2650
	dev_info(&wc->dev->dev, "opvxd115: Span %d configured for %s/%s%s\n",
2651
			unit + 1, framing, line, crc4);
2652
}
2653
2654
static int t4_startup(struct file *file, struct dahdi_span *span)
2655
{
2656
#ifdef SUPPORT_GEN1
2657
	int i;
2658
#endif
2659
	int tspan;
2660
	unsigned long flags;
2661
	int alreadyrunning;
2662
	struct t4_span *ts = t4_from_span(span);
2663
	struct t4 *wc = ts->owner;
2664
2665
	set_bit(T4_IGNORE_LATENCY, &wc->checkflag);
2666
	if (debug)
2667
		dev_info(&wc->dev->dev, "About to enter startup!\n");
2668
	tspan = span->offset + 1;
2669
	if (tspan < 0) {
2670
		dev_info(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
2671
				span->spanno);
2672
		return -1;
2673
	}
2674
2675
	spin_lock_irqsave(&wc->reglock, flags);
2676
2677
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
2678
2679
#ifdef SUPPORT_GEN1
2680
	/* initialize the start value for the entire chunk of last ec buffer */
2681
	for(i = 0; i < span->channels; i++)
2682
	{
2683
		memset(ts->ec_chunk1[i],
2684
			DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
2685
		memset(ts->ec_chunk2[i],
2686
			DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
2687
	}
2688
#endif
2689
	/* Force re-evaluation of timing source */
2690
	wc->syncsrc = -1;
2691
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
2692
2693
	if (ts->spantype == TYPE_E1) { /* if this is an E1 card */
2694
		__t4_configure_e1(wc, span->offset, span->lineconfig);
2695
	} else { /* is a T1 card */
2696
		__t4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
2697
	}
2698
2699
	/* Note clear channel status */
2700
	wc->tspans[span->offset]->notclear = 0;
2701
	__set_clear(wc, span->offset);
2702
	
2703
	if (!alreadyrunning) {
2704
		span->flags |= DAHDI_FLAG_RUNNING;
2705
		wc->spansstarted++;
2706
2707
		if (wc->flags & FLAG_5THGEN)
2708
			__t4_pci_out(wc, 5, (ms_per_irq << 16) | wc->numbufs);
2709
		/* enable interrupts */
2710
		/* Start DMA, enabling DMA interrupts on read only */
2711
#if 0
2712
		/* Enable framer only interrupts */
2713
		wc->dmactrl |= 1 << 27;
2714
#endif
2715
		wc->dmactrl |= (ts->spanflags & FLAG_2NDGEN) ? 0xc0000000 : 0xc0000003;
2716
#ifdef VPM_SUPPORT
2717
		wc->dmactrl |= wc->vpm;
2718
#endif
2719
		/* Seed interrupt register */
2720
		__t4_pci_out(wc, WC_INTR, 0x0c);
2721
		if (noburst || !(ts->spanflags & FLAG_BURST))
2722
			wc->dmactrl |= (1 << 26);
2723
		__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2724
2725
		/* Startup HDLC controller too */
2726
	}
2727
2728
	if (ts->sigchan) {
2729
		struct dahdi_chan *sigchan = ts->sigchan;
2730
2731
		spin_unlock_irqrestore(&wc->reglock, flags);
2732
		if (hdlc_start(wc, span->offset, sigchan, ts->sigmode)) {
2733
			dev_notice(&wc->dev->dev, "Error initializing "
2734
					"signalling controller\n");
2735
			return -1;
2736
		}
2737
		spin_lock_irqsave(&wc->reglock, flags);
2738
	}
2739
2740
	spin_unlock_irqrestore(&wc->reglock, flags);
2741
2742
	t4_check_alarms(wc, span->offset);
2743
	t4_check_sigbits(wc, span->offset);
2744
2745
	if (wc->tspans[0]->sync == span->spanno)
2746
		dev_info(&wc->dev->dev, "SPAN %d: Primary Sync Source\n",
2747
				span->spanno);
2748
#ifdef VPM_SUPPORT
2749
	if (!alreadyrunning && !wc->vpm) {
2750
		wait_a_little();
2751
		t4_vpm400_init(wc);
2752
		if (!wc->vpm)
2753
			t4_vpm450_init(wc);
2754
		wc->dmactrl |= wc->vpm;
2755
		t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2756
		if (wc->vpm)
2757
			set_span_devicetype(wc);
2758
	}
2759
#endif
2760
	if (debug)
2761
		dev_info(&wc->dev->dev, "Completed startup!\n");
2762
	clear_bit(T4_IGNORE_LATENCY, &wc->checkflag);
2763
	return 0;
2764
}
2765
2766
#ifdef SUPPORT_GEN1
2767
static inline void e1_check(struct t4 *wc, int span, int val)
2768
{
2769
	struct t4_span *ts = wc->tspans[span];
2770
	if ((ts->span.channels > 24) &&
2771
	    (ts->span.flags & DAHDI_FLAG_RUNNING) &&
2772
	    !(ts->span.alarms) &&
2773
	    (!wc->e1recover))   {
2774
		if (val != 0x1b) {
2775
			ts->e1check++;
2776
		} else
2777
			ts->e1check = 0;
2778
		if (ts->e1check > 100) {
2779
			/* Wait 1000 ms */
2780
			wc->e1recover = 1000 * 8;
2781
			wc->tspans[0]->e1check = 0;
2782
			if (debug & DEBUG_MAIN)
2783
				dev_notice(&wc->dev->dev, "Detected loss of "
2784
					"E1 alignment on span %d!\n", span);
2785
			t4_reset_dma(wc);
2786
		}
2787
	}
2788
}
2789
2790
static void t4_receiveprep(struct t4 *wc, int irq)
2791
{
2792
	volatile unsigned int *readchunk;
2793
	int dbl = 0;
2794
	int x,y,z;
2795
	unsigned int tmp;
2796
	int offset=0;
2797
	if (!wc->t1e1)
2798
		offset = 4;
2799
	if (irq & 1) {
2800
		/* First part */
2801
		readchunk = wc->readchunk;
2802
		if (!wc->last0) 
2803
			dbl = 1;
2804
		wc->last0 = 0;
2805
	} else {
2806
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE * 32;
2807
		if (wc->last0) 
2808
			dbl = 1;
2809
		wc->last0 = 1;
2810
	}
2811
	if (dbl) {
2812
		for (x=0;x<wc->numspans;x++)
2813
			wc->ddev->irqmisses++;
2814
		if (debug & DEBUG_MAIN)
2815
			dev_notice(&wc->dev->dev, "opvxd115: Double/missed "
2816
				"interrupt detected\n");
2817
	}
2818
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
2819
		for (z=0;z<24;z++) {
2820
			/* All T1/E1 channels */
2821
			tmp = readchunk[z+1+offset];
2822
			wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
2823
		}
2824
		if (wc->t1e1) {
2825
			if (wc->e1recover > 0)
2826
				wc->e1recover--;
2827
			tmp = readchunk[0];
2828
			e1_check(wc, 0, (tmp & 0x7f000000) >> 24);
2829
			for (z=24;z<31;z++) {
2830
				/* Only E1 channels now */
2831
				tmp = readchunk[z+1];
2832
				if (wc->tspans[0]->span.channels > 24)
2833
					wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
2834
			}
2835
		}
2836
		/* Advance pointer by 4 TDM frame lengths */
2837
		readchunk += 32;
2838
	}
2839
	for (x=0;x<wc->numspans;x++) {
2840
		if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
2841
			for (y=0;y<wc->tspans[x]->span.channels;y++) {
2842
				/* Echo cancel double buffered data */
2843
				dahdi_ec_chunk(wc->tspans[x]->span.chans[y], 
2844
				    wc->tspans[x]->span.chans[y]->readchunk, 
2845
					wc->tspans[x]->ec_chunk2[y]);
2846
				memcpy(wc->tspans[x]->ec_chunk2[y],wc->tspans[x]->ec_chunk1[y],
2847
					DAHDI_CHUNKSIZE);
2848
				memcpy(wc->tspans[x]->ec_chunk1[y],
2849
					wc->tspans[x]->span.chans[y]->writechunk,
2850
						DAHDI_CHUNKSIZE);
2851
			}
2852
			dahdi_receive(&wc->tspans[x]->span);
2853
		}
2854
	}
2855
}
2856
#endif
2857
2858
#if (DAHDI_CHUNKSIZE != 8)
2859
#error Sorry, nextgen does not support chunksize != 8
2860
#endif
2861
2862
static inline void __receive_span(struct t4_span *ts)
2863
{
2864
#ifdef VPM_SUPPORT
2865
	int y;
2866
	unsigned long merged;
2867
	merged = ts->dtmfactive & ts->dtmfmutemask;
2868
	if (merged) {
2869
		for (y=0;y<ts->span.channels;y++) {
2870
			/* Mute any DTMFs which are supposed to be muted */
2871
			if (test_bit(y, &merged)) {
2872
				memset(ts->span.chans[y]->readchunk, DAHDI_XLAW(0, ts->span.chans[y]), DAHDI_CHUNKSIZE);
2873
			}
2874
		}
2875
	}
2876
#endif	
2877
2878
#ifdef ENABLE_PREFETCH
2879
	prefetch((void *)(ts->readchunk));
2880
	prefetch((void *)(ts->writechunk));
2881
	prefetch((void *)(ts->readchunk + 8));
2882
	prefetch((void *)(ts->writechunk + 8));
2883
	prefetch((void *)(ts->readchunk + 16));
2884
	prefetch((void *)(ts->writechunk + 16));
2885
	prefetch((void *)(ts->readchunk + 24));
2886
	prefetch((void *)(ts->writechunk + 24));
2887
	prefetch((void *)(ts->readchunk + 32));
2888
	prefetch((void *)(ts->writechunk + 32));
2889
	prefetch((void *)(ts->readchunk + 40));
2890
	prefetch((void *)(ts->writechunk + 40));
2891
	prefetch((void *)(ts->readchunk + 48));
2892
	prefetch((void *)(ts->writechunk + 48));
2893
	prefetch((void *)(ts->readchunk + 56));
2894
	prefetch((void *)(ts->writechunk + 56));
2895
#endif
2896
2897
	dahdi_ec_span(&ts->span);
2898
	dahdi_receive(&ts->span);
2899
}
2900
2901
static inline void __transmit_span(struct t4_span *ts)
2902
{
2903
	dahdi_transmit(&ts->span);
2904
}
2905
2906
#ifdef ENABLE_WORKQUEUES
2907
static void workq_handlespan(void *data)
2908
{
2909
	struct t4_span *ts = data;
2910
	struct t4 *wc = ts->owner;
2911
	
2912
	__receive_span(ts);
2913
	__transmit_span(ts);
2914
	atomic_dec(&wc->worklist);
2915
	if (!atomic_read(&wc->worklist))
2916
		t4_pci_out(wc, WC_INTR, 0);
2917
}
2918
#else
2919
static void t4_prep_gen2(struct t4 *wc)
2920
{
2921
	int x;
2922
	for (x=0;x<wc->numspans;x++) {
2923
		if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
2924
			__receive_span(wc->tspans[x]);
2925
			__transmit_span(wc->tspans[x]);
2926
		}
2927
	}
2928
}
2929
2930
#endif
2931
#ifdef SUPPORT_GEN1
2932
static void t4_transmitprep(struct t4 *wc, int irq)
2933
{
2934
	volatile unsigned int *writechunk;
2935
	int x,y,z;
2936
	unsigned int tmp;
2937
	int offset=0;
2938
	if (!wc->t1e1)
2939
		offset = 4;
2940
	if (irq & 1) {
2941
		/* First part */
2942
		writechunk = wc->writechunk + 1;
2943
	} else {
2944
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE * 32  + 1;
2945
	}
2946
	for (y=0;y<wc->numspans;y++) {
2947
		if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING) 
2948
			dahdi_transmit(&wc->tspans[y]->span);
2949
	}
2950
2951
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
2952
		/* Once per chunk */
2953
		for (z=0;z<24;z++) {
2954
			/* All T1/E1 channels */
2955
			tmp = (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
2956
			writechunk[z+offset] = tmp;
2957
		}
2958
		if (wc->t1e1) {
2959
			for (z=24;z<31;z++) {
2960
				/* Only E1 channels now */
2961
				tmp = 0;
2962
				if (wc->tspans[0]->span.channels > 24)
2963
					tmp |= (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
2964
				writechunk[z] = tmp;
2965
			}
2966
		}
2967
		/* Advance pointer by 4 TDM frame lengths */
2968
		writechunk += 32;
2969
	}
2970
2971
}
2972
#endif
2973
2974
static void t4_check_sigbits(struct t4 *wc, int span)
2975
{
2976
	int a,i,rxs;
2977
	struct t4_span *ts = wc->tspans[span];
2978
2979
	if (debug & DEBUG_RBS)
2980
		dev_notice(&wc->dev->dev, "Checking sigbits on span %d\n",
2981
				span + 1);
2982
2983
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
2984
		return;
2985
	if (ts->spantype == TYPE_E1) {
2986
		for (i = 0; i < 15; i++) {
2987
			a = t4_framer_in(wc, span, 0x71 + i);
2988
			/* Get high channel in low bits */
2989
			rxs = (a & 0xf);
2990
			if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
2991
				if (ts->span.chans[i+16]->rxsig != rxs)
2992
					dahdi_rbsbits(ts->span.chans[i+16], rxs);
2993
			}
2994
			rxs = (a >> 4) & 0xf;
2995
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
2996
				if (ts->span.chans[i]->rxsig != rxs)
2997
					dahdi_rbsbits(ts->span.chans[i], rxs);
2998
			}
2999
		}
3000
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
3001
		for (i = 0; i < 24; i+=4) {
3002
			a = t4_framer_in(wc, span, 0x70 + (i>>2));
3003
			/* Get high channel in low bits */
3004
			rxs = (a & 0x3) << 2;
3005
			if (!(ts->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
3006
				if (ts->span.chans[i+3]->rxsig != rxs)
3007
					dahdi_rbsbits(ts->span.chans[i+3], rxs);
3008
			}
3009
			rxs = (a & 0xc);
3010
			if (!(ts->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
3011
				if (ts->span.chans[i+2]->rxsig != rxs)
3012
					dahdi_rbsbits(ts->span.chans[i+2], rxs);
3013
			}
3014
			rxs = (a >> 2) & 0xc;
3015
			if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
3016
				if (ts->span.chans[i+1]->rxsig != rxs)
3017
					dahdi_rbsbits(ts->span.chans[i+1], rxs);
3018
			}
3019
			rxs = (a >> 4) & 0xc;
3020
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
3021
				if (ts->span.chans[i]->rxsig != rxs)
3022
					dahdi_rbsbits(ts->span.chans[i], rxs);
3023
			}
3024
		}
3025
	} else {
3026
		for (i = 0; i < 24; i+=2) {
3027
			a = t4_framer_in(wc, span, 0x70 + (i>>1));
3028
			/* Get high channel in low bits */
3029
			rxs = (a & 0xf);
3030
			if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
3031
				/* XXX Not really reset on every trans! XXX */
3032
				if (ts->span.chans[i+1]->rxsig != rxs) {
3033
					dahdi_rbsbits(ts->span.chans[i+1], rxs);
3034
				}
3035
			}
3036
			rxs = (a >> 4) & 0xf;
3037
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
3038
				/* XXX Not really reset on every trans! XXX */
3039
				if (ts->span.chans[i]->rxsig != rxs) {
3040
					dahdi_rbsbits(ts->span.chans[i], rxs);
3041
				}
3042
			}
3043
		}
3044
	}
3045
}
3046
3047
static void t4_check_alarms(struct t4 *wc, int span)
3048
{
3049
	unsigned char c, d, e;
3050
	int alarms;
3051
	int x,j;
3052
	struct t4_span *ts = wc->tspans[span];
3053
	unsigned long flags;
3054
3055
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
3056
		return;
3057
3058
	spin_lock_irqsave(&wc->reglock, flags);
3059
3060
	c = __t4_framer_in(wc, span, 0x4c);
3061
	d = __t4_framer_in(wc, span, 0x4d);
3062
3063
	/* Assume no alarms */
3064
	alarms = 0;
3065
3066
	/* And consider only carrier alarms */
3067
	ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
3068
3069
	if (ts->spantype == TYPE_E1) {
3070
		if (c & 0x04) {
3071
			/* No multiframe found, force RAI high after 400ms only if
3072
			   we haven't found a multiframe since last loss
3073
			   of frame */
3074
			if (!(ts->spanflags & FLAG_NMF)) {
3075
				__t4_framer_out(wc, span, 0x20, 0x9f | 0x20);	/* LIM0: Force RAI High */
3076
				ts->spanflags |= FLAG_NMF;
3077
				dev_notice(&wc->dev->dev,
3078
					"NMF workaround on!\n");
3079
			}
3080
			__t4_framer_out(wc, span, 0x1e, 0xc3);	/* Reset to CRC4 mode */
3081
			__t4_framer_out(wc, span, 0x1c, 0xf2);	/* Force Resync */
3082
			__t4_framer_out(wc, span, 0x1c, 0xf0);	/* Force Resync */
3083
		} else if (!(c & 0x02)) {
3084
			if ((ts->spanflags & FLAG_NMF)) {
3085
				__t4_framer_out(wc, span, 0x20, 0x9f);	/* LIM0: Clear forced RAI */
3086
				ts->spanflags &= ~FLAG_NMF;
3087
				dev_notice(&wc->dev->dev,
3088
					"NMF workaround off!\n");
3089
			}
3090
		}
3091
	} else {
3092
		/* Detect loopup code if we're not sending one */
3093
		if ((!ts->span.mainttimer) && (d & 0x08)) {
3094
			/* Loop-up code detected */
3095
			if ((ts->loopupcnt++ > 80)  && (ts->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
3096
				__t4_framer_out(wc, span, 0x36, 0x08);	/* LIM0: Disable any local loop */
3097
				__t4_framer_out(wc, span, 0x37, 0xf6 );	/* LIM1: Enable remote loop */
3098
				ts->span.maintstat = DAHDI_MAINT_REMOTELOOP;
3099
			}
3100
		} else
3101
			ts->loopupcnt = 0;
3102
		/* Same for loopdown code */
3103
		if ((!ts->span.mainttimer) && (d & 0x10)) {
3104
			/* Loop-down code detected */
3105
			if ((ts->loopdowncnt++ > 80)  && (ts->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
3106
				__t4_framer_out(wc, span, 0x36, 0x08);	/* LIM0: Disable any local loop */
3107
				__t4_framer_out(wc, span, 0x37, 0xf0 );	/* LIM1: Disable remote loop */
3108
				ts->span.maintstat = DAHDI_MAINT_NONE;
3109
			}
3110
		} else
3111
			ts->loopdowncnt = 0;
3112
	}
3113
3114
	if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
3115
		for (x=0,j=0;x < ts->span.channels;x++)
3116
			if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
3117
#ifdef CONFIG_DAHDI_NET
3118
					||
3119
			    (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
3120
#endif
3121
			    )
3122
				j++;
3123
		if (!j)
3124
			alarms |= DAHDI_ALARM_NOTOPEN;
3125
	}
3126
3127
	/* Loss of Frame Alignment */
3128
	if (c & 0x20) {
3129
		if (ts->alarmcount >= alarmdebounce) {
3130
3131
			/* Disable Slip Interrupts */
3132
			e = __t4_framer_in(wc, span, 0x17);
3133
			__t4_framer_out(wc, span, 0x17, (e|0x03));
3134
3135
			alarms |= DAHDI_ALARM_RED;
3136
		} else {
3137
			if (unlikely(debug && !ts->alarmcount)) {
3138
				/* starting to debounce LOF/LFA */
3139
				dev_info(&wc->dev->dev, "opvxd115: LOF/LFA "
3140
					"detected on span %d but debouncing "
3141
					"for %d ms\n", span + 1,
3142
					alarmdebounce);
3143
			}
3144
			ts->alarmcount++;
3145
		}
3146
	} else
3147
		ts->alarmcount = 0;
3148
3149
	/* Loss of Signal */
3150
	if (c & 0x80) {
3151
		if (ts->losalarmcount >= losalarmdebounce) {
3152
			/* Disable Slip Interrupts */
3153
			e = __t4_framer_in(wc, span, 0x17);
3154
			__t4_framer_out(wc, span, 0x17, (e|0x03));
3155
3156
			alarms |= DAHDI_ALARM_RED;
3157
		} else {
3158
			if (unlikely(debug && !ts->losalarmcount)) {
3159
				/* starting to debounce LOS */
3160
				dev_info(&wc->dev->dev, "opvxd115: LOS "
3161
					"detected on span %d but debouncing "
3162
					"for %d ms\n",
3163
					span + 1, losalarmdebounce);
3164
			}
3165
			ts->losalarmcount++;
3166
		}
3167
	} else
3168
		ts->losalarmcount = 0;
3169
3170
	/* Alarm Indication Signal */
3171
	if (c & 0x40) {
3172
		if (ts->aisalarmcount >= aisalarmdebounce)
3173
			alarms |= DAHDI_ALARM_BLUE;
3174
		else {
3175
			if (unlikely(debug && !ts->aisalarmcount)) {
3176
				/* starting to debounce AIS */
3177
				dev_info(&wc->dev->dev, "opvxd115: AIS "
3178
					"detected on span %d but debouncing "
3179
					"for %d ms\n",
3180
					span + 1, aisalarmdebounce);
3181
			}
3182
			ts->aisalarmcount++;
3183
		}
3184
	} else
3185
		ts->aisalarmcount = 0;
3186
3187
#ifdef DAHDI_SPAN_OPS
3188
	/* Add detailed alarm status information to a red alarm state */
3189
	if (alarms & DAHDI_ALARM_RED) {
3190
		if (c & FRS0_LOS)
3191
			alarms |= DAHDI_ALARM_LOS;
3192
		if (c & FRS0_LFA)
3193
			alarms |= DAHDI_ALARM_LFA;
3194
		if (c & FRS0_LMFA)
3195
			alarms |= DAHDI_ALARM_LMFA;
3196
	}
3197
3198
	if (unlikely(debug)) {
3199
		/* Check to ensure the xmit line isn't shorted */
3200
		if (unlikely(d & FRS1_XLS)) {
3201
			dev_info(&wc->dev->dev,
3202
				"Detected a possible hardware malfunction"\
3203
				" this card may need servicing\n");
3204
		}
3205
	}
3206
#endif
3207
3208
	if (((!ts->span.alarms) && alarms) || 
3209
	    (ts->span.alarms && (!alarms))) 
3210
		set_bit(T4_CHECK_TIMING, &wc->checkflag);
3211
3212
	/* Keep track of recovering */
3213
	if ((!alarms) && ts->span.alarms) 
3214
		ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
3215
	if (ts->alarmtimer)
3216
		alarms |= DAHDI_ALARM_RECOVER;
3217
3218
	/* If receiving alarms, go into Yellow alarm state */
3219
	if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
3220
		/* We manually do yellow alarm to handle RECOVER and NOTOPEN, otherwise it's auto anyway */
3221
		unsigned char fmr4;
3222
		fmr4 = __t4_framer_in(wc, span, 0x20);
3223
		__t4_framer_out(wc, span, 0x20, fmr4 | 0x20);
3224
		dev_info(&wc->dev->dev, "Setting yellow alarm span %d\n",
3225
								span+1);
3226
		ts->spanflags |= FLAG_SENDINGYELLOW;
3227
	} else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
3228
		unsigned char fmr4;
3229
		/* We manually do yellow alarm to handle RECOVER  */
3230
		fmr4 = __t4_framer_in(wc, span, 0x20);
3231
		__t4_framer_out(wc, span, 0x20, fmr4 & ~0x20);
3232
		dev_info(&wc->dev->dev, "Clearing yellow alarm span %d\n",
3233
								span+1);
3234
3235
		/* Re-enable timing slip interrupts */
3236
		e = __t4_framer_in(wc, span, 0x17);
3237
3238
		__t4_framer_out(wc, span, 0x17, (e & ~(0x03)));
3239
3240
		ts->spanflags &= ~FLAG_SENDINGYELLOW;
3241
	}
3242
3243
	/* Re-check the timing source when we enter/leave alarm, not withstanding
3244
	   yellow alarm */
3245
	if (c & 0x10) { /* receiving yellow (RAI) */
3246
		if (ts->yelalarmcount >= yelalarmdebounce)
3247
			alarms |= DAHDI_ALARM_YELLOW;
3248
		else {
3249
			if (unlikely(debug && !ts->yelalarmcount)) {
3250
				/* starting to debounce AIS */
3251
				dev_info(&wc->dev->dev, "wct%dxxp: yellow "
3252
					"(RAI) detected on span %d but "
3253
					"debouncing for %d ms\n",
3254
					wc->numspans, span + 1,
3255
					yelalarmdebounce);
3256
			}
3257
			ts->yelalarmcount++;
3258
		}
3259
	} else
3260
		ts->yelalarmcount = 0;
3261
3262
	if (ts->span.mainttimer || ts->span.maintstat) 
3263
		alarms |= DAHDI_ALARM_LOOPBACK;
3264
	ts->span.alarms = alarms;
3265
	spin_unlock_irqrestore(&wc->reglock, flags);
3266
	dahdi_alarm_notify(&ts->span);
3267
}
3268
3269
static void t4_do_counters(struct t4 *wc)
3270
{
3271
	int span;
3272
	for (span=0;span<wc->numspans;span++) {
3273
		struct t4_span *ts = wc->tspans[span];
3274
		int docheck=0;
3275
3276
		spin_lock(&wc->reglock);
3277
		if (ts->loopupcnt || ts->loopdowncnt || ts->alarmcount
3278
			|| ts->losalarmcount || ts->aisalarmcount
3279
			|| ts->yelalarmcount)
3280
			docheck++;
3281
3282
		if (ts->alarmtimer) {
3283
			if (!--ts->alarmtimer) {
3284
				docheck++;
3285
				ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
3286
			}
3287
		}
3288
		spin_unlock(&wc->reglock);
3289
		if (docheck) {
3290
			t4_check_alarms(wc, span);
3291
			dahdi_alarm_notify(&ts->span);
3292
		}
3293
	}
3294
}
3295
3296
static inline void __handle_leds(struct t4 *wc)
3297
{
3298
	int x;
3299
3300
	wc->blinktimer++;
3301
	for (x=0;x<wc->numspans;x++) {
3302
		struct t4_span *ts = wc->tspans[x];
3303
		if (ts->span.flags & DAHDI_FLAG_RUNNING) {
3304
			if ((ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) || ts->losalarmcount) {
3305
#ifdef FANCY_ALARM
3306
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
3307
					__t4_set_led(wc, x, WC_RED);
3308
				}
3309
				if (wc->blinktimer == 0xf) {
3310
					__t4_set_led(wc, x, WC_OFF);
3311
				}
3312
#else
3313
				if (wc->blinktimer == 160) {
3314
					__t4_set_led(wc, x, WC_RED);
3315
				} else if (wc->blinktimer == 480) {
3316
					__t4_set_led(wc, x, WC_OFF);
3317
				}
3318
#endif
3319
			} else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
3320
				/* Yellow Alarm */
3321
				__t4_set_led(wc, x, WC_YELLOW);
3322
			} else if (ts->span.mainttimer || ts->span.maintstat) {
3323
#ifdef FANCY_ALARM
3324
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
3325
					__t4_set_led(wc, x, WC_GREEN);
3326
				}
3327
				if (wc->blinktimer == 0xf) {
3328
					__t4_set_led(wc, x, WC_OFF);
3329
				}
3330
#else
3331
				if (wc->blinktimer == 160) {
3332
					__t4_set_led(wc, x, WC_GREEN);
3333
				} else if (wc->blinktimer == 480) {
3334
					__t4_set_led(wc, x, WC_OFF);
3335
				}
3336
#endif
3337
			} else {
3338
				/* No Alarm */
3339
				__t4_set_led(wc, x, WC_GREEN);
3340
			}
3341
		}	else
3342
				__t4_set_led(wc, x, WC_OFF);
3343
3344
	}
3345
#ifdef FANCY_ALARM
3346
	if (wc->blinktimer == 0xf) {
3347
		wc->blinktimer = -1;
3348
		wc->alarmpos++;
3349
		if (wc->alarmpos >= (sizeof(altab) / sizeof(altab[0])))
3350
			wc->alarmpos = 0;
3351
	}
3352
#else
3353
	if (wc->blinktimer == 480)
3354
		wc->blinktimer = 0;
3355
#endif
3356
}
3357
3358
static inline void t4_framer_interrupt(struct t4 *wc, int span)
3359
{
3360
	unsigned char gis, isr0, isr1, isr2, isr3, isr4;
3361
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
3362
	/* Check interrupts for a given span */
3363
	unsigned char reg;
3364
#endif
3365
	int readsize = -1;
3366
	struct t4_span *ts = wc->tspans[span];
3367
	struct dahdi_chan *sigchan;
3368
	unsigned long flags;
3369
3370
3371
	/* 1st gen cards isn't used interrupts */
3372
	gis = t4_framer_in(wc, span, FRMR_GIS);
3373
	isr0 = (gis & FRMR_GIS_ISR0) ? t4_framer_in(wc, span, FRMR_ISR0) : 0;
3374
	isr1 = (gis & FRMR_GIS_ISR1) ? t4_framer_in(wc, span, FRMR_ISR1) : 0;
3375
	isr2 = (gis & FRMR_GIS_ISR2) ? t4_framer_in(wc, span, FRMR_ISR2) : 0;
3376
	isr3 = (gis & FRMR_GIS_ISR3) ? t4_framer_in(wc, span, FRMR_ISR3) : 0;
3377
	isr4 = (gis & FRMR_GIS_ISR4) ? t4_framer_in(wc, span, FRMR_ISR4) : 0;
3378
3379
 	if ((debug & DEBUG_FRAMER) && !(isr3 & ISR3_SEC)) {
3380
 		dev_info(&wc->dev->dev, "gis: %02x, isr0: %02x, isr1: %02x, "\
3381
 			"isr2: %02x, isr3: %08x, isr4: %02x, intcount=%u\n",
3382
 			gis, isr0, isr1, isr2, isr3, isr4, wc->intcount);
3383
 	}
3384
 
3385
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
3386
	/* Collect performance counters once per second */
3387
 	if (isr3 & ISR3_SEC) {
3388
 		ts->span.count.fe += t4_framer_in(wc, span, FECL_T);
3389
 		ts->span.count.crc4 += t4_framer_in(wc, span, CEC1L_T);
3390
 		ts->span.count.cv += t4_framer_in(wc, span, CVCL_T);
3391
 		ts->span.count.ebit += t4_framer_in(wc, span, EBCL_T);
3392
 		ts->span.count.be += t4_framer_in(wc, span, BECL_T);
3393
 		ts->span.count.prbs = t4_framer_in(wc, span, FRS1_T);
3394
 	}
3395
 
3396
	/* Collect errored second counter once per second */
3397
 	if (isr3 & ISR3_ES) {
3398
 		ts->span.count.errsec += 1;
3399
 	}
3400
 
3401
 	if (isr3 & 0x08) {
3402
 		reg = t4_framer_in(wc, span, FRS1_T);
3403
		dev_info(&wc->dev->dev, "FRS1: %d\n", reg);
3404
 		if (reg & LLBDD) {
3405
 			dev_info(&wc->dev->dev, "Line loop-back activation "\
3406
 					"signal detected with status: %01d "\
3407
 					"for span %d\n", reg & LLBAD, span+1);
3408
 		}
3409
 	}
3410
#endif
3411
3412
	if (isr0)
3413
		t4_check_sigbits(wc, span);
3414
3415
	if (ts->spantype == TYPE_E1) {
3416
		/* E1 checks */
3417
		if ((isr3 & 0x38) || isr2 || isr1)
3418
			t4_check_alarms(wc, span);
3419
	} else {
3420
		/* T1 checks */
3421
		if (isr2 || (isr3 & 0x08))
3422
			t4_check_alarms(wc, span);
3423
	}
3424
	if (!ts->span.alarms) {
3425
		if ((isr3 & 0x3) || (isr4 & 0xc0))
3426
			ts->span.count.timingslips++;
3427
3428
		if (debug & DEBUG_MAIN) {
3429
			if (isr3 & 0x02)
3430
				dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
3431
					"slip NEGATIVE on span %d\n",
3432
					span + 1);
3433
			if (isr3 & 0x01)
3434
				dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
3435
					"slip POSITIVE on span %d\n",
3436
					span + 1);
3437
			if (isr4 & 0x80)
3438
				dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
3439
					"slip POSITIVE on span %d\n",
3440
					span + 1);
3441
			if (isr4 & 0x40)
3442
				dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
3443
					"slip NEGATIVE on span %d\n",
3444
					span + 1);
3445
		}
3446
	} else
3447
		ts->span.count.timingslips = 0;
3448
3449
	spin_lock_irqsave(&wc->reglock, flags);
3450
	/* HDLC controller checks - receive side */
3451
	if (!ts->sigchan) {
3452
		spin_unlock_irqrestore(&wc->reglock, flags);
3453
		return;
3454
	}
3455
3456
	sigchan = ts->sigchan;
3457
	spin_unlock_irqrestore(&wc->reglock, flags);
3458
3459
	if (isr0 & FRMR_ISR0_RME) {
3460
		readsize = (t4_framer_in(wc, span, FRMR_RBCH) << 8) | t4_framer_in(wc, span, FRMR_RBCL);
3461
		if (debug & DEBUG_FRAMER)
3462
			dev_notice(&wc->dev->dev, "Received data length is %d "
3463
				"(%d)\n", readsize,
3464
				readsize & FRMR_RBCL_MAX_SIZE);
3465
		/* RPF isn't set on last part of frame */
3466
		if ((readsize > 0) && ((readsize &= FRMR_RBCL_MAX_SIZE) == 0))
3467
			readsize = FRMR_RBCL_MAX_SIZE + 1;
3468
	} else if (isr0 & FRMR_ISR0_RPF)
3469
		readsize = FRMR_RBCL_MAX_SIZE + 1;
3470
3471
	if (readsize > 0) {
3472
		int i;
3473
		unsigned char readbuf[FRMR_RBCL_MAX_SIZE + 1];
3474
3475
		if (debug & DEBUG_FRAMER)
3476
			dev_notice(&wc->dev->dev, "Framer %d: Got RPF/RME! "
3477
				"readsize is %d\n", sigchan->span->offset,
3478
				readsize);
3479
3480
		for (i = 0; i < readsize; i++)
3481
			readbuf[i] = t4_framer_in(wc, span, FRMR_RXFIFO);
3482
3483
		/* Tell the framer to clear the RFIFO */
3484
		t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC);
3485
3486
		if (debug & DEBUG_FRAMER) {
3487
			dev_notice(&wc->dev->dev, "RX(");
3488
			for (i = 0; i < readsize; i++)
3489
				dev_notice(&wc->dev->dev, "%s%02x",
3490
					(i ? " " : ""), readbuf[i]);
3491
			dev_notice(&wc->dev->dev, ")\n");
3492
		}
3493
3494
		if (isr0 & FRMR_ISR0_RME) {
3495
			/* Do checks for HDLC problems */
3496
			unsigned char rsis = readbuf[readsize-1];
3497
#if 0
3498
			unsigned int olddebug = debug;
3499
#endif
3500
			unsigned char rsis_reg = t4_framer_in(wc, span, FRMR_RSIS);
3501
3502
#if 0
3503
			if ((rsis != 0xA2) || (rsis != rsis_reg))
3504
				debug |= DEBUG_FRAMER;
3505
#endif
3506
3507
			++ts->frames_in;
3508
			if ((debug & DEBUG_FRAMER) && !(ts->frames_in & 0x0f))
3509
				dev_notice(&wc->dev->dev, "Received %d frames "
3510
					"on span %d\n", ts->frames_in, span);
3511
			if (debug & DEBUG_FRAMER)
3512
				dev_notice(&wc->dev->dev, "Received HDLC frame"
3513
					" %d.  RSIS = 0x%x (%x)\n",
3514
					ts->frames_in, rsis, rsis_reg);
3515
			if (!(rsis & FRMR_RSIS_CRC16)) {
3516
				if (debug & DEBUG_FRAMER)
3517
					dev_notice(&wc->dev->dev, "CRC check "
3518
							"failed %d\n", span);
3519
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_BADFCS);
3520
			} else if (rsis & FRMR_RSIS_RAB) {
3521
				if (debug & DEBUG_FRAMER)
3522
					dev_notice(&wc->dev->dev, "ABORT of "
3523
						"current frame due to "
3524
						"overflow %d\n", span);
3525
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
3526
			} else if (rsis & FRMR_RSIS_RDO) {
3527
				if (debug & DEBUG_FRAMER)
3528
					dev_notice(&wc->dev->dev, "HDLC "
3529
						"overflow occured %d\n",
3530
						span);
3531
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_OVERRUN);
3532
			} else if (!(rsis & FRMR_RSIS_VFR)) {
3533
				if (debug & DEBUG_FRAMER)
3534
					dev_notice(&wc->dev->dev, "Valid Frame"
3535
						" check failed on span %d\n",
3536
						span);
3537
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
3538
			} else {
3539
				dahdi_hdlc_putbuf(sigchan, readbuf, readsize - 1);
3540
				dahdi_hdlc_finish(sigchan);
3541
				if (debug & DEBUG_FRAMER)
3542
					dev_notice(&wc->dev->dev, "Received "
3543
						"valid HDLC frame on span %d"
3544
						"\n", span);
3545
			}
3546
#if 0
3547
			debug = olddebug;
3548
#endif
3549
		} else if (isr0 & FRMR_ISR0_RPF)
3550
			dahdi_hdlc_putbuf(sigchan, readbuf, readsize);
3551
	}
3552
3553
	/* Transmit side */
3554
	if (isr1 & FRMR_ISR1_XDU) {
3555
		if (debug & DEBUG_FRAMER)
3556
			dev_notice(&wc->dev->dev, "XDU: Resetting signal "
3557
					"controller!\n");
3558
		t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
3559
	} else if (isr1 & FRMR_ISR1_XPR) {
3560
		if (debug & DEBUG_FRAMER)
3561
			dev_notice(&wc->dev->dev, "Sigchan %d is %p\n",
3562
					sigchan->chanpos, sigchan);
3563
3564
		if (debug & DEBUG_FRAMER)
3565
			dev_notice(&wc->dev->dev, "Framer %d: Got XPR!\n",
3566
					sigchan->span->offset);
3567
		t4_hdlc_xmit_fifo(wc, span, ts);
3568
	}
3569
3570
	if (isr1 & FRMR_ISR1_ALLS) {
3571
		if (debug & DEBUG_FRAMER)
3572
			dev_notice(&wc->dev->dev, "ALLS received\n");
3573
	}
3574
}
3575
3576
#ifdef SUPPORT_GEN1
3577
DAHDI_IRQ_HANDLER(t4_interrupt)
3578
{
3579
	struct t4 *wc = dev_id;
3580
	unsigned long flags;
3581
	int x;
3582
	
3583
	unsigned int status;
3584
	unsigned int status2;
3585
3586
#if 0
3587
	if (wc->intcount < 20)
3588
		dev_notice(&wc->dev->dev, "Pre-interrupt\n");
3589
#endif
3590
	
3591
	/* Make sure it's really for us */
3592
	status = __t4_pci_in(wc, WC_INTR);
3593
3594
	/* Process framer interrupts */
3595
	status2 = t4_framer_in(wc, 0, FRMR_CIS);
3596
	if (status2 & 0x0f) {
3597
		for (x = 0; x < wc->numspans; ++x) {
3598
			if (status2 & (1 << x))
3599
				t4_framer_interrupt(wc, x);
3600
		}
3601
	}
3602
3603
	/* Ignore if it's not for us */
3604
	if (!status)
3605
		return IRQ_NONE;
3606
3607
	__t4_pci_out(wc, WC_INTR, 0);
3608
3609
	if (!wc->spansstarted) {
3610
		dev_notice(&wc->dev->dev, "Not prepped yet!\n");
3611
		return IRQ_NONE;
3612
	}
3613
3614
	wc->intcount++;
3615
#if 0
3616
	if (wc->intcount < 20)
3617
		dev_notice(&wc->dev->dev, "Got interrupt, status = %08x\n",
3618
				status);
3619
#endif		
3620
3621
	if (status & 0x3) {
3622
		t4_receiveprep(wc, status);
3623
		t4_transmitprep(wc, status);
3624
	}
3625
	
3626
#if 0
3627
	if ((wc->intcount < 10) || !(wc->intcount % 1000)) {
3628
		status2 = t4_framer_in(wc, 0, FRMR_CIS);
3629
		dev_notice(&wc->dev->dev, "Status2: %04x\n", status2);
3630
		for (x = 0;x<wc->numspans;x++) {
3631
			status2 = t4_framer_in(wc, x, FRMR_FRS0);
3632
			dev_notice(&wc->dev->dev, "FRS0/%d: %04x\n", x,
3633
					status2);
3634
		}
3635
	}
3636
#endif
3637
	t4_do_counters(wc);
3638
3639
	x = wc->intcount & 15 /* 63 */;
3640
	switch(x) {
3641
	case 0:
3642
	case 1:
3643
	case 2:
3644
	case 3:
3645
		t4_check_sigbits(wc, x);
3646
		break;
3647
	case 4:
3648
	case 5:
3649
	case 6:
3650
	case 7:
3651
		t4_check_alarms(wc, x - 4);
3652
		break;
3653
	}
3654
3655
	spin_lock_irqsave(&wc->reglock, flags);
3656
3657
	__handle_leds(wc);
3658
3659
	if (test_bit(T4_CHECK_TIMING, &wc->checkflag))
3660
		__t4_set_timing_source_auto(wc);
3661
3662
	spin_unlock_irqrestore(&wc->reglock, flags);
3663
3664
	return IRQ_RETVAL(1);
3665
}
3666
#endif
3667
3668
static int t4_allocate_buffers(struct t4 *wc, int numbufs, volatile unsigned int **oldalloc, dma_addr_t *oldwritedma)
3669
{
3670
	volatile unsigned int *alloc;
3671
	dma_addr_t writedma;
3672
3673
	alloc =
3674
		/* 32 channels, Double-buffer, Read/Write, 4 spans */
3675
		(unsigned int *)pci_alloc_consistent(wc->dev, numbufs * T4_BASE_SIZE * 2, &writedma);
3676
3677
	if (!alloc) {
3678
		dev_notice(&wc->dev->dev, "wct%dxxp: Unable to allocate "
3679
				"DMA-able memory\n", wc->numspans);
3680
		return -ENOMEM;
3681
	}
3682
3683
	if (oldwritedma)
3684
		*oldwritedma = wc->writedma;
3685
	if (oldalloc)
3686
		*oldalloc = wc->writechunk;
3687
3688
	wc->writechunk = alloc;
3689
	wc->writedma = writedma;
3690
3691
	/* Read is after the whole write piece (in words) */
3692
	wc->readchunk = wc->writechunk + (T4_BASE_SIZE * numbufs) / 4;
3693
	
3694
	/* Same thing but in bytes...  */
3695
	wc->readdma = wc->writedma + (T4_BASE_SIZE * numbufs);
3696
3697
	wc->numbufs = numbufs;
3698
	
3699
	/* Initialize Write/Buffers to all blank data */
3700
	memset((void *)wc->writechunk,0x00, T4_BASE_SIZE * numbufs);
3701
	memset((void *)wc->readchunk,0xff, T4_BASE_SIZE * numbufs);
3702
3703
	dev_notice(&wc->dev->dev, "DMA memory base of size %d at %p.  Read: "
3704
		"%p and Write %p\n", numbufs * T4_BASE_SIZE * 2,
3705
		wc->writechunk, wc->readchunk, wc->writechunk);
3706
3707
	return 0;
3708
}
3709
3710
static void t4_increase_latency(struct t4 *wc, int newlatency)
3711
{
3712
	unsigned long flags;
3713
	volatile unsigned int *oldalloc;
3714
	dma_addr_t oldaddr;
3715
	int oldbufs;
3716
3717
	spin_lock_irqsave(&wc->reglock, flags);
3718
3719
	__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3720
	/* Acknowledge any pending interrupts */
3721
	__t4_pci_out(wc, WC_INTR, 0x00000000);
3722
3723
	__t4_pci_in(wc, WC_VERSION);
3724
3725
	oldbufs = wc->numbufs;
3726
3727
	if (t4_allocate_buffers(wc, newlatency, &oldalloc, &oldaddr)) {
3728
		dev_info(&wc->dev->dev, "Error allocating latency buffers for "
3729
				"latency of %d\n", newlatency);
3730
		__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3731
		spin_unlock_irqrestore(&wc->reglock, flags);
3732
		return;
3733
	}
3734
3735
	__t4_pci_out(wc, WC_RDADDR, wc->readdma);
3736
	__t4_pci_out(wc, WC_WRADDR, wc->writedma);
3737
3738
	__t4_pci_in(wc, WC_VERSION);
3739
3740
	__t4_pci_out(wc, 5, (ms_per_irq << 16) | newlatency);
3741
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3742
3743
	__t4_pci_in(wc, WC_VERSION);
3744
3745
	wc->rxident = 0;
3746
	wc->lastindex = 0;
3747
3748
	spin_unlock_irqrestore(&wc->reglock, flags);
3749
3750
	pci_free_consistent(wc->dev, T4_BASE_SIZE * oldbufs * 2, (void *)oldalloc, oldaddr);
3751
3752
	dev_info(&wc->dev->dev, "Increased latency to %d\n", newlatency);
3753
3754
}
3755
3756
static void t4_isr_bh(unsigned long data)
3757
{
3758
	struct t4 *wc = (struct t4 *)data;
3759
3760
	if (test_bit(T4_CHANGE_LATENCY, &wc->checkflag)) {
3761
		if (wc->needed_latency != wc->numbufs) {
3762
			t4_increase_latency(wc, wc->needed_latency);
3763
			clear_bit(T4_CHANGE_LATENCY, &wc->checkflag);
3764
		}
3765
	}
3766
#ifdef VPM_SUPPORT
3767
	if (wc->vpm) {
3768
		if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) {
3769
			if (wc->vpm450m) {
3770
				/* How stupid is it that the octasic can't generate an
3771
				   interrupt when there's a tone, in spite of what their
3772
				   documentation says? */
3773
				t4_check_vpm450(wc);
3774
			} else
3775
				t4_check_vpm400(wc, wc->vpm400checkstatus);
3776
		}
3777
	}
3778
#endif
3779
}
3780
3781
DAHDI_IRQ_HANDLER(t4_interrupt_gen2)
3782
{
3783
	struct t4 *wc = dev_id;
3784
	unsigned int status;
3785
	unsigned char rxident, expected;
3786
	
3787
	/* Check this first in case we get a spurious interrupt */
3788
	if (unlikely(test_bit(T4_STOP_DMA, &wc->checkflag))) {
3789
		/* Stop DMA cleanly if requested */
3790
		wc->dmactrl = 0x0;
3791
		t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3792
		/* Acknowledge any pending interrupts */
3793
		t4_pci_out(wc, WC_INTR, 0x00000000);
3794
		spin_lock(&wc->reglock);
3795
		__t4_set_sclk_src(wc, WC_SELF, 0, 0);
3796
		spin_unlock(&wc->reglock);
3797
		return IRQ_RETVAL(1);
3798
	}
3799
3800
	/* Make sure it's really for us */
3801
	status = __t4_pci_in(wc, WC_INTR);
3802
3803
	/* Ignore if it's not for us */
3804
	if (!(status & 0x7)) {
3805
		return IRQ_NONE;
3806
	}
3807
3808
#ifdef ENABLE_WORKQUEUES
3809
	__t4_pci_out(wc, WC_INTR, status & 0x00000008);
3810
#endif
3811
3812
	if (unlikely(!wc->spansstarted)) {
3813
		dev_info(&wc->dev->dev, "Not prepped yet!\n");
3814
		return IRQ_NONE;
3815
	}
3816
3817
	wc->intcount++;
3818
3819
	if ((wc->flags & FLAG_5THGEN) && (status & 0x2)) {
3820
		rxident = (status >> 16) & 0x7f;
3821
		expected = (wc->rxident + ms_per_irq) % 128;
3822
	
3823
		if ((rxident != expected) && !test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
3824
			int needed_latency;
3825
			int smallest_max;
3826
3827
			if (debug & DEBUG_MAIN)
3828
				dev_warn(&wc->dev->dev, "Missed interrupt.  "
3829
					"Expected ident of %d and got ident "
3830
					"of %d\n", expected, rxident);
3831
3832
			if (test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
3833
				dev_info(&wc->dev->dev,
3834
					"Should have ignored latency\n");
3835
			}
3836
			if (rxident > wc->rxident) {
3837
				needed_latency = rxident - wc->rxident;
3838
			} else {
3839
				needed_latency = (128 - wc->rxident) + rxident;
3840
			}
3841
3842
			needed_latency += 1;
3843
3844
			smallest_max = (max_latency >= GEN5_MAX_LATENCY) ? GEN5_MAX_LATENCY : max_latency;
3845
3846
			if (needed_latency > smallest_max) {
3847
				dev_info(&wc->dev->dev, "Truncating latency "
3848
					"request to %d instead of %d\n",
3849
					smallest_max, needed_latency);
3850
				needed_latency = smallest_max;
3851
			}
3852
3853
			if (needed_latency > wc->numbufs) {
3854
				int x;
3855
3856
				dev_info(&wc->dev->dev, "Need to increase "
3857
					"latency.  Estimated latency should "
3858
					"be %d\n", needed_latency);
3859
				for (x = 0; x < wc->numspans; x++)
3860
					wc->ddev->irqmisses++;
3861
				wc->needed_latency = needed_latency;
3862
				__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3863
				set_bit(T4_CHANGE_LATENCY, &wc->checkflag);
3864
				goto out;
3865
			}
3866
		}
3867
	
3868
		wc->rxident = rxident;
3869
	}
3870
3871
	if (unlikely((wc->intcount < 20)))
3872
3873
		dev_info(&wc->dev->dev, "2G: Got interrupt, status = %08x, "
3874
			"CIS = %04x\n", status, t4_framer_in(wc, 0, FRMR_CIS));
3875
3876
	if (likely(status & 0x2)) {
3877
#ifdef ENABLE_WORKQUEUES
3878
		int cpus = num_online_cpus();
3879
		atomic_set(&wc->worklist, wc->numspans);
3880
		if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
3881
			t4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
3882
		else
3883
			atomic_dec(&wc->worklist);
3884
#else
3885
#if 1
3886
		unsigned int reg5 = __t4_pci_in(wc, 5);
3887
		if (wc->intcount < 20) {
3888
3889
			dev_info(&wc->dev->dev, "Reg 5 is %08x\n", reg5);
3890
		}
3891
#endif
3892
3893
		if (wc->flags & FLAG_5THGEN) {
3894
			unsigned int current_index = (reg5 >> 8) & 0x7f;
3895
3896
			while (((wc->lastindex + 1) % wc->numbufs) != current_index) {
3897
				wc->lastindex = (wc->lastindex + 1) % wc->numbufs;
3898
				setup_chunks(wc, wc->lastindex);
3899
				t4_prep_gen2(wc);
3900
			}
3901
		} else {
3902
			t4_prep_gen2(wc);
3903
		}
3904
3905
#endif
3906
		t4_do_counters(wc);
3907
		spin_lock(&wc->reglock);
3908
		__handle_leds(wc);
3909
		spin_unlock(&wc->reglock);
3910
3911
	}
3912
3913
	if (unlikely(status & 0x1)) {
3914
		unsigned char cis;
3915
3916
		cis = t4_framer_in(wc, 0, FRMR_CIS);
3917
		if (cis & FRMR_CIS_GIS1)
3918
			t4_framer_interrupt(wc, 0);
3919
		if (cis & FRMR_CIS_GIS2)
3920
			t4_framer_interrupt(wc, 1);
3921
		if (cis & FRMR_CIS_GIS3)
3922
			t4_framer_interrupt(wc, 2);
3923
		if (cis & FRMR_CIS_GIS4)
3924
			t4_framer_interrupt(wc, 3);
3925
	}
3926
3927
	if (wc->vpm && vpmdtmfsupport) {
3928
		if (wc->vpm450m) {
3929
			/* How stupid is it that the octasic can't generate an
3930
			   interrupt when there's a tone, in spite of what their
3931
			   documentation says? */
3932
			if (!(wc->intcount & 0xf)) {
3933
				set_bit(T4_CHECK_VPM, &wc->checkflag);
3934
			}
3935
		} else if ((status & 0xff00) != 0xff00) {
3936
			wc->vpm400checkstatus = (status & 0xff00) >> 8;
3937
			set_bit(T4_CHECK_VPM, &wc->checkflag);
3938
		}
3939
	}
3940
3941
	spin_lock(&wc->reglock);
3942
3943
	if (unlikely(test_bit(T4_CHECK_TIMING, &wc->checkflag))) {
3944
		__t4_set_timing_source_auto(wc);
3945
	}
3946
3947
	spin_unlock(&wc->reglock);
3948
3949
out:
3950
	if (unlikely(test_bit(T4_CHANGE_LATENCY, &wc->checkflag) || test_bit(T4_CHECK_VPM, &wc->checkflag)))
3951
		tasklet_schedule(&wc->t4_tlet);
3952
3953
#ifndef ENABLE_WORKQUEUES
3954
	__t4_pci_out(wc, WC_INTR, 0);
3955
#endif	
3956
3957
	return IRQ_RETVAL(1);
3958
}
3959
3960
#ifdef SUPPORT_GEN1
3961
static int t4_reset_dma(struct t4 *wc)
3962
{
3963
	/* Turn off DMA and such */
3964
	wc->dmactrl = 0x0;
3965
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3966
	t4_pci_out(wc, WC_COUNT, 0);
3967
	t4_pci_out(wc, WC_RDADDR, 0);
3968
	t4_pci_out(wc, WC_WRADDR, 0);
3969
	t4_pci_out(wc, WC_INTR, 0);
3970
	/* Turn it all back on */
3971
	t4_pci_out(wc, WC_RDADDR, wc->readdma);
3972
	t4_pci_out(wc, WC_WRADDR, wc->writedma);
3973
	t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
3974
	t4_pci_out(wc, WC_INTR, 0);
3975
#ifdef VPM_SUPPORT
3976
	wc->dmactrl = 0xc0000000 | (1 << 29) | wc->vpm;
3977
#else	
3978
	wc->dmactrl = 0xc0000000 | (1 << 29);
3979
#endif
3980
	if (noburst)
3981
		wc->dmactrl |= (1 << 26);
3982
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3983
	return 0;
3984
}
3985
#endif
3986
3987
#ifdef VPM_SUPPORT
3988
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold)
3989
{
3990
	unsigned int x;
3991
3992
	for (x = 0; x < 8; x++) {
3993
		t4_vpm_out(wc, x, 0xC4, (threshold >> 8) & 0xFF);
3994
		t4_vpm_out(wc, x, 0xC5, (threshold & 0xFF));
3995
	}
3996
	dev_info(&wc->dev->dev, "VPM: DTMF threshold set to %d\n", threshold);
3997
}
3998
3999
static unsigned int t4_vpm_mask(int chip)
4000
{
4001
	unsigned int mask=0;
4002
	switch(vpmspans) {
4003
	case 4:
4004
		mask = 0x55555555 << (chip >> 2);
4005
		break;
4006
	case 2:
4007
		mask = 0x11111111 << (chip >> 1);
4008
		break;
4009
	case 1:
4010
		mask = 0x01010101 << chip;
4011
		break;
4012
	}
4013
	return mask;
4014
}
4015
4016
static int t4_vpm_spanno(int chip)
4017
{
4018
	int spanno = 0;
4019
	switch(vpmspans) {
4020
	case 4:
4021
		spanno = chip & 0x3;
4022
		break;
4023
	case 2:
4024
		spanno = chip & 0x1;
4025
		break;
4026
	/* Case 1 is implicit */
4027
	}
4028
	return spanno;
4029
}
4030
4031
static int t4_vpm_echotail(void)
4032
{
4033
	int echotail = 0x01ff;
4034
	switch(vpmspans) {
4035
	case 4:
4036
		echotail = 0x007f;
4037
		break;
4038
	case 2:
4039
		echotail = 0x00ff;
4040
		break;
4041
	/* Case 1 is implicit */
4042
	}
4043
	return echotail;
4044
}
4045
4046
static void t4_vpm450_init(struct t4 *wc)
4047
{
4048
	unsigned int check1, check2;
4049
	int laws[1] = { 0, };
4050
	int x;
4051
	unsigned int vpm_capacity;
4052
	struct firmware embedded_firmware;
4053
	const struct firmware *firmware = &embedded_firmware;
4054
#if !defined(HOTPLUG_FIRMWARE)
4055
	extern void _binary_dahdi_fw_oct6114_032_bin_size;
4056
	extern void _binary_dahdi_fw_oct6114_064_bin_size;
4057
	extern void _binary_dahdi_fw_oct6114_128_bin_size;
4058
	extern u8 _binary_dahdi_fw_oct6114_032_bin_start[];
4059
	extern u8 _binary_dahdi_fw_oct6114_064_bin_start[];
4060
	extern u8 _binary_dahdi_fw_oct6114_128_bin_start[];
4061
#else
4062
	static const char oct032_firmware[] = "dahdi-fw-oct6114-032.bin";
4063
	static const char oct064_firmware[] = "dahdi-fw-oct6114-064.bin";
4064
	static const char oct128_firmware[] = "dahdi-fw-oct6114-128.bin";
4065
#endif
4066
4067
	if (!vpmsupport) {
4068
		dev_info(&wc->dev->dev, "VPM450: Support Disabled\n");
4069
		return;
4070
	}
4071
4072
	/* Turn on GPIO/DATA mux if supported */
4073
	t4_gpio_setdir(wc, (1 << 24), (1 << 24));
4074
	__t4_raw_oct_out(wc, 0x000a, 0x5678);
4075
	__t4_raw_oct_out(wc, 0x0004, 0x1234);
4076
	check1 = __t4_raw_oct_in(wc, 0x0004);
4077
	check2 = __t4_raw_oct_in(wc, 0x000a);
4078
	if (debug)
4079
		dev_notice(&wc->dev->dev, "OCT Result: %04x/%04x\n",
4080
			__t4_raw_oct_in(wc, 0x0004),
4081
			__t4_raw_oct_in(wc, 0x000a));
4082
	if (__t4_raw_oct_in(wc, 0x0004) != 0x1234) {
4083
		dev_notice(&wc->dev->dev, "VPM450: Not Present\n");
4084
		return;
4085
	}
4086
4087
	/* Setup alaw vs ulaw rules */
4088
	for (x = 0;x < wc->numspans; x++) {
4089
		if (wc->tspans[x]->span.channels > 24)
4090
			laws[x] = 1;
4091
	}
4092
4093
	switch ((vpm_capacity = get_vpm450m_capacity(wc))) {
4094
	case 32:
4095
#if defined(HOTPLUG_FIRMWARE)
4096
		if ((request_firmware(&firmware, oct032_firmware, &wc->dev->dev) != 0) ||
4097
		    !firmware) {
4098
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4099
				"available from userspace\n", oct032_firmware);
4100
			return;
4101
		}
4102
#else
4103
		embedded_firmware.data = _binary_dahdi_fw_oct6114_032_bin_start;
4104
		/* Yes... this is weird. objcopy gives us a symbol containing
4105
		   the size of the firmware, not a pointer a variable containing
4106
		   the size. The only way we can get the value of the symbol
4107
		   is to take its address, so we define it as a pointer and
4108
		   then cast that value to the proper type.
4109
	      */
4110
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_032_bin_size;
4111
#endif
4112
		break;
4113
	case 64:
4114
#if defined(HOTPLUG_FIRMWARE)
4115
		if ((request_firmware(&firmware, oct064_firmware, &wc->dev->dev) != 0) ||
4116
		    !firmware) {
4117
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4118
				"available from userspace\n", oct064_firmware);
4119
			return;
4120
		}
4121
#else
4122
		embedded_firmware.data = _binary_dahdi_fw_oct6114_064_bin_start;
4123
		/* Yes... this is weird. objcopy gives us a symbol containing
4124
		   the size of the firmware, not a pointer a variable containing
4125
		   the size. The only way we can get the value of the symbol
4126
		   is to take its address, so we define it as a pointer and
4127
		   then cast that value to the proper type.
4128
	      */
4129
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_064_bin_size;
4130
#endif
4131
		break;
4132
	case 128:
4133
#if defined(HOTPLUG_FIRMWARE)
4134
		if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
4135
		    !firmware) {
4136
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4137
				"available from userspace\n", oct128_firmware);
4138
			return;
4139
		}
4140
#else
4141
		embedded_firmware.data = _binary_dahdi_fw_oct6114_128_bin_start;
4142
		/* Yes... this is weird. objcopy gives us a symbol containing
4143
		   the size of the firmware, not a pointer a variable containing
4144
		   the size. The only way we can get the value of the symbol
4145
		   is to take its address, so we define it as a pointer and
4146
		   then cast that value to the proper type.
4147
		*/
4148
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_128_bin_size;
4149
#endif
4150
		break;
4151
	default:
4152
		dev_notice(&wc->dev->dev, "Unsupported channel capacity found "
4153
				"on VPM module (%d).\n", vpm_capacity);
4154
		return;
4155
	}
4156
4157
	if (!(wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) {
4158
		dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
4159
		if (firmware != &embedded_firmware)
4160
			release_firmware(firmware);
4161
		return;
4162
	}
4163
4164
	if (firmware != &embedded_firmware)
4165
		release_firmware(firmware);
4166
4167
	if (vpmdtmfsupport == -1) {
4168
		dev_notice(&wc->dev->dev, "VPM450: hardware DTMF disabled.\n");
4169
		vpmdtmfsupport = 0;
4170
	}
4171
4172
	wc->vpm = T4_VPM_PRESENT;
4173
	dev_info(&wc->dev->dev, "VPM450: Present and operational servicing %d "
4174
			"span(s)\n", wc->numspans);
4175
		
4176
}
4177
4178
static void t4_vpm400_init(struct t4 *wc)
4179
{
4180
	unsigned char reg;
4181
	unsigned int mask;
4182
	unsigned int ver;
4183
	unsigned int i, x, y, gen2vpm=0;
4184
4185
	if (!vpmsupport) {
4186
		dev_info(&wc->dev->dev, "VPM400: Support Disabled\n");
4187
		return;
4188
	}
4189
4190
	switch(vpmspans) {
4191
	case 4:
4192
	case 2:
4193
	case 1:
4194
		break;
4195
	default:
4196
		dev_notice(&wc->dev->dev, "VPM400: %d is not a valid vpmspans "
4197
				"value, using 4\n", vpmspans);
4198
		vpmspans = 1;
4199
	}
4200
4201
	for (x=0;x<8;x++) {
4202
		int spanno = t4_vpm_spanno(x);
4203
		struct t4_span *ts = wc->tspans[spanno];
4204
		int echotail = t4_vpm_echotail();
4205
4206
		ver = t4_vpm_in(wc, x, 0x1a0); /* revision */
4207
		if ((ver != 0x26) && (ver != 0x33)) {
4208
			if (x)
4209
				dev_notice(&wc->dev->dev,
4210
					"VPM400: Inoperable\n");
4211
			return;
4212
		}
4213
		if (ver == 0x33) {
4214
			if (x && !gen2vpm) {
4215
				dev_notice(&wc->dev->dev,
4216
					"VPM400: Inconsistent\n");
4217
				return;
4218
			}
4219
			ts->spanflags |= FLAG_VPM2GEN;
4220
			gen2vpm++;
4221
		} else if (gen2vpm) {
4222
			dev_notice(&wc->dev->dev,
4223
				"VPM400: Inconsistent\n");
4224
			return;
4225
		}
4226
4227
4228
		/* Setup GPIO's */
4229
		for (y=0;y<4;y++) {
4230
			t4_vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
4231
			t4_vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
4232
			t4_vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
4233
		}
4234
4235
		/* Setup TDM path - sets fsync and tdm_clk as inputs */
4236
		reg = t4_vpm_in(wc, x, 0x1a3); /* misc_con */
4237
		t4_vpm_out(wc, x, 0x1a3, reg & ~2);
4238
4239
		/* Setup timeslots */
4240
		t4_vpm_out(wc, x, 0x02f, 0x20 | (spanno << 3)); 
4241
4242
		/* Setup Echo length (128 taps) */
4243
		t4_vpm_out(wc, x, 0x022, (echotail >> 8));
4244
		t4_vpm_out(wc, x, 0x023, (echotail & 0xff));
4245
		
4246
		/* Setup the tdm channel masks for all chips*/
4247
		mask = t4_vpm_mask(x);
4248
		for (i = 0; i < 4; i++)
4249
			t4_vpm_out(wc, x, 0x30 + i, (mask >> (i << 3)) & 0xff);
4250
4251
		/* Setup convergence rate */
4252
		reg = t4_vpm_in(wc,x,0x20);
4253
		reg &= 0xE0;
4254
		if (ts->spantype == TYPE_E1) {
4255
			if (x < vpmspans)
4256
				dev_info(&wc->dev->dev, "VPM400: Span %d "
4257
						"A-law mode\n", spanno);
4258
			reg |= 0x01;
4259
		} else {
4260
			if (x < vpmspans)
4261
				dev_info(&wc->dev->dev, "VPM400: Span %d "
4262
						"U-law mode\n", spanno);
4263
			reg &= ~0x01;
4264
		}
4265
		t4_vpm_out(wc,x,0x20,(reg | 0x20));
4266
		
4267
		/* Initialize echo cans */
4268
		for (i = 0 ; i < MAX_TDM_CHAN; i++) {
4269
			if (mask & (0x00000001 << i))
4270
				t4_vpm_out(wc,x,i,0x00);
4271
		}
4272
4273
		wait_a_little();
4274
4275
		/* Put in bypass mode */
4276
		for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
4277
			if (mask & (0x00000001 << i)) {
4278
				t4_vpm_out(wc,x,i,0x01);
4279
			}
4280
		}
4281
4282
		/* Enable bypass */
4283
		for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
4284
			if (mask & (0x00000001 << i))
4285
				t4_vpm_out(wc,x,0x78 + i,0x01);
4286
		}
4287
      
4288
		/* set DTMF detection threshold */
4289
		t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
4290
4291
		/* Enable DTMF detectors (always DTMF detect all spans) */
4292
		for (i = 0; i < MAX_DTMF_DET; i++) {
4293
			t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 0 : 1));
4294
		}
4295
		for (i = 0x34; i < 0x38; i++)
4296
			t4_vpm_out(wc, x, i, 0x00);
4297
		for (i = 0x3C; i < 0x40; i++)
4298
			t4_vpm_out(wc, x, i, 0x00);
4299
4300
		for (i = 0x48; i < 0x4B; i++)
4301
			t4_vpm_out(wc, x, i, 0x00);
4302
		for (i = 0x50; i < 0x53; i++)
4303
			t4_vpm_out(wc, x, i, 0x00);
4304
		for (i = 0xB8; i < 0xBE; i++)
4305
			t4_vpm_out(wc, x, i, 0xFF);
4306
		if (gen2vpm) {
4307
			for (i = 0xBE; i < 0xC0; i++)
4308
				t4_vpm_out(wc, x, i, 0xFF);
4309
		} else {
4310
			for (i = 0xBE; i < 0xC0; i++)
4311
				t4_vpm_out(wc, x, i, 0x00);
4312
		}
4313
		for (i = 0xC0; i < 0xC4; i++)
4314
			t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA);
4315
4316
	} 
4317
	if (vpmdtmfsupport == -1) {
4318
		dev_info(&wc->dev->dev, "VPM400: hardware DTMF enabled.\n");
4319
		vpmdtmfsupport = 0;
4320
	}
4321
	dev_info(&wc->dev->dev, "VPM400%s: Present and operational servicing "
4322
		"%d span(s)\n", (gen2vpm ? " (2nd Gen)" : ""), wc->numspans);
4323
	wc->vpm = T4_VPM_PRESENT;
4324
}
4325
4326
#endif
4327
4328
static void t4_tsi_reset(struct t4 *wc) 
4329
{
4330
	int x;
4331
	for (x=0;x<128;x++) {
4332
		wc->dmactrl &= ~0x00007fff;
4333
		wc->dmactrl |= (0x00004000 | (x << 7));
4334
		t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4335
	}
4336
	wc->dmactrl &= ~0x00007fff;
4337
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4338
}
4339
4340
/* Note that channels here start from 1 */
4341
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan)
4342
{
4343
	unsigned long flags;
4344
	int fromts, tots;
4345
4346
	fromts = (fromspan << 5) |(fromchan);
4347
	tots = (tospan << 5) | (tochan);
4348
4349
	if (!wc->t1e1) {
4350
		fromts += 4;
4351
		tots += 4;
4352
	}
4353
	spin_lock_irqsave(&wc->reglock, flags);
4354
	wc->dmactrl &= ~0x00007fff;
4355
	wc->dmactrl |= (0x00004000 | (tots << 7) | (fromts));
4356
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4357
	wc->dmactrl &= ~0x00007fff;
4358
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4359
	spin_unlock_irqrestore(&wc->reglock, flags);
4360
}
4361
4362
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan)
4363
{
4364
	unsigned long flags;
4365
	int tots;
4366
4367
	tots = (tospan << 5) | (tochan);
4368
4369
	if (!wc->t1e1) 
4370
		tots += 4;
4371
	spin_lock_irqsave(&wc->reglock, flags);
4372
	wc->dmactrl &= ~0x00007fff;
4373
	wc->dmactrl |= (0x00004000 | (tots << 7));
4374
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4375
	if (debug & DEBUG_TSI)
4376
		dev_notice(&wc->dev->dev, "Sending '%08x\n", wc->dmactrl);
4377
	wc->dmactrl &= ~0x00007fff;
4378
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4379
	spin_unlock_irqrestore(&wc->reglock, flags);
4380
}
4381
#ifdef CONFIG_EXTENDED_RESET
4382
static void t4_extended_reset(struct t4 *wc)
4383
{
4384
	unsigned int oldreg = t4_pci_in(wc, 0x4);
4385
4386
	udelay(1000);
4387
4388
	t4_pci_out(wc, 0x4, 0x42000000);
4389
	t4_pci_out(wc, 0xa, 0x42000000);
4390
	t4_pci_out(wc, 0xa, 0x00080000);
4391
	t4_pci_out(wc, 0xa, 0x00080000);
4392
	t4_pci_out(wc, 0xa, 0x00080000);
4393
	t4_pci_out(wc, 0xa, 0x00180000);
4394
	t4_pci_out(wc, 0xa, 0x00080000);
4395
	t4_pci_out(wc, 0xa, 0x00180000);
4396
	t4_pci_out(wc, 0xa, 0x00080000);
4397
	t4_pci_out(wc, 0xa, 0x00180000);
4398
	t4_pci_out(wc, 0xa, 0x00080000);
4399
	t4_pci_out(wc, 0xa, 0x00180000);
4400
	t4_pci_out(wc, 0xa, 0x00080000);
4401
	t4_pci_out(wc, 0xa, 0x00180000);
4402
	t4_pci_out(wc, 0xa, 0x00080000);
4403
	t4_pci_out(wc, 0xa, 0x00180000);
4404
	t4_pci_out(wc, 0x4, oldreg);
4405
4406
	udelay(1000);
4407
}
4408
#endif
4409
4410
static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
4411
{
4412
	unsigned int version;
4413
4414
	version = t4_pci_in(wc, WC_VERSION);
4415
	dev_info(&wc->dev->dev, "Firmware Version: %08x\n", version);
4416
	dev_info(&wc->dev->dev, "Burst Mode: %s\n",
4417
		(!(cardflags & FLAG_BURST) && noburst) ? "Off" : "On");
4418
#ifdef ENABLE_WORKQUEUES
4419
	dev_info(&wc->dev->dev, "Work Queues: Enabled\n");
4420
#endif
4421
4422
#ifdef CONFIG_EXTENDED_RESET
4423
	t4_extended_reset(wc);
4424
#endif
4425
4426
	/* Make sure DMA engine is not running and interrupts are acknowledged */
4427
	wc->dmactrl = 0x0;
4428
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4429
	/* Reset Framer and friends */
4430
	t4_pci_out(wc, WC_LEDS, 0x00000000);
4431
4432
	/* Set DMA addresses */
4433
	t4_pci_out(wc, WC_RDADDR, wc->readdma);
4434
	t4_pci_out(wc, WC_WRADDR, wc->writedma);
4435
4436
	/* Setup counters, interrupt flags (ignored in Gen2) */
4437
	if (cardflags & FLAG_2NDGEN) {
4438
		t4_tsi_reset(wc);
4439
	} else {
4440
		t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
4441
	}
4442
	
4443
	/* Reset pending interrupts */
4444
	t4_pci_out(wc, WC_INTR, 0x00000000);
4445
4446
	/* Read T1/E1 status */
4447
	if (t1e1override > -1)
4448
		wc->t1e1 = t1e1override;
4449
	else
4450
		wc->t1e1 = ((t4_pci_in(wc, WC_LEDS)) & 0x0f00) >> 8;
4451
	wc->order = ((t4_pci_in(wc, WC_LEDS)) & 0xf0000000) >> 28;
4452
	order_index[wc->order]++;
4453
	return 0;
4454
}
4455
4456
static int t4_hardware_init_2(struct t4 *wc)
4457
{
4458
	int x;
4459
	unsigned int regval;
4460
4461
	if (t4_pci_in(wc, WC_VERSION) >= 0xc01a0165) {
4462
		wc->tspans[0]->spanflags |= FLAG_OCTOPT;
4463
		dev_info(&wc->dev->dev, "Octasic Optimizations: Enabled\n");
4464
	}
4465
	/* Setup LEDS, take out of reset */
4466
	t4_pci_out(wc, WC_LEDS, 0x000000ff);
4467
	t4_activate(wc);
4468
4469
	/* 
4470
	 * In order to find out the QFALC framer version, we have to temporarily term off compat
4471
	 * mode and take a peak at VSTR.  We turn compat back on when we are done.
4472
	 */
4473
	if (t4_framer_in(wc, 0, 0x4a) != 0x05)
4474
		dev_info(&wc->dev->dev, "WARNING: FALC framer not intialized "
4475
				"in compatibility mode.\n");
4476
	regval = t4_framer_in(wc, 0 ,0xd6);
4477
	regval |= (1 << 5); /* set COMP_DIS*/
4478
	t4_framer_out(wc, 0, 0xd6, regval);
4479
	regval = t4_framer_in(wc, 0, 0x4a);
4480
	if (regval == 0x05)
4481
		dev_info(&wc->dev->dev, "FALC Framer Version: 2.1 or "
4482
				"earlier\n");
4483
	else if (regval == 0x20) {
4484
		dev_info(&wc->dev->dev, "FALC Framer Version: 3.1\n");
4485
		wc->falc31 = 1;
4486
	} else
4487
		dev_info(&wc->dev->dev, "FALC Framer Version: Unknown "
4488
				"(VSTR = 0x%02x)\n", regval);
4489
	regval = t4_framer_in(wc, 0 ,0xd6);
4490
	regval &= ~(1 << 5); /* clear COMP_DIS*/
4491
	t4_framer_out(wc, 0, 0xd6, regval);
4492
	
4493
	t4_framer_out(wc, 0, 0x4a, 0xaa);
4494
	dev_info(&wc->dev->dev, "Board ID: %02x\n", wc->order);
4495
4496
	for (x=0;x< 11;x++)
4497
		dev_info(&wc->dev->dev, "Reg %d: 0x%08x\n", x,
4498
				t4_pci_in(wc, x));
4499
	return 0;
4500
}
4501
4502
static int __devinit t4_launch(struct t4 *wc)
4503
{
4504
	int x;
4505
	unsigned long flags;
4506
	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &wc->tspans[0]->span.flags))
4507
		return 0;
4508
	dev_info(&wc->dev->dev, "opvxd115: Launching card: %d\n",
4509
			wc->order);
4510
4511
	/* Setup serial parameters and system interface */
4512
	for (x=0;x<PORTS_PER_FRAMER;x++)
4513
		t4_serial_setup(wc, x);
4514
4515
	for (x = 0; x < wc->numspans; ++x) {
4516
		list_add_tail(&wc->tspans[x]->span.device_node,
4517
			      &wc->ddev->spans);
4518
	}
4519
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
4520
		dev_err(&wc->dev->dev, "Unable to register span %s\n",
4521
				wc->tspans[0]->span.name);
4522
		return -1;
4523
	}
4524
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
4525
	spin_lock_irqsave(&wc->reglock, flags);
4526
	__t4_set_sclk_src(wc, WC_SELF, 0, 0);
4527
	spin_unlock_irqrestore(&wc->reglock, flags);
4528
	tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
4529
	return 0;
4530
}
4531
4532
static void free_wc(struct t4 *wc)
4533
{
4534
	unsigned int x, y;
4535
4536
	for (x = 0; x < sizeof(wc->tspans)/sizeof(wc->tspans[0]); x++) {
4537
		if (!wc->tspans[x]) {
4538
			continue;
4539
		}
4540
4541
		for (y = 0; y < sizeof(wc->tspans[x]->chans)/sizeof(wc->tspans[x]->chans[0]); y++) {
4542
			if (wc->tspans[x]->chans[y]) {
4543
				kfree(wc->tspans[x]->chans[y]);
4544
			}
4545
			if (wc->tspans[x]->ec[y])
4546
				kfree(wc->tspans[x]->ec[y]);
4547
		}
4548
		kfree(wc->tspans[x]);
4549
	}
4550
	kfree(wc);
4551
}
4552
4553
static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
4554
{
4555
	struct t4 *wc;
4556
	struct devtype *dt;
4557
	unsigned int x, f;
4558
	int init_latency;
4559
	
4560
	if (pci_enable_device(pdev)) {
4561
		return -EIO;
4562
	}
4563
4564
	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
4565
		return -ENOMEM;
4566
	}
4567
4568
	memset(wc, 0x0, sizeof(*wc));
4569
	spin_lock_init(&wc->reglock);
4570
	dt = (struct devtype *) (ent->driver_data);
4571
4572
	wc->flags = dt->flags;
4573
4574
	wc->numspans = 1;
4575
	
4576
	wc->variety = dt->desc;
4577
	
4578
	wc->memaddr = pci_resource_start(pdev, 0);
4579
	wc->memlen = pci_resource_len(pdev, 0);
4580
	wc->membase = ioremap(wc->memaddr, wc->memlen);
4581
	/* This rids of the Double missed interrupt message after loading */
4582
	wc->last0 = 1;
4583
#if 0
4584
	if (!request_mem_region(wc->memaddr, wc->memlen, wc->variety))
4585
		dev_info(&wc->dev->dev, "opvxd115: Unable to request memory "
4586
				"region :(, using anyway...\n");
4587
#endif
4588
	if (pci_request_regions(pdev, wc->variety))
4589
		dev_info(&pdev->dev, "opvxd115: Unable to request regions\n");
4590
	
4591
	dev_info(&pdev->dev, "Found opvxd115 at base address %08lx, remapped "
4592
			"to %p\n", wc->memaddr, wc->membase);
4593
	
4594
	wc->dev = pdev;
4595
	
4596
	/* Enable bus mastering */
4597
	pci_set_master(pdev);
4598
4599
	/* Keep track of which device we are */
4600
	pci_set_drvdata(pdev, wc);
4601
4602
	if (wc->flags & FLAG_5THGEN) {
4603
		if ((ms_per_irq > 1) && (latency <= ((ms_per_irq) << 1))) {
4604
			init_latency = ms_per_irq << 1;
4605
		} else {
4606
			if (latency > 2)
4607
				init_latency = latency;
4608
			else
4609
				init_latency = 2;
4610
		}
4611
		dev_info(&wc->dev->dev, "5th gen card with initial latency of "
4612
			"%d and %d ms per IRQ\n", init_latency, ms_per_irq);
4613
	} else {
4614
		if (wc->flags & FLAG_2NDGEN)
4615
			init_latency = 1;
4616
		else
4617
			init_latency = 2;
4618
	}
4619
4620
	if (max_latency < init_latency) {
4621
		printk(KERN_INFO "maxlatency must be set to something greater than %d ms, increasing it to %d\n", init_latency, init_latency);
4622
		max_latency = init_latency;
4623
	}
4624
	
4625
	if (t4_allocate_buffers(wc, init_latency, NULL, NULL)) {
4626
		return -ENOMEM;
4627
	}
4628
4629
	/* Initialize hardware */
4630
	t4_hardware_init_1(wc, wc->flags);
4631
	
4632
	for(x = 0; x < MAX_T4_CARDS; x++) {
4633
		if (!cards[x])
4634
			break;
4635
	}
4636
	
4637
	if (x >= MAX_T4_CARDS) {
4638
		dev_notice(&wc->dev->dev, "No cards[] slot available!!\n");
4639
		kfree(wc);
4640
		return -ENOMEM;
4641
	}
4642
	
4643
	wc->num = x;
4644
	cards[x] = wc;
4645
	
4646
#ifdef ENABLE_WORKQUEUES
4647
	if (wc->flags & FLAG_2NDGEN) {
4648
		char tmp[20];
4649
4650
		sprintf(tmp, "opvxd115");
4651
		wc->workq = create_workqueue(tmp);
4652
	}
4653
#endif			
4654
4655
	/* Allocate pieces we need here */
4656
	for (x = 0; x < PORTS_PER_FRAMER; x++) {
4657
		if (!(wc->tspans[x] = kmalloc(sizeof(*wc->tspans[x]), GFP_KERNEL))) {
4658
			free_wc(wc);
4659
			return -ENOMEM;
4660
		}
4661
4662
		memset(wc->tspans[x], 0, sizeof(*wc->tspans[x]));
4663
4664
		if (wc->t1e1 & (1 << x)) {
4665
			wc->tspans[x]->spantype = TYPE_E1;
4666
		} else {
4667
			if (j1mode)
4668
				wc->tspans[x]->spantype = TYPE_J1;
4669
			else
4670
				wc->tspans[x]->spantype = TYPE_T1;
4671
		}
4672
4673
		for (f = 0; f < (wc->tspans[x]->spantype == TYPE_E1 ? 31 : 24); f++) {
4674
			if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
4675
				free_wc(wc);
4676
				return -ENOMEM;
4677
			}
4678
			memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
4679
			if (!(wc->tspans[x]->ec[f] = kmalloc(sizeof(*wc->tspans[x]->ec[f]), GFP_KERNEL))) {
4680
				free_wc(wc);
4681
				return -ENOMEM;
4682
			}
4683
			memset(wc->tspans[x]->ec[f], 0, sizeof(*wc->tspans[x]->ec[f]));
4684
		}
4685
4686
#ifdef ENABLE_WORKQUEUES
4687
		INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
4688
#endif				
4689
		wc->tspans[x]->spanflags |= wc->flags;
4690
	}
4691
	
4692
	/* Continue hardware intiialization */
4693
	t4_hardware_init_2(wc);
4694
	
4695
#ifdef SUPPORT_GEN1
4696
	if (request_irq(pdev->irq, (wc->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, DAHDI_IRQ_SHARED_DISABLED, "opvxd115", wc)) 
4697
#else
4698
		if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
4699
			dev_notice(&wc->dev->dev, "This driver does not "
4700
					"support 1st gen modules\n");
4701
			free_wc(wc);
4702
			return -ENODEV;
4703
		}	
4704
			if (request_irq(pdev->irq, t4_interrupt_gen2, DAHDI_IRQ_SHARED_DISABLED, "opvxd115", wc)) 
4705
#endif
4706
	{
4707
		dev_notice(&wc->dev->dev, "opvxd115: Unable to request IRQ %d\n",
4708
				pdev->irq);
4709
		free_wc(wc);
4710
		return -EIO;
4711
	}
4712
	
4713
	init_spans(wc);
4714
	/* get the current number of probed cards and run a slice of a tail
4715
	 * insertion sort */
4716
	for (x = 0; x < MAX_T4_CARDS; x++) {
4717
		if (!cards[x+1])
4718
			break;
4719
	}
4720
	for ( ; x > 0; x--) {
4721
		if (cards[x]->order < cards[x-1]->order) {
4722
			struct t4 *tmp = cards[x];
4723
			cards[x] = cards[x-1];
4724
			cards[x-1] = tmp;
4725
		} else {
4726
			/* if we're not moving it, we won't move any more
4727
			 * since all cards are sorted on addition */
4728
			break;
4729
		}
4730
	}
4731
	
4732
	dev_info(&wc->dev->dev, "Found an OpenVox Card: %s\n", wc->variety);
4733
	wc->gpio = 0x00000000;
4734
	t4_pci_out(wc, WC_GPIO, wc->gpio);
4735
	t4_gpio_setdir(wc, (1 << 17), (1 << 17));
4736
	t4_gpio_setdir(wc, (0xff), (0xff));
4737
4738
	create_sysfs_files(wc);
4739
	
4740
#if 0
4741
	for (x=0;x<0x10000;x++) {
4742
		__t4_raw_oct_out(wc, 0x0004, x);
4743
		__t4_raw_oct_out(wc, 0x000a, x ^ 0xffff);
4744
		if (__t4_raw_oct_in(wc, 0x0004) != x) 
4745
			dev_notice(&wc->dev->dev, "Register 4 failed %04x\n",
4746
					x);
4747
		if (__t4_raw_oct_in(wc, 0x000a) != (x ^ 0xffff))
4748
			dev_notice(&wc->dev->dev, "Register 10 failed %04x\n",
4749
					x);
4750
	}
4751
#endif
4752
4753
	return 0;
4754
}
4755
4756
static int t4_hardware_stop(struct t4 *wc)
4757
{
4758
4759
	/* Turn off DMA, leave interrupts enabled */
4760
	set_bit(T4_STOP_DMA, &wc->checkflag);
4761
4762
	/* Wait for interrupts to stop */
4763
	msleep(25);
4764
4765
	/* Turn off counter, address, etc */
4766
	if (wc->tspans[0]->spanflags & FLAG_2NDGEN) {
4767
		t4_tsi_reset(wc);
4768
	} else {
4769
		t4_pci_out(wc, WC_COUNT, 0x000000);
4770
	}
4771
	t4_pci_out(wc, WC_RDADDR, 0x0000000);
4772
	t4_pci_out(wc, WC_WRADDR, 0x0000000);
4773
	wc->gpio = 0x00000000;
4774
	t4_pci_out(wc, WC_GPIO, wc->gpio);
4775
	t4_pci_out(wc, WC_LEDS, 0x00000000);
4776
4777
	dev_notice(&wc->dev->dev, "\nStopped opvxd115, Turned off DMA\n");
4778
	return 0;
4779
}
4780
4781
static void __devexit t4_remove_one(struct pci_dev *pdev)
4782
{
4783
	struct t4 *wc = pci_get_drvdata(pdev);
4784
	int basesize;
4785
4786
	if (!wc) {
4787
		return;
4788
	}
4789
4790
	remove_sysfs_files(wc);
4791
4792
	/* Stop hardware */
4793
	t4_hardware_stop(wc);
4794
	
4795
	/* Release vpm450m */
4796
	if (wc->vpm450m)
4797
		release_vpm450m(wc->vpm450m);
4798
	wc->vpm450m = NULL;
4799
	/* Unregister spans */
4800
4801
	basesize = DAHDI_MAX_CHUNKSIZE * 32 * 4;
4802
	if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN))
4803
		basesize = basesize * 2;
4804
4805
	dahdi_unregister_device(wc->ddev);
4806
	kfree(wc->ddev->location);
4807
	kfree(wc->ddev->devicetype);
4808
	dahdi_free_device(wc->ddev);
4809
#ifdef ENABLE_WORKQUEUES
4810
	if (wc->workq) {
4811
		flush_workqueue(wc->workq);
4812
		destroy_workqueue(wc->workq);
4813
	}
4814
#endif			
4815
	
4816
	free_irq(pdev->irq, wc);
4817
	
4818
	if (wc->membase)
4819
		iounmap(wc->membase);
4820
	
4821
	pci_release_regions(pdev);		
4822
	
4823
	/* Immediately free resources */
4824
	pci_free_consistent(pdev, T4_BASE_SIZE * wc->numbufs * 2, (void *)wc->writechunk, wc->writedma);
4825
	
4826
	order_index[wc->order]--;
4827
	
4828
	cards[wc->num] = NULL;
4829
	pci_set_drvdata(pdev, NULL);
4830
	free_wc(wc);
4831
}
4832
4833
4834
static struct pci_device_id t4_pci_tbl[] __devinitdata =
4835
{
4836
	{ 0x1b74, 0x0115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd115 }, /* OpenVox D115P/D115E */
4837
	{ 0x1b74, 0xd130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd130 }, /* OpenVox D130P/D130E */
4838
	{ 0, }
4839
};
4840
4841
static struct pci_driver t4_driver = {
4842
	.name = "opvxd115",
4843
	.probe = t4_init_one,
4844
	.remove = __devexit_p(t4_remove_one),
4845
	.id_table = t4_pci_tbl,
4846
};
4847
4848
static int __init t4_init(void)
4849
{
4850
	int res;
4851
	res = dahdi_pci_module(&t4_driver);
4852
	if (res)
4853
		return -ENODEV;
4854
	/* initialize cards since we have all of them */
4855
	/* warn for missing zero and duplicate numbers */
4856
	if (cards[0] && cards[0]->order != 0) {
4857
		printk(KERN_NOTICE "opvxd115: Ident of first card is not zero (%d)\n",
4858
			cards[0]->order);
4859
	}
4860
	for (res = 0; cards[res]; res++) {
4861
		/* warn the user of duplicate ident values it is probably
4862
		 * unintended */
4863
		if (debug && res < 15 && cards[res+1] &&
4864
		    cards[res]->order == cards[res+1]->order) {
4865
			printk(KERN_NOTICE "opvxd115: Duplicate ident value found (%d)\n",
4866
				cards[res]->order);
4867
		}
4868
		t4_launch(cards[res]);
4869
	}
4870
	return 0;
4871
}
4872
4873
static void __exit t4_cleanup(void)
4874
{
4875
	pci_unregister_driver(&t4_driver);
4876
}
4877
4878
4879
MODULE_AUTHOR("mark.liu <mark.liu@openvox.cn>");
4880
MODULE_DESCRIPTION("Unified OpenVox Single T1/E1/J1 Card Driver");
4881
MODULE_ALIAS("opvxd115");
4882
MODULE_LICENSE("GPL v2");
4883
4884
module_param(pedanticpci, int, 0600);
4885
module_param(debug, int, 0600);
4886
module_param(noburst, int, 0600);
4887
module_param(timingcable, int, 0600);
4888
module_param(t1e1override, int, 0600);
4889
module_param(alarmdebounce, int, 0600);
4890
module_param(losalarmdebounce, int, 0600);
4891
module_param(aisalarmdebounce, int, 0600);
4892
module_param(yelalarmdebounce, int, 0600);
4893
module_param(max_latency, int, 0600);
4894
module_param(j1mode, int, 0600);
4895
module_param(sigmode, int, 0600);
4896
module_param(latency, int, 0600);
4897
module_param(ms_per_irq, int, 0600);
4898
#ifdef VPM_SUPPORT
4899
module_param(vpmsupport, int, 0600);
4900
module_param(vpmdtmfsupport, int, 0600);
4901
module_param(vpmspans, int, 0600);
4902
module_param(dtmfthreshold, int, 0600);
4903
#endif
4904
4905
MODULE_DEVICE_TABLE(pci, t4_pci_tbl);
4906
4907
module_init(t4_init);
4908
module_exit(t4_cleanup);
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/Kbuild (+32 lines)
Line 0 Link Here
1
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115) += opvxd115.o
2
3
FIRM_DIR	:= ../firmware
4
5
EXTRA_CFLAGS += -I$(src)/.. $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
6
7
ifeq ($(HOTPLUG_FIRMWARE),yes)
8
  EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
9
endif
10
11
opvxd115-objs := base.o vpm450m.o
12
13
DAHDI_KERNEL_H_NAME:=kernel.h
14
DAHDI_KERNEL_H_PATH:=$(DAHDI_INCLUDE)/dahdi/$(DAHDI_KERNEL_H_NAME)
15
ifneq ($(DAHDI_KERNEL_H_PATH),)
16
        DAHDI_SPAN_MODULE:=$(shell if grep -C 5 "struct dahdi_span {" $(DAHDI_KERNEL_H_PATH) | grep -q "struct module \*owner"; then echo "yes"; else echo "no"; fi)
17
        DAHDI_SPAN_OPS:=$(shell if grep -q "struct dahdi_span_ops {" $(DAHDI_KERNEL_H_PATH); then echo "yes"; else echo "no"; fi)
18
        ifeq ($(DAHDI_SPAN_MODULE),yes)
19
                EXTRA_CFLAGS+=-DDAHDI_SPAN_MODULE
20
        else
21
                ifeq ($(DAHDI_SPAN_OPS),yes)
22
                        EXTRA_CFLAGS+=-DDAHDI_SPAN_OPS
23
                endif
24
        endif
25
endif
26
27
ifneq ($(HOTPLUG_FIRMWARE),yes)
28
opvxd115-objs += $(FIRM_DIR)/dahdi-fw-oct6114-032.o
29
endif
30
31
$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-032.o: $(obj)/base.o
32
	$(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-oct6114-032.o
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/Makefile (+8 lines)
Line 0 Link Here
1
ifdef KBUILD_EXTMOD
2
# We only get here on kernels 2.6.0-2.6.9 .
3
# For newer kernels, Kbuild will be included directly by the kernel
4
# build system.
5
include $(src)/Kbuild
6
7
else
8
endif
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/opvxd115-diag.c (+427 lines)
Line 0 Link Here
1
/*
2
 * See http://www.asterisk.org for more information about
3
 * the Asterisk project. Please do not directly contact
4
 * any of the maintainers of this project for assistance;
5
 * the project provides a web site, mailing lists and IRC
6
 * channels for your use.
7
 *
8
 * This program is free software, distributed under the terms of
9
 * the GNU General Public License Version 2 as published by the
10
 * Free Software Foundation. See the LICENSE file included with
11
 * this program for more details.
12
 */
13
14
#include <fcntl.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <unistd.h>
18
#include <sys/ioctl.h>
19
#include <errno.h>
20
#include <string.h>
21
#include <dahdi/user.h>
22
#include "opvxd115.h"
23
24
struct t4_reg_def {
25
	int reg;
26
	char *name;
27
	int global;
28
};
29
static struct t4_reg_def xreginfo[] = {
30
	{ 0x00, "RDADDR" },
31
	{ 0x01, "WRADDR" },
32
	{ 0x02, "COUNT" },
33
	{ 0x03, "DMACTRL" },
34
	{ 0x04, "WCINTR" },
35
	{ 0x06, "VERSION" },
36
	{ 0x07, "LEDS" },
37
	{ 0x08, "GPIOCTL" },
38
	{ 0x09, "GPIO" }, 
39
	{ 0x0A, "LADDR" },
40
	{ 0x0b, "LDATA" },
41
};
42
43
static struct t4_reg_def reginfo[] = {
44
	{ 0x00, "XFIFO" },
45
	{ 0x01, "XFIFO" },
46
	{ 0x02, "CMDR" },
47
	{ 0x03, "MODE" },
48
	{ 0x04, "RAH1" },
49
	{ 0x05, "RAH2" },
50
	{ 0x06, "RAL1" },
51
	{ 0x07, "RAL2" },
52
	{ 0x08, "IPC", 1 },
53
	{ 0x09, "CCR1" },
54
	{ 0x0a, "CCR2" },
55
	{ 0x0c, "RTR1" },
56
	{ 0x0d, "RTR2" },
57
	{ 0x0e, "RTR3" },
58
	{ 0x0f, "RTR4" },
59
	{ 0x10, "TTR1" },
60
	{ 0x11, "TTR2" },
61
	{ 0x12, "TTR3" },
62
	{ 0x13, "TTR4" },
63
	{ 0x14, "IMR0" },
64
	{ 0x15, "IMR1" },
65
	{ 0x16, "IMR2" },
66
	{ 0x17, "IMR3" },
67
	{ 0x18, "IMR4" },
68
	{ 0x1b, "IERR" },
69
	{ 0x1c, "FMR0" },
70
	{ 0x1d, "FMR1" },
71
	{ 0x1e, "FMR2" },
72
	{ 0x1f, "LOOP" },
73
	{ 0x20, "XSW" },
74
	{ 0x21, "XSP" },
75
	{ 0x22, "XC0" },
76
	{ 0x23, "XC1" },
77
	{ 0x24, "RC0" },
78
	{ 0x25, "RC1" },
79
	{ 0x26, "XPM0" },
80
	{ 0x27, "XPM1" },
81
	{ 0x28, "XPM2" },
82
	{ 0x29, "TSWM" },
83
	{ 0x2b, "IDLE" },
84
	{ 0x2c, "XSA4" },
85
	{ 0x2d, "XSA5" },
86
	{ 0x2e, "XSA6" },
87
	{ 0x2f, "XSA7" },
88
	{ 0x30, "XSA8" },
89
	{ 0x31, "FMR3" },
90
	{ 0x32, "ICB1" },
91
	{ 0x33, "ICB2" },
92
	{ 0x34, "ICB3" },
93
	{ 0x35, "ICB4" },
94
	{ 0x36, "LIM0" },
95
	{ 0x37, "LIM1" },
96
	{ 0x38, "PCD" },
97
	{ 0x39, "PCR" },
98
	{ 0x3a, "LIM2" },
99
	{ 0x3b, "LCR1" },
100
	{ 0x3c, "LCR2" },
101
	{ 0x3d, "LCR3" },
102
	{ 0x3e, "SIC1" },
103
	{ 0x3f, "SIC2" },
104
	{ 0x40, "SIC3" },
105
	{ 0x44, "CMR1" },
106
	{ 0x45, "CMR2" },
107
	{ 0x46, "GCR" },
108
	{ 0x47, "ESM" },
109
	{ 0x60, "DEC" },
110
	{ 0x70, "XS1" },
111
	{ 0x71, "XS2" },
112
	{ 0x72, "XS3" },
113
	{ 0x73, "XS4" },
114
	{ 0x74, "XS5" },
115
	{ 0x75, "XS6" },
116
	{ 0x76, "XS7" },
117
	{ 0x77, "XS8" },
118
	{ 0x78, "XS9" },
119
	{ 0x79, "XS10" },
120
	{ 0x7a, "XS11" },
121
	{ 0x7b, "XS12" },
122
	{ 0x7c, "XS13" },
123
	{ 0x7d, "XS14" },
124
	{ 0x7e, "XS15" },
125
	{ 0x7f, "XS16" },
126
	{ 0x80, "PC1" },
127
	{ 0x81, "PC2" },
128
	{ 0x82, "PC3" },
129
	{ 0x83, "PC4" },
130
	{ 0x84, "PC5" },
131
	{ 0x85, "GPC1", 1 },
132
	{ 0x87, "CMDR2" },
133
	{ 0x8d, "CCR5" },
134
	{ 0x92, "GCM1", 1 },
135
	{ 0x93, "GCM2", 1 },
136
	{ 0x94, "GCM3", 1 },
137
	{ 0x95, "GCM4", 1 },
138
	{ 0x96, "GCM5", 1 },
139
	{ 0x97, "GCM6", 1 },
140
	{ 0x98, "GCM7", 1 },
141
	{ 0x99, "GCM8", 1 },
142
	{ 0xa0, "TSEO" },
143
	{ 0xa1, "TSBS1" },
144
	{ 0xa8, "TPC0" },	
145
};
146
147
static struct t4_reg_def t1_reginfo[] = {
148
	{ 0x00, "XFIFO" },
149
	{ 0x01, "XFIFO" },
150
	{ 0x02, "CMDR" },
151
	{ 0x03, "MODE" },
152
	{ 0x04, "RAH1" },
153
	{ 0x05, "RAH2" },
154
	{ 0x06, "RAL1" },
155
	{ 0x07, "RAL2" },
156
	{ 0x08, "IPC", 1 },
157
	{ 0x09, "CCR1" },
158
	{ 0x0a, "CCR2" },
159
	{ 0x0c, "RTR1" },
160
	{ 0x0d, "RTR2" },
161
	{ 0x0e, "RTR3" },
162
	{ 0x0f, "RTR4" },
163
	{ 0x10, "TTR1" },
164
	{ 0x11, "TTR2" },
165
	{ 0x12, "TTR3" },
166
	{ 0x13, "TTR4" },
167
	{ 0x14, "IMR0" },
168
	{ 0x15, "IMR1" },
169
	{ 0x16, "IMR2" },
170
	{ 0x17, "IMR3" },
171
	{ 0x18, "IMR4" },
172
	{ 0x1b, "IERR" },
173
	{ 0x1c, "FMR0" },
174
	{ 0x1d, "FMR1" },
175
	{ 0x1e, "FMR2" },
176
	{ 0x1f, "LOOP" },
177
	{ 0x20, "FMR4" },
178
	{ 0x21, "FMR5" },
179
	{ 0x22, "XC0" },
180
	{ 0x23, "XC1" },
181
	{ 0x24, "RC0" },
182
	{ 0x25, "RC1" },
183
	{ 0x26, "XPM0" },
184
	{ 0x27, "XPM1" },
185
	{ 0x28, "XPM2" },
186
	{ 0x2b, "IDLE" },
187
	{ 0x2c, "XDL1" },
188
	{ 0x2d, "XDL2" },
189
	{ 0x2e, "XDL3" },
190
	{ 0x2f, "CCB1" },
191
	{ 0x30, "CCB2" },
192
	{ 0x31, "CCB3" },
193
	{ 0x32, "ICB1" },
194
	{ 0x33, "ICB2" },
195
	{ 0x34, "ICB3" },
196
	{ 0x36, "LIM0" },
197
	{ 0x37, "LIM1" },
198
	{ 0x38, "PCD" },
199
	{ 0x39, "PCR" },
200
	{ 0x3a, "LIM2" },
201
	{ 0x3b, "LCR1" },
202
	{ 0x3c, "LCR2" },
203
	{ 0x3d, "LCR3" },
204
	{ 0x3e, "SIC1" },
205
	{ 0x3f, "SIC2" },
206
	{ 0x40, "SIC3" },
207
	{ 0x44, "CMR1" },
208
	{ 0x45, "CMR2" },
209
	{ 0x46, "GCR" },
210
	{ 0x47, "ESM" },
211
	{ 0x60, "DEC" },
212
	{ 0x70, "XS1" },
213
	{ 0x71, "XS2" },
214
	{ 0x72, "XS3" },
215
	{ 0x73, "XS4" },
216
	{ 0x74, "XS5" },
217
	{ 0x75, "XS6" },
218
	{ 0x76, "XS7" },
219
	{ 0x77, "XS8" },
220
	{ 0x78, "XS9" },
221
	{ 0x79, "XS10" },
222
	{ 0x7a, "XS11" },
223
	{ 0x7b, "XS12" },
224
	{ 0x80, "PC1" },
225
	{ 0x81, "PC2" },
226
	{ 0x82, "PC3" },
227
	{ 0x83, "PC4" },
228
	{ 0x84, "PC5" },
229
	{ 0x85, "GPC1", 1 },
230
	{ 0x87, "CMDR2" },
231
	{ 0x8d, "CCR5" },
232
	{ 0x92, "GCM1", 1 },
233
	{ 0x93, "GCM2", 1 },
234
	{ 0x94, "GCM3", 1 },
235
	{ 0x95, "GCM4", 1 },
236
	{ 0x96, "GCM5", 1 },
237
	{ 0x97, "GCM6", 1 },
238
	{ 0x98, "GCM7", 1 },
239
	{ 0x99, "GCM8", 1 },
240
	{ 0xa0, "TSEO" },
241
	{ 0xa1, "TSBS1" },
242
	{ 0xa8, "TPC0" },	
243
};
244
245
static struct t4_reg_def t1_sreginfo[] = {
246
	{ 0x00, "RFIFO" },
247
	{ 0x01, "RFIFO" },
248
	{ 0x49, "RBD" },
249
	{ 0x4a, "VSTR", 1 },
250
	{ 0x4b, "RES" },
251
	{ 0x4c, "FRS0" },
252
	{ 0x4d, "FRS1" },
253
	{ 0x4e, "FRS2" },
254
	{ 0x4f, "Old FRS1" },
255
	{ 0x50, "FECL" },
256
	{ 0x51, "FECH" },
257
	{ 0x52, "CVCL" },
258
	{ 0x53, "CVCH" },
259
	{ 0x54, "CECL" },
260
	{ 0x55, "CECH" },
261
	{ 0x56, "EBCL" },
262
	{ 0x57, "EBCH" },
263
	{ 0x58, "BECL" },
264
	{ 0x59, "BECH" },
265
	{ 0x5a, "COEC" },
266
	{ 0x5c, "RDL1" },
267
	{ 0x5d, "RDL2" },
268
	{ 0x5e, "RDL3" },
269
	{ 0x62, "RSP1" },
270
	{ 0x63, "RSP2" },
271
	{ 0x64, "SIS" },
272
	{ 0x65, "RSIS" },
273
	{ 0x66, "RBCL" },
274
	{ 0x67, "RBCH" },
275
	{ 0x68, "ISR0" },
276
	{ 0x69, "ISR1" },
277
	{ 0x6a, "ISR2" },
278
	{ 0x6b, "ISR3" },
279
	{ 0x6c, "ISR4" },
280
	{ 0x6e, "GIS" },
281
	{ 0x6f, "CIS", 1 },
282
	{ 0x70, "RS1" },
283
	{ 0x71, "RS2" },
284
	{ 0x72, "RS3" },
285
	{ 0x73, "RS4" },
286
	{ 0x74, "RS5" },
287
	{ 0x75, "RS6" },
288
	{ 0x76, "RS7" },
289
	{ 0x77, "RS8" },
290
	{ 0x78, "RS9" },
291
	{ 0x79, "RS10" },
292
	{ 0x7a, "RS11" },
293
	{ 0x7b, "RS12" },
294
};
295
296
static struct t4_reg_def sreginfo[] = {
297
	{ 0x00, "RFIFO" },
298
	{ 0x01, "RFIFO" },
299
	{ 0x49, "RBD" },
300
	{ 0x4a, "VSTR", 1 },
301
	{ 0x4b, "RES" },
302
	{ 0x4c, "FRS0" },
303
	{ 0x4d, "FRS1" },
304
	{ 0x4e, "RSW" },
305
	{ 0x4f, "RSP" },
306
	{ 0x50, "FECL" },
307
	{ 0x51, "FECH" },
308
	{ 0x52, "CVCL" },
309
	{ 0x53, "CVCH" },
310
	{ 0x54, "CEC1L" },
311
	{ 0x55, "CEC1H" },
312
	{ 0x56, "EBCL" },
313
	{ 0x57, "EBCH" },
314
	{ 0x58, "CEC2L" },
315
	{ 0x59, "CEC2H" },
316
	{ 0x5a, "CEC3L" },
317
	{ 0x5b, "CEC3H" },
318
	{ 0x5c, "RSA4" },
319
	{ 0x5d, "RSA5" },
320
	{ 0x5e, "RSA6" },
321
	{ 0x5f, "RSA7" },
322
	{ 0x60, "RSA8" },
323
	{ 0x61, "RSA6S" },
324
	{ 0x62, "RSP1" },
325
	{ 0x63, "RSP2" },
326
	{ 0x64, "SIS" },
327
	{ 0x65, "RSIS" },
328
	{ 0x66, "RBCL" },
329
	{ 0x67, "RBCH" },
330
	{ 0x68, "ISR0" },
331
	{ 0x69, "ISR1" },
332
	{ 0x6a, "ISR2" },
333
	{ 0x6b, "ISR3" },
334
	{ 0x6c, "ISR4" },
335
	{ 0x6e, "GIS" },
336
	{ 0x6f, "CIS", 1 },
337
	{ 0x70, "RS1" },
338
	{ 0x71, "RS2" },
339
	{ 0x72, "RS3" },
340
	{ 0x73, "RS4" },
341
	{ 0x74, "RS5" },
342
	{ 0x75, "RS6" },
343
	{ 0x76, "RS7" },
344
	{ 0x77, "RS8" },
345
	{ 0x78, "RS9" },
346
	{ 0x79, "RS10" },
347
	{ 0x7a, "RS11" },
348
	{ 0x7b, "RS12" },
349
	{ 0x7c, "RS13" },
350
	{ 0x7d, "RS14" },
351
	{ 0x7e, "RS15" },
352
	{ 0x7f, "RS16" },
353
};
354
355
static char *tobin(int x)
356
{
357
	static char s[9] = "";
358
	int y,z=0;
359
	for (y=7;y>=0;y--) {
360
		if (x & (1 << y))
361
			s[z++] = '1';
362
		else
363
			s[z++] = '0';
364
	}
365
	s[z] = '\0';
366
	return s;
367
}
368
369
static char *tobin32(unsigned int x)
370
{
371
	static char s[33] = "";
372
	int y,z=0;
373
	for (y=31;y>=0;y--) {
374
		if (x & (1 << y))
375
			s[z++] = '1';
376
		else
377
			s[z++] = '0';
378
	}
379
	s[z] = '\0';
380
	return s;
381
}
382
383
int main(int argc, char *argv[])
384
{
385
	int fd;
386
	int x;
387
	char fn[256];
388
	struct t4_regs regs;
389
	if ((argc < 2) || ((*(argv[1]) != '/') && !atoi(argv[1]))) {
390
		fprintf(stderr, "Usage: opvxd115-diag <channel>\n");
391
		exit(1);
392
	}
393
	if (*(argv[1]) == '/')
394
		dahdi_copy_string(fn, argv[1], sizeof(fn));
395
	else
396
		snprintf(fn, sizeof(fn), "/dev/dahdi/%d", atoi(argv[1]));
397
	fd = open(fn, O_RDWR);
398
	if (fd <0) {
399
		fprintf(stderr, "Unable to open '%s': %s\n", fn, strerror(errno));
400
		exit(1);
401
	}
402
	if (ioctl(fd, WCT4_GET_REGS, &regs)) {
403
		fprintf(stderr, "Unable to get registers: %s\n", strerror(errno));
404
		exit(1);
405
	}
406
	printf("PCI Registers:\n");
407
	for (x=0;x<sizeof(xreginfo) / sizeof(xreginfo[0]);x++) {
408
		fprintf(stdout, "%s (%02x): %08x (%s)\n", xreginfo[x].name, xreginfo[x].reg, regs.pci[xreginfo[x].reg], tobin32(regs.pci[xreginfo[x].reg]));
409
	}
410
	printf("\nE1 Control Registers:\n");
411
	for (x=0;x<sizeof(reginfo) / sizeof(reginfo[0]);x++) {
412
		fprintf(stdout, "%s (%02x): %02x (%s)\n", reginfo[x].name, reginfo[x].reg, regs.regs[reginfo[x].reg], tobin(regs.regs[reginfo[x].reg]));
413
	}
414
	printf("\nE1 Status Registers:\n");
415
	for (x=0;x<sizeof(sreginfo) / sizeof(sreginfo[0]);x++) {
416
		fprintf(stdout, "%s (%02x): %02x (%s)\n", sreginfo[x].name, sreginfo[x].reg, regs.regs[sreginfo[x].reg], tobin(regs.regs[sreginfo[x].reg]));
417
	}
418
	printf("\nT1 Control Registers:\n");
419
	for (x=0;x<sizeof(t1_reginfo) / sizeof(t1_reginfo[0]);x++) {
420
		fprintf(stdout, "%s (%02x): %02x (%s)\n", t1_reginfo[x].name, t1_reginfo[x].reg, regs.regs[t1_reginfo[x].reg], tobin(regs.regs[t1_reginfo[x].reg]));
421
	}
422
	printf("\nT1 Status Registers:\n");
423
	for (x=0;x<sizeof(t1_sreginfo) / sizeof(t1_sreginfo[0]);x++) {
424
		fprintf(stdout, "%s (%02x): %02x (%s)\n", t1_sreginfo[x].name, t1_sreginfo[x].reg, regs.regs[t1_sreginfo[x].reg], tobin(regs.regs[t1_sreginfo[x].reg]));
425
	}
426
	exit(0);
427
}
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/opvxd115.h (+124 lines)
Line 0 Link Here
1
/*
2
 * Wildcard T400P FXS Interface Driver for DAHDI Telephony interface
3
 *
4
 * Written by Mark Spencer <markster@linux-support.net>
5
 *
6
 * Copyright (C) 2001-2008, Digium, Inc.
7
 *
8
 * All rights reserved.
9
 *
10
 */
11
12
/*
13
 * See http://www.asterisk.org for more information about
14
 * the Asterisk project. Please do not directly contact
15
 * any of the maintainers of this project for assistance;
16
 * the project provides a web site, mailing lists and IRC
17
 * channels for your use.
18
 *
19
 * This program is free software, distributed under the terms of
20
 * the GNU General Public License Version 2 as published by the
21
 * Free Software Foundation. See the LICENSE file included with
22
 * this program for more details.
23
 */
24
25
#include <linux/ioctl.h>
26
27
#define FRMR_TTR_BASE 0x10
28
#define FRMR_RTR_BASE 0x0c
29
#define FRMR_TSEO 0xa0
30
#define FRMR_TSBS1 0xa1
31
#define FRMR_CCR1 0x09
32
#define FRMR_CCR1_ITF 0x08
33
#define FRMR_CCR1_EITS 0x10
34
#define FRMR_CCR2 0x0a
35
#define FRMR_CCR2_RCRC 0x04
36
#define FRMR_CCR2_RADD 0x10
37
#define FRMR_MODE 0x03
38
#define FRMR_MODE_NO_ADDR_CMP 0x80
39
#define FRMR_MODE_SS7 0x20
40
#define FRMR_MODE_HRAC 0x08
41
#define FRMR_IMR0 0x14
42
#define FRMR_IMR0_RME 0x80
43
#define FRMR_IMR0_RPF 0x01
44
#define FRMR_IMR1 0x15
45
#define FRMR_IMR1_ALLS 0x20
46
#define FRMR_IMR1_XDU 0x10
47
#define FRMR_IMR1_XPR 0x01
48
#define FRMR_XC0 0x22
49
#define FRMR_XC1 0x23
50
#define FRMR_RC0 0x24
51
#define FRMR_RC1 0x25
52
#define FRMR_SIC1 0x3e
53
#define FRMR_SIC2 0x3f
54
#define FRMR_SIC3 0x40
55
#define FRMR_CMR1 0x44
56
#define FRMR_CMR2 0x45
57
#define FRMR_GCR 0x46
58
#define FRMR_ISR0 0x68
59
#define FRMR_ISR0_RME 0x80
60
#define FRMR_ISR0_RPF 0x01
61
#define FRMR_ISR1 0x69
62
#define FRMR_ISR1_ALLS 0x20
63
#define FRMR_ISR1_XDU 0x10
64
#define FRMR_ISR1_XPR 0x01
65
#define FRMR_ISR2 0x6a
66
#define FRMR_ISR3 0x6b
67
#define FRMR_ISR4 0x6c
68
#define FRMR_GIS  0x6e
69
#define FRMR_GIS_ISR0 0x01
70
#define FRMR_GIS_ISR1 0x02
71
#define FRMR_GIS_ISR2 0x04
72
#define FRMR_GIS_ISR3 0x08
73
#define FRMR_GIS_ISR4 0x10
74
#define FRMR_CIS 0x6f
75
#define FRMR_CIS_GIS1 0x01
76
#define FRMR_CIS_GIS2 0x02
77
#define FRMR_CIS_GIS3 0x04
78
#define FRMR_CIS_GIS4 0x08
79
#define FRMR_CMDR 0x02
80
#define FRMR_CMDR_SRES 0x01
81
#define FRMR_CMDR_XRES 0x10
82
#define FRMR_CMDR_RMC 0x80
83
#define FRMR_CMDR_XTF 0x04
84
#define FRMR_CMDR_XHF 0x08
85
#define FRMR_CMDR_XME 0x02
86
#define FRMR_RSIS 0x65
87
#define FRMR_RSIS_VFR 0x80
88
#define FRMR_RSIS_RDO 0x40
89
#define FRMR_RSIS_CRC16 0x20
90
#define FRMR_RSIS_RAB 0x10
91
#define FRMR_RBCL 0x66
92
#define FRMR_RBCL_MAX_SIZE 0x1f
93
#define FRMR_RBCH 0x67
94
#define FRMR_RXFIFO 0x00
95
#define FRMR_SIS 0x64
96
#define FRMR_SIS_XFW 0x40
97
#define FRMR_TXFIFO 0x00
98
99
#define FRS0 0x4c
100
#define FRS0_LOS (1<<7)
101
#define FRS0_LFA (1<<5)
102
#define FRS0_LMFA (1<<1)
103
104
#define FRS1 0x4d
105
#define FRS1_XLS (1<<1)
106
#define FRS1_XLO (1<<0)
107
108
#define NUM_REGS 0xa9
109
#define NUM_PCI 12
110
111
struct t4_regs {
112
	unsigned int pci[NUM_PCI];
113
	unsigned char regs[NUM_REGS];
114
};
115
116
#define T4_CHECK_VPM		0
117
#define T4_LOADING_FW		1
118
#define T4_STOP_DMA		2
119
#define T4_CHECK_TIMING		3
120
#define T4_CHANGE_LATENCY	4
121
#define T4_IGNORE_LATENCY	5
122
123
#define WCT4_GET_REGS	_IOW (DAHDI_CODE, 60, struct t4_regs)
124
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/vpm450m.c (+587 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2005-2006 Digium, Inc.
3
 *
4
 * Mark Spencer <markster@digium.com>
5
 * Modified by mark.liu@openvox.cn 06/16/2009
6
 
7
 * All Rights Reserved
8
 */
9
10
/*
11
 * See http://www.asterisk.org for more information about
12
 * the Asterisk project. Please do not directly contact
13
 * any of the maintainers of this project for assistance;
14
 * the project provides a web site, mailing lists and IRC
15
 * channels for your use.
16
 *
17
 * This program is free software, distributed under the terms of
18
 * the GNU General Public License Version 2 as published by the
19
 * Free Software Foundation. See the LICENSE file included with
20
 * this program for more details.
21
 */
22
23
#include <linux/slab.h>
24
#include <linux/vmalloc.h>
25
#include <linux/string.h>
26
#include <linux/time.h>
27
#include <linux/version.h>
28
29
#include "vpm450m.h"
30
#include "oct6100api/oct6100_api.h"
31
32
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
33
#include <linux/config.h>
34
#endif
35
36
/* API for Octasic access */
37
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
38
{
39
	/* Why couldn't they just take a timeval like everyone else? */
40
	struct timeval tv;
41
	unsigned long long total_usecs;
42
	unsigned int mask = ~0;
43
	
44
	do_gettimeofday(&tv);
45
	total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) + 
46
				  (((unsigned long long)(tv.tv_usec)));
47
	f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
48
	f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
49
	return cOCT6100_ERR_OK;
50
}
51
52
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
53
{
54
	memset(f_pAddress, f_ulPattern, f_ulLength);
55
	return cOCT6100_ERR_OK;
56
}
57
58
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
59
{
60
	memcpy(f_pDestination, f_pSource, f_ulLength);
61
	return cOCT6100_ERR_OK;
62
}
63
64
UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
65
{
66
	return cOCT6100_ERR_OK;
67
}
68
69
UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
70
{
71
#ifdef OCTASIC_DEBUG
72
	printk(KERN_DEBUG "I should never be called! (destroy serialize object)\n");
73
#endif
74
	return cOCT6100_ERR_OK;
75
}
76
77
UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
78
{
79
	/* Not needed */
80
	return cOCT6100_ERR_OK;
81
}
82
83
UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
84
{
85
	/* Not needed */
86
	return cOCT6100_ERR_OK;
87
}
88
89
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
90
{
91
	oct_set_reg(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
92
	return cOCT6100_ERR_OK;
93
}
94
95
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
96
{
97
	unsigned int x;
98
	for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
99
		oct_set_reg(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
100
	}
101
	return cOCT6100_ERR_OK;
102
}
103
104
UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
105
{
106
	unsigned int x;
107
	for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
108
		oct_set_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
109
	}
110
	return cOCT6100_ERR_OK;
111
}
112
113
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
114
{
115
	*(f_pReadParams->pusReadData) = oct_get_reg(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
116
	return cOCT6100_ERR_OK;
117
}
118
119
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
120
{
121
	unsigned int x;
122
	for (x=0;x<f_pBurstParams->ulReadLength;x++) {
123
		f_pBurstParams->pusReadData[x] = oct_get_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
124
	}
125
	return cOCT6100_ERR_OK;
126
}
127
128
#define SOUT_G168_1100GB_ON 0x40000004
129
#define SOUT_DTMF_1 0x40000011
130
#define SOUT_DTMF_2 0x40000012
131
#define SOUT_DTMF_3 0x40000013
132
#define SOUT_DTMF_A 0x4000001A
133
#define SOUT_DTMF_4 0x40000014
134
#define SOUT_DTMF_5 0x40000015
135
#define SOUT_DTMF_6 0x40000016
136
#define SOUT_DTMF_B 0x4000001B
137
#define SOUT_DTMF_7 0x40000017
138
#define SOUT_DTMF_8 0x40000018
139
#define SOUT_DTMF_9 0x40000019
140
#define SOUT_DTMF_C 0x4000001C
141
#define SOUT_DTMF_STAR 0x4000001E
142
#define SOUT_DTMF_0 0x40000010
143
#define SOUT_DTMF_POUND 0x4000001F
144
#define SOUT_DTMF_D 0x4000001D
145
146
#define ROUT_G168_2100GB_ON 0x10000000
147
#define ROUT_G168_2100GB_WSPR 0x10000002
148
#define ROUT_SOUT_G168_2100HB_END 0x50000003
149
#define ROUT_G168_1100GB_ON 0x10000004
150
151
#define ROUT_DTMF_1 0x10000011
152
#define ROUT_DTMF_2 0x10000012
153
#define ROUT_DTMF_3 0x10000013
154
#define ROUT_DTMF_A 0x1000001A
155
#define ROUT_DTMF_4 0x10000014
156
#define ROUT_DTMF_5 0x10000015
157
#define ROUT_DTMF_6 0x10000016
158
#define ROUT_DTMF_B 0x1000001B
159
#define ROUT_DTMF_7 0x10000017
160
#define ROUT_DTMF_8 0x10000018
161
#define ROUT_DTMF_9 0x10000019
162
#define ROUT_DTMF_C 0x1000001C
163
#define ROUT_DTMF_STAR 0x1000001E
164
#define ROUT_DTMF_0 0x10000010
165
#define ROUT_DTMF_POUND 0x1000001F
166
#define ROUT_DTMF_D 0x1000001D
167
168
#if 0 
169
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
170
#else
171
#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
172
#endif
173
174
struct vpm450m {
175
	tPOCT6100_INSTANCE_API pApiInstance;
176
	UINT32 aulEchoChanHndl[ 128 ];
177
	int chanflags[128];
178
	int ecmode[128];
179
	int numchans;
180
};
181
182
#define FLAG_DTMF	 (1 << 0)
183
#define FLAG_MUTE	 (1 << 1)
184
#define FLAG_ECHO	 (1 << 2)
185
186
static unsigned int tones[] = {
187
	SOUT_DTMF_1,
188
	SOUT_DTMF_2,
189
	SOUT_DTMF_3,
190
	SOUT_DTMF_A,
191
	SOUT_DTMF_4,
192
	SOUT_DTMF_5,
193
	SOUT_DTMF_6,
194
	SOUT_DTMF_B,
195
	SOUT_DTMF_7,
196
	SOUT_DTMF_8,
197
	SOUT_DTMF_9,
198
	SOUT_DTMF_C,
199
	SOUT_DTMF_STAR,
200
	SOUT_DTMF_0,
201
	SOUT_DTMF_POUND,
202
	SOUT_DTMF_D,
203
	SOUT_G168_1100GB_ON,
204
205
	ROUT_DTMF_1,
206
	ROUT_DTMF_2,
207
	ROUT_DTMF_3,
208
	ROUT_DTMF_A,
209
	ROUT_DTMF_4,
210
	ROUT_DTMF_5,
211
	ROUT_DTMF_6,
212
	ROUT_DTMF_B,
213
	ROUT_DTMF_7,
214
	ROUT_DTMF_8,
215
	ROUT_DTMF_9,
216
	ROUT_DTMF_C,
217
	ROUT_DTMF_STAR,
218
	ROUT_DTMF_0,
219
	ROUT_DTMF_POUND,
220
	ROUT_DTMF_D,
221
	ROUT_G168_1100GB_ON,
222
};
223
224
static void vpm450m_setecmode(struct vpm450m *vpm450m, int channel, int mode)
225
{
226
	tOCT6100_CHANNEL_MODIFY *modify;
227
	UINT32 ulResult;
228
229
	if (vpm450m->ecmode[channel] == mode)
230
		return;
231
	modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
232
	if (!modify) {
233
		printk(KERN_NOTICE "opvxd115: Unable to allocate memory for setec!\n");
234
		return;
235
	}
236
	Oct6100ChannelModifyDef(modify);
237
	modify->ulEchoOperationMode = mode;
238
	modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
239
	ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
240
	if (ulResult != GENERIC_OK) {
241
		printk(KERN_NOTICE "Failed to apply echo can changes on channel %d!\n", channel);
242
	} else {
243
#ifdef OCTASIC_DEBUG
244
		printk(KERN_DEBUG "Echo can on channel %d set to %d\n", channel, mode);
245
#endif
246
		vpm450m->ecmode[channel] = mode;
247
	}
248
	kfree(modify);
249
}
250
251
void vpm450m_setdtmf(struct vpm450m *vpm450m, int channel, int detect, int mute)
252
{
253
	tOCT6100_CHANNEL_MODIFY *modify;
254
	UINT32 ulResult;
255
256
	modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_KERNEL);
257
	if (!modify) {
258
		printk(KERN_NOTICE "opvxd115: Unable to allocate memory for setdtmf!\n");
259
		return;
260
	}
261
	Oct6100ChannelModifyDef(modify);
262
	modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
263
	if (mute) {
264
		vpm450m->chanflags[channel] |= FLAG_MUTE;
265
		modify->VqeConfig.fDtmfToneRemoval = TRUE;
266
	} else {
267
		vpm450m->chanflags[channel] &= ~FLAG_MUTE;
268
		modify->VqeConfig.fDtmfToneRemoval = FALSE;
269
	}
270
	if (detect)
271
		vpm450m->chanflags[channel] |= FLAG_DTMF;
272
	else
273
		vpm450m->chanflags[channel] &= ~FLAG_DTMF;
274
	if (vpm450m->chanflags[channel] & (FLAG_DTMF|FLAG_MUTE)) {
275
		if (!(vpm450m->chanflags[channel] & FLAG_ECHO)) {
276
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
277
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
278
		}
279
	} else {
280
		if (!(vpm450m->chanflags[channel] & FLAG_ECHO))
281
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
282
	}
283
284
	ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
285
	if (ulResult != GENERIC_OK) {
286
		printk(KERN_NOTICE "Failed to apply dtmf mute changes on channel %d!\n", channel);
287
	}
288
/*	printk(KERN_DEBUG "VPM450m: Setting DTMF on channel %d: %s / %s\n", channel, (detect ? "DETECT" : "NO DETECT"), (mute ? "MUTE" : "NO MUTE")); */
289
	kfree(modify);
290
}
291
292
void vpm450m_setec(struct vpm450m *vpm450m, int channel, int eclen)
293
{
294
	if (eclen) {
295
		vpm450m->chanflags[channel] |= FLAG_ECHO;
296
		vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
297
		vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
298
	} else {
299
		vpm450m->chanflags[channel] &= ~FLAG_ECHO;
300
		if (vpm450m->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
301
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
302
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
303
		} else
304
			vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
305
	}
306
/*	printk(KERN_DEBUG "VPM450m: Setting EC on channel %d to %d\n", channel, eclen); */
307
}
308
309
int vpm450m_checkirq(struct vpm450m *vpm450m)
310
{
311
	tOCT6100_INTERRUPT_FLAGS InterruptFlags;
312
	
313
	Oct6100InterruptServiceRoutineDef(&InterruptFlags);
314
	Oct6100InterruptServiceRoutine(vpm450m->pApiInstance, &InterruptFlags);
315
316
	return InterruptFlags.fToneEventsPending ? 1 : 0;
317
}
318
319
int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start)
320
{
321
	tOCT6100_TONE_EVENT tonefound;
322
	tOCT6100_EVENT_GET_TONE tonesearch;
323
	UINT32 ulResult;
324
	
325
	Oct6100EventGetToneDef(&tonesearch);
326
	tonesearch.pToneEvent = &tonefound;
327
	tonesearch.ulMaxToneEvent = 1;
328
	ulResult = Oct6100EventGetTone(vpm450m->pApiInstance, &tonesearch);
329
	if (tonesearch.ulNumValidToneEvent) {
330
		if (channel)
331
			*channel = tonefound.ulUserChanId;
332
		if (tone) {
333
			switch(tonefound.ulToneDetected) {
334
			case SOUT_DTMF_1:
335
				*tone = '1';
336
				break;
337
			case SOUT_DTMF_2:
338
				*tone = '2';
339
				break;
340
			case SOUT_DTMF_3:
341
				*tone = '3';
342
				break;
343
			case SOUT_DTMF_A:
344
				*tone = 'A';
345
				break;
346
			case SOUT_DTMF_4:
347
				*tone = '4';
348
				break;
349
			case SOUT_DTMF_5:
350
				*tone = '5';
351
				break;
352
			case SOUT_DTMF_6:
353
				*tone = '6';
354
				break;
355
			case SOUT_DTMF_B:
356
				*tone = 'B';
357
				break;
358
			case SOUT_DTMF_7:
359
				*tone = '7';
360
				break;
361
			case SOUT_DTMF_8:
362
				*tone = '8';
363
				break;
364
			case SOUT_DTMF_9:
365
				*tone = '9';
366
				break;
367
			case SOUT_DTMF_C:
368
				*tone = 'C';
369
				break;
370
			case SOUT_DTMF_STAR:
371
				*tone = '*';
372
				break;
373
			case SOUT_DTMF_0:
374
				*tone = '0';
375
				break;
376
			case SOUT_DTMF_POUND:
377
				*tone = '#';
378
				break;
379
			case SOUT_DTMF_D:
380
				*tone = 'D';
381
				break;
382
			case SOUT_G168_1100GB_ON:
383
				*tone = 'f';
384
				break;
385
			default:
386
#ifdef OCTASIC_DEBUG
387
				printk(KERN_DEBUG "Unknown tone value %08x\n", tonefound.ulToneDetected);
388
#endif
389
				*tone = 'u';
390
				break;
391
			}
392
		}
393
		if (start)
394
			*start = (tonefound.ulEventType == cOCT6100_TONE_PRESENT);
395
		return 1;
396
	}
397
	return 0;
398
}
399
400
unsigned int get_vpm450m_capacity(void *wc)
401
{
402
	UINT32 ulResult;
403
404
	tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
405
406
	Oct6100ApiGetCapacityPinsDef(&CapacityPins);
407
	CapacityPins.pProcessContext = wc;
408
	CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
409
	CapacityPins.fEnableMemClkOut = TRUE;
410
	CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
411
412
	ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
413
	if (ulResult != cOCT6100_ERR_OK) {
414
		printk(KERN_DEBUG "Failed to get chip capacity, code %08x!\n", ulResult);
415
		return 0;
416
	}
417
418
	return CapacityPins.ulCapacityValue;
419
}
420
421
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
422
{
423
	tOCT6100_CHIP_OPEN *ChipOpen;
424
	tOCT6100_GET_INSTANCE_SIZE InstanceSize;
425
	tOCT6100_CHANNEL_OPEN *ChannelOpen;
426
	UINT32 ulResult;
427
	struct vpm450m *vpm450m;
428
	int x,y,law;
429
#ifdef CONFIG_4KSTACKS
430
	unsigned long flags;
431
#endif
432
	
433
	if (!(vpm450m = kmalloc(sizeof(struct vpm450m), GFP_KERNEL)))
434
		return NULL;
435
436
	memset(vpm450m, 0, sizeof(struct vpm450m));
437
438
	if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
439
		kfree(vpm450m);
440
		return NULL;
441
	}
442
443
	memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
444
445
	if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
446
		kfree(vpm450m);
447
		kfree(ChipOpen);
448
		return NULL;
449
	}
450
451
	memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
452
453
	for (x=0;x<128;x++)
454
		vpm450m->ecmode[x] = -1;
455
456
	vpm450m->numchans = numspans * 32;
457
	printk(KERN_INFO "VPM450: echo cancellation for %d channels\n", vpm450m->numchans);
458
		
459
	Oct6100ChipOpenDef(ChipOpen);
460
461
	/* Setup Chip Open Parameters */
462
	ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
463
	Oct6100GetInstanceSizeDef(&InstanceSize);
464
465
	ChipOpen->pProcessContext = wc;
466
467
	ChipOpen->pbyImageFile = firmware->data;
468
	ChipOpen->ulImageSize = firmware->size;
469
	ChipOpen->fEnableMemClkOut = TRUE;
470
	ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
471
	ChipOpen->ulMaxChannels = vpm450m->numchans;
472
	ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
473
	ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
474
	ChipOpen->ulNumMemoryChips = 1;
475
	ChipOpen->ulMaxTdmStreams = 4;
476
	ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
477
	ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
478
#if 0
479
	ChipOpen->fEnableAcousticEcho = TRUE;
480
#endif		
481
482
	ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
483
	if (ulResult != cOCT6100_ERR_OK) {
484
		printk(KERN_NOTICE "Failed to get instance size, code %08x!\n", ulResult);
485
		kfree(vpm450m);
486
		kfree(ChipOpen);
487
		kfree(ChannelOpen);
488
		return NULL;
489
	}
490
	
491
	
492
	vpm450m->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
493
	if (!vpm450m->pApiInstance) {
494
		printk(KERN_NOTICE "Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
495
		kfree(vpm450m);
496
		kfree(ChipOpen);
497
		kfree(ChannelOpen);
498
		return NULL;
499
	}
500
501
	/* I don't know what to curse more in this comment, the problems caused by
502
	 * the 4K kernel stack limit change or the octasic API for being so darn
503
	 * stack unfriendly.  Stupid, stupid, stupid.  So we disable IRQs so we
504
	 * don't run the risk of overflowing the stack while we initialize the
505
	 * octasic. */
506
#ifdef CONFIG_4KSTACKS
507
	local_irq_save(flags);
508
#endif
509
	ulResult = Oct6100ChipOpen(vpm450m->pApiInstance, ChipOpen);
510
	if (ulResult != cOCT6100_ERR_OK) {
511
		printk(KERN_NOTICE "Failed to open chip, code %08x!\n", ulResult);
512
#ifdef CONFIG_4KSTACKS
513
		local_irq_restore(flags);
514
#endif
515
		kfree(vpm450m);
516
		kfree(ChipOpen);
517
		kfree(ChannelOpen);
518
		return NULL;
519
	}
520
	for (x=0;x<128;x++) {
521
		if ((x & 0x03) < numspans) {
522
			/* span timeslots are interleaved 12341234... 
523
		 	*  therefore, the lower 2 bits tell us which span this 
524
			*  timeslot/channel
525
		 	*/
526
			if (isalaw[x & 0x03]) 
527
				law = cOCT6100_PCM_A_LAW;
528
			else
529
				law = cOCT6100_PCM_U_LAW;
530
			Oct6100ChannelOpenDef(ChannelOpen);
531
			ChannelOpen->pulChannelHndl = &vpm450m->aulEchoChanHndl[x];
532
			ChannelOpen->ulUserChanId = x;
533
			ChannelOpen->TdmConfig.ulRinPcmLaw = law;
534
			ChannelOpen->TdmConfig.ulRinStream = 0;
535
			ChannelOpen->TdmConfig.ulRinTimeslot = x;
536
			ChannelOpen->TdmConfig.ulSinPcmLaw = law;
537
			ChannelOpen->TdmConfig.ulSinStream = 1;
538
			ChannelOpen->TdmConfig.ulSinTimeslot = x;
539
			ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
540
			ChannelOpen->TdmConfig.ulSoutStream = 2;
541
			ChannelOpen->TdmConfig.ulSoutTimeslot = x;
542
			ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
543
			ChannelOpen->TdmConfig.ulRoutStream = 3;
544
			ChannelOpen->TdmConfig.ulRoutTimeslot = x;
545
			ChannelOpen->VqeConfig.fEnableNlp = TRUE;
546
			ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
547
			ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
548
			
549
			ChannelOpen->fEnableToneDisabler = TRUE;
550
			ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
551
			
552
			ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, ChannelOpen);
553
			if (ulResult != GENERIC_OK) {
554
				printk(KERN_NOTICE "Failed to open channel %d!\n", x);
555
			}
556
			for (y=0;y<sizeof(tones) / sizeof(tones[0]); y++) {
557
				tOCT6100_TONE_DETECTION_ENABLE enable;
558
				Oct6100ToneDetectionEnableDef(&enable);
559
				enable.ulChannelHndl = vpm450m->aulEchoChanHndl[x];
560
				enable.ulToneNumber = tones[y];
561
				if (Oct6100ToneDetectionEnable(vpm450m->pApiInstance, &enable) != GENERIC_OK) 
562
					printk(KERN_NOTICE "Failed to enable tone detection on channel %d for tone %d!\n", x, y);
563
			}
564
		}
565
	}
566
567
#ifdef CONFIG_4KSTACKS
568
	local_irq_restore(flags);
569
#endif
570
	kfree(ChipOpen);
571
	kfree(ChannelOpen);
572
	return vpm450m;
573
}
574
575
void release_vpm450m(struct vpm450m *vpm450m)
576
{
577
	UINT32 ulResult;
578
	tOCT6100_CHIP_CLOSE ChipClose;
579
580
	Oct6100ChipCloseDef(&ChipClose);
581
	ulResult = Oct6100ChipClose(vpm450m->pApiInstance, &ChipClose);
582
	if (ulResult != cOCT6100_ERR_OK) {
583
		printk(KERN_NOTICE "Failed to close chip, code %08x!\n", ulResult);
584
	}
585
	vfree(vpm450m->pApiInstance);
586
	kfree(vpm450m);
587
}
(-)dahdi-linux-2.7.0/drivers/dahdi/opvxd115/vpm450m.h (+43 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2005-2006 Digium, Inc.
3
 *
4
 * Mark Spencer <markster@digium.com>
5
 *
6
 * All Rights Reserved
7
 *
8
 */
9
10
/*
11
 * See http://www.asterisk.org for more information about
12
 * the Asterisk project. Please do not directly contact
13
 * any of the maintainers of this project for assistance;
14
 * the project provides a web site, mailing lists and IRC
15
 * channels for your use.
16
 *
17
 * This program is free software, distributed under the terms of
18
 * the GNU General Public License Version 2 as published by the
19
 * Free Software Foundation. See the LICENSE file included with
20
 * this program for more details.
21
 */
22
23
#ifndef _VPM450M_H
24
#define _VPM450M_H
25
26
#include <linux/firmware.h>
27
28
struct vpm450m;
29
30
/* From driver */
31
unsigned int oct_get_reg(void *data, unsigned int reg);
32
void oct_set_reg(void *data, unsigned int reg, unsigned int val);
33
34
/* From vpm450m */
35
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
36
unsigned int get_vpm450m_capacity(void *wc);
37
void vpm450m_setec(struct vpm450m *instance, int channel, int eclen);
38
void vpm450m_setdtmf(struct vpm450m *instance, int channel, int dtmfdetect, int dtmfmute);
39
int vpm450m_checkirq(struct vpm450m *vpm450m);
40
int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start);
41
void release_vpm450m(struct vpm450m *instance);
42
43
#endif
(-)dahdi-linux-2.7.0/drivers/dahdi/wcopenpci.c (+1784 lines)
Line 0 Link Here
1
/*
2
 * Voicetronix OpenPCI Interface Driver for Zapata Telephony interface
3
 *
4
 * Written by Mark Spencer <markster@linux-support.net>
5
 *            Matthew Fredrickson <creslin@linux-support.net>
6
 *            Ben Kramer <ben@voicetronix.com.au>
7
 *            Ron Lee <ron@voicetronix.com.au>
8
 *
9
 * Copyright (C) 2001, Linux Support Services, Inc.
10
 * Copyright (C) 2005 - 2007, Voicetronix
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
 *
28
 */
29
30
/* Conditional debug options */
31
#define VERBOSE_TIMING 0
32
33
/* Driver constants */
34
#define DRIVER_DESCRIPTION  "Voicetronix OpenPCI DAHDI driver"
35
#define DRIVER_AUTHOR	"Mark Spencer <markster@digium.com> "\
36
			"Voicetronix <support@voicetronix.com.au>"
37
38
#define NAME      "wcopenpci"
39
#define MAX_PORTS 8	    /* Maximum number of ports on each carrier */
40
#define MAX_CARDS 8	    /* Maximum number of carriers per host */
41
42
#define DEFAULT_COUNTRY  "AUSTRALIA"
43
44
45
#include <linux/init.h>
46
#include <linux/module.h>
47
#include <linux/pci.h>
48
#include <linux/delay.h>
49
#include <linux/sched.h>
50
51
#include <dahdi/kernel.h>
52
#include <dahdi/version.h>
53
#include "proslic.h"
54
#include <dahdi/wctdm_user.h>
55
#include <linux/interrupt.h>
56
#include <linux/mutex.h>
57
58
#include "fxo_modes.h"
59
60
static struct ps_country_reg {
61
	const char *country;
62
	unsigned short value;
63
} ps_country_regs[] = {
64
	{"ARGENTINA",  0x8},
65
	{"AUSTRALIA",  0xD},
66
	{"AUSTRIA",    0xD},
67
	{"BAHRAIN",    0xC},
68
	{"BELGIUM",    0xC},
69
	{"BRAZIL",     0x8},
70
	{"BULGARIA",   0xD},
71
	{"CANADA",     0x8},
72
	{"CHILE",      0x8},
73
	{"CHINA",      0xC},
74
	{"COLOMBIA",   0x8},
75
	{"CROATIA",    0xC},
76
	{"CYPRUS",     0xC},
77
	{"CZECH",      0xC},
78
	{"DENMARK",    0xC},
79
	{"ECUADOR",    0x8},
80
	{"EGYPT",      0x8},
81
	{"ELSALVADOR", 0x8},
82
	{"FINLAND",    0xC},
83
	{"FRANCE",     0xC},
84
	{"GERMANY",    0xD},
85
	{"GREECE",     0xC},
86
	{"GUAM",       0x8},
87
	{"HONGKONG",   0x8},
88
	{"HUNGARY",    0x8},
89
	{"ICELAND",    0xC},
90
	{"INDIA",      0xF},
91
	{"INDONESIA",  0x8},
92
	{"IRELAND",    0xC},
93
	{"ISRAEL",     0xC},
94
	{"ITALY",      0xC},
95
	{"JAPAN",      0x8},
96
	{"JORDAN",     0x8},
97
	{"KAZAKHSTAN", 0x8},
98
	{"KUWAIT",     0x8},
99
	{"LATVIA",     0xC},
100
	{"LEBANON",    0xC},
101
	{"LUXEMBOURG", 0xC},
102
	{"MACAO",      0x8},
103
	{"MALAYSIA",   0x8},
104
	{"MALTA",      0xC},
105
	{"MEXICO",     0x8},
106
	{"MOROCCO",    0xC},
107
	{"NETHERLANDS", 0xC},
108
	{"NEWZEALAND", 0xF},
109
	{"NIGERIA",    0xC},
110
	{"NORWAY",     0xC},
111
	{"OMAN",       0x8},
112
	{"PAKISTAN",   0x8},
113
	{"PERU",       0x8},
114
	{"PHILIPPINES", 0x8},
115
	{"POLAND",     0x8},
116
	{"PORTUGAL",   0xC},
117
	{"ROMANIA",    0x8},
118
	{"RUSSIA",     0x8},
119
	{"SAUDIARABIA", 0x8},
120
	{"SINGAPORE",  0x8},
121
	{"SLOVAKIA",   0xE},
122
	{"SLOVENIA",   0xE},
123
	{"SOUTHAFRICA", 0xE},
124
	{"SOUTHKOREA", 0x8},
125
	{"SPAIN",      0xC},
126
	{"SWEDEN",     0xC},
127
	{"SWITZERLAND", 0xC},
128
	{"SYRIA",      0x8},
129
	{"TAIWAN",     0x8},
130
	{"THAILAND",   0x8},
131
	{"UAE",        0x8},
132
	{"UK",         0xC},
133
	{"USA",        0x8},
134
	{"YEMEN",      0x8}
135
};
136
137
#define INOUT 2
138
139
/* Allocate enough memory for two zt chunks, receive and transmit.  Each
140
 * sample uses 32 bits.  Allocate an extra set just for control too */
141
#define VT_PCIDMA_BLOCKSIZE (DAHDI_MAX_CHUNKSIZE * INOUT * MAX_PORTS * 2 * 2)
142
#define VT_PCIDMA_MIDDLE    (DAHDI_MAX_CHUNKSIZE * MAX_PORTS - 4)
143
#define VT_PCIDMA_END       (DAHDI_MAX_CHUNKSIZE * MAX_PORTS * 2 - 4)
144
145
#define ID_DATA_MAXSIZE         30
146
147
#define NUM_CAL_REGS 12
148
#define NUM_FXO_REGS 60
149
150
#define TREG(addr)      (wc->ioaddr + addr)
151
152
#define TJ_CNTL         TREG(0x00)
153
#define TJ_OPER         TREG(0x01)
154
#define TJ_AUXC         TREG(0x02)
155
#define TJ_AUXD         TREG(0x03)
156
#define TJ_MASK0        TREG(0x04)
157
#define TJ_MASK1        TREG(0x05)
158
#define TJ_INTSTAT      TREG(0x06)
159
#define TJ_AUXR         TREG(0x07)
160
161
#define TJ_DMAWS        TREG(0x08)
162
#define TJ_DMAWI        TREG(0x0c)
163
#define TJ_DMAWE        TREG(0x10)
164
#define TJ_DMAWC        TREG(0x14)
165
#define TJ_DMARS        TREG(0x18)
166
#define TJ_DMARI        TREG(0x1c)
167
#define TJ_DMARE        TREG(0x20)
168
#define TJ_DMARC        TREG(0x24)
169
170
#define TJ_AUXINTPOL    TREG(0x2A)
171
172
#define TJ_AUXFUNC      TREG(0x2b)
173
#define TJ_SFDELAY      TREG(0x2c)
174
#define TJ_SERCTL       TREG(0x2d)
175
#define TJ_SFLC         TREG(0x2e)
176
#define TJ_FSCDELAY     TREG(0x2f)
177
178
#define TJ_REGBASE      TREG(0xc0)
179
180
#define PIB(addr)       (TJ_REGBASE + addr * 4)
181
182
#define HTXF_READY      (inb(PIB(0)) & 0x10)
183
#define HRXF_READY      (inb(PIB(0)) & 0x20)
184
185
186
#define VT_PORT_EMPTY	0
187
#define VT_PORT_VDAA	1   /* Voice DAA - FXO */
188
#define VT_PORT_PROSLIC	2   /* ProSLIC - FXS */
189
190
#define VBAT 0xC7
191
192
#define HKMODE_FWDACT   1
193
#define HKMODE_FWDONACT	2
194
#define HKMODE_RINGING	4
195
196
#define HOOK_ONHOOK     0
197
#define HOOK_OFFHOOK    1
198
199
#define	DSP_CODEC_RING		12	/* RING rising edge detected	*/
200
#define	DSP_CODEC_HKOFF		22	/* station port off hook        */
201
#define	DSP_CODEC_HKON		23	/* station port on hook         */
202
#define	DSP_RING_OFF		24	/* RING falling edge detected	*/
203
#define DSP_DROP		25
204
205
#define	DSP_CODEC_FLASH		26	/* station port hook flash      */
206
207
#define DSP_LOOP_OFFHOOK	38	/* Loop Off hook from OpenPCI   */
208
#define DSP_LOOP_ONHOOK		39	/* Loop On hook from OpenPCI    */
209
#define DSP_LOOP_POLARITY	40	/* Loop Polarity from OpenPCI   */
210
#define DSP_LOOP_NOBATT		41
211
212
#define DSP_PROSLIC_SANITY	50	/* Sanity alert from a ProSLIC port */
213
#define DSP_PROSLIC_PWR_ALARM	51	/* Power Alarm from a ProSLIC port  */
214
#define DSP_VDAA_ISO_FRAME_E	52	/* ISO-cap frame sync lost on VDAA port*/
215
216
#if VERBOSE_TIMING
217
 #define REPORT_WAIT(n,x)						    \
218
	 cardinfo(card->cardnum, #n " wait at %d, " #x " = %d", __LINE__, x )
219
#else
220
 #define REPORT_WAIT(n,x)
221
#endif
222
223
#define BUSY_WAIT(countvar,cond,delay,iter,failret)			    \
224
	countvar = 0;							    \
225
	while(cond){							    \
226
	    udelay(delay);						    \
227
	    if (++countvar > iter){					    \
228
		cardcrit(wc->boardnum, "busy wait FAILED at %d", __LINE__); \
229
		return failret;						    \
230
	    }								    \
231
	}								    \
232
	REPORT_WAIT(busy,i)
233
234
#define LOCKED_WAIT(countvar,cond,delay,iter,failret)			    \
235
	countvar = 0;							    \
236
	while(cond){							    \
237
	    udelay(delay);						    \
238
	    if (++countvar > iter){					    \
239
		dbginfo(wc->boardnum,"busy wait failed at %d",__LINE__);    \
240
		spin_unlock_irqrestore(&wc->lock, flags);		    \
241
		return failret;						    \
242
	    }								    \
243
	}								    \
244
	REPORT_WAIT(locked,i)
245
246
#define HTXF_WAIT()                 BUSY_WAIT(i,HTXF_READY,5,500,RET_FAIL)
247
#define HRXF_WAIT()                 BUSY_WAIT(i,!HRXF_READY,5,70000,RET_FAIL)
248
#define HTXF_WAIT_RET(failret)      BUSY_WAIT(i,HTXF_READY,5,500,failret)
249
#define HRXF_WAIT_RET(failret)      BUSY_WAIT(i,!HRXF_READY,5,1000,failret)
250
251
#define HTXF_WAIT_LOCKED()	    LOCKED_WAIT(i,HTXF_READY,5,500,RET_FAIL)
252
#define HRXF_WAIT_LOCKED()	    LOCKED_WAIT(i,!HRXF_READY,5,1000,RET_FAIL)
253
#define HTXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,HTXF_READY,5,500,failret)
254
#define HRXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,!HRXF_READY,5,1000,failret)
255
256
257
static struct openpci {
258
	struct pci_dev *dev;
259
	char *variety;
260
	int boardnum;
261
	int portcount;
262
	int porttype[MAX_PORTS];
263
264
        int firmware;
265
        char serial[ID_DATA_MAXSIZE];
266
267
	spinlock_t lock;
268
269
	//XXX Replace these with proper try_module_get locking in the dahdi driver.
270
	//int usecount;	//XXX
271
	//int dead;	//XXX
272
	union {
273
		struct {
274
			int offhook;
275
		} fxo;
276
		struct {
277
			int ohttimer;
278
			int idletxhookstate;  /* IDLE changing hook state */
279
			int lasttxhook;
280
		} fxs;
281
	} mod[MAX_PORTS];
282
283
	unsigned long		ioaddr;
284
	dma_addr_t		readdma;
285
	dma_addr_t		writedma;
286
	volatile unsigned int  *writechunk;  /* Double-word aligned write memory */
287
	volatile unsigned int  *readchunk;   /* Double-word aligned read memory */
288
289
	struct dahdi_chan _chans[MAX_PORTS];
290
	struct dahdi_chan *chans[MAX_PORTS];
291
	struct dahdi_device *ddev;
292
	struct dahdi_span span;
293
} *cards[MAX_CARDS];
294
295
/* You must hold this lock anytime you access or modify the cards[] array. */
296
static DEFINE_MUTEX(cards_mutex);
297
298
static unsigned char fxo_port_lookup[8] = { 0x0, 0x8, 0x4, 0xc, 0x10, 0x18, 0x14, 0x1c};
299
static unsigned char fxs_port_lookup[8] = { 0x0, 0x1, 0x2, 0x3, 0x10, 0x11, 0x12, 0x13};
300
static char wcopenpci[] = "Voicetronix OpenPCI";
301
302
static char *country = DEFAULT_COUNTRY;
303
static int reversepolarity;  /* = 0 */
304
static int debug;            /* = 0 */
305
306
module_param(country, charp, 0444);
307
module_param(debug, int, 0600);
308
module_param(reversepolarity, int, 0600);
309
MODULE_PARM_DESC(country, "Set the default country name");
310
MODULE_PARM_DESC(debug, "Enable verbose logging");
311
312
/* #define DEBUG_LOOP_VOLTAGE 1 */
313
#ifdef DEBUG_LOOP_VOLTAGE
314
 /* This param is a 32 bit bitfield where bit 1 << cardnum * 8 << portnum
315
  * will enable voltage monitoring on that port (fxo only presently)
316
  */
317
 static int voltmeter;        /* = 0 */
318
 module_param(voltmeter, int, 0600);
319
 MODULE_PARM_DESC(voltmeter, "Enable loop voltage metering");
320
#endif
321
322
323
/* boolean return values */
324
#define RET_OK   1
325
#define RET_FAIL 0
326
327
/* Convenience macros for logging */
328
#define info(format,...) printk(KERN_INFO NAME ": " format "\n" , ## __VA_ARGS__)
329
#define warn(format,...) printk(KERN_WARNING NAME ": " format "\n" , ## __VA_ARGS__)
330
#define crit(format,...) printk(KERN_CRIT NAME ": " format "\n" , ## __VA_ARGS__)
331
#define cardinfo(cardnum,format,...) info("[%02d] " format, cardnum , ## __VA_ARGS__)
332
#define cardwarn(cardnum,format,...) warn("[%02d] " format, cardnum , ## __VA_ARGS__)
333
#define cardcrit(cardnum,format,...) crit("[%02d] " format, cardnum , ## __VA_ARGS__)
334
#define dbginfo(cardnum,format,...) if (debug) info("[%02d] " format, cardnum , ## __VA_ARGS__)
335
336
337
static inline const char *porttype(struct openpci *wc, int port)
338
{
339
	switch( wc->porttype[port] ) {
340
		case VT_PORT_VDAA:    return "VDAA";
341
		case VT_PORT_PROSLIC: return "ProSLIC";
342
		case VT_PORT_EMPTY:   return "empty port";
343
		default:              return "unknown type";
344
	}
345
}
346
347
348
static int __read_reg_fxo(struct openpci *wc, int port, unsigned char reg,
349
		unsigned char *value)
350
{
351
	unsigned char portadr = fxo_port_lookup[port];
352
	int i;
353
354
	if (HRXF_READY) *value = inb(PIB(1));
355
356
	outb(0x11, PIB(1));    HTXF_WAIT();
357
	outb(0x2, PIB(1));     HTXF_WAIT();
358
	outb(portadr, PIB(1)); HTXF_WAIT();
359
	outb(reg, PIB(1));     HTXF_WAIT();
360
	HRXF_WAIT(); *value = inb(PIB(1));
361
362
	return RET_OK;
363
}
364
365
static int read_reg_fxo(struct openpci *wc, int port, unsigned char reg,
366
		unsigned char *value)
367
{
368
	unsigned long flags;
369
370
	spin_lock_irqsave(&wc->lock, flags);
371
	if (__read_reg_fxo(wc, port, reg, value)) {
372
		spin_unlock_irqrestore(&wc->lock, flags);
373
		return RET_OK;
374
	}
375
	spin_unlock_irqrestore(&wc->lock, flags);
376
	cardcrit(wc->boardnum, "FXO port %d, reg %d, read failed!", port, reg);
377
	return RET_FAIL;
378
}
379
380
static int __read_reg_fxs(struct openpci *wc, int port, unsigned char reg,
381
		unsigned char *value)
382
{
383
	unsigned char portadr = fxs_port_lookup[port];
384
	int i;
385
386
	if (HRXF_READY) *value = inb(PIB(1));
387
388
	outb(0x13, PIB(1));    HTXF_WAIT();
389
	outb(0x2, PIB(1));     HTXF_WAIT();
390
	outb(portadr, PIB(1)); HTXF_WAIT();
391
	outb(reg, PIB(1));     HTXF_WAIT();
392
	HRXF_WAIT(); *value = inb(PIB(1));
393
394
	return RET_OK;
395
}
396
397
static int read_reg_fxs(struct openpci *wc, int port, unsigned char reg,
398
		unsigned char *value)
399
{
400
	unsigned long flags;
401
402
	spin_lock_irqsave(&wc->lock, flags);
403
	if ( __read_reg_fxs(wc, port, reg, value) ) {
404
		spin_unlock_irqrestore(&wc->lock, flags);
405
		return RET_OK;
406
	}
407
	spin_unlock_irqrestore(&wc->lock, flags);
408
	cardcrit(wc->boardnum, "FXS port %d, reg %d, read failed!", port, reg);
409
	return RET_FAIL;
410
}
411
412
static int __write_reg_fxo(struct openpci *wc, int port, unsigned char reg,
413
		unsigned char value)
414
{
415
	unsigned char portadr = fxo_port_lookup[port];
416
	int i;
417
418
        outb(0x10, PIB(1) );   HTXF_WAIT();
419
        outb(0x3, PIB(1));     HTXF_WAIT();
420
        outb(portadr, PIB(1)); HTXF_WAIT();
421
        outb(reg, PIB(1));     HTXF_WAIT();
422
        outb(value, PIB(1));   HTXF_WAIT();
423
424
	return RET_OK;
425
}
426
427
static int write_reg_fxo(struct openpci *wc, int port, unsigned char reg,
428
		unsigned char value)
429
{
430
	unsigned long flags;
431
432
	spin_lock_irqsave(&wc->lock, flags);
433
	if (__write_reg_fxo(wc, port, reg, value)) {
434
		spin_unlock_irqrestore(&wc->lock, flags);
435
		return RET_OK;
436
	}
437
	spin_unlock_irqrestore(&wc->lock, flags);
438
	cardcrit(wc->boardnum, "FXO port %d, reg %d, write(%d) failed!",
439
			port, reg, value);
440
	return RET_FAIL;
441
}
442
443
static int __write_reg_fxs(struct openpci *wc, int port, unsigned char reg,
444
		unsigned char value)
445
{
446
	unsigned char portadr = fxs_port_lookup[port];
447
	int i;
448
449
        outb(0x12, PIB(1) );   HTXF_WAIT();
450
        outb(0x3, PIB(1));     HTXF_WAIT();
451
        outb(portadr, PIB(1)); HTXF_WAIT();
452
        outb(reg, PIB(1));     HTXF_WAIT();
453
        outb(value, PIB(1));   HTXF_WAIT();
454
455
	return RET_OK;
456
}
457
458
static int write_reg_fxs(struct openpci *wc, int port, unsigned char reg,
459
		unsigned char value)
460
{
461
	unsigned long flags;
462
463
	spin_lock_irqsave(&wc->lock, flags);
464
	if (__write_reg_fxs(wc, port, reg, value)) {
465
		spin_unlock_irqrestore(&wc->lock, flags);
466
		return RET_OK;
467
	}
468
	spin_unlock_irqrestore(&wc->lock, flags);
469
	cardcrit(wc->boardnum, "FXS port %d, reg %d, write(%d) failed!", port, reg, value);
470
	return RET_FAIL;
471
}
472
473
static int __wait_indreg_fxs(struct openpci *wc, int port)
474
{
475
	unsigned char value;
476
	int count = 100;
477
478
	while (--count) {
479
		if ( __read_reg_fxs(wc, port, I_STATUS, &value)) {
480
			if (value == 0)
481
				return RET_OK;
482
		} else {
483
			cardcrit(wc->boardnum,
484
				 "failed to read port %d PS_IND_ADDR_ST, retrying...",
485
				 port);
486
		}
487
		udelay(5);
488
	}
489
	cardcrit(wc->boardnum, "Failed to wait for indirect reg write to port %d", port);
490
	return RET_FAIL;
491
}
492
493
static int write_indreg_fxs(struct openpci *wc, int port, unsigned char reg,
494
		unsigned short value)
495
{
496
	unsigned long flags;
497
498
	spin_lock_irqsave(&wc->lock, flags);
499
	if (__wait_indreg_fxs(wc, port)
500
	 && __write_reg_fxs(wc, port, IDA_LO, value & 0xff)
501
	 && __write_reg_fxs(wc, port, IDA_HI, (value & 0xff00)>>8)
502
	 && __write_reg_fxs(wc, port, IAA, reg)
503
	 && __wait_indreg_fxs(wc, port))
504
	{
505
		spin_unlock_irqrestore(&wc->lock, flags);
506
		return RET_OK;
507
	}
508
	spin_unlock_irqrestore(&wc->lock, flags);
509
	cardcrit(wc->boardnum, "FXS indreg %d write failed on port %d",
510
			reg, port);
511
	return RET_FAIL;
512
}
513
514
static int read_indreg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned short *value)
515
{
516
	unsigned long flags;
517
	unsigned char lo, hi;
518
519
	spin_lock_irqsave(&wc->lock, flags);
520
	if (__wait_indreg_fxs(wc, port)
521
	 && __write_reg_fxs(wc, port, IAA, reg)
522
	 && __wait_indreg_fxs(wc, port)
523
	 && __read_reg_fxs(wc, port, IDA_LO, &lo)
524
	 && __read_reg_fxs(wc, port, IDA_HI, &hi) )
525
	{
526
		*value = lo | hi << 8;
527
		spin_unlock_irqrestore(&wc->lock, flags);
528
		return RET_OK;
529
	}
530
	spin_unlock_irqrestore(&wc->lock, flags);
531
	return RET_FAIL;
532
}
533
534
static void start_dma(struct openpci *wc)
535
{
536
	outb(0x0f, TJ_CNTL);
537
	set_current_state(TASK_INTERRUPTIBLE);
538
	schedule_timeout(1);
539
	outb(0x01, TJ_CNTL);
540
	outb(0x01, TJ_OPER);
541
}
542
543
static void restart_dma(struct openpci *wc)
544
{
545
	/* Reset Master and TDM */
546
	outb(0x01, TJ_CNTL);
547
	outb(0x01, TJ_OPER);
548
}
549
550
/* You must hold the card spinlock to call this function */
551
static int __ping_arm(struct openpci *wc)
552
{
553
	int i;
554
	int pong = 0;
555
556
	while (pong != 0x02) {
557
		outb(0x02, PIB(1)); HTXF_WAIT();
558
		HRXF_WAIT(); pong = inb(PIB(1));
559
		dbginfo(wc->boardnum, "ping_arm returned %x", pong);
560
	}
561
	while (pong == 0x02) {
562
		// Poke no-ops into the arm while it is still returning data,
563
		// if 500 usec elapses with no further response from it then
564
		// the message queue is should be completely cleared.
565
		outb(0x00, PIB(1)); HTXF_WAIT();
566
		i = 100;
567
		while (!HRXF_READY && --i)
568
			udelay(5);
569
		if (i == 0)
570
			break;
571
		pong = inb(PIB(1));
572
		dbginfo(wc->boardnum, "ping_arm returned %x.", pong);
573
	}
574
	return RET_OK;
575
}
576
577
static void arm_event(struct openpci *wc, char *msg)
578
{
579
	int port = msg[0];
580
581
	switch (msg[1]) {
582
		case DSP_LOOP_OFFHOOK:
583
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
584
			dbginfo(wc->boardnum, "Port %d Loop OffHook", port);
585
			break;
586
587
		case DSP_LOOP_ONHOOK:
588
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
589
			dbginfo(wc->boardnum, "Port %d Loop OnHook", port);
590
			break;
591
592
		case DSP_LOOP_POLARITY:
593
			dahdi_qevent_lock(wc->chans[port], DAHDI_EVENT_POLARITY);
594
			dbginfo(wc->boardnum, "Port %d Loop Polarity", port);
595
			break;
596
597
		case DSP_CODEC_RING:
598
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_RING);
599
			dbginfo(wc->boardnum, "Port %d Ring On", port);
600
			break;
601
602
		case DSP_RING_OFF:
603
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
604
			dbginfo(wc->boardnum, "Port %d Ring Off", port);
605
			break;
606
607
		case DSP_CODEC_HKOFF:
608
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
609
			dbginfo(wc->boardnum, "Port %d Station OffHook", port);
610
			if (reversepolarity)
611
				wc->mod[port].fxs.idletxhookstate = 5;
612
			else
613
				wc->mod[port].fxs.idletxhookstate = 1;
614
			break;
615
616
		case DSP_CODEC_HKON:
617
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
618
			dbginfo(wc->boardnum, "Port %d Station OnHook", port);
619
			if (reversepolarity)
620
				wc->mod[port].fxs.idletxhookstate = 6;
621
			else
622
				wc->mod[port].fxs.idletxhookstate = 2;
623
			break;
624
625
		case DSP_CODEC_FLASH:
626
			dahdi_qevent_lock(wc->chans[port],
627
					DAHDI_EVENT_WINKFLASH);
628
			dbginfo(wc->boardnum, "Port %d Station Flash", port);
629
			break;
630
631
		case DSP_DROP:
632
		case DSP_LOOP_NOBATT:
633
			break;
634
635
			//XXX What to do to recover from these?
636
		case DSP_PROSLIC_SANITY:
637
			dbginfo(wc->boardnum, "Port %d ProSlic has gone insane!", port);
638
			break;
639
640
		case DSP_PROSLIC_PWR_ALARM:
641
		{
642
			char errbuf[32] = " Unknown", *p = errbuf;
643
			int i = 49;
644
645
			msg[2] >>= 2;
646
			for (; i < 55; ++i, msg[2] >>= 1 )
647
			    if (msg[2] & 1) {
648
				    *(++p) = 'Q';
649
				    *(++p) = i;
650
				    *(++p) = ',';
651
			    }
652
			if (p != errbuf)
653
				*p = '\0';
654
			cardcrit(wc->boardnum,"%d: ProSlic power ALARM:%s",
655
					msg[0], errbuf);
656
			//write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook );
657
			return;
658
		}
659
660
		case DSP_VDAA_ISO_FRAME_E:
661
			dbginfo(wc->boardnum, "Port %d VDAA has lost ISO-Cap frame lock", port);
662
			break;
663
664
		default:
665
			cardwarn(wc->boardnum, "Unknown message from Arm[%d] for port %d",
666
						msg[1], port);
667
			break;
668
	}
669
}
670
671
/* You must hold the card spinlock to call this function */
672
static inline int __read_arm_byte( struct openpci *wc, unsigned char *msg)
673
{
674
	int i;
675
676
	HRXF_WAIT(); *msg = inb(PIB(1));
677
	return RET_OK;
678
}
679
680
static inline int read_arm_msg( struct openpci *wc, unsigned char *msg)
681
{
682
	unsigned long flags;
683
	int i, d, count;
684
	int ret = RET_OK;
685
686
	spin_lock_irqsave(&wc->lock, flags);
687
	outb(0x08, PIB(1)); HTXF_WAIT_LOCKED();
688
	//XXX Do we need to clear the interrupt flag even if this fails?
689
	HRXF_WAIT_LOCKED(); count = inb(PIB(1));
690
	if (count == 0) {
691
		ret = RET_FAIL;
692
	} else if ( count < 3 || count > 4 ) {
693
		cardcrit(wc->boardnum, "BOGUS arm message size %d, flushing queue", count);
694
		// NB: This may take a while (up to 500usec or more) to complete
695
		//     and we are in the isr at present when this is called, so
696
		//     we may miss an interrupt or two while this is done in the
697
		//     bottom half, but we are already in trouble, so...
698
		d = debug; debug = 5; __ping_arm( wc ); debug = d;
699
		ret = RET_FAIL;
700
	} else while (--count ) {
701
		if (! __read_arm_byte(wc, msg)) {
702
			cardcrit(wc->boardnum,
703
				 "Failed to read arm message %d more bytes expected",
704
				 count);
705
			ret = RET_FAIL;
706
			break;
707
		}
708
		++msg;
709
	}
710
	outb(0x09, PIB(1)); HTXF_WAIT_LOCKED();
711
	spin_unlock_irqrestore(&wc->lock, flags);
712
	return ret;
713
}
714
715
static void openpci_arm_work( void *cardptr )
716
{
717
	struct openpci *wc = (struct openpci*)cardptr;
718
	unsigned char armmsg[4];
719
720
	if (read_arm_msg(wc, armmsg))
721
		arm_event(wc, armmsg);
722
}
723
724
725
static inline void openpci_write(struct openpci *wc, unsigned char flags)
726
{
727
	int x,y;
728
	volatile unsigned int *writechunk;
729
730
	if (flags & 0x01)
731
		writechunk = wc->writechunk;
732
	else if (flags & 0x02)
733
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE*2;
734
	else {
735
		cardcrit(wc->boardnum, "bad write interrupt flags %x, at %x",
736
					flags, inb(TJ_DMAWC) );
737
		return;
738
	}
739
	/* get data */
740
	dahdi_transmit(&wc->span);
741
	for (y = 0, x = 0; x < DAHDI_CHUNKSIZE; ++x) {
742
		/* Send a sample, as a 32-bit word */
743
#ifdef __BIG_ENDIAN
744
#warning No big endian support (yet)
745
#else
746
		/* transmit second 4 ports */
747
		writechunk[y] = 0;
748
		if (wc->porttype[4])
749
			writechunk[y] |= (wc->chans[4]->writechunk[x] << 24);
750
		else
751
			writechunk[y] |= (0x01 << 24);
752
		if (wc->porttype[5])
753
			writechunk[y] |= (wc->chans[5]->writechunk[x] << 16);
754
		if (wc->porttype[6])
755
			writechunk[y] |= (wc->chans[6]->writechunk[x] << 8);
756
		if (wc->porttype[7])
757
			writechunk[y] |= (wc->chans[7]->writechunk[x]);
758
		++y;
759
760
		/* transmit first 4 ports */
761
		writechunk[y] = 0x01000000;
762
		/* Make sure first port doesnt equal 0x00 */
763
		if (wc->porttype[0]) {
764
			if (wc->chans[0]->writechunk[x] == 0)
765
				writechunk[y] |= (0x01 << 24);
766
			else
767
				writechunk[y] |= (wc->chans[0]->writechunk[x] << 24);
768
		}
769
		//else writechunk[y] |= (0x00 << 24);
770
		if (wc->porttype[1])
771
			writechunk[y] |= (wc->chans[1]->writechunk[x] << 16);
772
		if (wc->porttype[2])
773
			writechunk[y] |= (wc->chans[2]->writechunk[x] << 8);
774
		if (wc->porttype[3])
775
			writechunk[y] |= (wc->chans[3]->writechunk[x]);
776
		++y;
777
#endif
778
	}
779
}
780
781
static inline void openpci_read(struct openpci *wc, unsigned char flags)
782
{
783
	int x,y;
784
	volatile unsigned int *readchunk;
785
786
	if (flags & 0x08)
787
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE*2;
788
	else if (flags & 0x04)
789
		readchunk = wc->readchunk;
790
	else {
791
		cardcrit(wc->boardnum, "bad read interrupt flags %x, at %x",
792
					flags, inb(TJ_DMARC));
793
		return;
794
	}
795
796
	for (y = 0,x = 0; x < DAHDI_CHUNKSIZE; ++x) {
797
#ifdef __BIG_ENDIAN
798
#warning No big endian support (yet)
799
#else
800
		/* Receive first 4 ports */
801
802
		if (wc->porttype[0])
803
			wc->chans[0]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
804
		if (wc->porttype[1])
805
			wc->chans[1]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
806
		if (wc->porttype[2])
807
			wc->chans[2]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
808
		if (wc->porttype[3])
809
			wc->chans[3]->readchunk[x] = (readchunk[y]) & 0xff;
810
		++y;
811
		/* Receive second 4 ports */
812
		if (wc->porttype[4])
813
			wc->chans[4]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
814
		if (wc->porttype[5])
815
			wc->chans[5]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
816
		if (wc->porttype[6])
817
			wc->chans[6]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
818
		if (wc->porttype[7])
819
			wc->chans[7]->readchunk[x] = (readchunk[y]) & 0xff;
820
		++y;
821
#endif
822
	}
823
	/* XXX We're wasting 8 taps.  We should get closer :( */
824
	for (x = 0; x < MAX_PORTS; x++) {
825
		if (wc->porttype[x])
826
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
827
	}
828
	dahdi_receive(&wc->span);
829
}
830
831
DAHDI_IRQ_HANDLER(openpci_isr)
832
{
833
	struct openpci *wc = dev_id;
834
	unsigned long flags;
835
	unsigned char status;
836
837
	spin_lock_irqsave(&wc->lock, flags);
838
	status = inb(TJ_INTSTAT);
839
	outb(status, TJ_INTSTAT);
840
841
	if (!status) {
842
		if (inb(TJ_AUXR) & 0x02) {
843
			spin_unlock_irqrestore(&wc->lock, flags);
844
			return IRQ_NONE;
845
		}
846
		spin_unlock_irqrestore(&wc->lock, flags);
847
		openpci_arm_work(wc);
848
		return IRQ_HANDLED;
849
	}
850
	if (status & 0x10) {
851
		/* PCI Master abort */
852
		cardcrit(wc->boardnum, "PCI Master Abort.");
853
		/* Stop DMA, wait for watchdog */
854
		outb(0x00, TJ_OPER);
855
		spin_unlock_irqrestore(&wc->lock, flags);
856
		return IRQ_HANDLED;
857
	}
858
	spin_unlock_irqrestore(&wc->lock, flags);
859
860
	if (status & 0x20) {
861
		/* PCI Target abort */
862
		cardcrit(wc->boardnum, "PCI Target Abort.");
863
		return IRQ_HANDLED;
864
	}
865
	if (status & 0x03) {
866
		openpci_write(wc, status);
867
	}
868
	if (status & 0x0c) {
869
	    #ifdef DEBUG_LOOP_VOLTAGE
870
	    //{{{
871
		static int counter[MAX_CARDS];
872
		int card = wc->boardnum;
873
		int port = ++counter[card] & 0x07;
874
		int ignore = counter[card] & 0xf0;
875
876
		if (!ignore && (voltmeter & ((1 << (card * 8)) << port))) {
877
			unsigned char lv;
878
			if (wc->porttype[port] == VT_PORT_VDAA &&
879
					read_reg_fxo(wc, port, 29, &lv))
880
				cardinfo(wc->boardnum, "Port %d loop voltage %d",
881
							port, lv < 128 ? lv :
882
							lv - 256);
883
		}
884
	    //}}}
885
	    #endif
886
		openpci_read(wc, status);
887
	}
888
889
	return IRQ_HANDLED;
890
}
891
892
static int openpci_ioctl(struct dahdi_chan *chan, unsigned int cmd,
893
		unsigned long data)
894
{
895
	struct wctdm_stats stats;
896
	struct wctdm_regs regs;
897
	struct wctdm_regop regop;
898
	struct wctdm_echo_coefs echoregs;
899
	struct openpci *wc = chan->pvt;
900
	int port = chan->chanpos - 1;
901
	int x;
902
903
	switch (cmd) {
904
	case DAHDI_ONHOOKTRANSFER:
905
		if (wc->porttype[port] != VT_PORT_PROSLIC)
906
			return -EINVAL;
907
		if (get_user(x, (int __user *)data))
908
			return -EFAULT;
909
		wc->mod[port].fxs.ohttimer = x << 3;
910
		if (reversepolarity)
911
			wc->mod[port].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
912
		else
913
			wc->mod[port].fxs.idletxhookstate = 0x2;
914
		switch (wc->mod[port].fxs.lasttxhook) {
915
		    case 0x1:
916
		    case 0x5:
917
			if (reversepolarity)
918
				wc->mod[port].fxs.lasttxhook = 0x6;
919
			else
920
				wc->mod[port].fxs.lasttxhook = 0x2;
921
			if (!write_reg_fxs(wc, port, 64,
922
						wc->mod[port].fxs.lasttxhook))
923
				return -EIO;
924
		}
925
		break;
926
	case DAHDI_SETPOLARITY:
927
		if (get_user(x, (int __user *)data))
928
			return -EFAULT;
929
		if (wc->porttype[port] != VT_PORT_PROSLIC)
930
			return -EINVAL;
931
		/* Can't change polarity while ringing or when open */
932
		if ((wc->mod[port].fxs.lasttxhook == 0x04) ||
933
		    (wc->mod[port].fxs.lasttxhook == 0x00))
934
			return -EINVAL;
935
936
		if ((x && !reversepolarity) || (!x && reversepolarity))
937
			wc->mod[port].fxs.lasttxhook |= 0x04;
938
		else
939
			wc->mod[port].fxs.lasttxhook &= ~0x04;
940
		if (!write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook))
941
			return -EIO;
942
		break;
943
	case WCTDM_GET_STATS:
944
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
945
			unsigned char	linevolt;
946
			if (read_reg_fxs(wc, port, 80, &linevolt))
947
				stats.tipvolt = linevolt * -376;
948
			else
949
				return -EIO;
950
			if (read_reg_fxs(wc, port, 81, &linevolt))
951
				stats.ringvolt = linevolt * -376;
952
			else
953
				return -EIO;
954
			if (read_reg_fxs(wc, port, 82, &linevolt))
955
				stats.batvolt = linevolt * -376;
956
			else
957
				return -EIO;
958
		} else if (wc->porttype[port] == VT_PORT_VDAA) {
959
			unsigned char	linevolt;
960
			if (read_reg_fxo(wc, port, 29, &linevolt))
961
				stats.tipvolt = stats.ringvolt = stats.batvolt = linevolt * 1000;
962
			else
963
				return -EIO;
964
		} else
965
			return -EINVAL;
966
		if (copy_to_user((void __user *)data, &stats, sizeof(stats)))
967
			return -EFAULT;
968
		break;
969
	case WCTDM_GET_REGS:
970
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
971
			for (x = 0; x < NUM_INDIRECT_REGS; x++)
972
				if (!read_indreg_fxs(wc, port, x,
973
							&regs.indirect[x]))
974
					return -EIO;
975
			for (x = 0; x < NUM_REGS; x++)
976
				if (!read_reg_fxs(wc, port, x, &regs.direct[x]))
977
					return -EIO;
978
		} else {
979
			memset(&regs, 0, sizeof(regs));
980
			for (x = 0; x < NUM_FXO_REGS; x++) {
981
				if (!read_reg_fxo(wc, port, x, &regs.direct[x]))
982
					return -EIO;
983
			}
984
		}
985
		if (copy_to_user((void __user *)data, &regs, sizeof(regs)))
986
			return -EFAULT;
987
		break;
988
	case WCTDM_SET_REG:
989
		if (copy_from_user(&regop, (void __user *)data, sizeof(regop)))
990
			return -EFAULT;
991
		if (regop.indirect) {
992
			if (wc->porttype[port] != VT_PORT_PROSLIC)
993
				return -EINVAL;
994
			printk("Setting indirect %d to 0x%04x on %d\n",
995
				regop.reg, regop.val, chan->chanpos);
996
			if (!write_indreg_fxs(wc, port, regop.reg, regop.val))
997
				return -EIO;
998
		} else {
999
			regop.val &= 0xff;
1000
			printk("Setting direct %d to %04x on %d\n",
1001
				regop.reg, regop.val, chan->chanpos);
1002
			if (wc->porttype[port] == VT_PORT_PROSLIC) {
1003
				if (!write_reg_fxs(wc, port, regop.reg,
1004
							regop.val))
1005
					return -EIO;
1006
			} else {
1007
				if (!write_reg_fxo(wc, port, regop.reg,
1008
							regop.val))
1009
					return -EIO;
1010
			}
1011
		}
1012
		break;
1013
	case WCTDM_SET_ECHOTUNE:
1014
		cardinfo(wc->boardnum, "Setting echo registers");
1015
		if (copy_from_user(&echoregs, (void __user *)data, sizeof(echoregs)))
1016
			return -EFAULT;
1017
1018
		if (wc->porttype[port] == VT_PORT_VDAA) {
1019
			/* Set the ACIM and digital echo canceller registers */
1020
			if (!write_reg_fxo(wc, port, 30, echoregs.acim)
1021
			 || ! write_reg_fxo(wc, port, 45, echoregs.coef1)
1022
			 || ! write_reg_fxo(wc, port, 46, echoregs.coef2)
1023
			 || ! write_reg_fxo(wc, port, 47, echoregs.coef3)
1024
			 || ! write_reg_fxo(wc, port, 48, echoregs.coef4)
1025
			 || ! write_reg_fxo(wc, port, 49, echoregs.coef5)
1026
			 || ! write_reg_fxo(wc, port, 50, echoregs.coef6)
1027
			 || ! write_reg_fxo(wc, port, 51, echoregs.coef7)
1028
			 || ! write_reg_fxo(wc, port, 52, echoregs.coef8))
1029
			{
1030
				cardcrit(wc->boardnum, "Failed to set echo registers");
1031
				return -EIO;
1032
			}
1033
			break;
1034
		} else {
1035
			return -EINVAL;
1036
		}
1037
		break;
1038
	default:
1039
		return -ENOTTY;
1040
	}
1041
	return 0;
1042
}
1043
1044
static int openpci_open(struct dahdi_chan *chan)
1045
{
1046
	struct openpci *wc = chan->pvt;
1047
	if (!wc->porttype[chan->chanpos-1])
1048
		return -ENODEV;
1049
1050
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1051
	//    as the owner of the span that holds the pointer to this function,
1052
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1053
	//    fatal call to an invalid pointer is made.
1054
	//if (wc->dead) return -ENODEV;
1055
	//wc->usecount++;
1056
	try_module_get(THIS_MODULE);  //XXX
1057
1058
	return 0;
1059
}
1060
1061
static inline struct openpci* openpci_from_span(struct dahdi_span *span) {
1062
	return container_of(span, struct openpci, span);
1063
}
1064
1065
static int openpci_watchdog(struct dahdi_span *span, int event)
1066
{
1067
	info("TDM: Restarting DMA");
1068
	restart_dma(openpci_from_span(span));
1069
	return 0;
1070
}
1071
1072
static int openpci_close(struct dahdi_chan *chan)
1073
{
1074
	struct openpci *wc = chan->pvt;
1075
	int port = chan->chanpos - 1;
1076
1077
	//XXX wc->usecount--;
1078
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1079
	//    as the owner of the span that holds the pointer to this function,
1080
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1081
	//    fatal call to an invalid pointer is made.
1082
	module_put(THIS_MODULE);
1083
	if (wc->porttype[port] == VT_PORT_PROSLIC) {
1084
		if (reversepolarity)
1085
			wc->mod[port].fxs.idletxhookstate = 5;
1086
		else
1087
			wc->mod[port].fxs.idletxhookstate = 1;
1088
	}
1089
	/* If we're dead, release us now */
1090
	//XXX if (!wc->usecount && wc->dead) openpci_release(wc);
1091
1092
	return 0;
1093
}
1094
1095
static int openpci_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
1096
{
1097
	struct openpci *wc = chan->pvt;
1098
	int port = chan->chanpos - 1;
1099
	int new_hk_state;
1100
1101
	dbginfo(wc->boardnum, "Setting %s port %d hook state %s",
1102
		 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1103
		 port,
1104
		 txsig == 0 ? "ONHOOK" :
1105
		 txsig == 1 ? "OFFHOOK" :
1106
		 txsig == 2 ? "START" :
1107
		 txsig == 3 ? "KEWL" : "UNKNOWN" );
1108
1109
	switch(wc->porttype[port]) {
1110
	    case VT_PORT_VDAA:
1111
		switch(txsig) {
1112
		    case DAHDI_TXSIG_START:
1113
		    case DAHDI_TXSIG_OFFHOOK:
1114
			if (write_reg_fxo(wc, port, 5, 0x9)
1115
					&& write_reg_fxo(wc, port, 0x20, 0x0))
1116
				wc->mod[port].fxo.offhook = 1;
1117
			else
1118
				cardcrit(wc->boardnum,
1119
						"Failed set fxo off-hook");
1120
			break;
1121
1122
		    case DAHDI_TXSIG_ONHOOK:
1123
			if (write_reg_fxo(wc, port, 5, 0x8)
1124
			 && write_reg_fxo(wc, port, 0x20, 0x3))
1125
				wc->mod[port].fxo.offhook = 0;
1126
			else
1127
				cardcrit(wc->boardnum, "Failed set fxo on-hook");
1128
			break;
1129
1130
		    default:
1131
			cardcrit(wc->boardnum,
1132
				 "Can't set FXO port %d tx state to %d",
1133
				 port, txsig);
1134
		}
1135
		break;
1136
1137
	    case VT_PORT_PROSLIC:
1138
		new_hk_state = wc->mod[port].fxs.lasttxhook;
1139
		switch(txsig) {
1140
		    case DAHDI_TXSIG_ONHOOK:
1141
			switch(chan->sig) {
1142
			case DAHDI_SIG_EM:
1143
			case DAHDI_SIG_FXOKS:
1144
			case DAHDI_SIG_FXOLS:
1145
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1146
				break;
1147
			case DAHDI_SIG_FXOGS:
1148
				new_hk_state = 3;
1149
				break;
1150
			}
1151
			break;
1152
1153
		    case DAHDI_TXSIG_OFFHOOK:
1154
			switch(chan->sig) {
1155
			case DAHDI_SIG_EM:
1156
				new_hk_state = 5;
1157
				break;
1158
			default:
1159
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1160
				break;
1161
			}
1162
			break;
1163
1164
		    case DAHDI_TXSIG_START:
1165
			new_hk_state = 4;
1166
			break;
1167
1168
		    case DAHDI_TXSIG_KEWL:
1169
			new_hk_state = 0;
1170
			break;
1171
1172
		    default:
1173
			cardinfo(wc->boardnum,
1174
				 "Can't set FXS port %d tx state to %d",
1175
				 port, txsig);
1176
		}
1177
		dbginfo(wc->boardnum, "%s port %d hook state old %d, new %d",
1178
			 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1179
			 port, wc->mod[port].fxs.lasttxhook, new_hk_state );
1180
1181
		if (new_hk_state != wc->mod[port].fxs.lasttxhook) {
1182
			if (write_reg_fxs(wc, port, 64, new_hk_state))
1183
				wc->mod[port].fxs.lasttxhook = new_hk_state;
1184
			else
1185
				cardcrit(wc->boardnum,
1186
					 "Failed to set port %d fxs hookstate from %d to %d",
1187
					 port, wc->mod[port].fxs.lasttxhook,
1188
					 new_hk_state);
1189
		}
1190
		break;
1191
1192
	    default:
1193
		cardcrit(wc->boardnum,
1194
			 "Unknown module type %d in openpci_hooksig",
1195
			 wc->porttype[port] );
1196
	}
1197
	return 0;
1198
}
1199
1200
static const struct dahdi_span_ops openpci_span_ops = {
1201
	.owner = THIS_MODULE,
1202
	.hooksig = openpci_hooksig,
1203
	.open = openpci_open,
1204
	.close = openpci_close,
1205
	.ioctl = openpci_ioctl,
1206
	.watchdog = openpci_watchdog
1207
};
1208
1209
static int span_initialize(struct openpci *wc)
1210
{
1211
	int x;
1212
1213
	wc->ddev = dahdi_create_device();
1214
	//XXX Set a THIS_MODULE as the owner of the span...
1215
	/* Zapata stuff */
1216
	sprintf(wc->span.name, "WCTDM/%d", wc->boardnum);
1217
	sprintf(wc->span.desc, "%s Board %d", wc->variety, wc->boardnum + 1);
1218
	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
1219
				      wc->dev->bus->number,
1220
				      PCI_SLOT(wc->dev->devfn) + 1);
1221
	if (!wc->ddev->location)
1222
		return -ENOMEM;
1223
	for (x = 0; x < MAX_PORTS; x++) {
1224
		struct dahdi_chan *chan = &wc->_chans[x];
1225
		wc->chans[x] = chan;
1226
		sprintf(chan->name, "WCTDM/%d/%d", wc->boardnum, x);
1227
		chan->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS
1228
			| DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM
1229
			| DAHDI_SIG_CLEAR;
1230
		chan->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS
1231
			| DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
1232
		chan->chanpos = x+1;
1233
		chan->pvt = wc;
1234
	}
1235
	wc->ddev->manufacturer = "Voicetronix";
1236
	wc->ddev->devicetype = wc->variety;
1237
	wc->span.deflaw = DAHDI_LAW_MULAW;
1238
	wc->span.chans = wc->chans;
1239
	wc->span.channels = MAX_PORTS;
1240
	wc->span.flags = DAHDI_FLAG_RBS;
1241
	wc->span.ops = &openpci_span_ops;
1242
1243
	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
1244
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
1245
		cardcrit(wc->boardnum, "Unable to register device with dahdi");
1246
		return RET_FAIL;
1247
	}
1248
	return RET_OK;
1249
}
1250
1251
static int get_port_type(struct openpci *wc, int port)
1252
{
1253
	int i, type;
1254
	unsigned long flags;
1255
1256
	spin_lock_irqsave(&wc->lock, flags);
1257
	outb(0x20, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1258
	outb(port, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1259
	HRXF_WAIT_LOCKED_RET(VT_PORT_EMPTY); type = inb(PIB(1));
1260
	spin_unlock_irqrestore(&wc->lock, flags);
1261
1262
	return type;
1263
}
1264
1265
static int check_ports(struct openpci *wc)
1266
{
1267
	int i = 0;
1268
1269
	wc->portcount = 0;
1270
	for (; i < MAX_PORTS; ++i ) {
1271
		wc->porttype[i] = get_port_type(wc, i);
1272
		dbginfo(wc->boardnum,"%d: %s", i, porttype(wc,i));
1273
1274
		switch( wc->porttype[i] ) {
1275
		    case VT_PORT_PROSLIC:
1276
			/* By default, don't send on hook */
1277
			if (reversepolarity)
1278
				wc->mod[i].fxs.idletxhookstate = 5;
1279
			else
1280
				wc->mod[i].fxs.idletxhookstate = 1;
1281
1282
		    case VT_PORT_VDAA:
1283
			++wc->portcount;
1284
		}
1285
	}
1286
	/* we 'succeed' if any ports were discovered. */
1287
	return wc->portcount ? RET_OK : RET_FAIL;
1288
}
1289
1290
static int configure_vdaa_country(struct openpci *wc, int port, char *name)
1291
{
1292
	unsigned char value;
1293
	int i;
1294
1295
	for (i = 0; i < sizeof(fxo_modes)/sizeof(struct fxo_mode); ++i) {
1296
		if (!strcmp(fxo_modes[i].name, name)) {
1297
			dbginfo(wc->boardnum, "%d: Setting country to %s",
1298
					port, name);
1299
			goto part2;
1300
		}
1301
	}
1302
	i = 3;
1303
	cardinfo(wc->boardnum, "Using default country %s", fxo_modes[i].name);
1304
1305
part2:
1306
	value  = (fxo_modes[i].ohs << 6);
1307
	value |= (fxo_modes[i].rz << 1);
1308
	value |= (fxo_modes[i].rt << 0);
1309
	if (!write_reg_fxo(wc, port, 16, value)) goto hell;
1310
1311
	/* DC Termination Control - Register 26 */
1312
	value  = (fxo_modes[i].dcv << 6);
1313
	value |= (fxo_modes[i].mini << 4);
1314
	value |= (fxo_modes[i].ilim << 1);
1315
	if (!write_reg_fxo(wc, port, 26, value)) goto hell;
1316
1317
	/* AC Termination Control - Register 30 */
1318
	value = (fxo_modes[i].acim << 0);
1319
	if (!write_reg_fxo(wc, port, 30, value)) goto hell;
1320
1321
	/* DAA Control 5 - Register 31 */
1322
	msleep(1);
1323
	if (!read_reg_fxo(wc, port, 31, &value)) goto hell;
1324
1325
	value = (value & 0xf7) | (fxo_modes[i].ohs2 << 3);
1326
	value = value | 0x02;
1327
	if (! write_reg_fxo(wc, port, 31, value)) goto hell;
1328
1329
	return RET_OK;
1330
1331
hell:
1332
	cardcrit(wc->boardnum, "port %d failed configure vdaa country", port);
1333
	return RET_FAIL;
1334
}
1335
1336
/* Do not call this from an interrupt context, it may sleep. */
1337
static void configure_vdaa_port(struct openpci *wc, int port)
1338
{
1339
	/* Set Country - default to Australia */
1340
	if (configure_vdaa_country(wc, port, country))
1341
		++wc->portcount;
1342
	else {
1343
		cardcrit(wc->boardnum, "FAILED to configure vdaa port %d.  Disabled.", port);
1344
		wc->porttype[port] = VT_PORT_EMPTY;
1345
	}
1346
}
1347
1348
static int configure_proslic_country(struct openpci *wc, int port,
1349
		const char *name)
1350
{
1351
	int i;
1352
1353
	for (i = 0; i < sizeof(ps_country_regs)/sizeof(struct ps_country_reg);
1354
			++i) {
1355
		if (!strcmp(ps_country_regs[i].country, name)) {
1356
			dbginfo(wc->boardnum, "%d: Setting country to %s",
1357
					port, name);
1358
			goto part2;
1359
		}
1360
	}
1361
	return -EINVAL;
1362
1363
part2:
1364
1365
	if (!write_reg_fxs(wc, port, 10, ps_country_regs[i].value)) {
1366
		cardcrit(wc->boardnum,"%d: failed to write PS_IMPEDANCE", port);
1367
		return -EIO;
1368
	}
1369
	return 0;
1370
}
1371
1372
/* Do not call this from an interrupt context, it may sleep. */
1373
static void configure_proslic_port(struct openpci *wc, int port)
1374
{
1375
	/* Set Country - default to Australia */
1376
	switch (configure_proslic_country(wc, port, country)) {
1377
		case 0:
1378
			break;
1379
1380
		case -EINVAL:
1381
			cardwarn(wc->boardnum, "%d: Country '%s' unknown, using default",
1382
					port, country);
1383
			if (configure_proslic_country(wc, port,
1384
						DEFAULT_COUNTRY) == 0 )
1385
				goto hell;
1386
1387
		default:
1388
			goto hell;
1389
	}
1390
1391
	++wc->portcount;
1392
	return;
1393
1394
hell:
1395
	cardcrit(wc->boardnum, "FAILED to configure proslic port %d.  Disabled.",
1396
			port);
1397
	wc->porttype[port] = VT_PORT_EMPTY;
1398
}
1399
1400
/* Do not call this from an interrupt context, it may (indirectly) sleep. */
1401
static int configure_ports(struct openpci *wc)
1402
{
1403
	unsigned long flags;
1404
	int i;
1405
1406
	wc->portcount = 0;
1407
	for (i = 0; i < MAX_PORTS; ++i) {
1408
		switch (wc->porttype[i]) {
1409
		    case VT_PORT_VDAA:    configure_vdaa_port(wc,i);    break;
1410
		    case VT_PORT_PROSLIC: configure_proslic_port(wc,i); break;
1411
		}
1412
	}
1413
1414
	spin_lock_irqsave(&wc->lock, flags);
1415
	outb(0x2c, PIB(1)); HTXF_WAIT_LOCKED();
1416
	outb(0xff, PIB(1)); HTXF_WAIT_LOCKED();
1417
	spin_unlock_irqrestore(&wc->lock, flags);
1418
1419
	/* otherwise we 'succeed' if any ports were configured successfully. */
1420
	return wc->portcount ? RET_OK : RET_FAIL;
1421
}
1422
1423
static int __get_arm_id(struct openpci *wc, int field, char *value)
1424
{
1425
	int i;
1426
	int x = 0;
1427
	int count = 0;
1428
1429
	outb(0x01, PIB(1));  HTXF_WAIT();
1430
	outb(field, PIB(1)); HTXF_WAIT();
1431
	HRXF_WAIT(); count = inb(PIB(1));
1432
	if (count > ID_DATA_MAXSIZE) {
1433
		cardcrit(wc->boardnum, "Too many bytes of id(%d) data %d/%d",
1434
					 field, count, ID_DATA_MAXSIZE);
1435
		return RET_FAIL;
1436
	}
1437
	//cardinfo(wc->boardnum, "get_arm_id(%d): byte count %d",field,count);
1438
	for (; x < count; ++x) {
1439
		HRXF_WAIT(); *value = inb(PIB(1));
1440
		//cardinfo(wc->boardnum, "get_arm_id(%d): byte %d => 0x%02x",field,x,tmp);
1441
		++value;
1442
	}
1443
	return RET_OK;
1444
}
1445
1446
static void enable_interrupts(struct openpci *wc)
1447
{
1448
	outb(0x3f, TJ_MASK0);
1449
	outb(0x02, TJ_MASK1);
1450
}
1451
1452
static void disable_interrupts(struct openpci *wc)
1453
{
1454
	outb(0x00, TJ_MASK0);
1455
	outb(0x00, TJ_MASK1);
1456
}
1457
1458
/* Do not call this from an interrupt context, it may sleep. */
1459
static int check_arm(struct openpci *wc)
1460
{
1461
	char model[ID_DATA_MAXSIZE + 1] = { 0 };
1462
	char date[ID_DATA_MAXSIZE + 1]  = { 0 };
1463
	unsigned long flags;
1464
	int i = 0;
1465
	int tmp = 0;
1466
1467
	spin_lock_irqsave(&wc->lock, flags);
1468
	while ((tmp != 0x88) && (++i < 100)) {
1469
		outb(0x88, PIB(0));
1470
		msleep(1);
1471
		tmp = inb(PIB(1));
1472
	}
1473
	if (i >= 1000)
1474
		goto limbo;
1475
	dbginfo(wc->boardnum, "Arm responded on attempt %d", i);
1476
1477
	/* Flush out the queue if we sent several pings before a response. */
1478
	if (i > 1)
1479
		__ping_arm(wc);
1480
1481
	if (!__get_arm_id(wc, 0, model))
1482
		goto hell;
1483
	sscanf(model, "OpenPCI8.%02d", &(wc->firmware));
1484
	cardinfo(wc->boardnum, "  model: %s", model);
1485
1486
	if (!__get_arm_id(wc, 1, date))
1487
		goto hell;
1488
	cardinfo(wc->boardnum, "  date: %s", date);
1489
1490
	if (!__get_arm_id(wc, 2, wc->serial))
1491
		goto hell;
1492
	cardinfo(wc->boardnum, "  serial: %s", wc->serial);
1493
1494
	spin_unlock_irqrestore(&wc->lock, flags);
1495
	return RET_OK;
1496
1497
hell:
1498
	spin_unlock_irqrestore(&wc->lock, flags);
1499
	cardwarn(wc->boardnum, "Found ARM processor, dumb firmware.");
1500
	return RET_OK;
1501
1502
limbo:
1503
	spin_unlock_irqrestore(&wc->lock, flags);
1504
	return RET_FAIL;
1505
}
1506
1507
static int arm_monitor(struct openpci *wc, int on)
1508
{
1509
	int i;
1510
	outb(on ? 0x06 : 0x07, PIB(1)); HTXF_WAIT();
1511
	return RET_OK;
1512
}
1513
1514
static int __devinit openpci_probe_board(struct pci_dev *pdev,
1515
		const struct pci_device_id *ent)
1516
{
1517
	struct openpci *wc;
1518
	int boardnum = 0;
1519
	int failret = -ENOMEM;
1520
	int tmp = 0;
1521
	int i;
1522
	unsigned long flags;
1523
1524
	if (ent->driver_data != (kernel_ulong_t)&wcopenpci) {
1525
		info("Probe of non-OpenPCI card, ignoring.");
1526
		return -EINVAL;
1527
	}
1528
	wc = kzalloc(sizeof(struct openpci), GFP_KERNEL);
1529
	if (!wc)
1530
		return -ENOMEM;
1531
1532
	mutex_lock(&cards_mutex);
1533
	for (; boardnum < MAX_CARDS && cards[boardnum]; ++boardnum)
1534
		;
1535
	if (boardnum >= MAX_CARDS) {
1536
		crit("Too many OpenPCI cards(%d), max is %d.",
1537
				boardnum, MAX_CARDS);
1538
		mutex_unlock(&cards_mutex);
1539
		goto hell;
1540
	}
1541
	cards[boardnum] = wc;
1542
	mutex_unlock(&cards_mutex);
1543
1544
	spin_lock_init(&wc->lock);
1545
	pci_set_drvdata(pdev, wc);
1546
1547
	wc->boardnum = boardnum;
1548
	wc->dev      = pdev;
1549
	wc->variety  = wcopenpci;
1550
1551
	cardinfo(boardnum, "Initialising card");
1552
	if (pci_enable_device(pdev)) {
1553
		failret = -EIO;
1554
		goto hell_2;
1555
	}
1556
	wc->ioaddr = pci_resource_start(pdev, 0);
1557
	if (!request_region(wc->ioaddr, 0xff, NAME)) {
1558
		cardcrit(boardnum, "Failed to lock IO region, another driver already using it");
1559
		failret = -EBUSY;
1560
		goto hell_2;
1561
	}
1562
1563
	spin_lock_irqsave(&wc->lock, flags);
1564
	outb(0xff, TJ_AUXD);		/* Set up TJ to access the ARM */
1565
	outb(0x78, TJ_AUXC);		/* Set up for Jtag */
1566
	outb(0x00, TJ_CNTL);		/* pull ERST low */
1567
	spin_unlock_irqrestore(&wc->lock, flags);
1568
	msleep(1);			/* Wait a bit */
1569
1570
	dbginfo(boardnum, "Starting ARM");
1571
	spin_lock_irqsave(&wc->lock, flags);
1572
	outb(0x01, TJ_CNTL);            /* pull ERST high again */
1573
	spin_unlock_irqrestore(&wc->lock, flags);
1574
	msleep(100);                    /* Give it all a chance to boot */
1575
1576
	if (!check_arm(wc)) {
1577
		cardcrit(boardnum, "Couldnt find ARM processor");
1578
		failret = -EIO;
1579
		goto hell_3;
1580
	}
1581
	if (wc->firmware < 11) {
1582
		cardcrit(boardnum,
1583
			 "Firmware version %d not supported by this driver",
1584
			 wc->firmware);
1585
		cardcrit(boardnum, " contact Voicetronix to have it updated");
1586
		failret = -ENODEV;
1587
		goto hell_3;
1588
	}
1589
	if (!check_ports(wc)) {
1590
		cardcrit(boardnum, "Couldnt find ports!");
1591
		failret = -EIO;
1592
		goto hell_3;
1593
	}
1594
1595
	wc->writechunk = pci_alloc_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1596
			&wc->writedma);
1597
	if (!wc->writechunk) {
1598
		cardcrit(boardnum, "Couldnt get DMA memory.");
1599
		goto hell_3;
1600
	}
1601
	wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE *
1602
		(MAX_PORTS * 2 / sizeof(int));
1603
	wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_PORTS*2);
1604
1605
	memset((void *)wc->writechunk, 0, VT_PCIDMA_BLOCKSIZE);
1606
1607
	spin_lock_irqsave(&wc->lock, flags);
1608
	outb(0xc1, TJ_SERCTL);
1609
	outb(0x0, TJ_FSCDELAY);
1610
1611
	outl(wc->writedma,                    TJ_DMAWS);
1612
	outl(wc->writedma + VT_PCIDMA_MIDDLE, TJ_DMAWI);
1613
	outl(wc->writedma + VT_PCIDMA_END,    TJ_DMAWE);
1614
	outl(wc->readdma,                     TJ_DMARS);
1615
	outl(wc->readdma + VT_PCIDMA_MIDDLE,  TJ_DMARI);
1616
	outl(wc->readdma + VT_PCIDMA_END,     TJ_DMARE);
1617
1618
	/* Clear interrupts */
1619
	outb(0xff, TJ_INTSTAT);
1620
	spin_unlock_irqrestore(&wc->lock, flags);
1621
1622
	if (!arm_monitor(wc, 1)) {
1623
		cardcrit(boardnum, "failed to start arm monitoring");
1624
		failret = -EIO;
1625
		goto hell_4;
1626
	}
1627
	msleep(1000);
1628
1629
	i = 0;
1630
	while (tmp != 0x88 && ++i < 1000) {
1631
		outb(0x88, PIB(0));
1632
		msleep(250);
1633
		tmp = inb(PIB(1));
1634
	}
1635
	if (i >= 1000) {
1636
		cardcrit(boardnum, "FAILED to initialise board");
1637
		goto hell_4;
1638
	}
1639
1640
	if (!check_ports(wc)) {
1641
		cardcrit(boardnum, "FAILED to initialise ports");
1642
		failret = -EIO;
1643
		goto hell_4;
1644
	}
1645
	if (!configure_ports(wc)) {
1646
		cardcrit(boardnum, "Failed to configure ports.");
1647
		failret = -EIO;
1648
		goto hell_4;
1649
	}
1650
	cardinfo(wc->boardnum, "have %d configured ports", wc->portcount);
1651
1652
	if (!span_initialize(wc)) {
1653
		cardcrit(boardnum, "Failed to register with dahdi driver");
1654
		failret = -EFAULT;
1655
		goto hell_4;
1656
	}
1657
1658
	/* Finalize signalling  */
1659
	for (i = 0; i < MAX_PORTS; ++i) {
1660
		if (wc->porttype[i] == VT_PORT_VDAA)
1661
			wc->chans[i]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS
1662
				| DAHDI_SIG_CLEAR | DAHDI_SIG_SF;
1663
		else if (wc->porttype[i] == VT_PORT_PROSLIC)
1664
			wc->chans[i]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS
1665
				| DAHDI_SIG_FXOGS | DAHDI_SIG_SF
1666
				| DAHDI_SIG_CLEAR | DAHDI_SIG_EM;
1667
		else if (wc->porttype[i])
1668
			cardcrit(wc->boardnum, "Port %d has unknown type (%d)",
1669
					i, wc->porttype[i]);
1670
	}
1671
1672
	/* Enable bus mastering */
1673
	pci_set_master(pdev);
1674
1675
	if (request_irq(pdev->irq, openpci_isr, DAHDI_IRQ_SHARED, NAME, wc)) {
1676
		cardcrit(boardnum, "Cant get IRQ!");
1677
		failret = -EIO;
1678
		goto hell_5;
1679
	}
1680
	cardinfo(boardnum, "Got IRQ %d", pdev->irq);
1681
1682
	enable_interrupts(wc);
1683
	start_dma(wc);
1684
1685
	cardinfo(boardnum, "Initialised card.");
1686
	return 0;
1687
1688
hell_5:
1689
	dahdi_unregister_device(wc->ddev);
1690
hell_4:
1691
	if (wc->writechunk)
1692
		pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1693
				    (void *)wc->writechunk, wc->writedma);
1694
hell_3:
1695
	outb(0x00, TJ_CNTL);
1696
	release_region(wc->ioaddr, 0xff);
1697
hell_2:
1698
	cards[boardnum] = NULL;
1699
hell:
1700
	kfree(wc->ddev->location);
1701
	dahdi_free_device(wc->ddev);
1702
	kfree(wc);
1703
	return failret;
1704
}
1705
1706
static void __devexit openpci_remove_board(struct pci_dev *pdev)
1707
{
1708
	struct openpci *wc = pci_get_drvdata(pdev);
1709
1710
	if (!wc)
1711
		return;
1712
1713
	arm_monitor(wc, 0);
1714
1715
	/* Stop DMA */
1716
	outb(0x00, TJ_OPER);
1717
	disable_interrupts(wc);
1718
1719
	//XXX Replace this usecount business...
1720
	//    and do this BEFORE we invalidate everything above...
1721
	//    check that we wont try to write to it in the meantime.
1722
	/* Release span, possibly delayed */
1723
	//XXX if (!wc->usecount) openpci_release(wc); else wc->dead = 1;
1724
1725
	dahdi_unregister_device(wc->ddev);
1726
	outb(0x00, TJ_CNTL);
1727
1728
	pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1729
			(void *)wc->writechunk, wc->writedma);
1730
	free_irq(pdev->irq, wc);
1731
1732
	release_region(wc->ioaddr, 0xff);
1733
1734
	mutex_lock(&cards_mutex);
1735
	cards[wc->boardnum] = NULL;
1736
	mutex_unlock(&cards_mutex);
1737
1738
	kfree(wc->ddev->location);
1739
	dahdi_free_device(wc->ddev);
1740
	kfree(wc);
1741
	cardinfo(wc->boardnum, "Removed OpenPCI card.");
1742
}
1743
1744
static DEFINE_PCI_DEVICE_TABLE(openpci_pci_tbl) = {
1745
	{ 0xe159, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t) &wcopenpci },
1746
	{ 0 }
1747
};
1748
1749
MODULE_DEVICE_TABLE(pci, openpci_pci_tbl);
1750
1751
static struct pci_driver openpci_driver = {
1752
	.name = NAME,
1753
	.probe = openpci_probe_board,
1754
	.remove = __devexit_p(openpci_remove_board),
1755
	.id_table = openpci_pci_tbl,
1756
};
1757
1758
static int __init openpci_init(void)
1759
{
1760
#ifdef __BIG_ENDIAN
1761
	warn("No big endian support (yet)");
1762
	return -ENODEV;
1763
#endif
1764
1765
	if (dahdi_pci_module(&openpci_driver))
1766
		return -ENODEV;
1767
1768
	info("Module loaded %s", debug ? "with debug enabled" : "");
1769
	return 0;
1770
}
1771
1772
static void __exit openpci_cleanup(void)
1773
{
1774
	pci_unregister_driver(&openpci_driver);
1775
	info("Module exit");
1776
}
1777
1778
module_init(openpci_init);
1779
module_exit(openpci_cleanup);
1780
1781
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
1782
MODULE_AUTHOR(DRIVER_AUTHOR);
1783
MODULE_VERSION(DAHDI_VERSION);
1784
MODULE_LICENSE("GPL");
(-)dahdi-linux-2.7.0/drivers/dahdi/wctc4xxp/base.c (-1 lines)
Lines 866-872 Link Here
866
	memset(dr->desc, 0, (sizeof(*d) + dr->padding) * DRING_SIZE);
866
	memset(dr->desc, 0, (sizeof(*d) + dr->padding) * DRING_SIZE);
867
	for (i = 0; i < DRING_SIZE; ++i) {
867
	for (i = 0; i < DRING_SIZE; ++i) {
868
		d = wctc4xxp_descriptor(dr, i);
868
		d = wctc4xxp_descriptor(dr, i);
869
		memset(d, 0, sizeof(*d));
870
		d->des1 = cpu_to_le32(des1);
869
		d->des1 = cpu_to_le32(des1);
871
	}
870
	}
872
871
(-)dahdi-linux-2.7.0/drivers/dahdi/zaphfc/base.c (+1720 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.c - Dahdi driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * Dahdi rewrite in hardhdlc mode
5
 * Jose A. Deniz <odicha@hotmail.com>
6
 *
7
 * Copyright (C) 2009, Jose A. Deniz
8
 * Copyright (C) 2006, headiisue GmbH; Jens Wilke
9
 * Copyright (C) 2004 Daniele Orlandi
10
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
11
 *
12
 * Jens Wilke <jw_vzaphfc@headissue.com>
13
 *
14
 * Original author of this code is
15
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
16
 *
17
 * Major rewrite of the driver made by
18
 * Klaus-Peter Junghanns <kpj@junghanns.net>
19
 *
20
 * This program is free software and may be modified and
21
 * distributed under the terms of the GNU Public License.
22
 *
23
 * Please read the README file for important infos.
24
 */
25
26
#include <linux/spinlock.h>
27
#include <linux/init.h>
28
#include <linux/pci.h>
29
#include <linux/interrupt.h>
30
#include <linux/module.h>
31
#include <linux/moduleparam.h>
32
#include <linux/version.h>
33
#include <linux/kernel.h>
34
#include <linux/delay.h>
35
#include <linux/sched.h>
36
#include <linux/proc_fs.h>
37
#include <linux/if_arp.h>
38
39
#include <dahdi/kernel.h>
40
41
#include "zaphfc.h"
42
#include "fifo.h"
43
44
#if CONFIG_PCI
45
46
#define DAHDI_B1 0
47
#define DAHDI_B2 1
48
#define DAHDI_D 2
49
50
#define D 0
51
#define B1 1
52
#define B2 2
53
54
/*
55
 * Mode Te for all
56
 */
57
static int modes;
58
static int nt_modes[hfc_MAX_BOARDS];
59
static int nt_modes_count;
60
static int force_l1_up;
61
static struct proc_dir_entry *hfc_proc_zaphfc_dir;
62
63
#ifdef DEBUG
64
int debug_level;
65
#endif
66
67
#ifndef FALSE
68
#define FALSE 0
69
#endif
70
#ifndef TRUE
71
#define TRUE (!FALSE)
72
#endif
73
74
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
75
#define	SET_PROC_DIRENTRY_OWNER(p)  do { (p)->owner = THIS_MODULE; } while (0);
76
#else
77
#define	SET_PROC_DIRENTRY_OWNER(p)	do { } while (0);
78
#endif
79
80
static struct pci_device_id hfc_pci_ids[] = {
81
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0,
82
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000,
84
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
85
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006,
86
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007,
88
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008,
90
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
91
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009,
92
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
93
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A,
94
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
95
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B,
96
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
97
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C,
98
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
99
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100,
100
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
101
	{PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1,
102
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
103
	{PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675,
104
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
105
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT,
106
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
107
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T,
108
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
109
	{PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575,
110
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
111
	{PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0,
112
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
113
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,
114
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
115
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,
116
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
117
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,
118
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,
120
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
121
	{PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_3069,
122
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
123
	{0,}
124
};
125
126
MODULE_DEVICE_TABLE(pci, hfc_pci_ids);
127
128
static int __devinit hfc_probe(struct pci_dev *dev
129
			, const struct pci_device_id *ent);
130
static void __devexit hfc_remove(struct pci_dev *dev);
131
132
static struct pci_driver hfc_driver = {
133
	.name     = hfc_DRIVER_NAME,
134
	.id_table = hfc_pci_ids,
135
	.probe    = hfc_probe,
136
	.remove   = hfc_remove,
137
};
138
139
/******************************************
140
 * HW routines
141
 ******************************************/
142
143
static void hfc_softreset(struct hfc_card *card)
144
{
145
	printk(KERN_INFO hfc_DRIVER_PREFIX
146
		"card %d: "
147
		"resetting\n",
148
		card->cardnum);
149
150
/*
151
 * Softreset procedure. Put it on, wait and off again
152
 */
153
	hfc_outb(card, hfc_CIRM, hfc_CIRM_RESET);
154
	udelay(6);
155
	hfc_outb(card, hfc_CIRM, 0);
156
157
	set_current_state(TASK_UNINTERRUPTIBLE);
158
	schedule_timeout((hfc_RESET_DELAY * HZ) / 1000);
159
}
160
161
static void hfc_resetCard(struct hfc_card *card)
162
{
163
	card->regs.m1 = 0;
164
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
165
166
	card->regs.m2 = 0;
167
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
168
169
	hfc_softreset(card);
170
171
	card->regs.trm = 0;
172
	hfc_outb(card, hfc_TRM, card->regs.trm);
173
174
	/*
175
	 * Select the non-capacitive line mode for the S/T interface
176
	 */
177
	card->regs.sctrl = hfc_SCTRL_NONE_CAP;
178
179
	if (card->nt_mode) {
180
		/*
181
		 * ST-Bit delay for NT-Mode
182
		 */
183
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_NT);
184
185
		card->regs.sctrl |= hfc_SCTRL_MODE_NT;
186
	} else {
187
		/*
188
		 * ST-Bit delay for TE-Mode
189
		 */
190
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_TE);
191
192
		card->regs.sctrl |= hfc_SCTRL_MODE_TE;
193
	}
194
195
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
196
197
	/*
198
	 * S/T Auto awake
199
	 */
200
	card->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
201
	hfc_outb(card, hfc_SCTRL_E, card->regs.sctrl_e);
202
203
	/*
204
	 * No B-channel enabled at startup
205
	 */
206
	card->regs.sctrl_r = 0;
207
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
208
209
	/*
210
	 * HFC Master Mode
211
	 */
212
	hfc_outb(card, hfc_MST_MODE, hfc_MST_MODE_MASTER);
213
214
	/*
215
	 * Connect internal blocks
216
	 */
217
	card->regs.connect =
218
		hfc_CONNECT_B1_HFC_from_ST |
219
		hfc_CONNECT_B1_ST_from_HFC |
220
		hfc_CONNECT_B1_GCI_from_HFC |
221
		hfc_CONNECT_B2_HFC_from_ST |
222
		hfc_CONNECT_B2_ST_from_HFC |
223
		hfc_CONNECT_B2_GCI_from_HFC;
224
	hfc_outb(card, hfc_CONNECT, card->regs.connect);
225
226
	/*
227
	 * All bchans are HDLC by default, not useful, actually
228
	 * since mode is set during open()
229
	 */
230
	hfc_outb(card, hfc_CTMT, 0);
231
232
	/*
233
	 * bit order
234
	 */
235
	hfc_outb(card, hfc_CIRM, 0);
236
237
	/*
238
	 * Enable D-rx FIFO. At least one FIFO must be enabled (by specs)
239
	 */
240
	card->regs.fifo_en = hfc_FIFOEN_DRX;
241
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
242
243
	card->late_irqs = 0;
244
245
	/*
246
	 * Clear already pending ints
247
	 */
248
	hfc_inb(card, hfc_INT_S1);
249
	hfc_inb(card, hfc_INT_S2);
250
251
	/*
252
	 * Enable IRQ output
253
	 */
254
	card->regs.m1 = hfc_INTS_DREC | hfc_INTS_L1STATE | hfc_INTS_TIMER;
255
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
256
257
	card->regs.m2 = hfc_M2_IRQ_ENABLE;
258
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
259
260
	/*
261
	 * Unlocks the states machine
262
	 */
263
	hfc_outb(card, hfc_STATES, 0);
264
265
	/*
266
	 * There's no need to explicitly activate L1 now.
267
	 * Activation is managed inside the interrupt routine.
268
	 */
269
}
270
271
static void hfc_update_fifo_state(struct hfc_card *card)
272
{
273
	/*
274
	 * I'm not sure if irqsave is needed but there could be a race
275
	 * condition since hfc_update_fifo_state could be called from
276
	 * both the IRQ handler and the *_(open|close) functions
277
	 */
278
279
	unsigned long flags;
280
	spin_lock_irqsave(&card->chans[B1].lock, flags);
281
	if (!card->fifo_suspended &&
282
		(card->chans[B1].status == open_framed ||
283
		card->chans[B1].status == open_voice)) {
284
285
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1RX)) {
286
			card->regs.fifo_en |= hfc_FIFOEN_B1RX;
287
			hfc_clear_fifo_rx(&card->chans[B1].rx);
288
		}
289
290
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1TX)) {
291
			card->regs.fifo_en |= hfc_FIFOEN_B1TX;
292
			hfc_clear_fifo_tx(&card->chans[B1].tx);
293
		}
294
	} else {
295
		if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
296
			card->regs.fifo_en &= ~hfc_FIFOEN_B1RX;
297
		if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
298
			card->regs.fifo_en &= ~hfc_FIFOEN_B1TX;
299
	}
300
	spin_unlock_irqrestore(&card->chans[B1].lock, flags);
301
302
	spin_lock_irqsave(&card->chans[B2].lock, flags);
303
	if (!card->fifo_suspended &&
304
		(card->chans[B2].status == open_framed ||
305
		card->chans[B2].status == open_voice ||
306
		card->chans[B2].status == sniff_aux)) {
307
308
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2RX)) {
309
			card->regs.fifo_en |= hfc_FIFOEN_B2RX;
310
			hfc_clear_fifo_rx(&card->chans[B2].rx);
311
		}
312
313
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2TX)) {
314
			card->regs.fifo_en |= hfc_FIFOEN_B2TX;
315
			hfc_clear_fifo_tx(&card->chans[B2].tx);
316
		}
317
	} else {
318
		if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
319
			card->regs.fifo_en &= ~hfc_FIFOEN_B2RX;
320
		if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
321
			card->regs.fifo_en &= ~hfc_FIFOEN_B2TX;
322
	}
323
	spin_unlock_irqrestore(&card->chans[B2].lock, flags);
324
325
	spin_lock_irqsave(&card->chans[D].lock, flags);
326
	if (!card->fifo_suspended &&
327
		card->chans[D].status == open_framed) {
328
329
		if (!(card->regs.fifo_en & hfc_FIFOEN_DTX)) {
330
			card->regs.fifo_en |= hfc_FIFOEN_DTX;
331
332
			card->chans[D].tx.ugly_framebuf_size = 0;
333
			card->chans[D].tx.ugly_framebuf_off = 0;
334
		}
335
	} else {
336
		if (card->regs.fifo_en & hfc_FIFOEN_DTX)
337
			card->regs.fifo_en &= ~hfc_FIFOEN_DTX;
338
	}
339
	spin_unlock_irqrestore(&card->chans[D].lock, flags);
340
341
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
342
}
343
344
static inline void hfc_suspend_fifo(struct hfc_card *card)
345
{
346
	card->fifo_suspended = TRUE;
347
348
	hfc_update_fifo_state(card);
349
350
	/*
351
	 * When L1 goes down D rx receives garbage; it is nice to
352
	 * clear it to avoid a CRC error on reactivation
353
	 * udelay is needed because the FIFO deactivation happens
354
	 * in 250us
355
	 */
356
	udelay(250);
357
	hfc_clear_fifo_rx(&card->chans[D].rx);
358
359
#ifdef DEBUG
360
	if (debug_level >= 3) {
361
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
362
			"card %d: "
363
			"FIFOs suspended\n",
364
			card->cardnum);
365
	}
366
#endif
367
}
368
369
static inline void hfc_resume_fifo(struct hfc_card *card)
370
{
371
	card->fifo_suspended = FALSE;
372
373
	hfc_update_fifo_state(card);
374
375
#ifdef DEBUG
376
	if (debug_level >= 3) {
377
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
378
			"card %d: "
379
			"FIFOs resumed\n",
380
			card->cardnum);
381
	}
382
#endif
383
}
384
385
static void hfc_check_l1_up(struct hfc_card *card)
386
{
387
	if ((!card->nt_mode && card->l1_state != 7)
388
		|| (card->nt_mode && card->l1_state != 3)) {
389
390
		hfc_outb(card, hfc_STATES, hfc_STATES_DO_ACTION |
391
			hfc_STATES_ACTIVATE|
392
				hfc_STATES_NT_G2_G3);
393
394
	/*
395
	 * 0 because this is quite verbose when an inferface is unconnected, jaw
396
	 */
397
#if 0
398
		if (debug_level >= 1) {
399
			printk(KERN_DEBUG hfc_DRIVER_PREFIX
400
				"card %d: "
401
				"L1 is down, bringing up L1.\n",
402
				card->cardnum);
403
		}
404
#endif
405
	}
406
}
407
408
409
/*******************
410
 * Dahdi interface *
411
 *******************/
412
413
static int hfc_zap_open(struct dahdi_chan *zaptel_chan)
414
{
415
	struct hfc_chan_duplex *chan = zaptel_chan->pvt;
416
	struct hfc_card *card = chan->card;
417
418
	spin_lock(&chan->lock);
419
420
	switch (chan->number) {
421
	case D:
422
		if (chan->status != free &&
423
			chan->status != open_framed) {
424
			spin_unlock(&chan->lock);
425
			return -EBUSY;
426
		}
427
		chan->status = open_framed;
428
	break;
429
430
	case B1:
431
	case B2:
432
		if (chan->status != free) {
433
			spin_unlock(&chan->lock);
434
			return -EBUSY;
435
		}
436
		chan->status = open_voice;
437
	break;
438
	}
439
440
	chan->open_by_zaptel = TRUE;
441
	try_module_get(THIS_MODULE);
442
	spin_unlock(&chan->lock);
443
444
	switch (chan->number) {
445
	case D:
446
	break;
447
448
	case B1:
449
		card->regs.m2 |= hfc_M2_PROC_TRANS;
450
		/*
451
		 * Enable transparent mode
452
		 */
453
		card->regs.ctmt |= hfc_CTMT_TRANSB1;
454
		/*
455
		* Reversed bit order
456
		*/
457
		card->regs.cirm |= hfc_CIRM_B1_REV;
458
		/*
459
		 * Enable transmission
460
		 */
461
		card->regs.sctrl |= hfc_SCTRL_B1_ENA;
462
		/*
463
		 * Enable reception
464
		 */
465
		card->regs.sctrl_r |= hfc_SCTRL_R_B1_ENA;
466
	break;
467
468
	case B2:
469
		card->regs.m2 |= hfc_M2_PROC_TRANS;
470
		card->regs.ctmt |= hfc_CTMT_TRANSB2;
471
		card->regs.cirm |= hfc_CIRM_B2_REV;
472
		card->regs.sctrl |= hfc_SCTRL_B2_ENA;
473
		card->regs.sctrl_r |= hfc_SCTRL_R_B2_ENA;
474
	break;
475
476
	}
477
478
	/*
479
	 * If not already enabled, enable processing transition (8KHz)
480
	 * interrupt
481
	 */
482
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
483
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
484
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
485
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
486
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
487
488
	hfc_update_fifo_state(card);
489
490
	printk(KERN_INFO hfc_DRIVER_PREFIX
491
		"card %d: "
492
		"chan %s opened as %s.\n",
493
		card->cardnum,
494
		chan->name,
495
		zaptel_chan->name);
496
497
	return 0;
498
}
499
500
static int hfc_zap_close(struct dahdi_chan *zaptel_chan)
501
{
502
	struct hfc_chan_duplex *chan = zaptel_chan->pvt;
503
	struct hfc_card *card = chan->card;
504
505
	if (!card) {
506
		printk(KERN_CRIT hfc_DRIVER_PREFIX
507
			"hfc_zap_close called with NULL card\n");
508
		return -1;
509
	}
510
511
	spin_lock(&chan->lock);
512
513
	if (chan->status == free) {
514
		spin_unlock(&chan->lock);
515
		return -EINVAL;
516
	}
517
518
	chan->status = free;
519
	chan->open_by_zaptel = FALSE;
520
521
	spin_unlock(&chan->lock);
522
523
	switch (chan->number) {
524
	case D:
525
	break;
526
527
	case B1:
528
		card->regs.ctmt &= ~hfc_CTMT_TRANSB1;
529
		card->regs.cirm &= ~hfc_CIRM_B1_REV;
530
		card->regs.sctrl &= ~hfc_SCTRL_B1_ENA;
531
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B1_ENA;
532
	break;
533
534
	case B2:
535
		card->regs.ctmt &= ~hfc_CTMT_TRANSB2;
536
		card->regs.cirm &= ~hfc_CIRM_B2_REV;
537
		card->regs.sctrl &= ~hfc_SCTRL_B2_ENA;
538
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B2_ENA;
539
	break;
540
	}
541
542
	if (card->chans[B1].status == free &&
543
		card->chans[B2].status == free)
544
		card->regs.m2 &= ~hfc_M2_PROC_TRANS;
545
546
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
547
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
548
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
549
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
550
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
551
552
	hfc_update_fifo_state(card);
553
554
	module_put(THIS_MODULE);
555
556
	printk(KERN_INFO hfc_DRIVER_PREFIX
557
		"card %d: "
558
		"chan %s closed as %s.\n",
559
		card->cardnum,
560
		chan->name,
561
		zaptel_chan->name);
562
563
	return 0;
564
}
565
566
static int hfc_zap_rbsbits(struct dahdi_chan *chan, int bits)
567
{
568
	return 0;
569
}
570
571
static int hfc_zap_ioctl(struct dahdi_chan *chan,
572
		unsigned int cmd, unsigned long data)
573
{
574
	switch (cmd) {
575
576
	default:
577
		return -ENOTTY;
578
	}
579
580
	return 0;
581
}
582
583
static void hfc_hdlc_hard_xmit(struct dahdi_chan *d_chan)
584
{
585
	struct hfc_chan_duplex *chan = d_chan->pvt;
586
	struct hfc_card *card = chan->card;
587
	struct dahdi_hfc *hfccard = card->ztdev;
588
589
	atomic_inc(&hfccard->hdlc_pending);
590
591
}
592
593
static int hfc_zap_startup(struct file *file, struct dahdi_span *span)
594
{
595
	struct dahdi_hfc *zthfc = dahdi_hfc_from_span(span);
596
	struct hfc_card *hfctmp = zthfc->card;
597
	int alreadyrunning;
598
599
	if (!hfctmp) {
600
		printk(KERN_INFO hfc_DRIVER_PREFIX
601
			"card %d: "
602
			"no card for span at startup!\n",
603
			hfctmp->cardnum);
604
	}
605
606
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
607
608
	if (!alreadyrunning)
609
		span->flags |= DAHDI_FLAG_RUNNING;
610
611
	return 0;
612
}
613
614
static int hfc_zap_shutdown(struct dahdi_span *span)
615
{
616
	return 0;
617
}
618
619
static int hfc_zap_maint(struct dahdi_span *span, int cmd)
620
{
621
	return 0;
622
}
623
624
static int hfc_zap_chanconfig(struct file *file, struct dahdi_chan *d_chan,
625
		int sigtype)
626
{
627
	struct hfc_chan_duplex *chan = d_chan->pvt;
628
	struct hfc_card *card = chan->card;
629
	struct dahdi_hfc *hfccard = card->ztdev;
630
631
	if ((sigtype == DAHDI_SIG_HARDHDLC) && (hfccard->sigchan == d_chan)) {
632
		hfccard->sigactive = 0;
633
		atomic_set(&hfccard->hdlc_pending, 0);
634
	}
635
636
	return 0;
637
}
638
639
static int hfc_zap_spanconfig(struct file *file, struct dahdi_span *span,
640
		struct dahdi_lineconfig *lc)
641
{
642
	span->lineconfig = lc->lineconfig;
643
644
	return 0;
645
}
646
647
static const struct dahdi_span_ops hfc_zap_span_ops = {
648
	.owner = THIS_MODULE,
649
	.chanconfig = hfc_zap_chanconfig,
650
	.spanconfig = hfc_zap_spanconfig,
651
	.startup = hfc_zap_startup,
652
	.shutdown = hfc_zap_shutdown,
653
	.maint = hfc_zap_maint,
654
	.rbsbits = hfc_zap_rbsbits,
655
	.open = hfc_zap_open,
656
	.close = hfc_zap_close,
657
	.ioctl = hfc_zap_ioctl,
658
	.hdlc_hard_xmit = hfc_hdlc_hard_xmit
659
};
660
661
static int hfc_zap_initialize(struct dahdi_hfc *hfccard)
662
{
663
	 struct hfc_card *hfctmp = hfccard->card;
664
	int i;
665
666
	hfccard->ddev = dahdi_create_device();
667
	hfccard->ddev->manufacturer = "Cologne Chips";
668
	hfccard->ddev->devicetype = "HFC-S PCI-A ISDN";
669
	hfccard->ddev->location = kasprintf(GFP_KERNEL,
670
			"PCI Bus %02d Slot %02d",
671
			hfctmp->pcidev->bus->number,
672
			PCI_SLOT(hfctmp->pcidev->devfn) + 1);
673
	memset(&hfccard->span, 0x0, sizeof(struct dahdi_span));
674
	sprintf(hfccard->span.name, "ZTHFC%d", hfctmp->cardnum + 1);
675
	sprintf(hfccard->span.desc,
676
			"HFC-S PCI A ISDN card %d [%s] ",
677
			hfctmp->cardnum,
678
			hfctmp->nt_mode ? "NT" : "TE");
679
	hfccard->span.spantype = hfctmp->nt_mode ? SPANTYPE_DIGITAL_BRI_NT : 
680
		SPANTYPE_DIGITAL_BRI_TE;
681
	hfccard->span.flags = 0;
682
	hfccard->span.ops = &hfc_zap_span_ops;
683
	hfccard->span.chans = hfccard->_chans;
684
	hfccard->span.channels = 3;
685
	for (i = 0; i < hfccard->span.channels; i++)
686
		hfccard->_chans[i] = &hfccard->chans[i];
687
	hfccard->span.deflaw = DAHDI_LAW_ALAW;
688
	hfccard->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS;
689
	hfccard->span.offset = 0;
690
691
	for (i = 0; i < hfccard->span.channels; i++) {
692
		memset(&hfccard->chans[i], 0x0, sizeof(struct dahdi_chan));
693
694
		sprintf(hfccard->chans[i].name,
695
				"ZTHFC%d/%d/%d",
696
				hfctmp->cardnum + 1, 0, i + 1);
697
698
		printk(KERN_INFO hfc_DRIVER_PREFIX
699
			"card %d: "
700
			"registered %s\n",
701
			hfctmp->cardnum,
702
			hfccard->chans[i].name);
703
704
		if (i == hfccard->span.channels - 1) {
705
			hfccard->chans[i].sigcap = DAHDI_SIG_HARDHDLC;
706
			hfccard->sigchan = &hfccard->chans[DAHDI_D];
707
			hfccard->sigactive = 0;
708
			atomic_set(&hfccard->hdlc_pending, 0);
709
		} else {
710
			hfccard->chans[i].sigcap =
711
				DAHDI_SIG_CLEAR | DAHDI_SIG_DACS;
712
		}
713
714
		hfccard->chans[i].chanpos = i + 1;
715
	}
716
717
	hfccard->chans[DAHDI_D].readchunk  =
718
		hfctmp->chans[D].rx.zaptel_buffer;
719
720
	hfccard->chans[DAHDI_D].writechunk =
721
		hfctmp->chans[D].tx.zaptel_buffer;
722
723
	hfccard->chans[DAHDI_D].pvt = &hfctmp->chans[D];
724
725
	hfccard->chans[DAHDI_B1].readchunk  =
726
		hfctmp->chans[B1].rx.zaptel_buffer;
727
728
	hfccard->chans[DAHDI_B1].writechunk =
729
		hfctmp->chans[B1].tx.zaptel_buffer;
730
731
	hfccard->chans[DAHDI_B1].pvt = &hfctmp->chans[B1];
732
733
	hfccard->chans[DAHDI_B2].readchunk  =
734
		hfctmp->chans[B2].rx.zaptel_buffer;
735
736
	hfccard->chans[DAHDI_B2].writechunk =
737
		hfctmp->chans[B2].tx.zaptel_buffer;
738
739
	hfccard->chans[DAHDI_B2].pvt = &hfctmp->chans[B2];
740
741
	list_add_tail(&hfccard->span.device_node, &hfccard->ddev->spans);
742
	if (dahdi_register_device(hfccard->ddev, &hfctmp->pcidev->dev)) {
743
		printk(KERN_ERR "unable to register DAHDI device %s!\n",
744
				hfccard->span.name);
745
		return -1; /* FIXME: release resources? */
746
	}
747
748
	return 0;
749
}
750
751
static void hfc_dahdi_free(struct dahdi_hfc *hfccard)
752
{
753
	kfree(hfccard->ddev->location);
754
	dahdi_free_device(hfccard->ddev);
755
}
756
757
static void hfc_zap_transmit(struct hfc_chan_simplex *chan)
758
{
759
	hfc_fifo_put(chan, chan->zaptel_buffer, DAHDI_CHUNKSIZE);
760
}
761
762
static void hfc_zap_receive(struct hfc_chan_simplex *chan)
763
{
764
	hfc_fifo_get(chan, chan->zaptel_buffer, DAHDI_CHUNKSIZE);
765
}
766
767
/******************************************
768
 * Interrupt Handler
769
 ******************************************/
770
771
static void hfc_handle_timer_interrupt(struct hfc_card *card);
772
static void hfc_handle_state_interrupt(struct hfc_card *card);
773
static void hfc_handle_processing_interrupt(struct hfc_card *card);
774
static void hfc_frame_arrived(struct hfc_chan_duplex *chan);
775
static void hfc_handle_voice(struct hfc_card *card);
776
777
#if (KERNEL_VERSION(2, 6, 24) < LINUX_VERSION_CODE)
778
static irqreturn_t hfc_interrupt(int irq, void *dev_id)
779
#else
780
static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
781
#endif
782
{
783
	struct hfc_card *card = dev_id;
784
	unsigned long flags;
785
	u8 status, s1, s2;
786
787
	if (!card) {
788
		printk(KERN_CRIT hfc_DRIVER_PREFIX
789
			"spurious interrupt (IRQ %d)\n",
790
			irq);
791
		return IRQ_NONE;
792
	}
793
794
	spin_lock_irqsave(&card->lock, flags);
795
	status = hfc_inb(card, hfc_STATUS);
796
	if (!(status & hfc_STATUS_ANYINT)) {
797
		/*
798
		 * maybe we are sharing the irq
799
		 */
800
		spin_unlock_irqrestore(&card->lock, flags);
801
		return IRQ_NONE;
802
	}
803
804
	/* We used to ingore the IRQ when the card was in processing
805
	 * state but apparently there is no restriction to access the
806
	 * card in such state:
807
	 *
808
	 * Joerg Ciesielski wrote:
809
	 * > There is no restriction for the IRQ handler to access
810
	 * > HFC-S PCI during processing phase. A IRQ latency of 375 us
811
	 * > is also no problem since there are no interrupt sources in
812
	 * > HFC-S PCI which must be handled very fast.
813
	 * > Due to its deep fifos the IRQ latency can be several ms with
814
	 * > out the risk of loosing data. Even the S/T state interrupts
815
	 * > must not be handled with a latency less than <5ms.
816
	 * >
817
	 * > The processing phase only indicates that HFC-S PCI is
818
	 * > processing the Fifos as PCI master so that data is read and
819
	 * > written in the 32k memory window. But there is no restriction
820
	 * > to access data in the memory window during this time.
821
	 *
822
	 * // if (status & hfc_STATUS_PCI_PROC) {
823
	 * // return IRQ_HANDLED;
824
	 * // }
825
	 */
826
827
	s1 = hfc_inb(card, hfc_INT_S1);
828
	s2 = hfc_inb(card, hfc_INT_S2);
829
830
	if (s1 != 0) {
831
		if (s1 & hfc_INTS_TIMER) {
832
			/*
833
			 * timer (bit 7)
834
			 */
835
			hfc_handle_timer_interrupt(card);
836
		}
837
838
		if (s1 & hfc_INTS_L1STATE) {
839
			/*
840
			 * state machine (bit 6)
841
			 */
842
			hfc_handle_state_interrupt(card);
843
		}
844
845
		if (s1 & hfc_INTS_DREC) {
846
			/*
847
			 * D chan RX (bit 5)
848
			 */
849
			hfc_frame_arrived(&card->chans[D]);
850
		}
851
852
		if (s1 & hfc_INTS_B1REC) {
853
			/*
854
			 * B1 chan RX (bit 3)
855
			 */
856
			hfc_frame_arrived(&card->chans[B1]);
857
		}
858
859
		if (s1 & hfc_INTS_B2REC) {
860
			/*
861
			 * B2 chan RX (bit 4)
862
			 */
863
			hfc_frame_arrived(&card->chans[B2]);
864
		}
865
866
		if (s1 & hfc_INTS_DTRANS) {
867
			/*
868
			 * D chan TX (bit 2)
869
			 */
870
		}
871
872
		if (s1 & hfc_INTS_B1TRANS) {
873
			/*
874
			 * B1 chan TX (bit 0)
875
			 */
876
		}
877
878
		if (s1 & hfc_INTS_B2TRANS) {
879
			/*
880
			 * B2 chan TX (bit 1)
881
			 */
882
		}
883
884
	}
885
886
	if (s2 != 0) {
887
		if (s2 & hfc_M2_PMESEL) {
888
			/*
889
			 * kaboom irq (bit 7)
890
			 *
891
			 * CologneChip says:
892
			 *
893
			 * the meaning of this fatal error bit is that HFC-S
894
			 * PCI as PCI master could not access the PCI bus
895
			 * within 125us to finish its data processing. If this
896
			 * happens only very seldom it does not cause big
897
			 * problems but of course some B-channel or D-channel
898
			 * data will be corrupted due to this event.
899
			 *
900
			 * Unfortunately this bit is only set once after the
901
			 * problem occurs and can only be reseted by a
902
			 * software reset. That means it is not easily
903
			 * possible to check how often this fatal error
904
			 * happens.
905
			 *
906
			 */
907
908
			if (!card->sync_loss_reported) {
909
				printk(KERN_CRIT hfc_DRIVER_PREFIX
910
					"card %d: "
911
					"sync lost, pci performance too low!\n",
912
					card->cardnum);
913
914
				card->sync_loss_reported = TRUE;
915
			}
916
		}
917
918
		if (s2 & hfc_M2_GCI_MON_REC) {
919
			/*
920
			 * RxR monitor channel (bit 2)
921
			 */
922
		}
923
924
		if (s2 & hfc_M2_GCI_I_CHG) {
925
			/*
926
			 * GCI I-change  (bit 1)
927
			 */
928
		}
929
930
		if (s2 & hfc_M2_PROC_TRANS) {
931
			/*
932
			 * processing/non-processing transition  (bit 0)
933
			 */
934
			hfc_handle_processing_interrupt(card);
935
		}
936
937
	}
938
939
	spin_unlock_irqrestore(&card->lock, flags);
940
941
	return IRQ_HANDLED;
942
}
943
944
static void hfc_handle_timer_interrupt(struct hfc_card *card)
945
{
946
	if (card->ignore_first_timer_interrupt) {
947
		card->ignore_first_timer_interrupt = FALSE;
948
		return;
949
	}
950
951
	if ((card->nt_mode && card->l1_state == 3) ||
952
		(!card->nt_mode && card->l1_state == 7)) {
953
954
		card->regs.ctmt &= ~hfc_CTMT_TIMER_MASK;
955
		hfc_outb(card, hfc_CTMT, card->regs.ctmt);
956
957
		hfc_resume_fifo(card);
958
	}
959
}
960
961
static void hfc_handle_state_interrupt(struct hfc_card *card)
962
{
963
	u8 new_state = hfc_inb(card, hfc_STATES)  & hfc_STATES_STATE_MASK;
964
965
#ifdef DEBUG
966
	if (debug_level >= 1) {
967
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
968
			"card %d: "
969
			"layer 1 state = %c%d\n",
970
			card->cardnum,
971
			card->nt_mode ? 'G' : 'F',
972
			new_state);
973
	}
974
#endif
975
976
	if (card->nt_mode) {
977
		/*
978
		 * NT mode
979
		 */
980
981
		if (new_state == 3) {
982
			/*
983
			 * fix to G3 state (see specs)
984
			 */
985
			hfc_outb(card, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
986
		}
987
988
		if (new_state == 3 && card->l1_state != 3)
989
			hfc_resume_fifo(card);
990
991
		if (new_state != 3 && card->l1_state == 3)
992
			hfc_suspend_fifo(card);
993
994
	} else {
995
		if (new_state == 3) {
996
			/*
997
			 * Keep L1 up... zaptel & libpri expects
998
			 * a always up L1...
999
			 * Enable only  when using an unpatched libpri
1000
			 */
1001
1002
			if (force_l1_up) {
1003
				hfc_outb(card, hfc_STATES,
1004
					hfc_STATES_DO_ACTION |
1005
					hfc_STATES_ACTIVATE|
1006
					hfc_STATES_NT_G2_G3);
1007
			}
1008
		}
1009
1010
		if (new_state == 7 && card->l1_state != 7) {
1011
			/*
1012
			 * TE is now active, schedule FIFO activation after
1013
			 * some time, otherwise the first frames are lost
1014
			 */
1015
1016
			card->regs.ctmt |= hfc_CTMT_TIMER_50 |
1017
				hfc_CTMT_TIMER_CLEAR;
1018
			hfc_outb(card, hfc_CTMT, card->regs.ctmt);
1019
1020
			/*
1021
			 * Activating the timer firest an
1022
			 * interrupt immediately, we
1023
			 * obviously need to ignore it
1024
			 */
1025
			card->ignore_first_timer_interrupt = TRUE;
1026
		}
1027
1028
		if (new_state != 7 && card->l1_state == 7) {
1029
			/*
1030
			 * TE has become inactive, disable FIFO
1031
			 */
1032
			hfc_suspend_fifo(card);
1033
		}
1034
	}
1035
1036
	card->l1_state = new_state;
1037
}
1038
1039
static void hfc_handle_processing_interrupt(struct hfc_card *card)
1040
{
1041
	int available_bytes = 0;
1042
1043
	/*
1044
	 * Synchronize with the first enabled channel
1045
	 */
1046
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1047
		available_bytes = hfc_fifo_used_rx(&card->chans[B1].rx);
1048
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1049
		available_bytes = hfc_fifo_used_rx(&card->chans[B2].rx);
1050
	else
1051
		available_bytes = -1;
1052
1053
	if ((available_bytes == -1 && card->ticks == 8) ||
1054
		available_bytes >= DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD) {
1055
		card->ticks = 0;
1056
1057
		if (available_bytes > DAHDI_CHUNKSIZE*2 + hfc_RX_FIFO_PRELOAD) {
1058
			card->late_irqs++;
1059
			/*
1060
			 * we are out of sync, clear fifos, jaw
1061
			 */
1062
			hfc_clear_fifo_rx(&card->chans[B1].rx);
1063
			hfc_clear_fifo_tx(&card->chans[B1].tx);
1064
			hfc_clear_fifo_rx(&card->chans[B2].rx);
1065
			hfc_clear_fifo_tx(&card->chans[B2].tx);
1066
1067
#ifdef DEBUG
1068
			if (debug_level >= 4) {
1069
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1070
					"card %d: "
1071
					"late IRQ, %d bytes late\n",
1072
					card->cardnum,
1073
					available_bytes -
1074
						(DAHDI_CHUNKSIZE +
1075
						 hfc_RX_FIFO_PRELOAD));
1076
			}
1077
#endif
1078
		} else {
1079
			hfc_handle_voice(card);
1080
		}
1081
	}
1082
1083
	card->ticks++;
1084
}
1085
1086
1087
static void hfc_handle_voice(struct hfc_card *card)
1088
{
1089
	struct dahdi_hfc *hfccard = card->ztdev;
1090
	int frame_left, res;
1091
	unsigned char buf[hfc_HDLC_BUF_LEN];
1092
	unsigned int size = sizeof(buf) / sizeof(buf[0]);
1093
1094
1095
	if (card->chans[B1].status != open_voice &&
1096
		card->chans[B2].status != open_voice)
1097
		return;
1098
1099
	dahdi_transmit(&hfccard->span);
1100
1101
	if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
1102
		hfc_zap_transmit(&card->chans[B1].tx);
1103
	if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
1104
		hfc_zap_transmit(&card->chans[B2].tx);
1105
1106
	/*
1107
	 * dahdi hdlc frame tx
1108
	 */
1109
1110
	if (atomic_read(&hfccard->hdlc_pending)) {
1111
		hfc_check_l1_up(card);
1112
		res = dahdi_hdlc_getbuf(hfccard->sigchan, buf, &size);
1113
			if (size > 0) {
1114
				hfccard->sigactive = 1;
1115
				memcpy(card->chans[D].tx.ugly_framebuf +
1116
				card->chans[D].tx.ugly_framebuf_size,
1117
				buf, size);
1118
				card->chans[D].tx.ugly_framebuf_size += size;
1119
			if (res != 0) {
1120
					hfc_fifo_put_frame(&card->chans[D].tx,
1121
					card->chans[D].tx.ugly_framebuf,
1122
					card->chans[D].tx.ugly_framebuf_size);
1123
					++hfccard->frames_out;
1124
					hfccard->sigactive = 0;
1125
					card->chans[D].tx.ugly_framebuf_size
1126
						= 0;
1127
					atomic_dec(&hfccard->hdlc_pending);
1128
				}
1129
			}
1130
	}
1131
	/*
1132
	 * dahdi hdlc frame tx done
1133
	 */
1134
1135
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1136
		hfc_zap_receive(&card->chans[B1].rx);
1137
	else
1138
		memset(&card->chans[B1].rx.zaptel_buffer, 0x7f,
1139
			sizeof(card->chans[B1].rx.zaptel_buffer));
1140
1141
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1142
		hfc_zap_receive(&card->chans[B2].rx);
1143
	else
1144
		memset(&card->chans[B2].rx.zaptel_buffer, 0x7f,
1145
			sizeof(card->chans[B1].rx.zaptel_buffer));
1146
1147
	/*
1148
	 * Echo cancellation
1149
	 */
1150
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B1],
1151
			card->chans[B1].rx.zaptel_buffer,
1152
			card->chans[B1].tx.zaptel_buffer);
1153
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B2],
1154
			card->chans[B2].rx.zaptel_buffer,
1155
			card->chans[B2].tx.zaptel_buffer);
1156
1157
	/*
1158
	 * dahdi hdlc frame rx
1159
	 */
1160
	if (hfc_fifo_has_frames(&card->chans[D].rx))
1161
		hfc_frame_arrived(&card->chans[D]);
1162
1163
	if (card->chans[D].rx.ugly_framebuf_size) {
1164
		frame_left = card->chans[D].rx.ugly_framebuf_size -
1165
			card->chans[D].rx.ugly_framebuf_off ;
1166
		if (frame_left > hfc_HDLC_BUF_LEN) {
1167
			dahdi_hdlc_putbuf(hfccard->sigchan,
1168
					card->chans[D].rx.ugly_framebuf +
1169
					card->chans[D].rx.ugly_framebuf_off,
1170
					hfc_HDLC_BUF_LEN);
1171
			card->chans[D].rx.ugly_framebuf_off +=
1172
				hfc_HDLC_BUF_LEN;
1173
		} else {
1174
			dahdi_hdlc_putbuf(hfccard->sigchan,
1175
					card->chans[D].rx.ugly_framebuf +
1176
					card->chans[D].rx.ugly_framebuf_off,
1177
					frame_left);
1178
			dahdi_hdlc_finish(hfccard->sigchan);
1179
			card->chans[D].rx.ugly_framebuf_size = 0;
1180
			card->chans[D].rx.ugly_framebuf_off = 0;
1181
		}
1182
	}
1183
	/*
1184
	 * dahdi hdlc frame rx done
1185
	 */
1186
1187
	if (hfccard->span.flags & DAHDI_FLAG_RUNNING)
1188
		dahdi_receive(&hfccard->span);
1189
1190
}
1191
1192
static void hfc_frame_arrived(struct hfc_chan_duplex *chan)
1193
{
1194
	struct hfc_card *card = chan->card;
1195
	int antiloop = 16;
1196
	struct sk_buff *skb;
1197
1198
	while (hfc_fifo_has_frames(&chan->rx) && --antiloop) {
1199
		int frame_size = hfc_fifo_get_frame_size(&chan->rx);
1200
1201
		if (frame_size < 3) {
1202
#ifdef DEBUG
1203
			if (debug_level >= 2)
1204
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1205
					"card %d: "
1206
					"chan %s: "
1207
					"invalid frame received, "
1208
					"just %d bytes\n",
1209
					card->cardnum,
1210
					chan->name,
1211
					frame_size);
1212
#endif
1213
1214
			hfc_fifo_drop_frame(&chan->rx);
1215
1216
1217
			continue;
1218
		} else if (frame_size == 3) {
1219
#ifdef DEBUG
1220
			if (debug_level >= 2)
1221
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1222
					"card %d: "
1223
					"chan %s: "
1224
					"empty frame received\n",
1225
					card->cardnum,
1226
					chan->name);
1227
#endif
1228
1229
			hfc_fifo_drop_frame(&chan->rx);
1230
1231
1232
			continue;
1233
		}
1234
1235
		if (chan->open_by_zaptel &&
1236
			card->chans[D].rx.ugly_framebuf_size) {
1237
1238
				/*
1239
				 * We have to wait for Dahdi to transmit the
1240
				 * frame... wait for next time
1241
				 */
1242
1243
				 break;
1244
		}
1245
1246
		skb = dev_alloc_skb(frame_size - 3);
1247
1248
		if (!skb) {
1249
			printk(KERN_ERR hfc_DRIVER_PREFIX
1250
				"card %d: "
1251
				"chan %s: "
1252
				"cannot allocate skb: frame dropped\n",
1253
				card->cardnum,
1254
				chan->name);
1255
1256
			hfc_fifo_drop_frame(&chan->rx);
1257
1258
1259
			continue;
1260
		}
1261
1262
1263
		/*
1264
		* HFC does the checksum
1265
		*/
1266
#ifndef CHECKSUM_HW
1267
		skb->ip_summed = CHECKSUM_COMPLETE;
1268
#else
1269
		skb->ip_summed = CHECKSUM_HW;
1270
#endif
1271
1272
		if (chan->open_by_zaptel) {
1273
			card->chans[D].rx.ugly_framebuf_size = frame_size - 1;
1274
1275
			if (hfc_fifo_get_frame(&card->chans[D].rx,
1276
				card->chans[D].rx.ugly_framebuf,
1277
				frame_size - 1) == -1) {
1278
				dev_kfree_skb(skb);
1279
				continue;
1280
			}
1281
1282
			memcpy(skb_put(skb, frame_size - 3),
1283
				card->chans[D].rx.ugly_framebuf,
1284
				frame_size - 3);
1285
		} else {
1286
			if (hfc_fifo_get_frame(&chan->rx,
1287
				skb_put(skb, frame_size - 3),
1288
				frame_size - 3) == -1) {
1289
				dev_kfree_skb(skb);
1290
				continue;
1291
			}
1292
		}
1293
	}
1294
1295
	if (!antiloop)
1296
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1297
			"card %d: "
1298
			"Infinite loop detected\n",
1299
			card->cardnum);
1300
}
1301
1302
/******************************************
1303
 * Module initialization and cleanup
1304
 ******************************************/
1305
1306
static int __devinit hfc_probe(struct pci_dev *pci_dev,
1307
	const struct pci_device_id *ent)
1308
{
1309
	static int cardnum;
1310
	int err;
1311
	int i;
1312
1313
	struct hfc_card *card = NULL;
1314
	struct dahdi_hfc *zthfc = NULL;
1315
	card = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
1316
	if (!card) {
1317
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1318
			"unable to kmalloc!\n");
1319
		err = -ENOMEM;
1320
		goto err_alloc_hfccard;
1321
	}
1322
1323
	memset(card, 0x00, sizeof(struct hfc_card));
1324
	card->cardnum = cardnum;
1325
	card->pcidev = pci_dev;
1326
	spin_lock_init(&card->lock);
1327
1328
	pci_set_drvdata(pci_dev, card);
1329
1330
	err = pci_enable_device(pci_dev);
1331
	if (err)
1332
		goto err_pci_enable_device;
1333
1334
	err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT);
1335
	if (err) {
1336
		printk(KERN_ERR hfc_DRIVER_PREFIX
1337
			"card %d: "
1338
			"No suitable DMA configuration available.\n",
1339
			card->cardnum);
1340
		goto err_pci_set_dma_mask;
1341
	}
1342
1343
	pci_write_config_word(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
1344
	err = pci_request_regions(pci_dev, hfc_DRIVER_NAME);
1345
	if (err) {
1346
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1347
			"card %d: "
1348
			"cannot request I/O memory region\n",
1349
			card->cardnum);
1350
		goto err_pci_request_regions;
1351
	}
1352
1353
	pci_set_master(pci_dev);
1354
1355
	if (!pci_dev->irq) {
1356
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1357
			"card %d: "
1358
			"no irq!\n",
1359
			card->cardnum);
1360
		err = -ENODEV;
1361
		goto err_noirq;
1362
	}
1363
1364
	card->io_bus_mem = pci_resource_start(pci_dev, 1);
1365
	if (!card->io_bus_mem) {
1366
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1367
			"card %d: "
1368
			"no iomem!\n",
1369
			card->cardnum);
1370
		err = -ENODEV;
1371
		goto err_noiobase;
1372
	}
1373
1374
	card->io_mem = ioremap(card->io_bus_mem, hfc_PCI_MEM_SIZE);
1375
	if (!(card->io_mem)) {
1376
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1377
			"card %d: "
1378
			"cannot ioremap I/O memory\n",
1379
			card->cardnum);
1380
		err = -ENODEV;
1381
		goto err_ioremap;
1382
	}
1383
1384
	/*
1385
	 * pci_alloc_consistent guarantees alignment
1386
	 * (Documentation/DMA-mapping.txt)
1387
	 */
1388
	card->fifo_mem = pci_alloc_consistent(pci_dev,
1389
			hfc_FIFO_SIZE, &card->fifo_bus_mem);
1390
	if (!card->fifo_mem) {
1391
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1392
			"card %d: "
1393
			"unable to allocate FIFO DMA memory!\n",
1394
			card->cardnum);
1395
		err = -ENOMEM;
1396
		goto err_alloc_fifo;
1397
	}
1398
1399
	memset(card->fifo_mem, 0x00, hfc_FIFO_SIZE);
1400
1401
	card->fifos = card->fifo_mem;
1402
1403
	pci_write_config_dword(card->pcidev, hfc_PCI_MWBA, card->fifo_bus_mem);
1404
1405
	err = request_irq(card->pcidev->irq, &hfc_interrupt,
1406
1407
#if (KERNEL_VERSION(2, 6, 23) < LINUX_VERSION_CODE)
1408
		IRQF_SHARED, hfc_DRIVER_NAME, card);
1409
#else
1410
		SA_SHIRQ, hfc_DRIVER_NAME, card);
1411
#endif
1412
1413
	if (err) {
1414
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1415
			"card %d: "
1416
			"unable to register irq\n",
1417
			card->cardnum);
1418
		goto err_request_irq;
1419
	}
1420
1421
	card->nt_mode = FALSE;
1422
1423
	if (modes & (1 << card->cardnum))
1424
		card->nt_mode = TRUE;
1425
1426
	for (i = 0; i < nt_modes_count; i++) {
1427
		if (nt_modes[i] == card->cardnum)
1428
			card->nt_mode = TRUE;
1429
	}
1430
1431
	/*
1432
	 * D Channel
1433
	 */
1434
	card->chans[D].card = card;
1435
	card->chans[D].name = "D";
1436
	card->chans[D].status = free;
1437
	card->chans[D].number = D;
1438
	spin_lock_init(&card->chans[D].lock);
1439
1440
	card->chans[D].rx.chan      = &card->chans[D];
1441
	card->chans[D].rx.fifo_base = card->fifos + 0x4000;
1442
	card->chans[D].rx.z_base    = card->fifos + 0x4000;
1443
	card->chans[D].rx.z1_base   = card->fifos + 0x6080;
1444
	card->chans[D].rx.z2_base   = card->fifos + 0x6082;
1445
	card->chans[D].rx.z_min     = 0x0000;
1446
	card->chans[D].rx.z_max     = 0x01FF;
1447
	card->chans[D].rx.f_min     = 0x10;
1448
	card->chans[D].rx.f_max     = 0x1F;
1449
	card->chans[D].rx.f1        = card->fifos + 0x60a0;
1450
	card->chans[D].rx.f2        = card->fifos + 0x60a1;
1451
	card->chans[D].rx.fifo_size = card->chans[D].rx.z_max
1452
		- card->chans[D].rx.z_min + 1;
1453
	card->chans[D].rx.f_num     = card->chans[D].rx.f_max
1454
		- card->chans[D].rx.f_min + 1;
1455
1456
	card->chans[D].tx.chan      = &card->chans[D];
1457
	card->chans[D].tx.fifo_base = card->fifos + 0x0000;
1458
	card->chans[D].tx.z_base    = card->fifos + 0x0000;
1459
	card->chans[D].tx.z1_base   = card->fifos + 0x2080;
1460
	card->chans[D].tx.z2_base   = card->fifos + 0x2082;
1461
	card->chans[D].tx.z_min     = 0x0000;
1462
	card->chans[D].tx.z_max     = 0x01FF;
1463
	card->chans[D].tx.f_min     = 0x10;
1464
	card->chans[D].tx.f_max     = 0x1F;
1465
	card->chans[D].tx.f1        = card->fifos + 0x20a0;
1466
	card->chans[D].tx.f2        = card->fifos + 0x20a1;
1467
	card->chans[D].tx.fifo_size = card->chans[D].tx.z_max -
1468
		card->chans[D].tx.z_min + 1;
1469
	card->chans[D].tx.f_num     = card->chans[D].tx.f_max -
1470
		card->chans[D].tx.f_min + 1;
1471
1472
	/*
1473
	 * B1 Channel
1474
	 */
1475
	card->chans[B1].card = card;
1476
	card->chans[B1].name = "B1";
1477
	card->chans[B1].status = free;
1478
	card->chans[B1].number = B1;
1479
	card->chans[B1].protocol = 0;
1480
	spin_lock_init(&card->chans[B1].lock);
1481
1482
	card->chans[B1].rx.chan      = &card->chans[B1];
1483
	card->chans[B1].rx.fifo_base = card->fifos + 0x4200;
1484
	card->chans[B1].rx.z_base    = card->fifos + 0x4000;
1485
	card->chans[B1].rx.z1_base   = card->fifos + 0x6000;
1486
	card->chans[B1].rx.z2_base   = card->fifos + 0x6002;
1487
	card->chans[B1].rx.z_min     = 0x0200;
1488
	card->chans[B1].rx.z_max     = 0x1FFF;
1489
	card->chans[B1].rx.f_min     = 0x00;
1490
	card->chans[B1].rx.f_max     = 0x1F;
1491
	card->chans[B1].rx.f1        = card->fifos + 0x6080;
1492
	card->chans[B1].rx.f2        = card->fifos + 0x6081;
1493
	card->chans[B1].rx.fifo_size = card->chans[B1].rx.z_max -
1494
		card->chans[B1].rx.z_min + 1;
1495
	card->chans[B1].rx.f_num     = card->chans[B1].rx.f_max -
1496
		card->chans[B1].rx.f_min + 1;
1497
1498
	card->chans[B1].tx.chan      = &card->chans[B1];
1499
	card->chans[B1].tx.fifo_base = card->fifos + 0x0200;
1500
	card->chans[B1].tx.z_base    = card->fifos + 0x0000;
1501
	card->chans[B1].tx.z1_base   = card->fifos + 0x2000;
1502
	card->chans[B1].tx.z2_base   = card->fifos + 0x2002;
1503
	card->chans[B1].tx.z_min     = 0x0200;
1504
	card->chans[B1].tx.z_max     = 0x1FFF;
1505
	card->chans[B1].tx.f_min     = 0x00;
1506
	card->chans[B1].tx.f_max     = 0x1F;
1507
	card->chans[B1].tx.f1        = card->fifos + 0x2080;
1508
	card->chans[B1].tx.f2        = card->fifos + 0x2081;
1509
	card->chans[B1].tx.fifo_size = card->chans[B1].tx.z_max -
1510
		card->chans[B1].tx.z_min + 1;
1511
	card->chans[B1].tx.f_num     = card->chans[B1].tx.f_max -
1512
		card->chans[B1].tx.f_min + 1;
1513
1514
	/*
1515
	 * B2 Channel
1516
	 */
1517
	card->chans[B2].card = card;
1518
	card->chans[B2].name = "B2";
1519
	card->chans[B2].status = free;
1520
	card->chans[B2].number = B2;
1521
	card->chans[B2].protocol = 0;
1522
	spin_lock_init(&card->chans[B2].lock);
1523
1524
	card->chans[B2].rx.chan      = &card->chans[B2];
1525
	card->chans[B2].rx.fifo_base = card->fifos + 0x6200,
1526
	card->chans[B2].rx.z_base    = card->fifos + 0x6000;
1527
	card->chans[B2].rx.z1_base   = card->fifos + 0x6100;
1528
	card->chans[B2].rx.z2_base   = card->fifos + 0x6102;
1529
	card->chans[B2].rx.z_min     = 0x0200;
1530
	card->chans[B2].rx.z_max     = 0x1FFF;
1531
	card->chans[B2].rx.f_min     = 0x00;
1532
	card->chans[B2].rx.f_max     = 0x1F;
1533
	card->chans[B2].rx.f1        = card->fifos + 0x6180;
1534
	card->chans[B2].rx.f2        = card->fifos + 0x6181;
1535
	card->chans[B2].rx.fifo_size = card->chans[B2].rx.z_max -
1536
		card->chans[B2].rx.z_min + 1;
1537
	card->chans[B2].rx.f_num     = card->chans[B2].rx.f_max -
1538
		card->chans[B2].rx.f_min + 1;
1539
1540
	card->chans[B2].tx.chan      = &card->chans[B2];
1541
	card->chans[B2].tx.fifo_base = card->fifos + 0x2200;
1542
	card->chans[B2].tx.z_base    = card->fifos + 0x2000;
1543
	card->chans[B2].tx.z1_base   = card->fifos + 0x2100;
1544
	card->chans[B2].tx.z2_base   = card->fifos + 0x2102;
1545
	card->chans[B2].tx.z_min     = 0x0200;
1546
	card->chans[B2].tx.z_max     = 0x1FFF;
1547
	card->chans[B2].tx.f_min     = 0x00;
1548
	card->chans[B2].tx.f_max     = 0x1F;
1549
	card->chans[B2].tx.f1        = card->fifos + 0x2180;
1550
	card->chans[B2].tx.f2        = card->fifos + 0x2181;
1551
	card->chans[B2].tx.fifo_size = card->chans[B2].tx.z_max -
1552
		card->chans[B2].tx.z_min + 1;
1553
	card->chans[B2].tx.f_num     = card->chans[B2].tx.f_max -
1554
		card->chans[B2].tx.f_min + 1;
1555
1556
	/*
1557
	 * All done
1558
	 */
1559
1560
	zthfc = kmalloc(sizeof(struct dahdi_hfc), GFP_KERNEL);
1561
	if (!zthfc) {
1562
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1563
			"unable to kmalloc!\n");
1564
		goto err_request_irq;
1565
	}
1566
	memset(zthfc, 0x0, sizeof(struct dahdi_hfc));
1567
1568
	zthfc->card = card;
1569
	hfc_zap_initialize(zthfc);
1570
	card->ztdev = zthfc;
1571
1572
	snprintf(card->proc_dir_name,
1573
			sizeof(card->proc_dir_name),
1574
			"%d", card->cardnum);
1575
	card->proc_dir = proc_mkdir(card->proc_dir_name, hfc_proc_zaphfc_dir);
1576
	SET_PROC_DIRENTRY_OWNER(card->proc_dir);
1577
1578
	hfc_resetCard(card);
1579
1580
	printk(KERN_INFO hfc_DRIVER_PREFIX
1581
		"card %d configured for %s mode at mem %#lx (0x%p) IRQ %u\n",
1582
		card->cardnum,
1583
		card->nt_mode ? "NT" : "TE",
1584
		card->io_bus_mem,
1585
		card->io_mem,
1586
		card->pcidev->irq);
1587
1588
	cardnum++;
1589
1590
	return 0;
1591
1592
err_request_irq:
1593
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1594
		card->fifo_mem, card->fifo_bus_mem);
1595
err_alloc_fifo:
1596
	iounmap(card->io_mem);
1597
err_ioremap:
1598
err_noiobase:
1599
err_noirq:
1600
	pci_release_regions(pci_dev);
1601
err_pci_request_regions:
1602
err_pci_set_dma_mask:
1603
err_pci_enable_device:
1604
	kfree(card);
1605
err_alloc_hfccard:
1606
	return err;
1607
}
1608
1609
static void __devexit hfc_remove(struct pci_dev *pci_dev)
1610
{
1611
	struct hfc_card *card = pci_get_drvdata(pci_dev);
1612
1613
1614
	printk(KERN_INFO hfc_DRIVER_PREFIX
1615
		"card %d: "
1616
		"shutting down card at %p.\n",
1617
		card->cardnum,
1618
		card->io_mem);
1619
1620
	hfc_softreset(card);
1621
1622
	dahdi_unregister_device(card->ztdev->ddev);
1623
	hfc_dahdi_free(card->ztdev);
1624
1625
1626
	/*
1627
	 * disable memio and bustmaster
1628
	 */
1629
	pci_write_config_word(pci_dev, PCI_COMMAND, 0);
1630
1631
	remove_proc_entry("bufs", card->proc_dir);
1632
	remove_proc_entry("fifos", card->proc_dir);
1633
	remove_proc_entry("info", card->proc_dir);
1634
	remove_proc_entry(card->proc_dir_name, hfc_proc_zaphfc_dir);
1635
1636
	free_irq(pci_dev->irq, card);
1637
1638
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1639
		card->fifo_mem, card->fifo_bus_mem);
1640
1641
	iounmap(card->io_mem);
1642
1643
	pci_release_regions(pci_dev);
1644
1645
	pci_disable_device(pci_dev);
1646
1647
	kfree(card);
1648
}
1649
1650
/******************************************
1651
 * Module stuff
1652
 ******************************************/
1653
1654
static int __init hfc_init_module(void)
1655
{
1656
	int ret;
1657
1658
	printk(KERN_INFO hfc_DRIVER_PREFIX
1659
		hfc_DRIVER_STRING " loading\n");
1660
1661
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1662
	hfc_proc_zaphfc_dir = proc_mkdir(hfc_DRIVER_NAME, NULL);
1663
#else
1664
	hfc_proc_zaphfc_dir = proc_mkdir(hfc_DRIVER_NAME, proc_root_driver);
1665
#endif
1666
1667
	ret = dahdi_pci_module(&hfc_driver);
1668
	return ret;
1669
}
1670
1671
module_init(hfc_init_module);
1672
1673
static void __exit hfc_module_exit(void)
1674
{
1675
	pci_unregister_driver(&hfc_driver);
1676
1677
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1678
	remove_proc_entry(hfc_DRIVER_NAME, NULL);
1679
#else
1680
	remove_proc_entry(hfc_DRIVER_NAME, proc_root_driver);
1681
#endif
1682
1683
	printk(KERN_INFO hfc_DRIVER_PREFIX
1684
		hfc_DRIVER_STRING " unloaded\n");
1685
}
1686
1687
module_exit(hfc_module_exit);
1688
1689
#endif
1690
1691
MODULE_DESCRIPTION(hfc_DRIVER_DESCR);
1692
MODULE_AUTHOR("Jens Wilke <jw_vzaphfc@headissue.com>, "
1693
		"Daniele (Vihai) Orlandi <daniele@orlandi.com>, "
1694
		"Jose A. Deniz <odicha@hotmail.com>");
1695
MODULE_ALIAS("vzaphfc");
1696
#ifdef MODULE_LICENSE
1697
MODULE_LICENSE("GPL");
1698
#endif
1699
1700
1701
module_param(modes, int, 0444);
1702
1703
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
1704
module_param_array(nt_modes, int, &nt_modes_count, 0444);
1705
#else
1706
module_param_array(nt_modes, int, nt_modes_count, 0444);
1707
#endif
1708
1709
module_param(force_l1_up, int, 0444);
1710
#ifdef DEBUG
1711
module_param(debug_level, int, 0444);
1712
#endif
1713
1714
MODULE_PARM_DESC(modes, "[Deprecated] bit-mask to configure NT mode");
1715
MODULE_PARM_DESC(nt_modes,
1716
		"Comma-separated list of card IDs to configure in NT mode");
1717
MODULE_PARM_DESC(force_l1_up, "Don't allow L1 to go down");
1718
#ifdef DEBUG
1719
MODULE_PARM_DESC(debug_level, "Debug verbosity level");
1720
#endif
(-)dahdi-linux-2.7.0/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.7.0/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.7.0/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.7.0/drivers/dahdi/zaphfc/zaphfc.h (+419 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * Dahdi port by Jose A. Deniz <odicha@hotmail.com>
5
 *
6
 * Copyright (C) 2009 Jose A. Deniz
7
 * Copyright (C) 2006 headissue GmbH; Jens Wilke
8
 * Copyright (C) 2004 Daniele Orlandi
9
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
10
 *
11
 * Jens Wilke <jw_vzaphfc@headissue.com>
12
 *
13
 * Orginal author of this code is
14
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
15
 *
16
 * Major rewrite of the driver made by
17
 * Klaus-Peter Junghanns <kpj@junghanns.net>
18
 *
19
 * This program is free software and may be modified and
20
 * distributed under the terms of the GNU Public License.
21
 *
22
 */
23
24
#ifndef _HFC_ZAPHFC_H
25
#define _HFC_ZAPHFC_H
26
27
#include <asm/io.h>
28
29
#define hfc_DRIVER_NAME "vzaphfc"
30
#define hfc_DRIVER_PREFIX hfc_DRIVER_NAME ": "
31
#define hfc_DRIVER_DESCR "HFC-S PCI A ISDN"
32
#define hfc_DRIVER_VERSION "1.42"
33
#define hfc_DRIVER_STRING hfc_DRIVER_DESCR " (V" hfc_DRIVER_VERSION ")"
34
35
#define hfc_MAX_BOARDS 32
36
37
#ifndef PCI_DMA_32BIT
38
#define PCI_DMA_32BIT	0x00000000ffffffffULL
39
#endif
40
41
#ifndef PCI_VENDOR_ID_SITECOM
42
#define PCI_VENDOR_ID_SITECOM 0x182D
43
#endif
44
45
#ifndef PCI_DEVICE_ID_SITECOM_3069
46
#define PCI_DEVICE_ID_SITECOM_3069 0x3069
47
#endif
48
49
#define hfc_RESET_DELAY 20
50
51
#define hfc_CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
52
#define hfc_CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
53
54
/* PCI memory mapped I/O */
55
56
#define hfc_PCI_MEM_SIZE	0x0100
57
#define hfc_PCI_MWBA		0x80
58
59
/* GCI/IOM bus monitor registers */
60
61
#define hfc_C_I       0x08
62
#define hfc_TRxR      0x0C
63
#define hfc_MON1_D    0x28
64
#define hfc_MON2_D    0x2C
65
66
67
/* GCI/IOM bus timeslot registers */
68
69
#define hfc_B1_SSL    0x80
70
#define hfc_B2_SSL    0x84
71
#define hfc_AUX1_SSL  0x88
72
#define hfc_AUX2_SSL  0x8C
73
#define hfc_B1_RSL    0x90
74
#define hfc_B2_RSL    0x94
75
#define hfc_AUX1_RSL  0x98
76
#define hfc_AUX2_RSL  0x9C
77
78
/* GCI/IOM bus data registers */
79
80
#define hfc_B1_D      0xA0
81
#define hfc_B2_D      0xA4
82
#define hfc_AUX1_D    0xA8
83
#define hfc_AUX2_D    0xAC
84
85
/* GCI/IOM bus configuration registers */
86
87
#define hfc_MST_EMOD  0xB4
88
#define hfc_MST_MODE	 0xB8
89
#define hfc_CONNECT	 0xBC
90
91
92
/* Interrupt and status registers */
93
94
#define hfc_FIFO_EN   0x44
95
#define hfc_TRM       0x48
96
#define hfc_B_MODE    0x4C
97
#define hfc_CHIP_ID   0x58
98
#define hfc_CIRM	 0x60
99
#define hfc_CTMT	 0x64
100
#define hfc_INT_M1	 0x68
101
#define hfc_INT_M2	 0x6C
102
#define hfc_INT_S1	 0x78
103
#define hfc_INT_S2	 0x7C
104
#define hfc_STATUS	 0x70
105
106
/* S/T section registers */
107
108
#define hfc_STATES	 0xC0
109
#define hfc_SCTRL	 0xC4
110
#define hfc_SCTRL_E   0xC8
111
#define hfc_SCTRL_R   0xCC
112
#define hfc_SQ	 0xD0
113
#define hfc_CLKDEL	 0xDC
114
#define hfc_B1_REC    0xF0
115
#define hfc_B1_SEND   0xF0
116
#define hfc_B2_REC    0xF4
117
#define hfc_B2_SEND   0xF4
118
#define hfc_D_REC     0xF8
119
#define hfc_D_SEND    0xF8
120
#define hfc_E_REC     0xFC
121
122
/* Bits and values in various HFC PCI registers */
123
124
/* bits in status register (READ) */
125
#define hfc_STATUS_PCI_PROC	0x02
126
#define hfc_STATUS_NBUSY	0x04
127
#define hfc_STATUS_TIMER_ELAP	0x10
128
#define hfc_STATUS_STATINT	0x20
129
#define hfc_STATUS_FRAMEINT	0x40
130
#define hfc_STATUS_ANYINT	0x80
131
132
/* bits in CTMT (Write) */
133
#define hfc_CTMT_TRANSB1	0x01
134
#define hfc_CTMT_TRANSB2	0x02
135
#define hfc_CTMT_TIMER_CLEAR	0x80
136
#define hfc_CTMT_TIMER_MASK	0x1C
137
#define hfc_CTMT_TIMER_3_125	(0x01 << 2)
138
#define hfc_CTMT_TIMER_6_25	(0x02 << 2)
139
#define hfc_CTMT_TIMER_12_5	(0x03 << 2)
140
#define hfc_CTMT_TIMER_25	(0x04 << 2)
141
#define hfc_CTMT_TIMER_50	(0x05 << 2)
142
#define hfc_CTMT_TIMER_400	(0x06 << 2)
143
#define hfc_CTMT_TIMER_800	(0x07 << 2)
144
#define hfc_CTMT_AUTO_TIMER	0x20
145
146
/* bits in CIRM (Write) */
147
#define hfc_CIRM_AUX_MSK	0x07
148
#define hfc_CIRM_RESET		0x08
149
#define hfc_CIRM_B1_REV		0x40
150
#define hfc_CIRM_B2_REV		0x80
151
152
/* bits in INT_M1 and INT_S1 */
153
#define hfc_INTS_B1TRANS	0x01
154
#define hfc_INTS_B2TRANS	0x02
155
#define hfc_INTS_DTRANS		0x04
156
#define hfc_INTS_B1REC		0x08
157
#define hfc_INTS_B2REC		0x10
158
#define hfc_INTS_DREC		0x20
159
#define hfc_INTS_L1STATE	0x40
160
#define hfc_INTS_TIMER		0x80
161
162
/* bits in INT_M2 */
163
#define hfc_M2_PROC_TRANS	0x01
164
#define hfc_M2_GCI_I_CHG	0x02
165
#define hfc_M2_GCI_MON_REC	0x04
166
#define hfc_M2_IRQ_ENABLE	0x08
167
#define hfc_M2_PMESEL		0x80
168
169
/* bits in STATES */
170
#define hfc_STATES_STATE_MASK	0x0F
171
#define hfc_STATES_LOAD_STATE	0x10
172
#define hfc_STATES_ACTIVATE	0x20
173
#define hfc_STATES_DO_ACTION	0x40
174
#define hfc_STATES_NT_G2_G3	0x80
175
176
/* bits in HFCD_MST_MODE */
177
#define hfc_MST_MODE_MASTER	0x01
178
#define hfc_MST_MODE_SLAVE	0x00
179
/* remaining bits are for codecs control */
180
181
/* bits in HFCD_SCTRL */
182
#define hfc_SCTRL_B1_ENA	0x01
183
#define hfc_SCTRL_B2_ENA	0x02
184
#define hfc_SCTRL_MODE_TE       0x00
185
#define hfc_SCTRL_MODE_NT       0x04
186
#define hfc_SCTRL_LOW_PRIO	0x08
187
#define hfc_SCTRL_SQ_ENA	0x10
188
#define hfc_SCTRL_TEST		0x20
189
#define hfc_SCTRL_NONE_CAP	0x40
190
#define hfc_SCTRL_PWR_DOWN	0x80
191
192
/* bits in SCTRL_E  */
193
#define hfc_SCTRL_E_AUTO_AWAKE	0x01
194
#define hfc_SCTRL_E_DBIT_1	0x04
195
#define hfc_SCTRL_E_IGNORE_COL	0x08
196
#define hfc_SCTRL_E_CHG_B1_B2	0x80
197
198
/* bits in SCTRL_R  */
199
#define hfc_SCTRL_R_B1_ENA	0x01
200
#define hfc_SCTRL_R_B2_ENA	0x02
201
202
/* bits in FIFO_EN register */
203
#define hfc_FIFOEN_B1TX		0x01
204
#define hfc_FIFOEN_B1RX		0x02
205
#define hfc_FIFOEN_B2TX		0x04
206
#define hfc_FIFOEN_B2RX		0x08
207
#define hfc_FIFOEN_DTX		0x10
208
#define hfc_FIFOEN_DRX		0x20
209
210
#define hfc_FIFOEN_B1		(hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
211
#define hfc_FIFOEN_B2		(hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
212
#define hfc_FIFOEN_D		(hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
213
214
/* bits in the CONNECT register */
215
#define	hfc_CONNECT_B1_HFC_from_ST		0x00
216
#define	hfc_CONNECT_B1_HFC_from_GCI		0x01
217
#define hfc_CONNECT_B1_ST_from_HFC		0x00
218
#define hfc_CONNECT_B1_ST_from_GCI		0x02
219
#define hfc_CONNECT_B1_GCI_from_HFC		0x00
220
#define hfc_CONNECT_B1_GCI_from_ST		0x04
221
222
#define	hfc_CONNECT_B2_HFC_from_ST		0x00
223
#define	hfc_CONNECT_B2_HFC_from_GCI		0x08
224
#define hfc_CONNECT_B2_ST_from_HFC		0x00
225
#define hfc_CONNECT_B2_ST_from_GCI		0x10
226
#define hfc_CONNECT_B2_GCI_from_HFC		0x00
227
#define hfc_CONNECT_B2_GCI_from_ST		0x20
228
229
/* bits in the TRM register */
230
#define hfc_TRM_TRANS_INT_00	0x00
231
#define hfc_TRM_TRANS_INT_01	0x01
232
#define hfc_TRM_TRANS_INT_10	0x02
233
#define hfc_TRM_TRANS_INT_11	0x04
234
#define hfc_TRM_ECHO		0x20
235
#define hfc_TRM_B1_PLUS_B2	0x40
236
#define hfc_TRM_IOM_TEST_LOOP	0x80
237
238
/* bits in the __SSL and __RSL registers */
239
#define	hfc_SRSL_STIO		0x40
240
#define hfc_SRSL_ENABLE		0x80
241
#define hfc_SRCL_SLOT_MASK	0x1f
242
243
/* FIFO memory definitions */
244
245
#define hfc_FIFO_SIZE		0x8000
246
247
#define hfc_UGLY_FRAMEBUF	0x2000
248
249
#define hfc_TX_FIFO_PRELOAD	(DAHDI_CHUNKSIZE + 2)
250
#define hfc_RX_FIFO_PRELOAD	4
251
252
/* HDLC STUFF */
253
#define hfc_HDLC_BUF_LEN	32
254
/* arbitrary, just the max # of byts we will send to DAHDI per call */
255
256
257
/* NOTE: FIFO pointers are not declared volatile because accesses to the
258
 *       FIFOs are inherently safe.
259
 */
260
261
#ifdef DEBUG
262
extern int debug_level;
263
#endif
264
265
struct hfc_chan;
266
267
struct hfc_chan_simplex {
268
	struct hfc_chan_duplex *chan;
269
270
	u8 zaptel_buffer[DAHDI_CHUNKSIZE];
271
272
	u8 ugly_framebuf[hfc_UGLY_FRAMEBUF];
273
	int ugly_framebuf_size;
274
	u16 ugly_framebuf_off;
275
276
	void *z1_base, *z2_base;
277
	void *fifo_base;
278
	void *z_base;
279
	u16 z_min;
280
	u16 z_max;
281
	u16 fifo_size;
282
283
	u8 *f1, *f2;
284
	u8 f_min;
285
	u8 f_max;
286
	u8 f_num;
287
288
	unsigned long long frames;
289
	unsigned long long bytes;
290
	unsigned long long fifo_full;
291
	unsigned long long crc;
292
	unsigned long long fifo_underrun;
293
};
294
295
enum hfc_chan_status {
296
	free,
297
	open_framed,
298
	open_voice,
299
	sniff_aux,
300
	loopback,
301
};
302
303
struct hfc_chan_duplex {
304
	struct hfc_card *card;
305
306
	char *name;
307
	int number;
308
309
	enum hfc_chan_status status;
310
	int open_by_netdev;
311
	int open_by_zaptel;
312
313
	unsigned short protocol;
314
315
	spinlock_t lock;
316
317
	struct hfc_chan_simplex rx;
318
	struct hfc_chan_simplex tx;
319
320
};
321
322
typedef struct hfc_card {
323
	int cardnum;
324
	struct pci_dev *pcidev;
325
	struct dahdi_hfc *ztdev;
326
	struct proc_dir_entry *proc_dir;
327
	char proc_dir_name[32];
328
329
	struct proc_dir_entry *proc_info;
330
	struct proc_dir_entry *proc_fifos;
331
	struct proc_dir_entry *proc_bufs;
332
333
	unsigned long io_bus_mem;
334
	void __iomem *io_mem;
335
336
	dma_addr_t fifo_bus_mem;
337
	void *fifo_mem;
338
	void *fifos;
339
340
	int nt_mode;
341
	int sync_loss_reported;
342
	int late_irqs;
343
344
	u8 l1_state;
345
	int fifo_suspended;
346
	int ignore_first_timer_interrupt;
347
348
	struct {
349
		u8 m1;
350
		u8 m2;
351
		u8 fifo_en;
352
		u8 trm;
353
		u8 connect;
354
		u8 sctrl;
355
		u8 sctrl_r;
356
		u8 sctrl_e;
357
		u8 ctmt;
358
		u8 cirm;
359
	} regs;
360
361
	struct hfc_chan_duplex chans[3];
362
	int echo_enabled;
363
364
365
366
	int debug_event;
367
368
	spinlock_t lock;
369
	unsigned int irq;
370
	unsigned int iomem;
371
	int ticks;
372
	int clicks;
373
	unsigned char *pci_io;
374
	void *fifomem;		/* start of the shared mem */
375
376
	unsigned int pcibus;
377
	unsigned int pcidevfn;
378
379
	int	drecinframe;
380
381
	unsigned char cardno;
382
	struct hfc_card *next;
383
384
} hfc_card;
385
386
typedef struct dahdi_hfc {
387
	unsigned int usecount;
388
	struct dahdi_device *ddev;
389
	struct dahdi_span span;
390
	struct dahdi_chan chans[3];
391
	struct dahdi_chan *_chans[3];
392
	struct hfc_card *card;
393
394
	/* pointer to the signalling channel for this span */
395
	struct dahdi_chan *sigchan;
396
	/* nonzero means we're in the middle of sending an HDLC frame */
397
	int sigactive;
398
	/* hdlc_hard_xmit() increments, hdlc_tx_frame() decrements */
399
	atomic_t hdlc_pending;
400
	int frames_out;
401
	int frames_in;
402
} dahdi_hfc;
403
404
static inline struct dahdi_hfc *dahdi_hfc_from_span(struct dahdi_span *span)
405
{
406
	return container_of(span, struct dahdi_hfc, span);
407
}
408
409
static inline u8 hfc_inb(struct hfc_card *card, int offset)
410
{
411
	return readb(card->io_mem + offset);
412
}
413
414
static inline void hfc_outb(struct hfc_card *card, int offset, u8 value)
415
{
416
	writeb(value, card->io_mem + offset);
417
}
418
419
#endif
(-)dahdi-linux-2.7.0/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.7.0/drivers/staging/echo/echo.h (+175 lines)
Line 0 Link Here
1
/*
2
 * SpanDSP - a series of DSP components for telephony
3
 *
4
 * echo.c - A line echo canceller.  This code is being developed
5
 *          against and partially complies with G168.
6
 *
7
 * Written by Steve Underwood <steveu@coppice.org>
8
 *         and David Rowe <david_at_rowetel_dot_com>
9
 *
10
 * Copyright (C) 2001 Steve Underwood and 2007 David Rowe
11
 *
12
 * All rights reserved.
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License version 2, as
16
 * published by the Free Software Foundation.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
 */
27
28
#ifndef __ECHO_H
29
#define __ECHO_H
30
31
/*
32
Line echo cancellation for voice
33
34
What does it do?
35
36
This module aims to provide G.168-2002 compliant echo cancellation, to remove
37
electrical echoes (e.g. from 2-4 wire hybrids) from voice calls.
38
39
40
How does it work?
41
42
The heart of the echo cancellor is FIR filter. This is adapted to match the
43
echo impulse response of the telephone line. It must be long enough to
44
adequately cover the duration of that impulse response. The signal transmitted
45
to the telephone line is passed through the FIR filter. Once the FIR is
46
properly adapted, the resulting output is an estimate of the echo signal
47
received from the line. This is subtracted from the received signal. The result
48
is an estimate of the signal which originated at the far end of the line, free
49
from echos of our own transmitted signal.
50
51
The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and
52
was introduced in 1960. It is the commonest form of filter adaption used in
53
things like modem line equalisers and line echo cancellers. There it works very
54
well.  However, it only works well for signals of constant amplitude. It works
55
very poorly for things like speech echo cancellation, where the signal level
56
varies widely.  This is quite easy to fix. If the signal level is normalised -
57
similar to applying AGC - LMS can work as well for a signal of varying
58
amplitude as it does for a modem signal. This normalised least mean squares
59
(NLMS) algorithm is the commonest one used for speech echo cancellation. Many
60
other algorithms exist - e.g. RLS (essentially the same as Kalman filtering),
61
FAP, etc. Some perform significantly better than NLMS.  However, factors such
62
as computational complexity and patents favour the use of NLMS.
63
64
A simple refinement to NLMS can improve its performance with speech. NLMS tends
65
to adapt best to the strongest parts of a signal. If the signal is white noise,
66
the NLMS algorithm works very well. However, speech has more low frequency than
67
high frequency content. Pre-whitening (i.e. filtering the signal to flatten its
68
spectrum) the echo signal improves the adapt rate for speech, and ensures the
69
final residual signal is not heavily biased towards high frequencies. A very
70
low complexity filter is adequate for this, so pre-whitening adds little to the
71
compute requirements of the echo canceller.
72
73
An FIR filter adapted using pre-whitened NLMS performs well, provided certain
74
conditions are met:
75
76
    - The transmitted signal has poor self-correlation.
77
    - There is no signal being generated within the environment being
78
      cancelled.
79
80
The difficulty is that neither of these can be guaranteed.
81
82
If the adaption is performed while transmitting noise (or something fairly
83
noise like, such as voice) the adaption works very well. If the adaption is
84
performed while transmitting something highly correlative (typically narrow
85
band energy such as signalling tones or DTMF), the adaption can go seriously
86
wrong. The reason is there is only one solution for the adaption on a near
87
random signal - the impulse response of the line. For a repetitive signal,
88
there are any number of solutions which converge the adaption, and nothing
89
guides the adaption to choose the generalised one. Allowing an untrained
90
canceller to converge on this kind of narrowband energy probably a good thing,
91
since at least it cancels the tones. Allowing a well converged canceller to
92
continue converging on such energy is just a way to ruin its generalised
93
adaption. A narrowband detector is needed, so adapation can be suspended at
94
appropriate times.
95
96
The adaption process is based on trying to eliminate the received signal. When
97
there is any signal from within the environment being cancelled it may upset
98
the adaption process. Similarly, if the signal we are transmitting is small,
99
noise may dominate and disturb the adaption process. If we can ensure that the
100
adaption is only performed when we are transmitting a significant signal level,
101
and the environment is not, things will be OK. Clearly, it is easy to tell when
102
we are sending a significant signal. Telling, if the environment is generating
103
a significant signal, and doing it with sufficient speed that the adaption will
104
not have diverged too much more we stop it, is a little harder.
105
106
The key problem in detecting when the environment is sourcing significant
107
energy is that we must do this very quickly. Given a reasonably long sample of
108
the received signal, there are a number of strategies which may be used to
109
assess whether that signal contains a strong far end component. However, by the
110
time that assessment is complete the far end signal will have already caused
111
major mis-convergence in the adaption process. An assessment algorithm is
112
needed which produces a fairly accurate result from a very short burst of far
113
end energy.
114
115
How do I use it?
116
117
The echo cancellor processes both the transmit and receive streams sample by
118
sample. The processing function is not declared inline. Unfortunately,
119
cancellation requires many operations per sample, so the call overhead is only
120
a minor burden.
121
*/
122
123
#include "fir.h"
124
#include "oslec.h"
125
126
/*
127
    G.168 echo canceller descriptor. This defines the working state for a line
128
    echo canceller.
129
*/
130
struct oslec_state {
131
	int16_t tx, rx;
132
	int16_t clean;
133
	int16_t clean_nlp;
134
135
	int nonupdate_dwell;
136
	int curr_pos;
137
	int taps;
138
	int log2taps;
139
	int adaption_mode;
140
141
	int cond_met;
142
	int32_t Pstates;
143
	int16_t adapt;
144
	int32_t factor;
145
	int16_t shift;
146
147
	/* Average levels and averaging filter states */
148
	int Ltxacc, Lrxacc, Lcleanacc, Lclean_bgacc;
149
	int Ltx, Lrx;
150
	int Lclean;
151
	int Lclean_bg;
152
	int Lbgn, Lbgn_acc, Lbgn_upper, Lbgn_upper_acc;
153
154
	/* foreground and background filter states */
155
	struct fir16_state_t fir_state;
156
	struct fir16_state_t fir_state_bg;
157
	int16_t *fir_taps16[2];
158
159
	/* DC blocking filter states */
160
	int tx_1, tx_2, rx_1, rx_2;
161
162
	/* optional High Pass Filter states */
163
	int32_t xvtx[5], yvtx[5];
164
	int32_t xvrx[5], yvrx[5];
165
166
	/* Parameters for the optional Hoth noise generator */
167
	int cng_level;
168
	int cng_rndnum;
169
	int cng_filter;
170
171
	/* snapshot sample of coeffs used for development */
172
	int16_t *snapshot;
173
};
174
175
#endif /* __ECHO_H */
(-)dahdi-linux-2.7.0/drivers/staging/echo/fir.h (+286 lines)
Line 0 Link Here
1
/*
2
 * SpanDSP - a series of DSP components for telephony
3
 *
4
 * fir.h - General telephony FIR routines
5
 *
6
 * Written by Steve Underwood <steveu@coppice.org>
7
 *
8
 * Copyright (C) 2002 Steve Underwood
9
 *
10
 * All rights reserved.
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License version 2, as
14
 * published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
 */
25
26
#if !defined(_FIR_H_)
27
#define _FIR_H_
28
29
/*
30
   Blackfin NOTES & IDEAS:
31
32
   A simple dot product function is used to implement the filter.  This performs
33
   just one MAC/cycle which is inefficient but was easy to implement as a first
34
   pass.  The current Blackfin code also uses an unrolled form of the filter
35
   history to avoid 0 length hardware loop issues.  This is wasteful of
36
   memory.
37
38
   Ideas for improvement:
39
40
   1/ Rewrite filter for dual MAC inner loop.  The issue here is handling
41
   history sample offsets that are 16 bit aligned - the dual MAC needs
42
   32 bit aligmnent.  There are some good examples in libbfdsp.
43
44
   2/ Use the hardware circular buffer facility tohalve memory usage.
45
46
   3/ Consider using internal memory.
47
48
   Using less memory might also improve speed as cache misses will be
49
   reduced. A drop in MIPs and memory approaching 50% should be
50
   possible.
51
52
   The foreground and background filters currenlty use a total of
53
   about 10 MIPs/ch as measured with speedtest.c on a 256 TAP echo
54
   can.
55
*/
56
57
#if defined(USE_MMX)  ||  defined(USE_SSE2)
58
#include "mmx.h"
59
#endif
60
61
/*
62
 * 16 bit integer FIR descriptor. This defines the working state for a single
63
 * instance of an FIR filter using 16 bit integer coefficients.
64
 */
65
struct fir16_state_t {
66
	int taps;
67
	int curr_pos;
68
	const int16_t *coeffs;
69
	int16_t *history;
70
};
71
72
/*
73
 * 32 bit integer FIR descriptor. This defines the working state for a single
74
 * instance of an FIR filter using 32 bit integer coefficients, and filtering
75
 * 16 bit integer data.
76
 */
77
struct fir32_state_t {
78
	int taps;
79
	int curr_pos;
80
	const int32_t *coeffs;
81
	int16_t *history;
82
};
83
84
/*
85
 * Floating point FIR descriptor. This defines the working state for a single
86
 * instance of an FIR filter using floating point coefficients and data.
87
 */
88
struct fir_float_state_t {
89
	int taps;
90
	int curr_pos;
91
	const float *coeffs;
92
	float *history;
93
};
94
95
static inline const int16_t *fir16_create(struct fir16_state_t *fir,
96
					      const int16_t *coeffs, int taps)
97
{
98
	fir->taps = taps;
99
	fir->curr_pos = taps - 1;
100
	fir->coeffs = coeffs;
101
#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
102
	fir->history = kcalloc(2 * taps, sizeof(int16_t), GFP_KERNEL);
103
#else
104
	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
105
#endif
106
	return fir->history;
107
}
108
109
static inline void fir16_flush(struct fir16_state_t *fir)
110
{
111
#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
112
	memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
113
#else
114
	memset(fir->history, 0, fir->taps * sizeof(int16_t));
115
#endif
116
}
117
118
static inline void fir16_free(struct fir16_state_t *fir)
119
{
120
	kfree(fir->history);
121
}
122
123
#ifdef __bfin__
124
static inline int32_t dot_asm(short *x, short *y, int len)
125
{
126
	int dot;
127
128
	len--;
129
130
	__asm__("I0 = %1;\n\t"
131
		"I1 = %2;\n\t"
132
		"A0 = 0;\n\t"
133
		"R0.L = W[I0++] || R1.L = W[I1++];\n\t"
134
		"LOOP dot%= LC0 = %3;\n\t"
135
		"LOOP_BEGIN dot%=;\n\t"
136
		"A0 += R0.L * R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
137
		"LOOP_END dot%=;\n\t"
138
		"A0 += R0.L*R1.L (IS);\n\t"
139
		"R0 = A0;\n\t"
140
		"%0 = R0;\n\t"
141
		: "=&d"(dot)
142
		: "a"(x), "a"(y), "a"(len)
143
		: "I0", "I1", "A1", "A0", "R0", "R1"
144
	);
145
146
	return dot;
147
}
148
#endif
149
150
static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
151
{
152
	int32_t y;
153
#if defined(USE_MMX)
154
	int i;
155
	union mmx_t *mmx_coeffs;
156
	union mmx_t *mmx_hist;
157
158
	fir->history[fir->curr_pos] = sample;
159
	fir->history[fir->curr_pos + fir->taps] = sample;
160
161
	mmx_coeffs = (union mmx_t *) fir->coeffs;
162
	mmx_hist = (union mmx_t *) &fir->history[fir->curr_pos];
163
	i = fir->taps;
164
	pxor_r2r(mm4, mm4);
165
	/* 8 samples per iteration, so the filter must be a multiple of
166
	   8 long. */
167
	while (i > 0) {
168
		movq_m2r(mmx_coeffs[0], mm0);
169
		movq_m2r(mmx_coeffs[1], mm2);
170
		movq_m2r(mmx_hist[0], mm1);
171
		movq_m2r(mmx_hist[1], mm3);
172
		mmx_coeffs += 2;
173
		mmx_hist += 2;
174
		pmaddwd_r2r(mm1, mm0);
175
		pmaddwd_r2r(mm3, mm2);
176
		paddd_r2r(mm0, mm4);
177
		paddd_r2r(mm2, mm4);
178
		i -= 8;
179
	}
180
	movq_r2r(mm4, mm0);
181
	psrlq_i2r(32, mm0);
182
	paddd_r2r(mm0, mm4);
183
	movd_r2m(mm4, y);
184
	emms();
185
#elif defined(USE_SSE2)
186
	int i;
187
	union xmm_t *xmm_coeffs;
188
	union xmm_t *xmm_hist;
189
190
	fir->history[fir->curr_pos] = sample;
191
	fir->history[fir->curr_pos + fir->taps] = sample;
192
193
	xmm_coeffs = (union xmm_t *) fir->coeffs;
194
	xmm_hist = (union xmm_t *) &fir->history[fir->curr_pos];
195
	i = fir->taps;
196
	pxor_r2r(xmm4, xmm4);
197
	/* 16 samples per iteration, so the filter must be a multiple of
198
	   16 long. */
199
	while (i > 0) {
200
		movdqu_m2r(xmm_coeffs[0], xmm0);
201
		movdqu_m2r(xmm_coeffs[1], xmm2);
202
		movdqu_m2r(xmm_hist[0], xmm1);
203
		movdqu_m2r(xmm_hist[1], xmm3);
204
		xmm_coeffs += 2;
205
		xmm_hist += 2;
206
		pmaddwd_r2r(xmm1, xmm0);
207
		pmaddwd_r2r(xmm3, xmm2);
208
		paddd_r2r(xmm0, xmm4);
209
		paddd_r2r(xmm2, xmm4);
210
		i -= 16;
211
	}
212
	movdqa_r2r(xmm4, xmm0);
213
	psrldq_i2r(8, xmm0);
214
	paddd_r2r(xmm0, xmm4);
215
	movdqa_r2r(xmm4, xmm0);
216
	psrldq_i2r(4, xmm0);
217
	paddd_r2r(xmm0, xmm4);
218
	movd_r2m(xmm4, y);
219
#elif defined(__bfin__)
220
	fir->history[fir->curr_pos] = sample;
221
	fir->history[fir->curr_pos + fir->taps] = sample;
222
	y = dot_asm((int16_t *) fir->coeffs, &fir->history[fir->curr_pos],
223
		    fir->taps);
224
#else
225
	int i;
226
	int offset1;
227
	int offset2;
228
229
	fir->history[fir->curr_pos] = sample;
230
231
	offset2 = fir->curr_pos;
232
	offset1 = fir->taps - offset2;
233
	y = 0;
234
	for (i = fir->taps - 1; i >= offset1; i--)
235
		y += fir->coeffs[i] * fir->history[i - offset1];
236
	for (; i >= 0; i--)
237
		y += fir->coeffs[i] * fir->history[i + offset2];
238
#endif
239
	if (fir->curr_pos <= 0)
240
		fir->curr_pos = fir->taps;
241
	fir->curr_pos--;
242
	return (int16_t) (y >> 15);
243
}
244
245
static inline const int16_t *fir32_create(struct fir32_state_t *fir,
246
					      const int32_t *coeffs, int taps)
247
{
248
	fir->taps = taps;
249
	fir->curr_pos = taps - 1;
250
	fir->coeffs = coeffs;
251
	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
252
	return fir->history;
253
}
254
255
static inline void fir32_flush(struct fir32_state_t *fir)
256
{
257
	memset(fir->history, 0, fir->taps * sizeof(int16_t));
258
}
259
260
static inline void fir32_free(struct fir32_state_t *fir)
261
{
262
	kfree(fir->history);
263
}
264
265
static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
266
{
267
	int i;
268
	int32_t y;
269
	int offset1;
270
	int offset2;
271
272
	fir->history[fir->curr_pos] = sample;
273
	offset2 = fir->curr_pos;
274
	offset1 = fir->taps - offset2;
275
	y = 0;
276
	for (i = fir->taps - 1; i >= offset1; i--)
277
		y += fir->coeffs[i] * fir->history[i - offset1];
278
	for (; i >= 0; i--)
279
		y += fir->coeffs[i] * fir->history[i + offset2];
280
	if (fir->curr_pos <= 0)
281
		fir->curr_pos = fir->taps;
282
	fir->curr_pos--;
283
	return (int16_t) (y >> 15);
284
}
285
286
#endif
(-)dahdi-linux-2.7.0/drivers/staging/echo/Kbuild (+6 lines)
Line 0 Link Here
1
ifdef DAHDI_USE_MMX
2
EXTRA_CFLAGS += -DUSE_MMX
3
endif
4
5
# An explicit 'obj-m' , unlike the Makefile
6
obj-m += echo.o
(-)dahdi-linux-2.7.0/drivers/staging/echo/mmx.h (+288 lines)
Line 0 Link Here
1
/*
2
 * mmx.h
3
 * Copyright (C) 1997-2001 H. Dietz and R. Fisher
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
#ifndef AVCODEC_I386MMX_H
22
#define AVCODEC_I386MMX_H
23
24
/*
25
 * The type of an value that fits in an MMX register (note that long
26
 * long constant values MUST be suffixed by LL and unsigned long long
27
 * values by ULL, lest they be truncated by the compiler)
28
 */
29
30
union mmx_t {
31
	long long               q;      /* Quadword (64-bit) value */
32
	unsigned long long      uq;     /* Unsigned Quadword */
33
	int                     d[2];   /* 2 Doubleword (32-bit) values */
34
	unsigned int            ud[2];  /* 2 Unsigned Doubleword */
35
	short                   w[4];   /* 4 Word (16-bit) values */
36
	unsigned short          uw[4];  /* 4 Unsigned Word */
37
	char                    b[8];   /* 8 Byte (8-bit) values */
38
	unsigned char           ub[8];  /* 8 Unsigned Byte */
39
	float                   s[2];   /* Single-precision (32-bit) value */
40
};        /* On an 8-byte (64-bit) boundary */
41
42
/* SSE registers */
43
union xmm_t {
44
	char b[16];
45
};
46
47
48
#define         mmx_i2r(op, imm, reg) \
49
	__asm__ __volatile__ (#op " %0, %%" #reg \
50
			: /* nothing */ \
51
			: "i" (imm))
52
53
#define         mmx_m2r(op, mem, reg) \
54
	__asm__ __volatile__ (#op " %0, %%" #reg \
55
			: /* nothing */ \
56
			: "m" (mem))
57
58
#define         mmx_r2m(op, reg, mem) \
59
	__asm__ __volatile__ (#op " %%" #reg ", %0" \
60
			: "=m" (mem) \
61
			: /* nothing */)
62
63
#define         mmx_r2r(op, regs, regd) \
64
	__asm__ __volatile__ (#op " %" #regs ", %" #regd)
65
66
67
#define         emms() __asm__ __volatile__ ("emms")
68
69
#define         movd_m2r(var, reg)           mmx_m2r(movd, var, reg)
70
#define         movd_r2m(reg, var)           mmx_r2m(movd, reg, var)
71
#define         movd_r2r(regs, regd)         mmx_r2r(movd, regs, regd)
72
73
#define         movq_m2r(var, reg)           mmx_m2r(movq, var, reg)
74
#define         movq_r2m(reg, var)           mmx_r2m(movq, reg, var)
75
#define         movq_r2r(regs, regd)         mmx_r2r(movq, regs, regd)
76
77
#define         packssdw_m2r(var, reg)       mmx_m2r(packssdw, var, reg)
78
#define         packssdw_r2r(regs, regd)     mmx_r2r(packssdw, regs, regd)
79
#define         packsswb_m2r(var, reg)       mmx_m2r(packsswb, var, reg)
80
#define         packsswb_r2r(regs, regd)     mmx_r2r(packsswb, regs, regd)
81
82
#define         packuswb_m2r(var, reg)       mmx_m2r(packuswb, var, reg)
83
#define         packuswb_r2r(regs, regd)     mmx_r2r(packuswb, regs, regd)
84
85
#define         paddb_m2r(var, reg)          mmx_m2r(paddb, var, reg)
86
#define         paddb_r2r(regs, regd)        mmx_r2r(paddb, regs, regd)
87
#define         paddd_m2r(var, reg)          mmx_m2r(paddd, var, reg)
88
#define         paddd_r2r(regs, regd)        mmx_r2r(paddd, regs, regd)
89
#define         paddw_m2r(var, reg)          mmx_m2r(paddw, var, reg)
90
#define         paddw_r2r(regs, regd)        mmx_r2r(paddw, regs, regd)
91
92
#define         paddsb_m2r(var, reg)         mmx_m2r(paddsb, var, reg)
93
#define         paddsb_r2r(regs, regd)       mmx_r2r(paddsb, regs, regd)
94
#define         paddsw_m2r(var, reg)         mmx_m2r(paddsw, var, reg)
95
#define         paddsw_r2r(regs, regd)       mmx_r2r(paddsw, regs, regd)
96
97
#define         paddusb_m2r(var, reg)        mmx_m2r(paddusb, var, reg)
98
#define         paddusb_r2r(regs, regd)      mmx_r2r(paddusb, regs, regd)
99
#define         paddusw_m2r(var, reg)        mmx_m2r(paddusw, var, reg)
100
#define         paddusw_r2r(regs, regd)      mmx_r2r(paddusw, regs, regd)
101
102
#define         pand_m2r(var, reg)           mmx_m2r(pand, var, reg)
103
#define         pand_r2r(regs, regd)         mmx_r2r(pand, regs, regd)
104
105
#define         pandn_m2r(var, reg)          mmx_m2r(pandn, var, reg)
106
#define         pandn_r2r(regs, regd)        mmx_r2r(pandn, regs, regd)
107
108
#define         pcmpeqb_m2r(var, reg)        mmx_m2r(pcmpeqb, var, reg)
109
#define         pcmpeqb_r2r(regs, regd)      mmx_r2r(pcmpeqb, regs, regd)
110
#define         pcmpeqd_m2r(var, reg)        mmx_m2r(pcmpeqd, var, reg)
111
#define         pcmpeqd_r2r(regs, regd)      mmx_r2r(pcmpeqd, regs, regd)
112
#define         pcmpeqw_m2r(var, reg)        mmx_m2r(pcmpeqw, var, reg)
113
#define         pcmpeqw_r2r(regs, regd)      mmx_r2r(pcmpeqw, regs, regd)
114
115
#define         pcmpgtb_m2r(var, reg)        mmx_m2r(pcmpgtb, var, reg)
116
#define         pcmpgtb_r2r(regs, regd)      mmx_r2r(pcmpgtb, regs, regd)
117
#define         pcmpgtd_m2r(var, reg)        mmx_m2r(pcmpgtd, var, reg)
118
#define         pcmpgtd_r2r(regs, regd)      mmx_r2r(pcmpgtd, regs, regd)
119
#define         pcmpgtw_m2r(var, reg)        mmx_m2r(pcmpgtw, var, reg)
120
#define         pcmpgtw_r2r(regs, regd)      mmx_r2r(pcmpgtw, regs, regd)
121
122
#define         pmaddwd_m2r(var, reg)        mmx_m2r(pmaddwd, var, reg)
123
#define         pmaddwd_r2r(regs, regd)      mmx_r2r(pmaddwd, regs, regd)
124
125
#define         pmulhw_m2r(var, reg)         mmx_m2r(pmulhw, var, reg)
126
#define         pmulhw_r2r(regs, regd)       mmx_r2r(pmulhw, regs, regd)
127
128
#define         pmullw_m2r(var, reg)         mmx_m2r(pmullw, var, reg)
129
#define         pmullw_r2r(regs, regd)       mmx_r2r(pmullw, regs, regd)
130
131
#define         por_m2r(var, reg)            mmx_m2r(por, var, reg)
132
#define         por_r2r(regs, regd)          mmx_r2r(por, regs, regd)
133
134
#define         pslld_i2r(imm, reg)          mmx_i2r(pslld, imm, reg)
135
#define         pslld_m2r(var, reg)          mmx_m2r(pslld, var, reg)
136
#define         pslld_r2r(regs, regd)        mmx_r2r(pslld, regs, regd)
137
#define         psllq_i2r(imm, reg)          mmx_i2r(psllq, imm, reg)
138
#define         psllq_m2r(var, reg)          mmx_m2r(psllq, var, reg)
139
#define         psllq_r2r(regs, regd)        mmx_r2r(psllq, regs, regd)
140
#define         psllw_i2r(imm, reg)          mmx_i2r(psllw, imm, reg)
141
#define         psllw_m2r(var, reg)          mmx_m2r(psllw, var, reg)
142
#define         psllw_r2r(regs, regd)        mmx_r2r(psllw, regs, regd)
143
144
#define         psrad_i2r(imm, reg)          mmx_i2r(psrad, imm, reg)
145
#define         psrad_m2r(var, reg)          mmx_m2r(psrad, var, reg)
146
#define         psrad_r2r(regs, regd)        mmx_r2r(psrad, regs, regd)
147
#define         psraw_i2r(imm, reg)          mmx_i2r(psraw, imm, reg)
148
#define         psraw_m2r(var, reg)          mmx_m2r(psraw, var, reg)
149
#define         psraw_r2r(regs, regd)        mmx_r2r(psraw, regs, regd)
150
151
#define         psrld_i2r(imm, reg)          mmx_i2r(psrld, imm, reg)
152
#define         psrld_m2r(var, reg)          mmx_m2r(psrld, var, reg)
153
#define         psrld_r2r(regs, regd)        mmx_r2r(psrld, regs, regd)
154
#define         psrlq_i2r(imm, reg)          mmx_i2r(psrlq, imm, reg)
155
#define         psrlq_m2r(var, reg)          mmx_m2r(psrlq, var, reg)
156
#define         psrlq_r2r(regs, regd)        mmx_r2r(psrlq, regs, regd)
157
#define         psrlw_i2r(imm, reg)          mmx_i2r(psrlw, imm, reg)
158
#define         psrlw_m2r(var, reg)          mmx_m2r(psrlw, var, reg)
159
#define         psrlw_r2r(regs, regd)        mmx_r2r(psrlw, regs, regd)
160
161
#define         psubb_m2r(var, reg)          mmx_m2r(psubb, var, reg)
162
#define         psubb_r2r(regs, regd)        mmx_r2r(psubb, regs, regd)
163
#define         psubd_m2r(var, reg)          mmx_m2r(psubd, var, reg)
164
#define         psubd_r2r(regs, regd)        mmx_r2r(psubd, regs, regd)
165
#define         psubw_m2r(var, reg)          mmx_m2r(psubw, var, reg)
166
#define         psubw_r2r(regs, regd)        mmx_r2r(psubw, regs, regd)
167
168
#define         psubsb_m2r(var, reg)         mmx_m2r(psubsb, var, reg)
169
#define         psubsb_r2r(regs, regd)       mmx_r2r(psubsb, regs, regd)
170
#define         psubsw_m2r(var, reg)         mmx_m2r(psubsw, var, reg)
171
#define         psubsw_r2r(regs, regd)       mmx_r2r(psubsw, regs, regd)
172
173
#define         psubusb_m2r(var, reg)        mmx_m2r(psubusb, var, reg)
174
#define         psubusb_r2r(regs, regd)      mmx_r2r(psubusb, regs, regd)
175
#define         psubusw_m2r(var, reg)        mmx_m2r(psubusw, var, reg)
176
#define         psubusw_r2r(regs, regd)      mmx_r2r(psubusw, regs, regd)
177
178
#define         punpckhbw_m2r(var, reg)      mmx_m2r(punpckhbw, var, reg)
179
#define         punpckhbw_r2r(regs, regd)    mmx_r2r(punpckhbw, regs, regd)
180
#define         punpckhdq_m2r(var, reg)      mmx_m2r(punpckhdq, var, reg)
181
#define         punpckhdq_r2r(regs, regd)    mmx_r2r(punpckhdq, regs, regd)
182
#define         punpckhwd_m2r(var, reg)      mmx_m2r(punpckhwd, var, reg)
183
#define         punpckhwd_r2r(regs, regd)    mmx_r2r(punpckhwd, regs, regd)
184
185
#define         punpcklbw_m2r(var, reg)      mmx_m2r(punpcklbw, var, reg)
186
#define         punpcklbw_r2r(regs, regd)    mmx_r2r(punpcklbw, regs, regd)
187
#define         punpckldq_m2r(var, reg)      mmx_m2r(punpckldq, var, reg)
188
#define         punpckldq_r2r(regs, regd)    mmx_r2r(punpckldq, regs, regd)
189
#define         punpcklwd_m2r(var, reg)      mmx_m2r(punpcklwd, var, reg)
190
#define         punpcklwd_r2r(regs, regd)    mmx_r2r(punpcklwd, regs, regd)
191
192
#define         pxor_m2r(var, reg)           mmx_m2r(pxor, var, reg)
193
#define         pxor_r2r(regs, regd)         mmx_r2r(pxor, regs, regd)
194
195
196
/* 3DNOW extensions */
197
198
#define         pavgusb_m2r(var, reg)        mmx_m2r(pavgusb, var, reg)
199
#define         pavgusb_r2r(regs, regd)      mmx_r2r(pavgusb, regs, regd)
200
201
202
/* AMD MMX extensions - also available in intel SSE */
203
204
205
#define         mmx_m2ri(op, mem, reg, imm) \
206
	__asm__ __volatile__ (#op " %1, %0, %%" #reg \
207
			: /* nothing */ \
208
			: "m" (mem), "i" (imm))
209
#define         mmx_r2ri(op, regs, regd, imm) \
210
	__asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
211
			: /* nothing */ \
212
			: "i" (imm))
213
214
#define         mmx_fetch(mem, hint) \
215
	__asm__ __volatile__ ("prefetch" #hint " %0" \
216
			: /* nothing */ \
217
			: "m" (mem))
218
219
220
#define         maskmovq(regs, maskreg)      mmx_r2ri(maskmovq, regs, maskreg)
221
222
#define         movntq_r2m(mmreg, var)       mmx_r2m(movntq, mmreg, var)
223
224
#define         pavgb_m2r(var, reg)          mmx_m2r(pavgb, var, reg)
225
#define         pavgb_r2r(regs, regd)        mmx_r2r(pavgb, regs, regd)
226
#define         pavgw_m2r(var, reg)          mmx_m2r(pavgw, var, reg)
227
#define         pavgw_r2r(regs, regd)        mmx_r2r(pavgw, regs, regd)
228
229
#define         pextrw_r2r(mmreg, reg, imm)  mmx_r2ri(pextrw, mmreg, reg, imm)
230
231
#define         pinsrw_r2r(reg, mmreg, imm)  mmx_r2ri(pinsrw, reg, mmreg, imm)
232
233
#define         pmaxsw_m2r(var, reg)         mmx_m2r(pmaxsw, var, reg)
234
#define         pmaxsw_r2r(regs, regd)       mmx_r2r(pmaxsw, regs, regd)
235
236
#define         pmaxub_m2r(var, reg)         mmx_m2r(pmaxub, var, reg)
237
#define         pmaxub_r2r(regs, regd)       mmx_r2r(pmaxub, regs, regd)
238
239
#define         pminsw_m2r(var, reg)         mmx_m2r(pminsw, var, reg)
240
#define         pminsw_r2r(regs, regd)       mmx_r2r(pminsw, regs, regd)
241
242
#define         pminub_m2r(var, reg)         mmx_m2r(pminub, var, reg)
243
#define         pminub_r2r(regs, regd)       mmx_r2r(pminub, regs, regd)
244
245
#define         pmovmskb(mmreg, reg) \
246
	__asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
247
248
#define         pmulhuw_m2r(var, reg)        mmx_m2r(pmulhuw, var, reg)
249
#define         pmulhuw_r2r(regs, regd)      mmx_r2r(pmulhuw, regs, regd)
250
251
#define         prefetcht0(mem)              mmx_fetch(mem, t0)
252
#define         prefetcht1(mem)              mmx_fetch(mem, t1)
253
#define         prefetcht2(mem)              mmx_fetch(mem, t2)
254
#define         prefetchnta(mem)             mmx_fetch(mem, nta)
255
256
#define         psadbw_m2r(var, reg)         mmx_m2r(psadbw, var, reg)
257
#define         psadbw_r2r(regs, regd)       mmx_r2r(psadbw, regs, regd)
258
259
#define         pshufw_m2r(var, reg, imm)    mmx_m2ri(pshufw, var, reg, imm)
260
#define         pshufw_r2r(regs, regd, imm)  mmx_r2ri(pshufw, regs, regd, imm)
261
262
#define         sfence() __asm__ __volatile__ ("sfence\n\t")
263
264
/* SSE2 */
265
#define         pshufhw_m2r(var, reg, imm)   mmx_m2ri(pshufhw, var, reg, imm)
266
#define         pshufhw_r2r(regs, regd, imm) mmx_r2ri(pshufhw, regs, regd, imm)
267
#define         pshuflw_m2r(var, reg, imm)   mmx_m2ri(pshuflw, var, reg, imm)
268
#define         pshuflw_r2r(regs, regd, imm) mmx_r2ri(pshuflw, regs, regd, imm)
269
270
#define         pshufd_r2r(regs, regd, imm)  mmx_r2ri(pshufd, regs, regd, imm)
271
272
#define         movdqa_m2r(var, reg)         mmx_m2r(movdqa, var, reg)
273
#define         movdqa_r2m(reg, var)         mmx_r2m(movdqa, reg, var)
274
#define         movdqa_r2r(regs, regd)       mmx_r2r(movdqa, regs, regd)
275
#define         movdqu_m2r(var, reg)         mmx_m2r(movdqu, var, reg)
276
#define         movdqu_r2m(reg, var)         mmx_r2m(movdqu, reg, var)
277
#define         movdqu_r2r(regs, regd)       mmx_r2r(movdqu, regs, regd)
278
279
#define         pmullw_r2m(reg, var)         mmx_r2m(pmullw, reg, var)
280
281
#define         pslldq_i2r(imm, reg)         mmx_i2r(pslldq, imm, reg)
282
#define         psrldq_i2r(imm, reg)         mmx_i2r(psrldq, imm, reg)
283
284
#define         punpcklqdq_r2r(regs, regd)   mmx_r2r(punpcklqdq, regs, regd)
285
#define         punpckhqdq_r2r(regs, regd)   mmx_r2r(punpckhqdq, regs, regd)
286
287
288
#endif /* AVCODEC_I386MMX_H */
(-)dahdi-linux-2.7.0/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 705860