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

Collapse All | Expand All

(-)dahdi-linux-2.6.1.ORIG/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 = "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 = "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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/drivers/dahdi/Kbuild (+8 lines)
Lines 31-36 Link Here
31
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
31
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
32
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
32
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
33
33
34
ifdef CONFIG_PCI
35
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_AP400)            += ap400/
36
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200)                += opvxa1200/
37
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115)         += opvxd115/
38
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCOPENPCI)                += wcopenpci.o
39
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_HFCS)           += hfcs/
40
endif
41
34
obj-m += $(DAHDI_MODULES_EXTRA)
42
obj-m += $(DAHDI_MODULES_EXTRA)
35
43
36
# If you want to build OSLEC, include the code in the standard location:
44
# If you want to build OSLEC, include the code in the standard location:
(-)dahdi-linux-2.6.1.ORIG/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_HFCS
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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/drivers/dahdi/opvxd115/base.c (+4911 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_EXPRESS (1 << 9)
234
#define FLAG_5THGEN  (1 << 10)
235
236
#define CANARY 0xc0de
237
238
239
#define PORTS_PER_FRAMER 4
240
241
struct devtype {
242
	char *desc;
243
	unsigned int flags;
244
};
245
246
static struct devtype opvxd115 = { "OpenVox D115P/D115E ", FLAG_2NDGEN};
247
static struct devtype opvxd130 = { "OpenVox D130P/D130E", FLAG_5THGEN | FLAG_BURST | FLAG_2NDGEN | FLAG_3RDGEN};
248
	
249
250
struct t4;
251
252
struct t4_span {
253
	struct t4 *owner;
254
	unsigned int *writechunk;					/* Double-word aligned write memory */
255
	unsigned int *readchunk;					/* Double-word aligned read memory */
256
	int spantype;		/* card type, T1 or E1 or J1 */
257
	int sync;
258
	int psync;
259
	int alarmtimer;
260
	int redalarms;
261
	int notclear;
262
	int alarmcount;
263
	int losalarmcount;
264
	int aisalarmcount;
265
	int yelalarmcount;
266
	int spanflags;
267
	int syncpos;
268
#ifdef SUPPORT_GEN1
269
	int e1check;			/* E1 check */
270
#endif
271
	struct dahdi_span span;
272
	unsigned char txsigs[16];	/* Transmit sigs */
273
	int loopupcnt;
274
	int loopdowncnt;
275
#ifdef SUPPORT_GEN1
276
	unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
277
	unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
278
#endif
279
	int irqmisses;
280
	
281
	/* HDLC controller fields */
282
	struct dahdi_chan *sigchan;
283
	unsigned char sigmode;
284
	int sigactive;
285
	int frames_out;
286
	int frames_in;
287
288
#ifdef VPM_SUPPORT
289
	unsigned long dtmfactive;
290
	unsigned long dtmfmask;
291
	unsigned long dtmfmutemask;
292
	short dtmfenergy[31];
293
	short dtmfdigit[31];
294
#endif
295
#ifdef ENABLE_WORKQUEUES
296
	struct work_struct swork;
297
#endif	
298
	struct dahdi_chan *chans[32];		/* Individual channels */
299
	struct dahdi_echocan_state *ec[32];	/* Echocan state for each channel */
300
};
301
302
struct t4 {
303
	/* This structure exists one per card */
304
	struct pci_dev *dev;		/* Pointer to PCI device */
305
	struct dahdi_device *ddev;	/* Pointer to DAHDI device */
306
	unsigned int intcount;
307
	int num;			/* Which card we are */
308
	int t1e1;			/* T1/E1 select pins */
309
	int globalconfig;	/* Whether global setup has been done */
310
	int syncsrc;			/* active sync source */
311
	struct t4_span *tspans[4];	/* Individual spans */
312
	int numspans;			/* Number of spans on the card */
313
	int blinktimer;
314
#ifdef FANCY_ALARM
315
	int alarmpos;
316
#endif
317
	int irq;			/* IRQ used by device */
318
	int order;			/* Order */
319
	int flags;                      /* Device flags */
320
	unsigned int falc31 : 1;	/* are we falc v3.1 (atomic not necessary) */
321
	int master;				/* Are we master */
322
	int ledreg;				/* LED Register */
323
	unsigned int gpio;
324
	unsigned int gpioctl;
325
	int e1recover;			/* E1 recovery timer */
326
	spinlock_t reglock;		/* lock register access */
327
	int spansstarted;		/* number of spans started */
328
	volatile unsigned int *writechunk;					/* Double-word aligned write memory */
329
	volatile unsigned int *readchunk;					/* Double-word aligned read memory */
330
	unsigned short canary;
331
#ifdef ENABLE_WORKQUEUES
332
	atomic_t worklist;
333
	struct workqueue_struct *workq;
334
#endif
335
	unsigned int passno;	/* number of interrupt passes */
336
	char *variety;
337
	int last0;		/* for detecting double-missed IRQ */
338
339
	/* DMA related fields */
340
	unsigned int dmactrl;
341
	dma_addr_t 	readdma;
342
	dma_addr_t	writedma;
343
	unsigned long memaddr;		/* Base address of card */
344
	unsigned long memlen;
345
	__iomem volatile unsigned int *membase;	/* Base address of card */
346
347
	/* Add this for our softlockup protector */
348
	unsigned int oct_rw_count;
349
350
	/* Flags for our bottom half */
351
	unsigned long checkflag;
352
	struct tasklet_struct t4_tlet;
353
	unsigned int vpm400checkstatus;
354
	/* Latency related additions */
355
	unsigned char rxident;
356
	unsigned char lastindex;
357
	int numbufs;
358
	int needed_latency;
359
	
360
#ifdef VPM_SUPPORT
361
	struct vpm450m *vpm450m;
362
	int vpm;
363
#endif	
364
365
};
366
367
#define T4_VPM_PRESENT (1 << 28)
368
369
#ifdef VPM_SUPPORT
370
static void t4_vpm400_init(struct t4 *wc);
371
static void t4_vpm450_init(struct t4 *wc);
372
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
373
374
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
375
376
static const struct dahdi_echocan_features vpm400m_ec_features = {
377
	.NLP_automatic = 1,
378
	.CED_tx_detect = 1,
379
	.CED_rx_detect = 1,
380
};
381
382
static const struct dahdi_echocan_features vpm450m_ec_features = {
383
	.NLP_automatic = 1,
384
	.CED_tx_detect = 1,
385
	.CED_rx_detect = 1,
386
};
387
388
static const struct dahdi_echocan_ops vpm400m_ec_ops = {
389
	.echocan_free = echocan_free,
390
};
391
392
static const struct dahdi_echocan_ops vpm450m_ec_ops = {
393
	.echocan_free = echocan_free,
394
};
395
#endif
396
397
static void __set_clear(struct t4 *wc, int span);
398
static int t4_startup(struct file *file, struct dahdi_span *span);
399
static int t4_shutdown(struct dahdi_span *span);
400
static int t4_rbsbits(struct dahdi_chan *chan, int bits);
401
static int t4_maint(struct dahdi_span *span, int cmd);
402
static int t4_clear_maint(struct dahdi_span *span);
403
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
404
static int t4_reset_counters(struct dahdi_span *span);
405
#endif
406
#ifdef SUPPORT_GEN1
407
static int t4_reset_dma(struct t4 *wc);
408
#endif
409
static void t4_hdlc_hard_xmit(struct dahdi_chan *chan);
410
static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
411
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan);
412
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan);
413
static void __t4_set_rclk_src(struct t4 *wc, int span);
414
static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave);
415
static void t4_check_alarms(struct t4 *wc, int span);
416
static void t4_check_sigbits(struct t4 *wc, int span);
417
418
#define WC_RDADDR	0
419
#define WC_WRADDR	1
420
#define WC_COUNT	2
421
#define WC_DMACTRL	3	
422
#define WC_INTR		4
423
/* #define WC_GPIO		5 */
424
#define WC_VERSION	6
425
#define WC_LEDS		7
426
#define WC_GPIOCTL	8
427
#define WC_GPIO		9
428
#define WC_LADDR	10
429
#define WC_LDATA		11
430
#define WC_LCS		(1 << 11)
431
#define WC_LCS2		(1 << 12)
432
#define WC_LALE			(1 << 13)
433
#define WC_LFRMR_CS	(1 << 10)	/* Framer's ChipSelect signal */
434
#define WC_ACTIVATE	(1 << 12)
435
#define WC_LREAD			(1 << 15)
436
#define WC_LWRITE		(1 << 16)
437
438
#define WC_OFF    (0)
439
#define WC_RED    (1)
440
#define WC_GREEN  (2)
441
#define WC_YELLOW (3)
442
443
#define WC_RECOVER 	0
444
#define WC_SELF 	1
445
446
#define LIM0_T 0x36 		/* Line interface mode 0 register */
447
#define LIM0_LL (1 << 1)	/* Local Loop */
448
#define LIM1_T 0x37		/* Line interface mode 1 register */
449
#define LIM1_RL (1 << 1)	/* Remote Loop */
450
451
#define FMR0 0x1C		/* Framer Mode Register 0 */
452
#define FMR0_SIM (1 << 0)	/* Alarm Simulation */
453
#define FMR1_T 0x1D		/* Framer Mode Register 1 */
454
#define FMR1_ECM (1 << 2)	/* Error Counter 1sec Interrupt Enable */
455
#define DEC_T 0x60		/* Diable Error Counter */
456
#define IERR_T 0x1B		/* Single Bit Defect Insertion Register */
457
#define IBV	0	 /* Bipolar violation */
458
#define IPE	(1 << 1) /* PRBS defect */
459
#define ICASE	(1 << 2) /* CAS defect */
460
#define ICRCE	(1 << 3) /* CRC defect */
461
#define IMFE	(1 << 4) /* Multiframe defect */
462
#define IFASE	(1 << 5) /* FAS defect */
463
#define ISR3_SEC (1 << 6)	/* Internal one-second interrupt bit mask */
464
#define ISR3_ES (1 << 7)	/* Errored Second interrupt bit mask */
465
#define ESM 0x47		/* Errored Second mask register */
466
467
#define FMR2_T 0x1E		/* Framer Mode Register 2 */
468
#define FMR2_PLB (1 << 2)	/* Framer Mode Register 2 */
469
470
#define FECL_T 0x50		/* Framing Error Counter Lower Byte */
471
#define FECH_T 0x51		/* Framing Error Counter Higher Byte */
472
#define CVCL_T 0x52		/* Code Violation Counter Lower Byte */
473
#define CVCH_T 0x53		/* Code Violation Counter Higher Byte */
474
#define CEC1L_T 0x54		/* CRC Error Counter 1 Lower Byte */
475
#define CEC1H_T 0x55		/* CRC Error Counter 1 Higher Byte */
476
#define EBCL_T 0x56		/* E-Bit Error Counter Lower Byte */
477
#define EBCH_T 0x57		/* E-Bit Error Counter Higher Byte */
478
#define BECL_T 0x58		/* Bit Error Counter Lower Byte */
479
#define BECH_T 0x59		/* Bit Error Counter Higher Byte */
480
#define COEC_T 0x5A		/* COFA Event Counter */
481
#define PRBSSTA_T 0xDA		/* PRBS Status Register */
482
483
#define LCR1_T 0x3B		/* Loop Code Register 1 */
484
#define EPRM (1 << 7)		/* Enable PRBS rx */
485
#define XPRBS (1 << 6)		/* Enable PRBS tx */
486
#define FLLB (1 << 1)		/* Framed line loop/Invert */
487
#define LLBP (1 << 0)		/* Line Loopback Pattern */
488
#define TPC0_T 0xA8		/* Test Pattern Control Register */
489
#define FRA (1 << 6)		/* Framed/Unframed Selection */
490
#define PRBS23 (3 << 4)		/* Pattern selection (23 poly) */
491
#define PRM (1 << 2)		/* Non framed mode */
492
#define FRS1_T 0x4D		/* Framer Receive Status Reg 1 */
493
#define LLBDD (1 << 4)
494
#define LLBAD (1 << 3)
495
496
#define MAX_T4_CARDS 64
497
498
static void t4_isr_bh(unsigned long data);
499
500
static struct t4 *cards[MAX_T4_CARDS];
501
502
503
#define MAX_TDM_CHAN 32
504
#define MAX_DTMF_DET 16
505
506
#define HDLC_IMR0_MASK (FRMR_IMR0_RME | FRMR_IMR0_RPF)
507
#if 0
508
#define HDLC_IMR1_MASK (FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR)
509
#else
510
#define HDLC_IMR1_MASK	(FRMR_IMR1_XDU | FRMR_IMR1_XPR)
511
#endif
512
513
static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
514
{
515
	unsigned int res = readl(&wc->membase[addr]);
516
	return res;
517
}
518
519
static inline void __t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
520
{
521
	unsigned int tmp;
522
	writel(value, &wc->membase[addr]);
523
	if (pedanticpci) {
524
		tmp = __t4_pci_in(wc, WC_VERSION);
525
		if ((tmp & 0xffff0000) != 0xc01a0000)
526
			dev_notice(&wc->dev->dev,
527
					"Version Synchronization Error!\n");
528
	}
529
#if 0
530
	tmp = __t4_pci_in(wc, addr);
531
	if ((value != tmp) && (addr != WC_LEDS) && (addr != WC_LDATA) &&
532
		(addr != WC_GPIO) && (addr != WC_INTR))
533
		dev_info(&wc->dev->dev, "Tried to load %08x into %08x, "
534
				"but got %08x instead\n", value, addr, tmp);
535
#endif		
536
}
537
538
static inline void __t4_gpio_set(struct t4 *wc, unsigned bits, unsigned int val)
539
{
540
	unsigned int newgpio;
541
	newgpio = wc->gpio & (~bits);
542
	newgpio |= val;
543
	if (newgpio != wc->gpio) {
544
		wc->gpio = newgpio;
545
		__t4_pci_out(wc, WC_GPIO, wc->gpio);
546
	}	
547
}
548
549
static inline void __t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
550
{
551
	unsigned int newgpioctl;
552
	newgpioctl = wc->gpioctl & (~bits);
553
	newgpioctl |= val;
554
	if (newgpioctl != wc->gpioctl) {
555
		wc->gpioctl = newgpioctl;
556
		__t4_pci_out(wc, WC_GPIOCTL, wc->gpioctl);
557
	}
558
}
559
560
static inline void t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
561
{
562
	unsigned long flags;
563
	spin_lock_irqsave(&wc->reglock, flags);
564
	__t4_gpio_setdir(wc, bits, val);
565
	spin_unlock_irqrestore(&wc->reglock, flags);
566
}
567
568
static inline void t4_gpio_set(struct t4 *wc, unsigned int bits, unsigned int val)
569
{
570
	unsigned long flags;
571
	spin_lock_irqsave(&wc->reglock, flags);
572
	__t4_gpio_set(wc, bits, val);
573
	spin_unlock_irqrestore(&wc->reglock, flags);
574
}
575
576
static inline void t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
577
{
578
	unsigned long flags;
579
	spin_lock_irqsave(&wc->reglock, flags);
580
	__t4_pci_out(wc, addr, value);
581
	spin_unlock_irqrestore(&wc->reglock, flags);
582
}
583
584
static inline void __t4_set_led(struct t4 *wc, int span, int color)
585
{
586
	int oldreg = wc->ledreg;
587
	wc->ledreg &= ~(0x3 << (span << 1));
588
	wc->ledreg |= (color << (span << 1));
589
	if (oldreg != wc->ledreg)
590
		__t4_pci_out(wc, WC_LEDS, wc->ledreg);
591
}
592
593
static inline void t4_activate(struct t4 *wc)
594
{
595
	wc->ledreg |= WC_ACTIVATE;
596
	t4_pci_out(wc, WC_LEDS, wc->ledreg);
597
}
598
599
static inline unsigned int t4_pci_in(struct t4 *wc, const unsigned int addr)
600
{
601
	unsigned int ret;
602
	unsigned long flags;
603
	
604
	spin_lock_irqsave(&wc->reglock, flags);
605
	ret = __t4_pci_in(wc, addr);
606
	spin_unlock_irqrestore(&wc->reglock, flags);
607
	return ret;
608
}
609
610
static inline unsigned int __t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
611
{
612
	unsigned int ret;
613
	unit &= 0x3;
614
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
615
	if (!pedanticpci)
616
		__t4_pci_in(wc, WC_VERSION);
617
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LREAD);
618
	if (!pedanticpci) {
619
		__t4_pci_in(wc, WC_VERSION);
620
	} else {
621
		__t4_pci_out(wc, WC_VERSION, 0);
622
	}
623
	ret = __t4_pci_in(wc, WC_LDATA);
624
 	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
625
626
	if (unlikely(debug & DEBUG_REGS))
627
		dev_info(&wc->dev->dev, "Reading unit %d address %02x is "
628
				"%02x\n", unit, addr, ret & 0xff);
629
630
	if (!pedanticpci)
631
		__t4_pci_in(wc, WC_VERSION);
632
633
	return ret & 0xff;
634
}
635
636
static inline unsigned int t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
637
{
638
	unsigned long flags;
639
	unsigned int ret;
640
	spin_lock_irqsave(&wc->reglock, flags);
641
	ret = __t4_framer_in(wc, unit, addr);
642
	spin_unlock_irqrestore(&wc->reglock, flags);
643
	return ret;
644
645
}
646
647
static inline void __t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
648
{
649
	unit &= 0x3;
650
	if (unlikely(debug & DEBUG_REGS))
651
		dev_info(&wc->dev->dev, "Writing %02x to address %02x of "
652
				"unit %d\n", value, addr, unit);
653
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
654
	__t4_pci_out(wc, WC_LDATA, value);
655
	if (!pedanticpci)
656
		__t4_pci_in(wc, WC_VERSION);
657
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE);
658
	if (!pedanticpci)
659
		__t4_pci_in(wc, WC_VERSION);
660
	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));	
661
	if (!pedanticpci)
662
		__t4_pci_in(wc, WC_VERSION);
663
	if (unlikely(debug & DEBUG_REGS))
664
		dev_info(&wc->dev->dev, "Write complete\n");
665
#if 0
666
	if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc))
667
	{ unsigned int tmp;
668
	tmp = __t4_framer_in(wc, unit, addr);
669
	if (tmp != value) {
670
		dev_notice(&wc->dev->dev, "Expected %d from unit %d "
671
				"register %d but got %d instead\n",
672
				value, unit, addr, tmp);
673
	} }
674
#endif	
675
}
676
677
static inline void t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
678
{
679
	unsigned long flags;
680
	spin_lock_irqsave(&wc->reglock, flags);
681
	__t4_framer_out(wc, unit, addr, value);
682
	spin_unlock_irqrestore(&wc->reglock, flags);
683
}
684
685
#ifdef VPM_SUPPORT
686
687
static inline void wait_a_little(void)
688
{
689
	unsigned long newjiffies=jiffies+2;
690
	while(jiffies < newjiffies);
691
}
692
693
static inline unsigned int __t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
694
{
695
	unsigned int ret;
696
	unit &= 0x7;
697
	__t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12));
698
	__t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12) | (1 << 11) | WC_LREAD);
699
	ret = __t4_pci_in(wc, WC_LDATA);
700
	__t4_pci_out(wc, WC_LADDR, 0);
701
	return ret & 0xff;
702
}
703
704
static inline void __t4_raw_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
705
{
706
	int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
707
	if (!octopt) 
708
		__t4_gpio_set(wc, 0xff, (addr >> 8));
709
	__t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
710
	if (!octopt)
711
		__t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
712
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
713
	if (!pedanticpci)
714
		__t4_pci_in(wc, WC_VERSION);
715
	if (!octopt)
716
		__t4_gpio_set(wc, 0xff, (value >> 8));
717
	__t4_pci_out(wc, WC_LDATA, (value & 0xffff));
718
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE | WC_LCS));
719
	if (!pedanticpci)
720
		__t4_pci_in(wc, WC_VERSION);
721
	__t4_pci_out(wc, WC_LADDR, (0));
722
	if (!pedanticpci)
723
		__t4_pci_in(wc, WC_VERSION);
724
}
725
726
static inline unsigned int __t4_raw_oct_in(struct t4 *wc, const unsigned int addr)
727
{
728
	unsigned int ret;
729
	int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
730
	if (!octopt)
731
		__t4_gpio_set(wc, 0xff, (addr >> 8));
732
	__t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
733
	if (!octopt)
734
		__t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
735
	if (!pedanticpci)
736
		__t4_pci_in(wc, WC_VERSION);
737
	__t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
738
	if (!pedanticpci)
739
		__t4_pci_in(wc, WC_VERSION);
740
#ifdef PEDANTIC_OCTASIC_CHECKING 
741
	__t4_pci_out(wc, WC_LADDR, (WC_LALE));
742
	if (!pedanticpci)
743
		__t4_pci_in(wc, WC_VERSION);
744
#endif
745
	if (!octopt) {
746
		__t4_gpio_setdir(wc, 0xff, 0x00);
747
		__t4_gpio_set(wc, 0xff, 0x00);
748
	}
749
	__t4_pci_out(wc, WC_LADDR, (WC_LREAD | WC_LALE | WC_LCS));
750
	if (!pedanticpci)
751
		__t4_pci_in(wc, WC_VERSION);
752
	if (octopt) {
753
		ret = __t4_pci_in(wc, WC_LDATA) & 0xffff;
754
	} else {
755
		ret = __t4_pci_in(wc, WC_LDATA) & 0xff;
756
		ret |= (__t4_pci_in(wc, WC_GPIO) & 0xff) << 8;
757
	}
758
	__t4_pci_out(wc, WC_LADDR, (0));
759
	if (!pedanticpci)
760
		__t4_pci_in(wc, WC_VERSION);
761
	if (!octopt)
762
		__t4_gpio_setdir(wc, 0xff, 0xff);
763
	return ret & 0xffff;
764
}
765
766
static inline unsigned int __t4_oct_in(struct t4 *wc, unsigned int addr)
767
{
768
#ifdef PEDANTIC_OCTASIC_CHECKING
769
	int count = 1000;
770
#endif
771
	__t4_raw_oct_out(wc, 0x0008, (addr >> 20));
772
	__t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
773
	__t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (1));
774
#ifdef PEDANTIC_OCTASIC_CHECKING
775
	while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
776
	if (count != 1000)
777
		dev_notice(&wc->dev->dev, "Yah, read can be slow...\n");
778
	if (!count)
779
		dev_notice(&wc->dev->dev, "Read timed out!\n");
780
#endif
781
	return __t4_raw_oct_in(wc, 0x0004);
782
}
783
784
static inline unsigned int t4_oct_in(struct t4 *wc, const unsigned int addr)
785
{
786
	unsigned long flags;
787
	unsigned int ret;
788
789
	spin_lock_irqsave(&wc->reglock, flags);
790
	ret = __t4_oct_in(wc, addr);
791
	spin_unlock_irqrestore(&wc->reglock, flags);
792
	return ret;
793
}
794
795
static inline unsigned int t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
796
{
797
	unsigned long flags;
798
	unsigned int ret;
799
	spin_lock_irqsave(&wc->reglock, flags);
800
	ret = __t4_vpm_in(wc, unit, addr);
801
	spin_unlock_irqrestore(&wc->reglock, flags);
802
	return ret;
803
}
804
805
static inline void __t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
806
{
807
	unit &= 0x7;
808
	if (debug & DEBUG_REGS)
809
		dev_notice(&wc->dev->dev, "Writing %02x to address %02x of "
810
				"ec unit %d\n", value, addr, unit);
811
	__t4_pci_out(wc, WC_LADDR, (addr & 0xff));
812
	__t4_pci_out(wc, WC_LDATA, value);
813
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
814
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11) | WC_LWRITE);
815
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
816
	__t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff));	
817
	__t4_pci_out(wc, WC_LADDR, 0);
818
	if (debug & DEBUG_REGS)
819
		dev_notice(&wc->dev->dev, "Write complete\n");
820
821
      
822
#if 0
823
	{ unsigned int tmp;
824
	tmp = t4_vpm_in(wc, unit, addr);
825
	if (tmp != value) {
826
		dev_notice(&wc->dev->dev, "Expected %d from unit %d echo "
827
				"register %d but got %d instead\n",
828
				value, unit, addr, tmp);
829
	} }
830
#endif
831
}
832
833
static inline void __t4_oct_out(struct t4 *wc, unsigned int addr, unsigned int value)
834
{
835
#ifdef PEDANTIC_OCTASIC_CHECKING
836
	int count = 1000;
837
#endif
838
	__t4_raw_oct_out(wc, 0x0008, (addr >> 20));
839
	__t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
840
	__t4_raw_oct_out(wc, 0x0004, value);
841
	__t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (3 << 12) | 1);
842
#ifdef PEDANTIC_OCTASIC_CHECKING
843
	while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
844
	if (count != 1000)
845
		dev_notice(&wc->dev->dev, "Yah, write can be slow\n");
846
	if (!count)
847
		dev_notice(&wc->dev->dev, "Write timed out!\n");
848
#endif
849
}
850
851
static inline void t4_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
852
{
853
	unsigned long flags;
854
855
	spin_lock_irqsave(&wc->reglock, flags);
856
	__t4_oct_out(wc, addr, value);
857
	spin_unlock_irqrestore(&wc->reglock, flags);
858
}
859
860
static inline void t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
861
{
862
	unsigned long flags;
863
	spin_lock_irqsave(&wc->reglock, flags);
864
	__t4_vpm_out(wc, unit, addr, value);
865
	spin_unlock_irqrestore(&wc->reglock, flags);
866
}
867
868
static const char vpm_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#'};
869
870
static void t4_check_vpm450(struct t4 *wc)
871
{
872
	int channel, tone, start, span;
873
874
	if (vpm450m_checkirq(wc->vpm450m)) {
875
		while(vpm450m_getdtmf(wc->vpm450m, &channel, &tone, &start)) {
876
			span = channel & 0x3;
877
			channel >>= 2;
878
			if (!wc->t1e1)
879
				channel -= 5;
880
			else
881
				channel -= 1;
882
			if (unlikely(debug))
883
				dev_info(&wc->dev->dev, "Got tone %s of '%c' "
884
					"on channel %d of span %d\n",
885
					(start ? "START" : "STOP"),
886
					tone, channel, span + 1);
887
			if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) {
888
				if (start) {
889
					/* The octasic is supposed to mute us, but...  Yah, you
890
					   guessed it.  */
891
					if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) {
892
						unsigned long flags;
893
						struct dahdi_chan *chan = wc->tspans[span]->span.chans[channel];
894
						int y;
895
						spin_lock_irqsave(&chan->lock, flags);
896
						for (y=0;y<chan->numbufs;y++) {
897
							if ((chan->inreadbuf > -1) && (chan->readidx[y]))
898
								memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
899
						}
900
						spin_unlock_irqrestore(&chan->lock, flags);
901
					}
902
					set_bit(channel, &wc->tspans[span]->dtmfactive);
903
					dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFDOWN | tone));
904
				} else {
905
					clear_bit(channel, &wc->tspans[span]->dtmfactive);
906
					dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFUP | tone));
907
				}
908
			}
909
		}
910
	}
911
}
912
913
static void t4_check_vpm400(struct t4 *wc, unsigned int newio)
914
{
915
	unsigned int digit, regval = 0;
916
	unsigned int regbyte;
917
	int x, i;
918
	short energy=0;
919
	static unsigned int lastio = 0;
920
	struct t4_span *ts;
921
922
	if (debug && (newio != lastio)) 
923
		dev_notice(&wc->dev->dev, "Last was %08x, new is %08x\n",
924
				lastio, newio);
925
926
	lastio = newio;
927
 
928
	for(x = 0; x < 8; x++) {
929
		if (newio & (1 << (7 - x)))
930
			continue;
931
		ts = wc->tspans[x%4];
932
		/* Start of DTMF detection process */	
933
		regbyte = t4_vpm_in(wc, x, 0xb8);
934
		t4_vpm_out(wc, x, 0xb8, regbyte); /* Write 1 to clear */
935
		regval = regbyte << 8;
936
		regbyte = t4_vpm_in(wc, x, 0xb9);
937
		t4_vpm_out(wc, x, 0xb9, regbyte);
938
		regval |= regbyte;
939
940
		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
941
			if(regval & 0x0001) {
942
				int channel = (i << 1) + (x >> 2);
943
				int base = channel - 1;
944
945
				if (!wc->t1e1)
946
					base -= 4;
947
				regbyte = t4_vpm_in(wc, x, 0xa8 + i);
948
				digit = vpm_digits[regbyte];
949
				if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
950
					energy = t4_vpm_in(wc, x, 0x58 + channel);
951
					energy = DAHDI_XLAW(energy, ts->chans[0]);
952
					ts->dtmfenergy[base] = energy;
953
				}
954
				set_bit(base, &ts->dtmfactive);
955
				if (ts->dtmfdigit[base]) {
956
					if (ts->dtmfmask & (1 << base))
957
						dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
958
				}
959
				ts->dtmfdigit[base] = digit;
960
				if (test_bit(base, &ts->dtmfmask))
961
					dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFDOWN | digit));
962
				if (test_bit(base, &ts->dtmfmutemask)) {
963
					/* Mute active receive buffer*/
964
					unsigned long flags;
965
					struct dahdi_chan *chan = ts->span.chans[base];
966
					int y;
967
					spin_lock_irqsave(&chan->lock, flags);
968
					for (y=0;y<chan->numbufs;y++) {
969
						if ((chan->inreadbuf > -1) && (chan->readidx[y]))
970
							memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
971
					}
972
					spin_unlock_irqrestore(&chan->lock, flags);
973
				}
974
				if (debug)
975
					dev_notice(&wc->dev->dev, "Digit "
976
						"Seen: %d, Span: %d, channel:"
977
						" %d, energy: %02x, 'channel "
978
						"%d' chip %d\n", digit, x % 4,
979
						base + 1, energy, channel, x);
980
				
981
			}
982
			regval = regval >> 1;
983
		}
984
		if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN))
985
			continue;
986
987
		/* Start of DTMF off detection process */	
988
		regbyte = t4_vpm_in(wc, x, 0xbc);
989
		t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */
990
		regval = regbyte << 8;
991
		regbyte = t4_vpm_in(wc, x, 0xbd);
992
		t4_vpm_out(wc, x, 0xbd, regbyte);
993
		regval |= regbyte;
994
995
		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
996
			if(regval & 0x0001) {
997
				int channel = (i << 1) + (x >> 2);
998
				int base = channel - 1;
999
1000
				if (!wc->t1e1)
1001
					base -= 4;
1002
				clear_bit(base, &ts->dtmfactive);
1003
				if (ts->dtmfdigit[base]) {
1004
					if (test_bit(base, &ts->dtmfmask))
1005
						dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
1006
				}
1007
				digit = ts->dtmfdigit[base];
1008
				ts->dtmfdigit[base] = 0;
1009
				if (debug)
1010
					dev_notice(&wc->dev->dev, "Digit "
1011
						"Gone: %d, Span: %d, channel:"
1012
						" %d, energy: %02x, 'channel "
1013
						"%d' chip %d\n", digit, x % 4,
1014
						base + 1, energy, channel, x);
1015
				
1016
			}
1017
			regval = regval >> 1;
1018
		}
1019
1020
	}
1021
}
1022
#endif
1023
1024
static void hdlc_stop(struct t4 *wc, unsigned int span)
1025
{
1026
	struct t4_span *t = wc->tspans[span];
1027
	unsigned char imr0, imr1, mode;
1028
	int i = 0;
1029
1030
	if (debug & DEBUG_FRAMER)
1031
		dev_notice(&wc->dev->dev, "Stopping HDLC controller on span "
1032
				"%d\n", span+1);
1033
	
1034
	/* Clear receive and transmit timeslots */
1035
	for (i = 0; i < 4; i++) {
1036
		t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00);
1037
		t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00);
1038
	}
1039
1040
	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
1041
	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
1042
1043
	/* Disable HDLC interrupts */
1044
	imr0 |= HDLC_IMR0_MASK;
1045
	t4_framer_out(wc, span, FRMR_IMR0, imr0);
1046
1047
	imr1 |= HDLC_IMR1_MASK;
1048
	t4_framer_out(wc, span, FRMR_IMR1, imr1);
1049
1050
	mode = t4_framer_in(wc, span, FRMR_MODE);
1051
	mode &= ~FRMR_MODE_HRAC;
1052
	t4_framer_out(wc, span, FRMR_MODE, mode);
1053
1054
	t->sigactive = 0;
1055
}
1056
1057
static inline void __t4_framer_cmd(struct t4 *wc, unsigned int span, int cmd)
1058
{
1059
	__t4_framer_out(wc, span, FRMR_CMDR, cmd);
1060
}
1061
1062
static inline void t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd)
1063
{
1064
	int sis;
1065
	int loops = 0;
1066
1067
	/* XXX could be time consuming XXX */
1068
	for (;;) {
1069
		sis = t4_framer_in(wc, span, FRMR_SIS);
1070
		if (!(sis & 0x04))
1071
			break;
1072
		if (!loops++ && (debug & DEBUG_FRAMER)) {
1073
			dev_notice(&wc->dev->dev, "!!!SIS Waiting before cmd "
1074
					"%02x\n", cmd);
1075
		}
1076
	}
1077
	if (loops && (debug & DEBUG_FRAMER))
1078
		dev_notice(&wc->dev->dev, "!!!SIS waited %d loops\n", loops);
1079
1080
	t4_framer_out(wc, span, FRMR_CMDR, cmd);
1081
}
1082
1083
static int hdlc_start(struct t4 *wc, unsigned int span, struct dahdi_chan *chan, unsigned char mode)
1084
{
1085
	struct t4_span *t = wc->tspans[span];
1086
	unsigned char imr0, imr1;
1087
	int offset = chan->chanpos;
1088
	unsigned long flags;
1089
1090
	if (debug & DEBUG_FRAMER)
1091
		dev_info(&wc->dev->dev, "Starting HDLC controller for channel "
1092
				"%d span %d\n", offset, span+1);
1093
1094
	if (mode != FRMR_MODE_NO_ADDR_CMP)
1095
		return -1;
1096
1097
	mode |= FRMR_MODE_HRAC;
1098
1099
	/* Make sure we're in the right mode */
1100
	t4_framer_out(wc, span, FRMR_MODE, mode);
1101
	t4_framer_out(wc, span, FRMR_TSEO, 0x00);
1102
	t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode);
1103
1104
	/* Set the interframe gaps, etc */
1105
	t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
1106
1107
	t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
1108
	
1109
	/* Set up the time slot that we want to tx/rx on */
1110
	t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
1111
	t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
1112
1113
	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
1114
	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
1115
1116
	/* Enable our interrupts again */
1117
	imr0 &= ~HDLC_IMR0_MASK;
1118
	t4_framer_out(wc, span, FRMR_IMR0, imr0);
1119
1120
	imr1 &= ~HDLC_IMR1_MASK;
1121
	t4_framer_out(wc, span, FRMR_IMR1, imr1);
1122
1123
	/* Reset the signaling controller */
1124
	t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
1125
1126
	spin_lock_irqsave(&wc->reglock, flags);
1127
	t->sigchan = chan;
1128
	spin_unlock_irqrestore(&wc->reglock, flags);
1129
1130
	t->sigactive = 0;
1131
1132
	return 0;
1133
}
1134
1135
static void __set_clear(struct t4 *wc, int span)
1136
{
1137
	int i,j;
1138
	int oldnotclear;
1139
	unsigned short val=0;
1140
	struct t4_span *ts = wc->tspans[span];
1141
1142
	oldnotclear = ts->notclear;
1143
	if ((ts->spantype == TYPE_T1) || (ts->spantype == TYPE_J1)) {
1144
		for (i=0;i<24;i++) {
1145
			j = (i/8);
1146
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
1147
				val |= 1 << (7 - (i % 8));
1148
				ts->notclear &= ~(1 << i);
1149
			} else
1150
				ts->notclear |= (1 << i);
1151
			if ((i % 8)==7) {
1152
				if (debug)
1153
					dev_notice(&wc->dev->dev, "Putting %d "
1154
						"in register %02x on span %d"
1155
						"\n", val, 0x2f + j, span + 1);
1156
				__t4_framer_out(wc, span, 0x2f + j, val);
1157
				val = 0;
1158
			}
1159
		}
1160
	} else {
1161
		for (i=0;i<31;i++) {
1162
			if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
1163
				ts->notclear &= ~(1 << i);
1164
			else 
1165
				ts->notclear |= (1 << i);
1166
		}
1167
	}
1168
	if (ts->notclear != oldnotclear) {
1169
		unsigned char reg;
1170
		reg = __t4_framer_in(wc, span, FRMR_IMR0);
1171
		if (ts->notclear)
1172
			reg &= ~0x08;
1173
		else
1174
			reg |= 0x08;
1175
		__t4_framer_out(wc, span, FRMR_IMR0, reg);
1176
	}
1177
}
1178
1179
#if 0
1180
static void set_clear(struct t4 *wc, int span)
1181
{
1182
	unsigned long flags;
1183
	spin_lock_irqsave(&wc->reglock, flags);
1184
	__set_clear(wc, span);
1185
	spin_unlock_irqrestore(&wc->reglock, flags);
1186
}
1187
#endif
1188
1189
static int t4_dacs(struct dahdi_chan *dst, struct dahdi_chan *src)
1190
{
1191
	struct t4 *wc;
1192
	struct t4_span *ts;
1193
	wc = dst->pvt;
1194
	ts = wc->tspans[dst->span->offset];
1195
	if (src && (src->pvt != dst->pvt)) {
1196
		if (ts->spanflags & FLAG_2NDGEN)
1197
			t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
1198
		wc = src->pvt;
1199
		if (ts->spanflags & FLAG_2NDGEN)
1200
			t4_tsi_unassign(wc, src->span->offset, src->chanpos);
1201
		if (debug)
1202
			dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
1203
				"default and...\n", src->span->offset,
1204
				src->chanpos);
1205
		if (debug)
1206
			dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
1207
				"default\n", dst->span->offset, dst->chanpos);
1208
		return -1;
1209
	}
1210
	if (src) {
1211
		t4_tsi_assign(wc, src->span->offset, src->chanpos, dst->span->offset, dst->chanpos);
1212
		if (debug)
1213
			dev_notice(&wc->dev->dev, "Assigning channel %d/%d -> "
1214
				"%d/%d!\n", src->span->offset, src->chanpos,
1215
				dst->span->offset, dst->chanpos);
1216
	} else {
1217
		t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
1218
		if (debug)
1219
			dev_notice(&wc->dev->dev, "Unassigning channel %d/%d!"
1220
				"\n", dst->span->offset, dst->chanpos);
1221
	}
1222
	return 0;
1223
}
1224
1225
#ifdef VPM_SUPPORT
1226
1227
void oct_set_reg(void *data, unsigned int reg, unsigned int val)
1228
{
1229
	struct t4 *wc = data;
1230
	t4_oct_out(wc, reg, val);
1231
}
1232
1233
unsigned int oct_get_reg(void *data, unsigned int reg)
1234
{
1235
	struct t4 *wc = data;
1236
	unsigned int ret;
1237
	ret = t4_oct_in(wc, reg);
1238
	return ret;
1239
}
1240
1241
static int t4_vpm_unit(int span, int channel)
1242
{
1243
	int unit = 0;
1244
	switch(vpmspans) {
1245
	case 4:
1246
		unit = span;
1247
		unit += (channel & 1) << 2;
1248
		break;
1249
	case 2:
1250
		unit = span;
1251
		unit += (channel & 0x3) << 1;
1252
		break;
1253
	case 1:
1254
		unit = span;
1255
		unit += (channel & 0x7);
1256
	}
1257
	return unit;
1258
}
1259
1260
static inline struct t4_span *t4_from_span(struct dahdi_span *span)
1261
{
1262
	return container_of(span, struct t4_span, span);
1263
}
1264
1265
static int t4_echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
1266
			  struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
1267
{
1268
	struct t4 *wc = chan->pvt;
1269
	struct t4_span *tspan = container_of(chan->span, struct t4_span, span);
1270
	int channel;
1271
	const struct dahdi_echocan_ops *ops;
1272
	const struct dahdi_echocan_features *features;
1273
1274
	if (!vpmsupport || !wc->vpm)
1275
		return -ENODEV;
1276
1277
	if (chan->span->offset >= vpmspans)
1278
		return -ENODEV;
1279
1280
	if (wc->vpm450m) {
1281
		ops = &vpm450m_ec_ops;
1282
		features = &vpm450m_ec_features;
1283
	} else {
1284
		ops = &vpm400m_ec_ops;
1285
		features = &vpm400m_ec_features;
1286
	}
1287
1288
	if (ecp->param_count > 0) {
1289
		dev_warn(&wc->dev->dev, "echo canceller does not support "
1290
				"parameters; failing request\n");
1291
		return -EINVAL;
1292
	}
1293
1294
	*ec = tspan->ec[chan->chanpos - 1];
1295
	(*ec)->ops = ops;
1296
	(*ec)->features = *features;
1297
1298
	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
1299
1300
	if (wc->vpm450m) {
1301
		channel = channel << 2;
1302
		channel |= chan->span->offset;
1303
		if (debug & DEBUG_ECHOCAN)
1304
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1305
				"Channel is %d, Span is %d, offset is %d "
1306
				"length %d\n", wc->num, chan->chanpos,
1307
				chan->span->offset, channel, ecp->tap_length);
1308
		vpm450m_setec(wc->vpm450m, channel, ecp->tap_length);
1309
	} else {
1310
		int unit = t4_vpm_unit(chan->span->offset, channel);
1311
1312
		if (debug & DEBUG_ECHOCAN)
1313
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1314
				"Channel is %d, Span is %d, unit is %d, "
1315
				"unit offset is %d length %d\n", wc->num,
1316
				chan->chanpos, chan->span->offset, unit,
1317
				channel, ecp->tap_length);
1318
		t4_vpm_out(wc, unit, channel, 0x3e);
1319
	}
1320
1321
	return 0;
1322
}
1323
1324
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
1325
{
1326
	struct t4 *wc = chan->pvt;
1327
	int channel;
1328
1329
	memset(ec, 0, sizeof(*ec));
1330
1331
	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
1332
1333
	if (wc->vpm450m) {
1334
		channel = channel << 2;
1335
		channel |= chan->span->offset;
1336
		if (debug & DEBUG_ECHOCAN)
1337
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1338
				"Channel is %d, Span is %d, offset is %d "
1339
				"length 0\n", wc->num, chan->chanpos,
1340
				chan->span->offset, channel);
1341
		vpm450m_setec(wc->vpm450m, channel, 0);
1342
	} else {
1343
		int unit = t4_vpm_unit(chan->span->offset, channel);
1344
1345
		if (debug & DEBUG_ECHOCAN)
1346
			dev_notice(&wc->dev->dev, "echocan: Card is %d, "
1347
				"Channel is %d, Span is %d, unit is %d, "
1348
				"unit offset is %d length 0\n", wc->num,
1349
				chan->chanpos, chan->span->offset, unit,
1350
				channel);
1351
		t4_vpm_out(wc, unit, channel, 0x01);
1352
	}
1353
}
1354
#endif
1355
1356
static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
1357
{
1358
	struct t4_regs regs;
1359
	int x;
1360
	struct t4 *wc = chan->pvt;
1361
#ifdef VPM_SUPPORT
1362
	int j;
1363
	int channel;
1364
	struct t4_span *ts = wc->tspans[chan->span->offset];
1365
#endif
1366
1367
#ifdef VPM_SUPPORT
1368
	if (dtmfthreshold == 0)
1369
		dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
1370
	if (lastdtmfthreshold != dtmfthreshold) {
1371
		lastdtmfthreshold = dtmfthreshold;
1372
		t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
1373
	}
1374
#endif
1375
1376
	switch(cmd) {
1377
	case WCT4_GET_REGS:
1378
		for (x=0;x<NUM_PCI;x++)
1379
			regs.pci[x] = t4_pci_in(wc, x);
1380
		for (x=0;x<NUM_REGS;x++)
1381
			regs.regs[x] = t4_framer_in(wc, chan->span->offset, x);
1382
		if (copy_to_user((__user void *) data, &regs, sizeof(regs)))
1383
			return -EFAULT;
1384
		break;
1385
#ifdef VPM_SUPPORT
1386
	case DAHDI_TONEDETECT:
1387
		if (get_user(j, (__user int *) data))
1388
			return -EFAULT;
1389
		if (!wc->vpm)
1390
			return -ENOSYS;
1391
		if (j && (vpmdtmfsupport == 0))
1392
			return -ENOSYS;
1393
		if (j & DAHDI_TONEDETECT_ON)
1394
			set_bit(chan->chanpos - 1, &ts->dtmfmask);
1395
		else
1396
			clear_bit(chan->chanpos - 1, &ts->dtmfmask);
1397
		if (j & DAHDI_TONEDETECT_MUTE)
1398
			set_bit(chan->chanpos - 1, &ts->dtmfmutemask);
1399
		else
1400
			clear_bit(chan->chanpos - 1, &ts->dtmfmutemask);
1401
		if (wc->vpm450m) {
1402
			channel = (chan->chanpos) << 2;
1403
			if (!wc->t1e1)
1404
				channel += (4 << 2);
1405
			channel |= chan->span->offset;
1406
			vpm450m_setdtmf(wc->vpm450m, channel, j & DAHDI_TONEDETECT_ON, j & DAHDI_TONEDETECT_MUTE);
1407
		}
1408
		return 0;
1409
#endif
1410
	default:
1411
		return -ENOTTY;
1412
	}
1413
	return 0;
1414
}
1415
1416
static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts)
1417
{
1418
	int res, i;
1419
	unsigned int size = 32;
1420
	unsigned char buf[32];
1421
1422
	res = dahdi_hdlc_getbuf(ts->sigchan, buf, &size);
1423
	if (debug & DEBUG_FRAMER)
1424
		dev_notice(&wc->dev->dev, "Got buffer sized %d and res %d "
1425
				"for %d\n", size, res, span);
1426
	if (size > 0) {
1427
		ts->sigactive = 1;
1428
1429
		if (debug & DEBUG_FRAMER) {
1430
			dev_notice(&wc->dev->dev, "TX(");
1431
			for (i = 0; i < size; i++)
1432
				dev_notice(&wc->dev->dev, "%s%02x",
1433
						(i ? " " : ""), buf[i]);
1434
			dev_notice(&wc->dev->dev, ")\n");
1435
		}
1436
1437
		for (i = 0; i < size; i++)
1438
			t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]);
1439
1440
		if (res) /* End of message */ {
1441
			if (debug & DEBUG_FRAMER)
1442
				dev_notice(&wc->dev->dev,
1443
					"transmiting XHF|XME\n");
1444
			t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME);
1445
#if 0
1446
			ts->sigactive = (__t4_framer_in(wc, span, FRMR_SIS) & FRMR_SIS_XFW) ? 0 : 1;
1447
#endif
1448
			++ts->frames_out;
1449
			if ((debug & DEBUG_FRAMER) && !(ts->frames_out & 0x0f))
1450
				dev_notice(&wc->dev->dev, "Transmitted %d "
1451
					"frames on span %d\n", ts->frames_out,
1452
					span);
1453
		} else { /* Still more to transmit */
1454
			if (debug & DEBUG_FRAMER)
1455
				dev_notice(&wc->dev->dev, "transmiting XHF\n");
1456
			t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF);
1457
		}
1458
	}
1459
	else if (res < 0)
1460
		ts->sigactive = 0;
1461
}
1462
1463
static void t4_hdlc_hard_xmit(struct dahdi_chan *chan)
1464
{
1465
	struct t4 *wc = chan->pvt;
1466
	int span = chan->span->offset;
1467
	struct t4_span *ts = wc->tspans[span];
1468
	unsigned long flags; 
1469
1470
	spin_lock_irqsave(&wc->reglock, flags);
1471
	if (!ts->sigchan) {
1472
		dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit: Invalid (NULL) "
1473
				"signalling channel\n");
1474
		spin_unlock_irqrestore(&wc->reglock, flags);
1475
		return;
1476
	}
1477
	spin_unlock_irqrestore(&wc->reglock, flags);
1478
1479
	if (debug & DEBUG_FRAMER)
1480
		dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit on channel %s "
1481
				"(sigchan %s), sigactive=%d\n", chan->name,
1482
				ts->sigchan->name, ts->sigactive);
1483
1484
	if ((ts->sigchan == chan) && !ts->sigactive)
1485
		t4_hdlc_xmit_fifo(wc, span, ts);
1486
}
1487
1488
static int t4_maint(struct dahdi_span *span, int cmd)
1489
{
1490
	struct t4_span *ts = t4_from_span(span);
1491
	struct t4 *wc = ts->owner;
1492
	unsigned int reg;
1493
#ifdef DAHDI_SPAN_OPS
1494
	unsigned long flags;
1495
#endif
1496
1497
	if (ts->spantype == TYPE_E1) {
1498
		switch(cmd) {
1499
		case DAHDI_MAINT_NONE:
1500
			dev_info(&wc->dev->dev, "Clearing all maint modes\n");
1501
			t4_clear_maint(span);
1502
			break;
1503
		case DAHDI_MAINT_LOCALLOOP:
1504
			dev_info(&wc->dev->dev,
1505
				 "Turning on local loopback\n");
1506
			t4_clear_maint(span);
1507
			reg = t4_framer_in(wc, span->offset, LIM0_T);
1508
			t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
1509
			break;
1510
#ifdef DAHDI_SPAN_OPS
1511
		case DAHDI_MAINT_NETWORKLINELOOP:
1512
			dev_info(&wc->dev->dev,
1513
				 "Turning on network line loopback\n");
1514
			t4_clear_maint(span);
1515
			reg = t4_framer_in(wc, span->offset, LIM1_T);
1516
			t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
1517
			break;
1518
		case DAHDI_MAINT_NETWORKPAYLOADLOOP:
1519
			dev_info(&wc->dev->dev,
1520
				 "Turning on network payload loopback\n");
1521
			t4_clear_maint(span);
1522
			reg = t4_framer_in(wc, span->offset, FMR2_T);
1523
			t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
1524
			break;
1525
#endif
1526
		case DAHDI_MAINT_LOOPUP:
1527
		case DAHDI_MAINT_LOOPDOWN:
1528
			dev_info(&wc->dev->dev,
1529
				"Loopup & loopdown supported in E1 mode\n");
1530
			return -ENOSYS;
1531
#ifdef DAHDI_SPAN_OPS
1532
		case DAHDI_MAINT_FAS_DEFECT:
1533
			t4_framer_out(wc, span->offset, IERR_T, IFASE);
1534
			break;
1535
		case DAHDI_MAINT_MULTI_DEFECT:
1536
			t4_framer_out(wc, span->offset, IERR_T, IMFE);
1537
			break;
1538
		case DAHDI_MAINT_CRC_DEFECT:
1539
			t4_framer_out(wc, span->offset, IERR_T, ICRCE);
1540
			break;
1541
		case DAHDI_MAINT_CAS_DEFECT:
1542
			t4_framer_out(wc, span->offset, IERR_T, ICASE);
1543
			break;
1544
		case DAHDI_MAINT_PRBS_DEFECT:
1545
			t4_framer_out(wc, span->offset, IERR_T, IPE);
1546
			break;
1547
		case DAHDI_MAINT_BIPOLAR_DEFECT:
1548
			t4_framer_out(wc, span->offset, IERR_T, IBV);
1549
			break;
1550
		case DAHDI_RESET_COUNTERS:
1551
			t4_reset_counters(span);
1552
			break;
1553
		case DAHDI_MAINT_ALARM_SIM:
1554
			dev_info(&wc->dev->dev, "Invoking alarm state");
1555
			reg = t4_framer_in(wc, span->offset, FMR0);
1556
			t4_framer_out(wc, span->offset, FMR0, (reg|FMR0_SIM));
1557
			break;
1558
#endif
1559
		default:
1560
			dev_info(&wc->dev->dev,
1561
					"Unknown E1 maint command: %d\n", cmd);
1562
			return -ENOSYS;
1563
		}
1564
	} else {
1565
		switch(cmd) {
1566
		case DAHDI_MAINT_NONE:
1567
			dev_info(&wc->dev->dev, "Clearing all maint modes\n");
1568
			t4_clear_maint(span);
1569
			break;
1570
		case DAHDI_MAINT_LOCALLOOP:
1571
			dev_info(&wc->dev->dev,
1572
				 "Turning on local loopback\n");
1573
			t4_clear_maint(span);
1574
			reg = t4_framer_in(wc, span->offset, LIM0_T);
1575
			t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
1576
			break;
1577
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1578
		case DAHDI_MAINT_NETWORKLINELOOP:
1579
			dev_info(&wc->dev->dev,
1580
				 "Turning on network line loopback\n");
1581
			t4_clear_maint(span);
1582
			reg = t4_framer_in(wc, span->offset, LIM1_T);
1583
			t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
1584
			break;
1585
		case DAHDI_MAINT_NETWORKPAYLOADLOOP:
1586
			dev_info(&wc->dev->dev,
1587
				 "Turning on network payload loopback\n");
1588
			t4_clear_maint(span);
1589
			reg = t4_framer_in(wc, span->offset, FMR2_T);
1590
			t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
1591
			break;
1592
#endif
1593
		case DAHDI_MAINT_LOOPUP:
1594
			dev_info(&wc->dev->dev, "Transmitting loopup code\n");
1595
			t4_clear_maint(span);
1596
			t4_framer_out(wc, span->offset, 0x21, 0x50);
1597
			break;
1598
		case DAHDI_MAINT_LOOPDOWN:
1599
			dev_info(&wc->dev->dev, "Transmitting loopdown code\n");
1600
			t4_clear_maint(span);
1601
			t4_framer_out(wc, span->offset, 0x21, 0x60);
1602
			break;
1603
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1604
		case DAHDI_MAINT_FAS_DEFECT:
1605
			t4_framer_out(wc, span->offset, IERR_T, IFASE);
1606
			break;
1607
		case DAHDI_MAINT_MULTI_DEFECT:
1608
			t4_framer_out(wc, span->offset, IERR_T, IMFE);
1609
			break;
1610
		case DAHDI_MAINT_CRC_DEFECT:
1611
			t4_framer_out(wc, span->offset, IERR_T, ICRCE);
1612
			break;
1613
		case DAHDI_MAINT_CAS_DEFECT:
1614
			t4_framer_out(wc, span->offset, IERR_T, ICASE);
1615
			break;
1616
		case DAHDI_MAINT_PRBS_DEFECT:
1617
			t4_framer_out(wc, span->offset, IERR_T, IPE);
1618
			break;
1619
		case DAHDI_MAINT_BIPOLAR_DEFECT:
1620
			t4_framer_out(wc, span->offset, IERR_T, IBV);
1621
			break;
1622
		case DAHDI_MAINT_PRBS:
1623
			dev_info(&wc->dev->dev, "PRBS not supported\n");
1624
#if 0
1625
			dev_notice(&wc->dev->dev, "Enabling PRBS!\n");
1626
			span->mainttimer = 1;
1627
			/* Enable PRBS monitor */
1628
			reg = t4_framer_in(wc, span->offset, LCR1_T);
1629
			reg |= EPRM;
1630
1631
			/* Setup PRBS xmit */
1632
			t4_framer_out(wc, span->offset, TPC0_T, 0);
1633
1634
			/* Enable PRBS transmit */
1635
			reg |= XPRBS;
1636
			reg &= ~LLBP;
1637
			reg &= ~FLLB;
1638
			t4_framer_out(wc, span->offset, LCR1_T, reg);
1639
#endif
1640
			return -ENOSYS;
1641
		case DAHDI_RESET_COUNTERS:
1642
			t4_reset_counters(span);
1643
			break;
1644
#endif
1645
#ifdef DAHDI_SPAN_OPS
1646
		case DAHDI_MAINT_ALARM_SIM:
1647
			reg = t4_framer_in(wc, span->offset, FMR0);
1648
1649
			/*
1650
			 * The alarm simulation state machine requires us to
1651
			 * bring this bit up and down for at least 1 clock cycle
1652
			 */
1653
			spin_lock_irqsave(&wc->reglock, flags);
1654
			__t4_framer_out(wc, span->offset,
1655
					FMR0, (reg | FMR0_SIM));
1656
			udelay(1);
1657
			__t4_framer_out(wc, span->offset,
1658
					FMR0, (reg & ~FMR0_SIM));
1659
			udelay(1);
1660
			spin_unlock_irqrestore(&wc->reglock, flags);
1661
1662
			reg = t4_framer_in(wc, span->offset, 0x4e);
1663
			if (debug & DEBUG_MAIN) {
1664
				dev_info(&wc->dev->dev,
1665
					"FRS2(alarm state): %d\n",
1666
					((reg & 0xe0) >> 5));
1667
			}
1668
			break;
1669
#endif
1670
		default:
1671
			dev_info(&wc->dev->dev, "Unknown T1 maint command:%d\n",
1672
									cmd);
1673
			break;
1674
	   }
1675
    }
1676
	return 0;
1677
}
1678
1679
static int t4_clear_maint(struct dahdi_span *span)
1680
{
1681
	struct t4_span *ts = t4_from_span(span);
1682
	struct t4 *wc = ts->owner;
1683
	unsigned int reg;
1684
1685
	/* Clear local loop */
1686
	reg = t4_framer_in(wc, span->offset, LIM0_T);
1687
	t4_framer_out(wc, span->offset, LIM0_T, (reg & ~LIM0_LL));
1688
1689
	/* Clear Remote Loop */
1690
	reg = t4_framer_in(wc, span->offset, LIM1_T);
1691
	t4_framer_out(wc, span->offset, LIM1_T, (reg & ~LIM1_RL));
1692
1693
	/* Clear Remote Payload Loop */
1694
	reg = t4_framer_in(wc, span->offset, FMR2_T);
1695
	t4_framer_out(wc, span->offset, FMR2_T, (reg & ~FMR2_PLB));
1696
1697
	/* Clear PRBS */
1698
	reg = t4_framer_in(wc, span->offset, LCR1_T);
1699
	t4_framer_out(wc, span->offset, LCR1_T, (reg & ~(XPRBS | EPRM)));
1700
1701
	span->mainttimer = 0;
1702
1703
	return 0;
1704
}
1705
1706
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
1707
static int t4_reset_counters(struct dahdi_span *span)
1708
{
1709
	struct t4_span *ts = t4_from_span(span);
1710
	memset(&ts->span.count, 0, sizeof(ts->span.count));
1711
	return 0;
1712
}
1713
#endif
1714
1715
static int t4_rbsbits(struct dahdi_chan *chan, int bits)
1716
{
1717
	u_char m,c;
1718
	int k,n,b;
1719
	struct t4 *wc = chan->pvt;
1720
	struct t4_span *ts = wc->tspans[chan->span->offset];
1721
	unsigned long flags;
1722
	
1723
	if (debug & DEBUG_RBS)
1724
		dev_notice(&wc->dev->dev, "Setting bits to %d on channel %s\n",
1725
				bits, chan->name);
1726
	spin_lock_irqsave(&wc->reglock, flags);	
1727
	k = chan->span->offset;
1728
	if (ts->spantype == TYPE_E1) { /* do it E1 way */
1729
		if (chan->chanpos == 16) {
1730
			spin_unlock_irqrestore(&wc->reglock, flags);
1731
			return 0;
1732
		}
1733
		n = chan->chanpos - 1;
1734
		if (chan->chanpos > 15) n--;
1735
		b = (n % 15);
1736
		c = ts->txsigs[b];
1737
		m = (n / 15) << 2; /* nibble selector */
1738
		c &= (0xf << m); /* keep the other nibble */
1739
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
1740
		ts->txsigs[b] = c;
1741
		  /* output them to the chip */
1742
		__t4_framer_out(wc,k,0x71 + b,c); 
1743
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
1744
		n = chan->chanpos - 1;
1745
		b = (n/4);
1746
		c = ts->txsigs[b];
1747
		m = ((3 - (n % 4)) << 1); /* nibble selector */
1748
		c &= ~(0x3 << m); /* keep the other nibble */
1749
		c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
1750
		ts->txsigs[b] = c;
1751
		  /* output them to the chip */
1752
		__t4_framer_out(wc,k,0x70 + b,c); 
1753
		__t4_framer_out(wc,k,0x70 + b + 6,c); 
1754
	} else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
1755
		n = chan->chanpos - 1;
1756
		b = (n/2);
1757
		c = ts->txsigs[b];
1758
		m = ((n % 2) << 2); /* nibble selector */
1759
		c &= (0xf << m); /* keep the other nibble */
1760
		c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
1761
		ts->txsigs[b] = c;
1762
		  /* output them to the chip */
1763
		__t4_framer_out(wc,k,0x70 + b,c); 
1764
	} 
1765
	spin_unlock_irqrestore(&wc->reglock, flags);
1766
	if (debug & DEBUG_RBS)
1767
		dev_notice(&wc->dev->dev, "Finished setting RBS bits\n");
1768
	return 0;
1769
}
1770
1771
static int t4_shutdown(struct dahdi_span *span)
1772
{
1773
	int tspan;
1774
	int wasrunning;
1775
	unsigned long flags;
1776
	struct t4_span *ts = t4_from_span(span);
1777
	struct t4 *wc = ts->owner;
1778
1779
	tspan = span->offset + 1;
1780
	if (tspan < 0) {
1781
		dev_notice(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
1782
				span->spanno);
1783
		return -1;
1784
	}
1785
1786
	if (debug & DEBUG_MAIN)
1787
		dev_notice(&wc->dev->dev, "Shutting down span %d (%s)\n",
1788
				span->spanno, span->name);
1789
1790
	/* Stop HDLC controller if runned */
1791
	if (ts->sigchan)
1792
		hdlc_stop(wc, span->offset);
1793
	
1794
	spin_lock_irqsave(&wc->reglock, flags);
1795
	wasrunning = span->flags & DAHDI_FLAG_RUNNING;
1796
1797
	span->flags &= ~DAHDI_FLAG_RUNNING;
1798
	__t4_set_led(wc, span->offset, WC_OFF);
1799
	if ((wc->numspans == 1) && 
1800
	    (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING))) {
1801
		/* No longer in use, disable interrupts */
1802
		dev_info(&wc->dev->dev, "opvxd115: Disabling interrupts since "
1803
				"there are no active spans\n");
1804
		set_bit(T4_STOP_DMA, &wc->checkflag);
1805
	} else
1806
		set_bit(T4_CHECK_TIMING, &wc->checkflag);
1807
1808
	spin_unlock_irqrestore(&wc->reglock, flags);
1809
1810
	/* Wait for interrupt routine to shut itself down */
1811
	msleep(10);
1812
	if (wasrunning)
1813
		wc->spansstarted--;
1814
1815
	if (debug & DEBUG_MAIN)
1816
		dev_notice(&wc->dev->dev, "Span %d (%s) shutdown\n",
1817
				span->spanno, span->name);
1818
	return 0;
1819
}
1820
1821
static void t4_chan_set_sigcap(struct dahdi_span *span, int x)
1822
{
1823
	struct t4_span *wc = container_of(span, struct t4_span, span);
1824
	struct dahdi_chan *chan = wc->chans[x];
1825
	chan->sigcap = DAHDI_SIG_CLEAR;
1826
	/* E&M variant supported depends on span type */
1827
	if (wc->spantype == TYPE_E1) {
1828
		/* E1 sigcap setup */
1829
		if (span->lineconfig & DAHDI_CONFIG_CCS) {
1830
			/* CCS setup */
1831
			chan->sigcap |= DAHDI_SIG_MTP2 | DAHDI_SIG_SF |
1832
				DAHDI_SIG_HARDHDLC;
1833
			return;
1834
		}
1835
		/* clear out sig and sigcap for channel 16 on E1 CAS
1836
		 * lines, otherwise, set it correctly */
1837
		if (x == 15) {
1838
			/* CAS signaling channel setup */
1839
			wc->chans[15]->sigcap = 0;
1840
			wc->chans[15]->sig = 0;
1841
			return;
1842
		}
1843
		/* normal CAS setup */
1844
		chan->sigcap |= DAHDI_SIG_EM_E1 | DAHDI_SIG_FXSLS |
1845
			DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_SF |
1846
			DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS |
1847
			DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS;
1848
	} else {
1849
		/* T1 sigcap setup */
1850
		chan->sigcap |= DAHDI_SIG_EM | DAHDI_SIG_FXSLS |
1851
			DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_MTP2 |
1852
			DAHDI_SIG_SF | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS |
1853
			DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS |
1854
			DAHDI_SIG_HARDHDLC;
1855
	}
1856
}
1857
1858
static int t4_spanconfig(struct file *file, struct dahdi_span *span,
1859
		struct dahdi_lineconfig *lc)
1860
{
1861
	int i;
1862
	struct t4_span *ts = t4_from_span(span);
1863
	struct t4 *wc = ts->owner;
1864
1865
	if (debug)
1866
		dev_info(&wc->dev->dev, "About to enter spanconfig!\n");
1867
	if (debug & DEBUG_MAIN)
1868
		dev_notice(&wc->dev->dev, "opvxd115: Configuring span %d\n",
1869
				span->spanno);
1870
1871
	if (lc->sync < 0)
1872
		lc->sync = 0;
1873
	if (lc->sync > wc->numspans)
1874
		lc->sync = 0;
1875
	
1876
	/* remove this span number from the current sync sources, if there */
1877
	for(i = 0; i < wc->numspans; i++) {
1878
		if (wc->tspans[i]->sync == span->spanno) {
1879
			wc->tspans[i]->sync = 0;
1880
			wc->tspans[i]->psync = 0;
1881
		}
1882
	}
1883
	wc->tspans[span->offset]->syncpos = lc->sync;
1884
	/* if a sync src, put it in proper place */
1885
	if (lc->sync) {
1886
		wc->tspans[lc->sync - 1]->sync = span->spanno;
1887
		wc->tspans[lc->sync - 1]->psync = span->offset + 1;
1888
	}
1889
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
1890
1891
	/* Make sure this is clear in case of multiple startup and shutdown
1892
	 * iterations */
1893
	clear_bit(T4_STOP_DMA, &wc->checkflag);
1894
	
1895
	/* make sure that sigcaps gets updated if necessary */
1896
	for (i = 0; i < span->channels; i++)
1897
		t4_chan_set_sigcap(span, i);
1898
1899
	/* If we're already running, then go ahead and apply the changes */
1900
	if (span->flags & DAHDI_FLAG_RUNNING)
1901
		return t4_startup(file, span);
1902
1903
	if (debug)
1904
		dev_info(&wc->dev->dev, "Done with spanconfig!\n");
1905
	return 0;
1906
}
1907
1908
static int t4_chanconfig(struct file *file, struct dahdi_chan *chan,
1909
		int sigtype)
1910
{
1911
	int alreadyrunning;
1912
	unsigned long flags;
1913
	struct t4 *wc = chan->pvt;
1914
	struct t4_span *ts = wc->tspans[chan->span->offset];
1915
1916
	alreadyrunning = ts->span.flags & DAHDI_FLAG_RUNNING;
1917
	if (debug & DEBUG_MAIN) {
1918
		if (alreadyrunning)
1919
			dev_notice(&wc->dev->dev, "opvxd115: Reconfigured "
1920
				"channel %d (%s) sigtype %d\n",
1921
				chan->channo, chan->name, sigtype);
1922
		else
1923
			dev_notice(&wc->dev->dev, "opvxd115: Configured channel"
1924
				" %d (%s) sigtype %d\n",
1925
				chan->channo, chan->name, sigtype);
1926
	}
1927
1928
	spin_lock_irqsave(&wc->reglock, flags);	
1929
1930
	if (alreadyrunning)
1931
		__set_clear(wc, chan->span->offset);
1932
1933
	spin_unlock_irqrestore(&wc->reglock, flags);	
1934
1935
	/* (re)configure signalling channel */
1936
	if ((sigtype == DAHDI_SIG_HARDHDLC) || (ts->sigchan == chan)) {
1937
		if (debug & DEBUG_FRAMER)
1938
			dev_notice(&wc->dev->dev, "%sonfiguring hardware HDLC "
1939
				"on %s\n",
1940
				((sigtype == DAHDI_SIG_HARDHDLC) ? "C" : "Unc"),
1941
				chan->name);
1942
		if (alreadyrunning) {
1943
			if (ts->sigchan)
1944
				hdlc_stop(wc, ts->sigchan->span->offset);
1945
			if (sigtype == DAHDI_SIG_HARDHDLC) {
1946
				if (hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
1947
					dev_notice(&wc->dev->dev, "Error "
1948
						"initializing signalling "
1949
						"controller\n");
1950
					return -1;
1951
				}
1952
			} else {
1953
				spin_lock_irqsave(&wc->reglock, flags);
1954
				ts->sigchan = NULL;
1955
				spin_unlock_irqrestore(&wc->reglock, flags);
1956
			}
1957
		
1958
		}
1959
		else {
1960
			spin_lock_irqsave(&wc->reglock, flags);
1961
			ts->sigchan = (sigtype == DAHDI_SIG_HARDHDLC) ? chan : NULL;
1962
			spin_unlock_irqrestore(&wc->reglock, flags);
1963
			ts->sigactive = 0;
1964
		}
1965
	}
1966
	return 0;
1967
}
1968
1969
static int t4_open(struct dahdi_chan *chan)
1970
{
1971
	return 0;
1972
}
1973
1974
static int t4_close(struct dahdi_chan *chan)
1975
{
1976
	return 0;
1977
}
1978
1979
static void set_span_devicetype(struct t4 *wc)
1980
{
1981
	struct dahdi_device *ddev = wc->ddev;
1982
	const char *devicetype_old = ddev->devicetype;
1983
	char *extra_str = "";
1984
1985
	if (wc->vpm == T4_VPM_PRESENT)
1986
		extra_str = (!wc->vpm450m) ? " (VPM400M)" : " (VPMOCT032)",
1987
	wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s%s",
1988
			wc->variety, extra_str);
1989
1990
	/* On the off chance that we were able to allocate it previously. */
1991
	if (!wc->ddev->devicetype)
1992
		wc->ddev->devicetype = devicetype_old;
1993
	else
1994
		kfree(devicetype_old);
1995
}
1996
1997
/* The number of cards we have seen with each
1998
   possible 'order' switch setting.
1999
*/
2000
static unsigned int order_index[16];
2001
2002
static void setup_chunks(struct t4 *wc, int which)
2003
{
2004
	struct t4_span *ts;
2005
	int offset = 1;
2006
	int x, y;
2007
	int gen2;
2008
2009
	if (!wc->t1e1)
2010
		offset += 4;
2011
2012
	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
2013
2014
	for (x = 0; x < wc->numspans; x++) {
2015
		ts = wc->tspans[x];
2016
		ts->writechunk = (void *)(wc->writechunk + (x * 32 * 2) + (which * (1024 >> 2)));
2017
		ts->readchunk = (void *)(wc->readchunk + (x * 32 * 2) + (which * (1024 >> 2)));
2018
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
2019
			struct dahdi_chan *mychans = ts->chans[y];
2020
			if (gen2) {
2021
				mychans->writechunk = (void *)(wc->writechunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
2022
				mychans->readchunk = (void *)(wc->readchunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
2023
			}
2024
		}
2025
	}
2026
}
2027
2028
#ifdef DAHDI_SPAN_OPS
2029
static const struct dahdi_span_ops t4_gen1_span_ops = {
2030
	.owner = THIS_MODULE,
2031
	.spanconfig = t4_spanconfig,
2032
	.chanconfig = t4_chanconfig,
2033
	.startup = t4_startup,
2034
	.shutdown = t4_shutdown,
2035
	.rbsbits = t4_rbsbits,
2036
	.maint = t4_maint,
2037
	.open = t4_open,
2038
	.close  = t4_close,
2039
	.ioctl = t4_ioctl,
2040
	.hdlc_hard_xmit = t4_hdlc_hard_xmit,
2041
};
2042
2043
static const struct dahdi_span_ops t4_gen2_span_ops = {
2044
	.owner = THIS_MODULE,
2045
	.spanconfig = t4_spanconfig,
2046
	.chanconfig = t4_chanconfig,
2047
	.startup = t4_startup,
2048
	.shutdown = t4_shutdown,
2049
	.rbsbits = t4_rbsbits,
2050
	.maint = t4_maint,
2051
	.open = t4_open,
2052
	.close  = t4_close,
2053
	.ioctl = t4_ioctl,
2054
	.hdlc_hard_xmit = t4_hdlc_hard_xmit,
2055
	.dacs = t4_dacs,
2056
#ifdef VPM_SUPPORT
2057
	.echocan_create = t4_echocan_create,
2058
#endif
2059
};
2060
#endif
2061
2062
static void init_spans(struct t4 *wc)
2063
{
2064
	int x,y;
2065
	int gen2;
2066
	struct t4_span *ts;
2067
	unsigned int reg;
2068
2069
	wc->ddev->manufacturer = "OpenVox";
2070
	if (order_index[wc->order] == 1)
2071
		wc->ddev->location = kasprintf(GFP_KERNEL,
2072
				"Board ID Switch %d", wc->order);
2073
	else
2074
		wc->ddev->location = kasprintf(GFP_KERNEL,
2075
				"PCI%s Bus %02d Slot %02d",
2076
				(ts->spanflags & FLAG_EXPRESS) ?
2077
					" Express" : " ",
2078
				wc->dev->bus->number,
2079
				PCI_SLOT(wc->dev->devfn) + 1);
2080
	if (!wc->ddev->location)
2081
		return; /* FIXME: Error handling */
2082
2083
	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
2084
	for (x = 0; x < wc->numspans; x++) {
2085
		ts = wc->tspans[x];
2086
		sprintf(ts->span.name, "D115/D130/%d/%d", wc->num, x + 1);
2087
		snprintf(ts->span.desc, sizeof(ts->span.desc) - 1,
2088
			 "D115/D130 (E1|T1) Card %d Span %d", wc->num, x+1);
2089
		switch (ts->spantype) {
2090
		case TYPE_T1:
2091
			ts->span.spantype = "T1";
2092
			break;
2093
		case TYPE_E1:
2094
			ts->span.spantype = "E1";
2095
			break;
2096
		case TYPE_J1:
2097
			ts->span.spantype = "J1";
2098
			break;
2099
		}
2100
#ifdef DAHDI_SPAN_MODULE	
2101
		ts->span.owner = THIS_MODULE;
2102
#endif
2103
#ifdef DAHDI_SPAN_OPS
2104
		if (gen2) {
2105
			ts->span.ops = &t4_gen2_span_ops;
2106
		} else {
2107
			ts->span.ops = &t4_gen1_span_ops;
2108
		}
2109
#else
2110
		ts->span.spanconfig = t4_spanconfig;
2111
		ts->span.chanconfig = t4_chanconfig;
2112
		ts->span.startup = t4_startup;
2113
		ts->span.shutdown = t4_shutdown;
2114
		ts->span.rbsbits = t4_rbsbits;
2115
		ts->span.maint = t4_maint;
2116
		ts->span.open = t4_open;
2117
		ts->span.close  = t4_close;
2118
		ts->span.ioctl = t4_ioctl;
2119
		ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
2120
		if (gen2) {
2121
#ifdef VPM_SUPPORT
2122
		if (vpmsupport)
2123
			ts->span.echocan_create = t4_echocan_create;
2124
#endif			
2125
			ts->span.dacs = t4_dacs;
2126
		}
2127
		ts->span.pvt = ts;
2128
#endif
2129
2130
		/* HDLC Specific init */
2131
		ts->sigchan = NULL;
2132
		ts->sigmode = sigmode;
2133
		ts->sigactive = 0;
2134
		
2135
		if (ts->spantype == TYPE_T1 || ts->spantype == TYPE_J1) {
2136
			ts->span.channels = 24;
2137
			ts->span.deflaw = DAHDI_LAW_MULAW;
2138
			ts->span.linecompat = DAHDI_CONFIG_AMI |
2139
				DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 |
2140
				DAHDI_CONFIG_ESF;
2141
		} else {
2142
			ts->span.channels = 31;
2143
			ts->span.deflaw = DAHDI_LAW_ALAW;
2144
			ts->span.linecompat = DAHDI_CONFIG_AMI |
2145
				DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS |
2146
				DAHDI_CONFIG_CRC4;
2147
		}
2148
		ts->span.chans = ts->chans;
2149
		ts->span.flags = DAHDI_FLAG_RBS;
2150
2151
		ts->owner = wc;
2152
		ts->span.offset = x;
2153
		ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
2154
		ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
2155
2156
		for (y=0;y<wc->tspans[x]->span.channels;y++) {
2157
			struct dahdi_chan *mychans = ts->chans[y];
2158
			sprintf(mychans->name, "D115/D130/%d/%d/%d", wc->num, x + 1, y + 1);
2159
			t4_chan_set_sigcap(&ts->span, x);
2160
			mychans->pvt = wc;
2161
			mychans->chanpos = y + 1;
2162
		}
2163
2164
		/* Enable 1sec timer interrupt */
2165
		reg = t4_framer_in(wc, x, FMR1_T);
2166
		t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
2167
2168
		/* Enable Errored Second interrupt */
2169
		t4_framer_out(wc, x, ESM, 0);
2170
2171
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
2172
		t4_reset_counters(&ts->span);
2173
#endif
2174
	}
2175
2176
	set_span_devicetype(wc);
2177
	setup_chunks(wc, 0);
2178
	wc->lastindex = 0;
2179
}
2180
2181
static void t4_serial_setup(struct t4 *wc, int unit)
2182
{
2183
	if (!wc->globalconfig) {
2184
		wc->globalconfig = 1;
2185
		if (debug)
2186
			dev_info(&wc->dev->dev, "opvxd115: Setting up global "
2187
					"serial parameters\n");
2188
		t4_framer_out(wc, 0, 0x85, 0xe0);	/* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
2189
		t4_framer_out(wc, 0, 0x08, 0x01);	/* IPC: Interrupt push/pull active low */
2190
	
2191
		/* Global clocks (8.192 Mhz CLK) */
2192
		t4_framer_out(wc, 0, 0x92, 0x00);	
2193
		t4_framer_out(wc, 0, 0x93, 0x18);
2194
		t4_framer_out(wc, 0, 0x94, 0xfb);
2195
		t4_framer_out(wc, 0, 0x95, 0x0b);
2196
		t4_framer_out(wc, 0, 0x96, 0x00);
2197
		t4_framer_out(wc, 0, 0x97, 0x0b);
2198
		t4_framer_out(wc, 0, 0x98, 0xdb);
2199
		t4_framer_out(wc, 0, 0x99, 0xdf);
2200
	}
2201
2202
	/* Configure interrupts */	
2203
	t4_framer_out(wc, unit, FRMR_GCR, 0x00);	/* GCR: Interrupt on Activation/Deactivation of each */
2204
2205
	/* Configure system interface */
2206
	t4_framer_out(wc, unit, FRMR_SIC1, 0xc2);	/* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */
2207
	t4_framer_out(wc, unit, FRMR_SIC2, 0x20 | (unit << 1)); /* SIC2: No FFS, no center receive eliastic buffer, phase */
2208
	t4_framer_out(wc, unit, FRMR_SIC3, 0x04);	/* SIC3: Edges for capture */
2209
	t4_framer_out(wc, unit, FRMR_CMR2, 0x00);	/* CMR2: We provide sync and clock for tx and rx. */
2210
	if (!wc->t1e1) { /* T1 mode */
2211
		t4_framer_out(wc, unit, FRMR_XC0, 0x03);	/* XC0: Normal operation of Sa-bits */
2212
		t4_framer_out(wc, unit, FRMR_XC1, 0x84);	/* XC1: 0 offset */
2213
		if (wc->tspans[unit]->spantype == TYPE_J1)
2214
			t4_framer_out(wc, unit, FRMR_RC0, 0x83);	/* RC0: Just shy of 1023 */
2215
		else
2216
			t4_framer_out(wc, unit, FRMR_RC0, 0x03);	/* RC0: Just shy of 1023 */
2217
		t4_framer_out(wc, unit, FRMR_RC1, 0x84);	/* RC1: The rest of RC0 */
2218
	} else { /* E1 mode */
2219
		t4_framer_out(wc, unit, FRMR_XC0, 0x00);	/* XC0: Normal operation of Sa-bits */
2220
		t4_framer_out(wc, unit, FRMR_XC1, 0x04);	/* XC1: 0 offset */
2221
		t4_framer_out(wc, unit, FRMR_RC0, 0x04);	/* RC0: Just shy of 1023 */
2222
		t4_framer_out(wc, unit, FRMR_RC1, 0x04);	/* RC1: The rest of RC0 */
2223
	}
2224
	
2225
	/* Configure ports */
2226
	t4_framer_out(wc, unit, 0x80, 0x00);	/* PC1: SPYR/SPYX input on RPA/XPA */
2227
	if (wc->falc31) {
2228
			  t4_framer_out(wc, unit, 0x81, 0xBB);	/* PC2: RMFB/XSIG output/input on RPB/XPB */
2229
			  t4_framer_out(wc, unit, 0x82, 0xBB);	/* PC3: Some unused stuff */
2230
			  t4_framer_out(wc, unit, 0x83, 0xBB);	/* PC4: Some more unused stuff */
2231
	} else {
2232
			  t4_framer_out(wc, unit, 0x81, 0x22);	/* PC2: RMFB/XSIG output/input on RPB/XPB */
2233
			  t4_framer_out(wc, unit, 0x82, 0x65);	/* PC3: Some unused stuff */
2234
			  t4_framer_out(wc, unit, 0x83, 0x35);	/* PC4: Some more unused stuff */
2235
	}
2236
	t4_framer_out(wc, unit, 0x84, 0x01);	/* PC5: XMFS active low, SCLKR is input, RCLK is output */
2237
	if (debug & DEBUG_MAIN)
2238
		dev_notice(&wc->dev->dev, "Successfully initialized serial "
2239
				"bus for unit %d\n", unit);
2240
}
2241
2242
static int syncsrc = 0;
2243
static int syncnum = 0 /* -1 */;
2244
static int syncspan = 0;
2245
#ifdef DEFINE_SPINLOCK
2246
static DEFINE_SPINLOCK(synclock);
2247
#else
2248
static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
2249
#endif
2250
2251
static void __t4_set_rclk_src(struct t4 *wc, int span)
2252
{
2253
	int cmr1 = 0x38;	/* Clock Mode: RCLK sourced by DCO-R1
2254
				   by default, Disable Clock-Switching */
2255
2256
	cmr1 |= (span << 6);
2257
	__t4_framer_out(wc, 0, 0x44, cmr1);
2258
2259
	dev_info(&wc->dev->dev, "RCLK source set to span %d\n", span+1);
2260
}
2261
2262
static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave)
2263
{
2264
	if (slave) {
2265
		wc->dmactrl |= (1 << 25);
2266
		dev_info(&wc->dev->dev, "SCLK is slaved to timing cable\n");
2267
	} else {
2268
		wc->dmactrl &= ~(1 << 25);
2269
	}
2270
2271
	if (master) {
2272
		wc->dmactrl |= (1 << 24);
2273
		dev_info(&wc->dev->dev, "SCLK is master to timing cable\n");
2274
	} else {
2275
		wc->dmactrl &= ~(1 << 24);
2276
	}
2277
2278
	if (mode == WC_RECOVER)
2279
		wc->dmactrl |= (1 << 29); /* Recover timing from RCLK */
2280
2281
	if (mode == WC_SELF)
2282
		wc->dmactrl &= ~(1 << 29);/* Provide timing from MCLK */
2283
2284
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2285
}
2286
2287
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
2288
static ssize_t t4_timing_master_show(struct device *dev,
2289
				     struct device_attribute *attr,
2290
				     char *buf)
2291
{
2292
	struct t4 *wc = dev_get_drvdata(dev);
2293
	if (wc->dmactrl & (1 << 29))
2294
		return sprintf(buf, "%d\n", wc->syncsrc);
2295
	else
2296
		return sprintf(buf, "%d\n", -1);
2297
}
2298
2299
static DEVICE_ATTR(timing_master, 0400, t4_timing_master_show, NULL);
2300
2301
static void create_sysfs_files(struct t4 *wc)
2302
{
2303
	int ret;
2304
	ret = device_create_file(&wc->dev->dev,
2305
				 &dev_attr_timing_master);
2306
	if (ret) {
2307
		dev_info(&wc->dev->dev,
2308
			"Failed to create device attributes.\n");
2309
	}
2310
}
2311
2312
static void remove_sysfs_files(struct t4 *wc)
2313
{
2314
	device_remove_file(&wc->dev->dev,
2315
			   &dev_attr_timing_master);
2316
}
2317
2318
#else
2319
2320
static inline void create_sysfs_files(struct t4 *wc) { return; }
2321
static inline void remove_sysfs_files(struct t4 *wc) { return; }
2322
2323
#endif /* LINUX_KERNEL > 2.6.18 */
2324
2325
static inline void __t4_update_timing(struct t4 *wc)
2326
{
2327
	int i;
2328
	/* update sync src info */
2329
	if (wc->syncsrc != syncsrc) {
2330
		dev_info(&wc->dev->dev, "Swapping card %d from %d to %d\n",
2331
				wc->num, wc->syncsrc, syncsrc);
2332
		wc->syncsrc = syncsrc;
2333
		/* Update sync sources */
2334
		for (i = 0; i < wc->numspans; i++) {
2335
			wc->tspans[i]->span.syncsrc = wc->syncsrc;
2336
		}
2337
		if (syncnum == wc->num) {
2338
			__t4_set_rclk_src(wc, syncspan-1);
2339
			__t4_set_sclk_src(wc, WC_RECOVER, 1, 0);
2340
			if (debug)
2341
				dev_notice(&wc->dev->dev, "Card %d, using sync "
2342
					"span %d, master\n", wc->num, syncspan);
2343
		} else {
2344
			__t4_set_sclk_src(wc, WC_RECOVER, 0, 1);
2345
			if (debug)
2346
				dev_notice(&wc->dev->dev, "Card %d, using "
2347
					"Timing Bus, NOT master\n", wc->num);
2348
		}
2349
	}
2350
}
2351
2352
static int __t4_findsync(struct t4 *wc)
2353
{
2354
	int i;
2355
	int x;
2356
	unsigned long flags;
2357
	int p;
2358
	int nonzero;
2359
	int newsyncsrc = 0;			/* DAHDI span number */
2360
	int newsyncnum = 0;			/* opvxd115 card number */
2361
	int newsyncspan = 0;		/* span on given opvxd115 card */
2362
	spin_lock_irqsave(&synclock, flags);
2363
#if 1
2364
	if (!wc->num) {
2365
		/* If we're the first card, go through all the motions, up to 8 levels
2366
		   of sync source */
2367
		p = 1;
2368
		while (p < 8) {
2369
			nonzero = 0;
2370
			for (x=0;cards[x];x++) {
2371
				for (i = 0; i < wc->numspans; i++) {
2372
					if (cards[x]->tspans[i]->syncpos) {
2373
						nonzero = 1;
2374
						if ((cards[x]->tspans[i]->syncpos == p) &&
2375
						    !(cards[x]->tspans[i]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_LOOPBACK)) &&
2376
							(cards[x]->tspans[i]->span.flags & DAHDI_FLAG_RUNNING)) {
2377
								/* This makes a good sync source */
2378
								newsyncsrc = cards[x]->tspans[i]->span.spanno;
2379
								newsyncnum = x;
2380
								newsyncspan = i + 1;
2381
								/* Jump out */
2382
								goto found;
2383
						}
2384
					}
2385
				}		
2386
			}
2387
			if (nonzero)
2388
				p++;
2389
			else 
2390
				break;
2391
		}
2392
found:		
2393
		if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) {
2394
			if (debug)
2395
				dev_notice(&wc->dev->dev, "New syncnum: %d "
2396
					"(was %d), syncsrc: %d (was %d), "
2397
					"syncspan: %d (was %d)\n", newsyncnum,
2398
					syncnum, newsyncsrc, syncsrc,
2399
					newsyncspan, syncspan);
2400
			syncnum = newsyncnum;
2401
			syncsrc = newsyncsrc;
2402
			syncspan = newsyncspan;
2403
			for (x=0;cards[x];x++) {
2404
				__t4_update_timing(cards[x]);
2405
			}
2406
		}
2407
	}
2408
	__t4_update_timing(wc);
2409
#endif	
2410
	spin_unlock_irqrestore(&synclock, flags);
2411
	return 0;
2412
}
2413
2414
static void __t4_set_timing_source_auto(struct t4 *wc)
2415
{
2416
	int x;
2417
	int firstprio, secondprio;
2418
	firstprio = secondprio = 4;
2419
2420
	if (debug)
2421
		dev_info(&wc->dev->dev, "timing source auto\n");
2422
	clear_bit(T4_CHECK_TIMING, &wc->checkflag);
2423
	if (timingcable) {
2424
		__t4_findsync(wc);
2425
	} else {
2426
		if (debug)
2427
			dev_info(&wc->dev->dev, "Evaluating spans for timing "
2428
					"source\n");
2429
		for (x=0;x<wc->numspans;x++) {
2430
			if ((wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) &&
2431
			   !(wc->tspans[x]->span.alarms & (DAHDI_ALARM_RED |
2432
							   DAHDI_ALARM_BLUE))) {
2433
				if (debug)
2434
					dev_info(&wc->dev->dev, "span %d is "
2435
						"green : syncpos %d\n", x+1,
2436
						wc->tspans[x]->syncpos);
2437
				if (wc->tspans[x]->syncpos) {
2438
					/* Valid rsync source in recovered
2439
					   timing mode */
2440
					if (firstprio == 4)
2441
						firstprio = x;
2442
					else if (wc->tspans[x]->syncpos <
2443
						wc->tspans[firstprio]->syncpos)
2444
						firstprio = x;
2445
				} else {
2446
					/* Valid rsync source in system timing
2447
					   mode */
2448
					if (secondprio == 4)
2449
						secondprio = x;
2450
				}
2451
			}
2452
		}
2453
		if (firstprio != 4) {
2454
			wc->syncsrc = firstprio;
2455
			__t4_set_rclk_src(wc, firstprio);
2456
			__t4_set_sclk_src(wc, WC_RECOVER, 0, 0);
2457
			dev_info(&wc->dev->dev, "Recovered timing mode, "\
2458
						"RCLK set to span %d\n",
2459
						firstprio+1);
2460
		} else if (secondprio != 4) {
2461
			wc->syncsrc = -1;
2462
			__t4_set_rclk_src(wc, secondprio);
2463
			__t4_set_sclk_src(wc, WC_SELF, 0, 0);
2464
			dev_info(&wc->dev->dev, "System timing mode, "\
2465
						"RCLK set to span %d\n",
2466
						secondprio+1);
2467
		} else {
2468
			wc->syncsrc = -1;
2469
			dev_info(&wc->dev->dev, "All spans in alarm : No valid"\
2470
						"span to source RCLK from\n");
2471
			/* Default rclk to lock with span 1 */
2472
			__t4_set_rclk_src(wc, 0);
2473
			__t4_set_sclk_src(wc, WC_SELF, 0, 0);
2474
		}
2475
	}
2476
}
2477
2478
static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel)
2479
{
2480
	unsigned int fmr4, fmr2, fmr1, fmr0, lim2;
2481
	char *framing, *line;
2482
	int mytxlevel;
2483
	if ((txlevel > 7) || (txlevel < 4))
2484
		mytxlevel = 0;
2485
	else
2486
		mytxlevel = txlevel - 4;
2487
	fmr1 = 0x9c; /* FMR1: Mode 1, T1 mode, CRC on for ESF, 8.192 Mhz system data rate, no XAIS */
2488
	fmr2 = 0x20; /* FMR2: no payload loopback, don't auto yellow */
2489
	fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */
2490
	lim2 = 0x21; /* LIM2: 50% peak is a "1", Advanced Loss recovery */
2491
	lim2 |= (mytxlevel << 6);	/* LIM2: Add line buildout */
2492
	__t4_framer_out(wc, unit, 0x1d, fmr1);
2493
	__t4_framer_out(wc, unit, 0x1e, fmr2);
2494
2495
	/* Configure line interface */
2496
	if (lineconfig & DAHDI_CONFIG_AMI) {
2497
		line = "AMI";
2498
		/* workaround for errata #2 in ES v3 09-10-16 */
2499
		fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
2500
	} else {
2501
		line = "B8ZS";
2502
		fmr0 = 0xf0;
2503
	}
2504
	if (lineconfig & DAHDI_CONFIG_D4) {
2505
		framing = "D4";
2506
	} else {
2507
		framing = "ESF";
2508
		fmr4 |= 0x2;
2509
		fmr2 |= 0xc0;
2510
	}
2511
	__t4_framer_out(wc, unit, 0x1c, fmr0);
2512
	__t4_framer_out(wc, unit, 0x20, fmr4);
2513
	__t4_framer_out(wc, unit, 0x21, 0x40);	/* FMR5: Enable RBS mode */
2514
2515
	__t4_framer_out(wc, unit, 0x37, 0xf0 );	/* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
2516
	__t4_framer_out(wc, unit, 0x36, 0x08);	/* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
2517
2518
	__t4_framer_out(wc, unit, 0x02, 0x50);	/* CMDR: Reset the receiver and transmitter line interface */
2519
	__t4_framer_out(wc, unit, 0x02, 0x00);	/* CMDR: Reset the receiver and transmitter line interface */
2520
2521
	if (wc->falc31) {
2522
		if (debug)
2523
			dev_info(&wc->dev->dev, "card %d span %d: setting Rtx "
2524
					"to 0ohm for T1\n", wc->num, unit);
2525
		__t4_framer_out(wc, unit, 0x86, 0x00);	/* PC6: set Rtx to 0ohm for T1 */
2526
2527
		// Hitting the bugfix register to fix errata #3
2528
		__t4_framer_out(wc, unit, 0xbd, 0x05);
2529
	}
2530
2531
	__t4_framer_out(wc, unit, 0x3a, lim2);	/* LIM2: 50% peak amplitude is a "1" */
2532
	__t4_framer_out(wc, unit, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
2533
	__t4_framer_out(wc, unit, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
2534
	
2535
	/* Generate pulse mask for T1 */
2536
	switch(mytxlevel) {
2537
	case 3:
2538
		__t4_framer_out(wc, unit, 0x26, 0x07);	/* XPM0 */
2539
		__t4_framer_out(wc, unit, 0x27, 0x01);	/* XPM1 */
2540
		__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2541
		break;
2542
	case 2:
2543
		__t4_framer_out(wc, unit, 0x26, 0x8c);	/* XPM0 */
2544
		__t4_framer_out(wc, unit, 0x27, 0x11);	/* XPM1 */
2545
		__t4_framer_out(wc, unit, 0x28, 0x01);	/* XPM2 */
2546
		break;
2547
	case 1:
2548
		__t4_framer_out(wc, unit, 0x26, 0x8c);	/* XPM0 */
2549
		__t4_framer_out(wc, unit, 0x27, 0x01);	/* XPM1 */
2550
		__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2551
		break;
2552
	case 0:
2553
	default:
2554
		__t4_framer_out(wc, unit, 0x26, 0xd7);	/* XPM0 */
2555
		__t4_framer_out(wc, unit, 0x27, 0x22);	/* XPM1 */
2556
		__t4_framer_out(wc, unit, 0x28, 0x01);	/* XPM2 */
2557
		break;
2558
	}
2559
2560
	/* Don't mask framer interrupts if hardware HDLC is in use */
2561
	__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0));	/* IMR0: We care about CAS changes, etc */
2562
	__t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0));	/* IMR1: We care about nothing */
2563
	__t4_framer_out(wc, unit, 0x16, 0x00);	/* IMR2: All the alarm stuff! */
2564
	__t4_framer_out(wc, unit, 0x17, 0x34);	/* IMR3: AIS and friends */
2565
	__t4_framer_out(wc, unit, 0x18, 0x3f);  /* IMR4: Slips on transmit */
2566
2567
	dev_info(&wc->dev->dev, "Span %d configured for %s/%s\n", unit + 1,
2568
			framing, line);
2569
}
2570
2571
static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
2572
{
2573
	unsigned int fmr2, fmr1, fmr0;
2574
	unsigned int cas = 0;
2575
	unsigned int imr3extra=0;
2576
	char *crc4 = "";
2577
	char *framing, *line;
2578
	fmr1 = 0x44; /* FMR1: E1 mode, Automatic force resync, PCM30 mode, 8.192 Mhz backplane, no XAIS */
2579
	fmr2 = 0x03; /* FMR2: Auto transmit remote alarm, auto loss of multiframe recovery, no payload loopback */
2580
	if (lineconfig & DAHDI_CONFIG_CRC4) {
2581
		fmr1 |= 0x08;	/* CRC4 transmit */
2582
		fmr2 |= 0xc0;	/* CRC4 receive */
2583
		crc4 = "/CRC4";
2584
	}
2585
	__t4_framer_out(wc, unit, 0x1d, fmr1);
2586
	__t4_framer_out(wc, unit, 0x1e, fmr2);
2587
2588
	/* Configure line interface */
2589
	if (lineconfig & DAHDI_CONFIG_AMI) {
2590
		line = "AMI";
2591
		/* workaround for errata #2 in ES v3 09-10-16 */
2592
		fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
2593
	} else {
2594
		line = "HDB3";
2595
		fmr0 = 0xf0;
2596
	}
2597
	if (lineconfig & DAHDI_CONFIG_CCS) {
2598
		framing = "CCS";
2599
		imr3extra = 0x28;
2600
	} else {
2601
		framing = "CAS";
2602
		cas = 0x40;
2603
	}
2604
	__t4_framer_out(wc, unit, 0x1c, fmr0);
2605
2606
	__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 */
2607
	__t4_framer_out(wc, unit, 0x36, 0x08);	/* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
2608
2609
	__t4_framer_out(wc, unit, 0x02, 0x50);	/* CMDR: Reset the receiver and transmitter line interface */
2610
	__t4_framer_out(wc, unit, 0x02, 0x00);	/* CMDR: Reset the receiver and transmitter line interface */
2611
2612
	if (wc->falc31) {
2613
		if (debug)
2614
			dev_info(&wc->dev->dev,
2615
					"setting Rtx to 7.5ohm for E1\n");
2616
		__t4_framer_out(wc, unit, 0x86, 0x40);	/* PC6: turn on 7.5ohm Rtx for E1 */
2617
	}
2618
2619
	/* Condition receive line interface for E1 after reset */
2620
	__t4_framer_out(wc, unit, 0xbb, 0x17);
2621
	__t4_framer_out(wc, unit, 0xbc, 0x55);
2622
	__t4_framer_out(wc, unit, 0xbb, 0x97);
2623
	__t4_framer_out(wc, unit, 0xbb, 0x11);
2624
	__t4_framer_out(wc, unit, 0xbc, 0xaa);
2625
	__t4_framer_out(wc, unit, 0xbb, 0x91);
2626
	__t4_framer_out(wc, unit, 0xbb, 0x12);
2627
	__t4_framer_out(wc, unit, 0xbc, 0x55);
2628
	__t4_framer_out(wc, unit, 0xbb, 0x92);
2629
	__t4_framer_out(wc, unit, 0xbb, 0x0c);
2630
	__t4_framer_out(wc, unit, 0xbb, 0x00);
2631
	__t4_framer_out(wc, unit, 0xbb, 0x8c);
2632
	
2633
	__t4_framer_out(wc, unit, 0x3a, 0x20);	/* LIM2: 50% peak amplitude is a "1" */
2634
	__t4_framer_out(wc, unit, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
2635
	__t4_framer_out(wc, unit, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
2636
	
2637
	__t4_framer_out(wc, unit, 0x20, 0x9f);	/* XSW: Spare bits all to 1 */
2638
	__t4_framer_out(wc, unit, 0x21, 0x1c|cas);	/* XSP: E-bit set when async. AXS auto, XSIF to 1 */
2639
	
2640
	
2641
	/* Generate pulse mask for E1 */
2642
	__t4_framer_out(wc, unit, 0x26, 0x54);	/* XPM0 */
2643
	__t4_framer_out(wc, unit, 0x27, 0x02);	/* XPM1 */
2644
	__t4_framer_out(wc, unit, 0x28, 0x00);	/* XPM2 */
2645
2646
	/* Don't mask framer interrupts if hardware HDLC is in use */
2647
	__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 */
2648
	__t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0));	/* IMR1: We care about loopup / loopdown */
2649
	__t4_framer_out(wc, unit, 0x16, 0x00);	/* IMR2: We care about all the alarm stuff! */
2650
	__t4_framer_out(wc, unit, 0x17, 0x04 | imr3extra); /* IMR3: AIS */
2651
	__t4_framer_out(wc, unit, 0x18, 0x3f);  /* IMR4: We care about slips on transmit */
2652
2653
	dev_info(&wc->dev->dev, "opvxd115: Span %d configured for %s/%s%s\n",
2654
			unit + 1, framing, line, crc4);
2655
}
2656
2657
static int t4_startup(struct file *file, struct dahdi_span *span)
2658
{
2659
#ifdef SUPPORT_GEN1
2660
	int i;
2661
#endif
2662
	int tspan;
2663
	unsigned long flags;
2664
	int alreadyrunning;
2665
	struct t4_span *ts = t4_from_span(span);
2666
	struct t4 *wc = ts->owner;
2667
2668
	set_bit(T4_IGNORE_LATENCY, &wc->checkflag);
2669
	if (debug)
2670
		dev_info(&wc->dev->dev, "About to enter startup!\n");
2671
	tspan = span->offset + 1;
2672
	if (tspan < 0) {
2673
		dev_info(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
2674
				span->spanno);
2675
		return -1;
2676
	}
2677
2678
	spin_lock_irqsave(&wc->reglock, flags);
2679
2680
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
2681
2682
#ifdef SUPPORT_GEN1
2683
	/* initialize the start value for the entire chunk of last ec buffer */
2684
	for(i = 0; i < span->channels; i++)
2685
	{
2686
		memset(ts->ec_chunk1[i],
2687
			DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
2688
		memset(ts->ec_chunk2[i],
2689
			DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
2690
	}
2691
#endif
2692
	/* Force re-evaluation of timing source */
2693
	wc->syncsrc = -1;
2694
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
2695
2696
	if (ts->spantype == TYPE_E1) { /* if this is an E1 card */
2697
		__t4_configure_e1(wc, span->offset, span->lineconfig);
2698
	} else { /* is a T1 card */
2699
		__t4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
2700
	}
2701
2702
	/* Note clear channel status */
2703
	wc->tspans[span->offset]->notclear = 0;
2704
	__set_clear(wc, span->offset);
2705
	
2706
	if (!alreadyrunning) {
2707
		span->flags |= DAHDI_FLAG_RUNNING;
2708
		wc->spansstarted++;
2709
2710
		if (wc->flags & FLAG_5THGEN)
2711
			__t4_pci_out(wc, 5, (ms_per_irq << 16) | wc->numbufs);
2712
		/* enable interrupts */
2713
		/* Start DMA, enabling DMA interrupts on read only */
2714
#if 0
2715
		/* Enable framer only interrupts */
2716
		wc->dmactrl |= 1 << 27;
2717
#endif
2718
		wc->dmactrl |= (ts->spanflags & FLAG_2NDGEN) ? 0xc0000000 : 0xc0000003;
2719
#ifdef VPM_SUPPORT
2720
		wc->dmactrl |= wc->vpm;
2721
#endif
2722
		/* Seed interrupt register */
2723
		__t4_pci_out(wc, WC_INTR, 0x0c);
2724
		if (noburst || !(ts->spanflags & FLAG_BURST))
2725
			wc->dmactrl |= (1 << 26);
2726
		__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2727
2728
		/* Startup HDLC controller too */
2729
	}
2730
2731
	if (ts->sigchan) {
2732
		struct dahdi_chan *sigchan = ts->sigchan;
2733
2734
		spin_unlock_irqrestore(&wc->reglock, flags);
2735
		if (hdlc_start(wc, span->offset, sigchan, ts->sigmode)) {
2736
			dev_notice(&wc->dev->dev, "Error initializing "
2737
					"signalling controller\n");
2738
			return -1;
2739
		}
2740
		spin_lock_irqsave(&wc->reglock, flags);
2741
	}
2742
2743
	spin_unlock_irqrestore(&wc->reglock, flags);
2744
2745
	t4_check_alarms(wc, span->offset);
2746
	t4_check_sigbits(wc, span->offset);
2747
2748
	if (wc->tspans[0]->sync == span->spanno)
2749
		dev_info(&wc->dev->dev, "SPAN %d: Primary Sync Source\n",
2750
				span->spanno);
2751
#ifdef VPM_SUPPORT
2752
	if (!alreadyrunning && !wc->vpm) {
2753
		wait_a_little();
2754
		t4_vpm400_init(wc);
2755
		if (!wc->vpm)
2756
			t4_vpm450_init(wc);
2757
		wc->dmactrl |= wc->vpm;
2758
		t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
2759
		if (wc->vpm)
2760
			set_span_devicetype(wc);
2761
	}
2762
#endif
2763
	if (debug)
2764
		dev_info(&wc->dev->dev, "Completed startup!\n");
2765
	clear_bit(T4_IGNORE_LATENCY, &wc->checkflag);
2766
	return 0;
2767
}
2768
2769
#ifdef SUPPORT_GEN1
2770
static inline void e1_check(struct t4 *wc, int span, int val)
2771
{
2772
	struct t4_span *ts = wc->tspans[span];
2773
	if ((ts->span.channels > 24) &&
2774
	    (ts->span.flags & DAHDI_FLAG_RUNNING) &&
2775
	    !(ts->span.alarms) &&
2776
	    (!wc->e1recover))   {
2777
		if (val != 0x1b) {
2778
			ts->e1check++;
2779
		} else
2780
			ts->e1check = 0;
2781
		if (ts->e1check > 100) {
2782
			/* Wait 1000 ms */
2783
			wc->e1recover = 1000 * 8;
2784
			wc->tspans[0]->e1check = 0;
2785
			if (debug & DEBUG_MAIN)
2786
				dev_notice(&wc->dev->dev, "Detected loss of "
2787
					"E1 alignment on span %d!\n", span);
2788
			t4_reset_dma(wc);
2789
		}
2790
	}
2791
}
2792
2793
static void t4_receiveprep(struct t4 *wc, int irq)
2794
{
2795
	volatile unsigned int *readchunk;
2796
	int dbl = 0;
2797
	int x,y,z;
2798
	unsigned int tmp;
2799
	int offset=0;
2800
	if (!wc->t1e1)
2801
		offset = 4;
2802
	if (irq & 1) {
2803
		/* First part */
2804
		readchunk = wc->readchunk;
2805
		if (!wc->last0) 
2806
			dbl = 1;
2807
		wc->last0 = 0;
2808
	} else {
2809
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE * 32;
2810
		if (wc->last0) 
2811
			dbl = 1;
2812
		wc->last0 = 1;
2813
	}
2814
	if (dbl) {
2815
		for (x=0;x<wc->numspans;x++)
2816
			wc->ddev->irqmisses++;
2817
		if (debug & DEBUG_MAIN)
2818
			dev_notice(&wc->dev->dev, "opvxd115: Double/missed "
2819
				"interrupt detected\n");
2820
	}
2821
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
2822
		for (z=0;z<24;z++) {
2823
			/* All T1/E1 channels */
2824
			tmp = readchunk[z+1+offset];
2825
			wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
2826
		}
2827
		if (wc->t1e1) {
2828
			if (wc->e1recover > 0)
2829
				wc->e1recover--;
2830
			tmp = readchunk[0];
2831
			e1_check(wc, 0, (tmp & 0x7f000000) >> 24);
2832
			for (z=24;z<31;z++) {
2833
				/* Only E1 channels now */
2834
				tmp = readchunk[z+1];
2835
				if (wc->tspans[0]->span.channels > 24)
2836
					wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
2837
			}
2838
		}
2839
		/* Advance pointer by 4 TDM frame lengths */
2840
		readchunk += 32;
2841
	}
2842
	for (x=0;x<wc->numspans;x++) {
2843
		if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
2844
			for (y=0;y<wc->tspans[x]->span.channels;y++) {
2845
				/* Echo cancel double buffered data */
2846
				dahdi_ec_chunk(wc->tspans[x]->span.chans[y], 
2847
				    wc->tspans[x]->span.chans[y]->readchunk, 
2848
					wc->tspans[x]->ec_chunk2[y]);
2849
				memcpy(wc->tspans[x]->ec_chunk2[y],wc->tspans[x]->ec_chunk1[y],
2850
					DAHDI_CHUNKSIZE);
2851
				memcpy(wc->tspans[x]->ec_chunk1[y],
2852
					wc->tspans[x]->span.chans[y]->writechunk,
2853
						DAHDI_CHUNKSIZE);
2854
			}
2855
			dahdi_receive(&wc->tspans[x]->span);
2856
		}
2857
	}
2858
}
2859
#endif
2860
2861
#if (DAHDI_CHUNKSIZE != 8)
2862
#error Sorry, nextgen does not support chunksize != 8
2863
#endif
2864
2865
static inline void __receive_span(struct t4_span *ts)
2866
{
2867
#ifdef VPM_SUPPORT
2868
	int y;
2869
	unsigned long merged;
2870
	merged = ts->dtmfactive & ts->dtmfmutemask;
2871
	if (merged) {
2872
		for (y=0;y<ts->span.channels;y++) {
2873
			/* Mute any DTMFs which are supposed to be muted */
2874
			if (test_bit(y, &merged)) {
2875
				memset(ts->span.chans[y]->readchunk, DAHDI_XLAW(0, ts->span.chans[y]), DAHDI_CHUNKSIZE);
2876
			}
2877
		}
2878
	}
2879
#endif	
2880
2881
#ifdef ENABLE_PREFETCH
2882
	prefetch((void *)(ts->readchunk));
2883
	prefetch((void *)(ts->writechunk));
2884
	prefetch((void *)(ts->readchunk + 8));
2885
	prefetch((void *)(ts->writechunk + 8));
2886
	prefetch((void *)(ts->readchunk + 16));
2887
	prefetch((void *)(ts->writechunk + 16));
2888
	prefetch((void *)(ts->readchunk + 24));
2889
	prefetch((void *)(ts->writechunk + 24));
2890
	prefetch((void *)(ts->readchunk + 32));
2891
	prefetch((void *)(ts->writechunk + 32));
2892
	prefetch((void *)(ts->readchunk + 40));
2893
	prefetch((void *)(ts->writechunk + 40));
2894
	prefetch((void *)(ts->readchunk + 48));
2895
	prefetch((void *)(ts->writechunk + 48));
2896
	prefetch((void *)(ts->readchunk + 56));
2897
	prefetch((void *)(ts->writechunk + 56));
2898
#endif
2899
2900
	dahdi_ec_span(&ts->span);
2901
	dahdi_receive(&ts->span);
2902
}
2903
2904
static inline void __transmit_span(struct t4_span *ts)
2905
{
2906
	dahdi_transmit(&ts->span);
2907
}
2908
2909
#ifdef ENABLE_WORKQUEUES
2910
static void workq_handlespan(void *data)
2911
{
2912
	struct t4_span *ts = data;
2913
	struct t4 *wc = ts->owner;
2914
	
2915
	__receive_span(ts);
2916
	__transmit_span(ts);
2917
	atomic_dec(&wc->worklist);
2918
	if (!atomic_read(&wc->worklist))
2919
		t4_pci_out(wc, WC_INTR, 0);
2920
}
2921
#else
2922
static void t4_prep_gen2(struct t4 *wc)
2923
{
2924
	int x;
2925
	for (x=0;x<wc->numspans;x++) {
2926
		if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
2927
			__receive_span(wc->tspans[x]);
2928
			__transmit_span(wc->tspans[x]);
2929
		}
2930
	}
2931
}
2932
2933
#endif
2934
#ifdef SUPPORT_GEN1
2935
static void t4_transmitprep(struct t4 *wc, int irq)
2936
{
2937
	volatile unsigned int *writechunk;
2938
	int x,y,z;
2939
	unsigned int tmp;
2940
	int offset=0;
2941
	if (!wc->t1e1)
2942
		offset = 4;
2943
	if (irq & 1) {
2944
		/* First part */
2945
		writechunk = wc->writechunk + 1;
2946
	} else {
2947
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE * 32  + 1;
2948
	}
2949
	for (y=0;y<wc->numspans;y++) {
2950
		if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING) 
2951
			dahdi_transmit(&wc->tspans[y]->span);
2952
	}
2953
2954
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
2955
		/* Once per chunk */
2956
		for (z=0;z<24;z++) {
2957
			/* All T1/E1 channels */
2958
			tmp = (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
2959
			writechunk[z+offset] = tmp;
2960
		}
2961
		if (wc->t1e1) {
2962
			for (z=24;z<31;z++) {
2963
				/* Only E1 channels now */
2964
				tmp = 0;
2965
				if (wc->tspans[0]->span.channels > 24)
2966
					tmp |= (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
2967
				writechunk[z] = tmp;
2968
			}
2969
		}
2970
		/* Advance pointer by 4 TDM frame lengths */
2971
		writechunk += 32;
2972
	}
2973
2974
}
2975
#endif
2976
2977
static void t4_check_sigbits(struct t4 *wc, int span)
2978
{
2979
	int a,i,rxs;
2980
	struct t4_span *ts = wc->tspans[span];
2981
2982
	if (debug & DEBUG_RBS)
2983
		dev_notice(&wc->dev->dev, "Checking sigbits on span %d\n",
2984
				span + 1);
2985
2986
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
2987
		return;
2988
	if (ts->spantype == TYPE_E1) {
2989
		for (i = 0; i < 15; i++) {
2990
			a = t4_framer_in(wc, span, 0x71 + i);
2991
			/* Get high channel in low bits */
2992
			rxs = (a & 0xf);
2993
			if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
2994
				if (ts->span.chans[i+16]->rxsig != rxs)
2995
					dahdi_rbsbits(ts->span.chans[i+16], rxs);
2996
			}
2997
			rxs = (a >> 4) & 0xf;
2998
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
2999
				if (ts->span.chans[i]->rxsig != rxs)
3000
					dahdi_rbsbits(ts->span.chans[i], rxs);
3001
			}
3002
		}
3003
	} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
3004
		for (i = 0; i < 24; i+=4) {
3005
			a = t4_framer_in(wc, span, 0x70 + (i>>2));
3006
			/* Get high channel in low bits */
3007
			rxs = (a & 0x3) << 2;
3008
			if (!(ts->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
3009
				if (ts->span.chans[i+3]->rxsig != rxs)
3010
					dahdi_rbsbits(ts->span.chans[i+3], rxs);
3011
			}
3012
			rxs = (a & 0xc);
3013
			if (!(ts->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
3014
				if (ts->span.chans[i+2]->rxsig != rxs)
3015
					dahdi_rbsbits(ts->span.chans[i+2], rxs);
3016
			}
3017
			rxs = (a >> 2) & 0xc;
3018
			if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
3019
				if (ts->span.chans[i+1]->rxsig != rxs)
3020
					dahdi_rbsbits(ts->span.chans[i+1], rxs);
3021
			}
3022
			rxs = (a >> 4) & 0xc;
3023
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
3024
				if (ts->span.chans[i]->rxsig != rxs)
3025
					dahdi_rbsbits(ts->span.chans[i], rxs);
3026
			}
3027
		}
3028
	} else {
3029
		for (i = 0; i < 24; i+=2) {
3030
			a = t4_framer_in(wc, span, 0x70 + (i>>1));
3031
			/* Get high channel in low bits */
3032
			rxs = (a & 0xf);
3033
			if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
3034
				/* XXX Not really reset on every trans! XXX */
3035
				if (ts->span.chans[i+1]->rxsig != rxs) {
3036
					dahdi_rbsbits(ts->span.chans[i+1], rxs);
3037
				}
3038
			}
3039
			rxs = (a >> 4) & 0xf;
3040
			if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
3041
				/* XXX Not really reset on every trans! XXX */
3042
				if (ts->span.chans[i]->rxsig != rxs) {
3043
					dahdi_rbsbits(ts->span.chans[i], rxs);
3044
				}
3045
			}
3046
		}
3047
	}
3048
}
3049
3050
static void t4_check_alarms(struct t4 *wc, int span)
3051
{
3052
	unsigned char c, d, e;
3053
	int alarms;
3054
	int x,j;
3055
	struct t4_span *ts = wc->tspans[span];
3056
	unsigned long flags;
3057
3058
	if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
3059
		return;
3060
3061
	spin_lock_irqsave(&wc->reglock, flags);
3062
3063
	c = __t4_framer_in(wc, span, 0x4c);
3064
	d = __t4_framer_in(wc, span, 0x4d);
3065
3066
	/* Assume no alarms */
3067
	alarms = 0;
3068
3069
	/* And consider only carrier alarms */
3070
	ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
3071
3072
	if (ts->spantype == TYPE_E1) {
3073
		if (c & 0x04) {
3074
			/* No multiframe found, force RAI high after 400ms only if
3075
			   we haven't found a multiframe since last loss
3076
			   of frame */
3077
			if (!(ts->spanflags & FLAG_NMF)) {
3078
				__t4_framer_out(wc, span, 0x20, 0x9f | 0x20);	/* LIM0: Force RAI High */
3079
				ts->spanflags |= FLAG_NMF;
3080
				dev_notice(&wc->dev->dev,
3081
					"NMF workaround on!\n");
3082
			}
3083
			__t4_framer_out(wc, span, 0x1e, 0xc3);	/* Reset to CRC4 mode */
3084
			__t4_framer_out(wc, span, 0x1c, 0xf2);	/* Force Resync */
3085
			__t4_framer_out(wc, span, 0x1c, 0xf0);	/* Force Resync */
3086
		} else if (!(c & 0x02)) {
3087
			if ((ts->spanflags & FLAG_NMF)) {
3088
				__t4_framer_out(wc, span, 0x20, 0x9f);	/* LIM0: Clear forced RAI */
3089
				ts->spanflags &= ~FLAG_NMF;
3090
				dev_notice(&wc->dev->dev,
3091
					"NMF workaround off!\n");
3092
			}
3093
		}
3094
	} else {
3095
		/* Detect loopup code if we're not sending one */
3096
		if ((!ts->span.mainttimer) && (d & 0x08)) {
3097
			/* Loop-up code detected */
3098
			if ((ts->loopupcnt++ > 80)  && (ts->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
3099
				__t4_framer_out(wc, span, 0x36, 0x08);	/* LIM0: Disable any local loop */
3100
				__t4_framer_out(wc, span, 0x37, 0xf6 );	/* LIM1: Enable remote loop */
3101
				ts->span.maintstat = DAHDI_MAINT_REMOTELOOP;
3102
			}
3103
		} else
3104
			ts->loopupcnt = 0;
3105
		/* Same for loopdown code */
3106
		if ((!ts->span.mainttimer) && (d & 0x10)) {
3107
			/* Loop-down code detected */
3108
			if ((ts->loopdowncnt++ > 80)  && (ts->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
3109
				__t4_framer_out(wc, span, 0x36, 0x08);	/* LIM0: Disable any local loop */
3110
				__t4_framer_out(wc, span, 0x37, 0xf0 );	/* LIM1: Disable remote loop */
3111
				ts->span.maintstat = DAHDI_MAINT_NONE;
3112
			}
3113
		} else
3114
			ts->loopdowncnt = 0;
3115
	}
3116
3117
	if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
3118
		for (x=0,j=0;x < ts->span.channels;x++)
3119
			if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
3120
#ifdef CONFIG_DAHDI_NET
3121
					||
3122
			    (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
3123
#endif
3124
			    )
3125
				j++;
3126
		if (!j)
3127
			alarms |= DAHDI_ALARM_NOTOPEN;
3128
	}
3129
3130
	/* Loss of Frame Alignment */
3131
	if (c & 0x20) {
3132
		if (ts->alarmcount >= alarmdebounce) {
3133
3134
			/* Disable Slip Interrupts */
3135
			e = __t4_framer_in(wc, span, 0x17);
3136
			__t4_framer_out(wc, span, 0x17, (e|0x03));
3137
3138
			alarms |= DAHDI_ALARM_RED;
3139
		} else {
3140
			if (unlikely(debug && !ts->alarmcount)) {
3141
				/* starting to debounce LOF/LFA */
3142
				dev_info(&wc->dev->dev, "opvxd115: LOF/LFA "
3143
					"detected on span %d but debouncing "
3144
					"for %d ms\n", span + 1,
3145
					alarmdebounce);
3146
			}
3147
			ts->alarmcount++;
3148
		}
3149
	} else
3150
		ts->alarmcount = 0;
3151
3152
	/* Loss of Signal */
3153
	if (c & 0x80) {
3154
		if (ts->losalarmcount >= losalarmdebounce) {
3155
			/* Disable Slip Interrupts */
3156
			e = __t4_framer_in(wc, span, 0x17);
3157
			__t4_framer_out(wc, span, 0x17, (e|0x03));
3158
3159
			alarms |= DAHDI_ALARM_RED;
3160
		} else {
3161
			if (unlikely(debug && !ts->losalarmcount)) {
3162
				/* starting to debounce LOS */
3163
				dev_info(&wc->dev->dev, "opvxd115: LOS "
3164
					"detected on span %d but debouncing "
3165
					"for %d ms\n",
3166
					span + 1, losalarmdebounce);
3167
			}
3168
			ts->losalarmcount++;
3169
		}
3170
	} else
3171
		ts->losalarmcount = 0;
3172
3173
	/* Alarm Indication Signal */
3174
	if (c & 0x40) {
3175
		if (ts->aisalarmcount >= aisalarmdebounce)
3176
			alarms |= DAHDI_ALARM_BLUE;
3177
		else {
3178
			if (unlikely(debug && !ts->aisalarmcount)) {
3179
				/* starting to debounce AIS */
3180
				dev_info(&wc->dev->dev, "opvxd115: AIS "
3181
					"detected on span %d but debouncing "
3182
					"for %d ms\n",
3183
					span + 1, aisalarmdebounce);
3184
			}
3185
			ts->aisalarmcount++;
3186
		}
3187
	} else
3188
		ts->aisalarmcount = 0;
3189
3190
#ifdef DAHDI_SPAN_OPS
3191
	/* Add detailed alarm status information to a red alarm state */
3192
	if (alarms & DAHDI_ALARM_RED) {
3193
		if (c & FRS0_LOS)
3194
			alarms |= DAHDI_ALARM_LOS;
3195
		if (c & FRS0_LFA)
3196
			alarms |= DAHDI_ALARM_LFA;
3197
		if (c & FRS0_LMFA)
3198
			alarms |= DAHDI_ALARM_LMFA;
3199
	}
3200
3201
	if (unlikely(debug)) {
3202
		/* Check to ensure the xmit line isn't shorted */
3203
		if (unlikely(d & FRS1_XLS)) {
3204
			dev_info(&wc->dev->dev,
3205
				"Detected a possible hardware malfunction"\
3206
				" this card may need servicing\n");
3207
		}
3208
	}
3209
#endif
3210
3211
	if (((!ts->span.alarms) && alarms) || 
3212
	    (ts->span.alarms && (!alarms))) 
3213
		set_bit(T4_CHECK_TIMING, &wc->checkflag);
3214
3215
	/* Keep track of recovering */
3216
	if ((!alarms) && ts->span.alarms) 
3217
		ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
3218
	if (ts->alarmtimer)
3219
		alarms |= DAHDI_ALARM_RECOVER;
3220
3221
	/* If receiving alarms, go into Yellow alarm state */
3222
	if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
3223
		/* We manually do yellow alarm to handle RECOVER and NOTOPEN, otherwise it's auto anyway */
3224
		unsigned char fmr4;
3225
		fmr4 = __t4_framer_in(wc, span, 0x20);
3226
		__t4_framer_out(wc, span, 0x20, fmr4 | 0x20);
3227
		dev_info(&wc->dev->dev, "Setting yellow alarm span %d\n",
3228
								span+1);
3229
		ts->spanflags |= FLAG_SENDINGYELLOW;
3230
	} else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
3231
		unsigned char fmr4;
3232
		/* We manually do yellow alarm to handle RECOVER  */
3233
		fmr4 = __t4_framer_in(wc, span, 0x20);
3234
		__t4_framer_out(wc, span, 0x20, fmr4 & ~0x20);
3235
		dev_info(&wc->dev->dev, "Clearing yellow alarm span %d\n",
3236
								span+1);
3237
3238
		/* Re-enable timing slip interrupts */
3239
		e = __t4_framer_in(wc, span, 0x17);
3240
3241
		__t4_framer_out(wc, span, 0x17, (e & ~(0x03)));
3242
3243
		ts->spanflags &= ~FLAG_SENDINGYELLOW;
3244
	}
3245
3246
	/* Re-check the timing source when we enter/leave alarm, not withstanding
3247
	   yellow alarm */
3248
	if (c & 0x10) { /* receiving yellow (RAI) */
3249
		if (ts->yelalarmcount >= yelalarmdebounce)
3250
			alarms |= DAHDI_ALARM_YELLOW;
3251
		else {
3252
			if (unlikely(debug && !ts->yelalarmcount)) {
3253
				/* starting to debounce AIS */
3254
				dev_info(&wc->dev->dev, "wct%dxxp: yellow "
3255
					"(RAI) detected on span %d but "
3256
					"debouncing for %d ms\n",
3257
					wc->numspans, span + 1,
3258
					yelalarmdebounce);
3259
			}
3260
			ts->yelalarmcount++;
3261
		}
3262
	} else
3263
		ts->yelalarmcount = 0;
3264
3265
	if (ts->span.mainttimer || ts->span.maintstat) 
3266
		alarms |= DAHDI_ALARM_LOOPBACK;
3267
	ts->span.alarms = alarms;
3268
	spin_unlock_irqrestore(&wc->reglock, flags);
3269
	dahdi_alarm_notify(&ts->span);
3270
}
3271
3272
static void t4_do_counters(struct t4 *wc)
3273
{
3274
	int span;
3275
	for (span=0;span<wc->numspans;span++) {
3276
		struct t4_span *ts = wc->tspans[span];
3277
		int docheck=0;
3278
3279
		spin_lock(&wc->reglock);
3280
		if (ts->loopupcnt || ts->loopdowncnt || ts->alarmcount
3281
			|| ts->losalarmcount || ts->aisalarmcount
3282
			|| ts->yelalarmcount)
3283
			docheck++;
3284
3285
		if (ts->alarmtimer) {
3286
			if (!--ts->alarmtimer) {
3287
				docheck++;
3288
				ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
3289
			}
3290
		}
3291
		spin_unlock(&wc->reglock);
3292
		if (docheck) {
3293
			t4_check_alarms(wc, span);
3294
			dahdi_alarm_notify(&ts->span);
3295
		}
3296
	}
3297
}
3298
3299
static inline void __handle_leds(struct t4 *wc)
3300
{
3301
	int x;
3302
3303
	wc->blinktimer++;
3304
	for (x=0;x<wc->numspans;x++) {
3305
		struct t4_span *ts = wc->tspans[x];
3306
		if (ts->span.flags & DAHDI_FLAG_RUNNING) {
3307
			if ((ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) || ts->losalarmcount) {
3308
#ifdef FANCY_ALARM
3309
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
3310
					__t4_set_led(wc, x, WC_RED);
3311
				}
3312
				if (wc->blinktimer == 0xf) {
3313
					__t4_set_led(wc, x, WC_OFF);
3314
				}
3315
#else
3316
				if (wc->blinktimer == 160) {
3317
					__t4_set_led(wc, x, WC_RED);
3318
				} else if (wc->blinktimer == 480) {
3319
					__t4_set_led(wc, x, WC_OFF);
3320
				}
3321
#endif
3322
			} else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
3323
				/* Yellow Alarm */
3324
				__t4_set_led(wc, x, WC_YELLOW);
3325
			} else if (ts->span.mainttimer || ts->span.maintstat) {
3326
#ifdef FANCY_ALARM
3327
				if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
3328
					__t4_set_led(wc, x, WC_GREEN);
3329
				}
3330
				if (wc->blinktimer == 0xf) {
3331
					__t4_set_led(wc, x, WC_OFF);
3332
				}
3333
#else
3334
				if (wc->blinktimer == 160) {
3335
					__t4_set_led(wc, x, WC_GREEN);
3336
				} else if (wc->blinktimer == 480) {
3337
					__t4_set_led(wc, x, WC_OFF);
3338
				}
3339
#endif
3340
			} else {
3341
				/* No Alarm */
3342
				__t4_set_led(wc, x, WC_GREEN);
3343
			}
3344
		}	else
3345
				__t4_set_led(wc, x, WC_OFF);
3346
3347
	}
3348
#ifdef FANCY_ALARM
3349
	if (wc->blinktimer == 0xf) {
3350
		wc->blinktimer = -1;
3351
		wc->alarmpos++;
3352
		if (wc->alarmpos >= (sizeof(altab) / sizeof(altab[0])))
3353
			wc->alarmpos = 0;
3354
	}
3355
#else
3356
	if (wc->blinktimer == 480)
3357
		wc->blinktimer = 0;
3358
#endif
3359
}
3360
3361
static inline void t4_framer_interrupt(struct t4 *wc, int span)
3362
{
3363
	unsigned char gis, isr0, isr1, isr2, isr3, isr4;
3364
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
3365
	/* Check interrupts for a given span */
3366
	unsigned char reg;
3367
#endif
3368
	int readsize = -1;
3369
	struct t4_span *ts = wc->tspans[span];
3370
	struct dahdi_chan *sigchan;
3371
	unsigned long flags;
3372
3373
3374
	/* 1st gen cards isn't used interrupts */
3375
	gis = t4_framer_in(wc, span, FRMR_GIS);
3376
	isr0 = (gis & FRMR_GIS_ISR0) ? t4_framer_in(wc, span, FRMR_ISR0) : 0;
3377
	isr1 = (gis & FRMR_GIS_ISR1) ? t4_framer_in(wc, span, FRMR_ISR1) : 0;
3378
	isr2 = (gis & FRMR_GIS_ISR2) ? t4_framer_in(wc, span, FRMR_ISR2) : 0;
3379
	isr3 = (gis & FRMR_GIS_ISR3) ? t4_framer_in(wc, span, FRMR_ISR3) : 0;
3380
	isr4 = (gis & FRMR_GIS_ISR4) ? t4_framer_in(wc, span, FRMR_ISR4) : 0;
3381
3382
 	if ((debug & DEBUG_FRAMER) && !(isr3 & ISR3_SEC)) {
3383
 		dev_info(&wc->dev->dev, "gis: %02x, isr0: %02x, isr1: %02x, "\
3384
 			"isr2: %02x, isr3: %08x, isr4: %02x, intcount=%u\n",
3385
 			gis, isr0, isr1, isr2, isr3, isr4, wc->intcount);
3386
 	}
3387
 
3388
#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
3389
	/* Collect performance counters once per second */
3390
 	if (isr3 & ISR3_SEC) {
3391
 		ts->span.count.fe += t4_framer_in(wc, span, FECL_T);
3392
 		ts->span.count.crc4 += t4_framer_in(wc, span, CEC1L_T);
3393
 		ts->span.count.cv += t4_framer_in(wc, span, CVCL_T);
3394
 		ts->span.count.ebit += t4_framer_in(wc, span, EBCL_T);
3395
 		ts->span.count.be += t4_framer_in(wc, span, BECL_T);
3396
 		ts->span.count.prbs = t4_framer_in(wc, span, FRS1_T);
3397
 	}
3398
 
3399
	/* Collect errored second counter once per second */
3400
 	if (isr3 & ISR3_ES) {
3401
 		ts->span.count.errsec += 1;
3402
 	}
3403
 
3404
 	if (isr3 & 0x08) {
3405
 		reg = t4_framer_in(wc, span, FRS1_T);
3406
		dev_info(&wc->dev->dev, "FRS1: %d\n", reg);
3407
 		if (reg & LLBDD) {
3408
 			dev_info(&wc->dev->dev, "Line loop-back activation "\
3409
 					"signal detected with status: %01d "\
3410
 					"for span %d\n", reg & LLBAD, span+1);
3411
 		}
3412
 	}
3413
#endif
3414
3415
	if (isr0)
3416
		t4_check_sigbits(wc, span);
3417
3418
	if (ts->spantype == TYPE_E1) {
3419
		/* E1 checks */
3420
		if ((isr3 & 0x38) || isr2 || isr1)
3421
			t4_check_alarms(wc, span);
3422
	} else {
3423
		/* T1 checks */
3424
		if (isr2 || (isr3 & 0x08))
3425
			t4_check_alarms(wc, span);
3426
	}
3427
	if (!ts->span.alarms) {
3428
		if ((isr3 & 0x3) || (isr4 & 0xc0))
3429
			ts->span.timingslips++;
3430
3431
		if (debug & DEBUG_MAIN) {
3432
			if (isr3 & 0x02)
3433
				dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
3434
					"slip NEGATIVE on span %d\n",
3435
					span + 1);
3436
			if (isr3 & 0x01)
3437
				dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
3438
					"slip POSITIVE on span %d\n",
3439
					span + 1);
3440
			if (isr4 & 0x80)
3441
				dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
3442
					"slip POSITIVE on span %d\n",
3443
					span + 1);
3444
			if (isr4 & 0x40)
3445
				dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
3446
					"slip NEGATIVE on span %d\n",
3447
					span + 1);
3448
		}
3449
	} else
3450
		ts->span.timingslips = 0;
3451
3452
	spin_lock_irqsave(&wc->reglock, flags);
3453
	/* HDLC controller checks - receive side */
3454
	if (!ts->sigchan) {
3455
		spin_unlock_irqrestore(&wc->reglock, flags);
3456
		return;
3457
	}
3458
3459
	sigchan = ts->sigchan;
3460
	spin_unlock_irqrestore(&wc->reglock, flags);
3461
3462
	if (isr0 & FRMR_ISR0_RME) {
3463
		readsize = (t4_framer_in(wc, span, FRMR_RBCH) << 8) | t4_framer_in(wc, span, FRMR_RBCL);
3464
		if (debug & DEBUG_FRAMER)
3465
			dev_notice(&wc->dev->dev, "Received data length is %d "
3466
				"(%d)\n", readsize,
3467
				readsize & FRMR_RBCL_MAX_SIZE);
3468
		/* RPF isn't set on last part of frame */
3469
		if ((readsize > 0) && ((readsize &= FRMR_RBCL_MAX_SIZE) == 0))
3470
			readsize = FRMR_RBCL_MAX_SIZE + 1;
3471
	} else if (isr0 & FRMR_ISR0_RPF)
3472
		readsize = FRMR_RBCL_MAX_SIZE + 1;
3473
3474
	if (readsize > 0) {
3475
		int i;
3476
		unsigned char readbuf[FRMR_RBCL_MAX_SIZE + 1];
3477
3478
		if (debug & DEBUG_FRAMER)
3479
			dev_notice(&wc->dev->dev, "Framer %d: Got RPF/RME! "
3480
				"readsize is %d\n", sigchan->span->offset,
3481
				readsize);
3482
3483
		for (i = 0; i < readsize; i++)
3484
			readbuf[i] = t4_framer_in(wc, span, FRMR_RXFIFO);
3485
3486
		/* Tell the framer to clear the RFIFO */
3487
		t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC);
3488
3489
		if (debug & DEBUG_FRAMER) {
3490
			dev_notice(&wc->dev->dev, "RX(");
3491
			for (i = 0; i < readsize; i++)
3492
				dev_notice(&wc->dev->dev, "%s%02x",
3493
					(i ? " " : ""), readbuf[i]);
3494
			dev_notice(&wc->dev->dev, ")\n");
3495
		}
3496
3497
		if (isr0 & FRMR_ISR0_RME) {
3498
			/* Do checks for HDLC problems */
3499
			unsigned char rsis = readbuf[readsize-1];
3500
#if 0
3501
			unsigned int olddebug = debug;
3502
#endif
3503
			unsigned char rsis_reg = t4_framer_in(wc, span, FRMR_RSIS);
3504
3505
#if 0
3506
			if ((rsis != 0xA2) || (rsis != rsis_reg))
3507
				debug |= DEBUG_FRAMER;
3508
#endif
3509
3510
			++ts->frames_in;
3511
			if ((debug & DEBUG_FRAMER) && !(ts->frames_in & 0x0f))
3512
				dev_notice(&wc->dev->dev, "Received %d frames "
3513
					"on span %d\n", ts->frames_in, span);
3514
			if (debug & DEBUG_FRAMER)
3515
				dev_notice(&wc->dev->dev, "Received HDLC frame"
3516
					" %d.  RSIS = 0x%x (%x)\n",
3517
					ts->frames_in, rsis, rsis_reg);
3518
			if (!(rsis & FRMR_RSIS_CRC16)) {
3519
				if (debug & DEBUG_FRAMER)
3520
					dev_notice(&wc->dev->dev, "CRC check "
3521
							"failed %d\n", span);
3522
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_BADFCS);
3523
			} else if (rsis & FRMR_RSIS_RAB) {
3524
				if (debug & DEBUG_FRAMER)
3525
					dev_notice(&wc->dev->dev, "ABORT of "
3526
						"current frame due to "
3527
						"overflow %d\n", span);
3528
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
3529
			} else if (rsis & FRMR_RSIS_RDO) {
3530
				if (debug & DEBUG_FRAMER)
3531
					dev_notice(&wc->dev->dev, "HDLC "
3532
						"overflow occured %d\n",
3533
						span);
3534
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_OVERRUN);
3535
			} else if (!(rsis & FRMR_RSIS_VFR)) {
3536
				if (debug & DEBUG_FRAMER)
3537
					dev_notice(&wc->dev->dev, "Valid Frame"
3538
						" check failed on span %d\n",
3539
						span);
3540
				dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
3541
			} else {
3542
				dahdi_hdlc_putbuf(sigchan, readbuf, readsize - 1);
3543
				dahdi_hdlc_finish(sigchan);
3544
				if (debug & DEBUG_FRAMER)
3545
					dev_notice(&wc->dev->dev, "Received "
3546
						"valid HDLC frame on span %d"
3547
						"\n", span);
3548
			}
3549
#if 0
3550
			debug = olddebug;
3551
#endif
3552
		} else if (isr0 & FRMR_ISR0_RPF)
3553
			dahdi_hdlc_putbuf(sigchan, readbuf, readsize);
3554
	}
3555
3556
	/* Transmit side */
3557
	if (isr1 & FRMR_ISR1_XDU) {
3558
		if (debug & DEBUG_FRAMER)
3559
			dev_notice(&wc->dev->dev, "XDU: Resetting signal "
3560
					"controller!\n");
3561
		t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
3562
	} else if (isr1 & FRMR_ISR1_XPR) {
3563
		if (debug & DEBUG_FRAMER)
3564
			dev_notice(&wc->dev->dev, "Sigchan %d is %p\n",
3565
					sigchan->chanpos, sigchan);
3566
3567
		if (debug & DEBUG_FRAMER)
3568
			dev_notice(&wc->dev->dev, "Framer %d: Got XPR!\n",
3569
					sigchan->span->offset);
3570
		t4_hdlc_xmit_fifo(wc, span, ts);
3571
	}
3572
3573
	if (isr1 & FRMR_ISR1_ALLS) {
3574
		if (debug & DEBUG_FRAMER)
3575
			dev_notice(&wc->dev->dev, "ALLS received\n");
3576
	}
3577
}
3578
3579
#ifdef SUPPORT_GEN1
3580
DAHDI_IRQ_HANDLER(t4_interrupt)
3581
{
3582
	struct t4 *wc = dev_id;
3583
	unsigned long flags;
3584
	int x;
3585
	
3586
	unsigned int status;
3587
	unsigned int status2;
3588
3589
#if 0
3590
	if (wc->intcount < 20)
3591
		dev_notice(&wc->dev->dev, "Pre-interrupt\n");
3592
#endif
3593
	
3594
	/* Make sure it's really for us */
3595
	status = __t4_pci_in(wc, WC_INTR);
3596
3597
	/* Process framer interrupts */
3598
	status2 = t4_framer_in(wc, 0, FRMR_CIS);
3599
	if (status2 & 0x0f) {
3600
		for (x = 0; x < wc->numspans; ++x) {
3601
			if (status2 & (1 << x))
3602
				t4_framer_interrupt(wc, x);
3603
		}
3604
	}
3605
3606
	/* Ignore if it's not for us */
3607
	if (!status)
3608
		return IRQ_NONE;
3609
3610
	__t4_pci_out(wc, WC_INTR, 0);
3611
3612
	if (!wc->spansstarted) {
3613
		dev_notice(&wc->dev->dev, "Not prepped yet!\n");
3614
		return IRQ_NONE;
3615
	}
3616
3617
	wc->intcount++;
3618
#if 0
3619
	if (wc->intcount < 20)
3620
		dev_notice(&wc->dev->dev, "Got interrupt, status = %08x\n",
3621
				status);
3622
#endif		
3623
3624
	if (status & 0x3) {
3625
		t4_receiveprep(wc, status);
3626
		t4_transmitprep(wc, status);
3627
	}
3628
	
3629
#if 0
3630
	if ((wc->intcount < 10) || !(wc->intcount % 1000)) {
3631
		status2 = t4_framer_in(wc, 0, FRMR_CIS);
3632
		dev_notice(&wc->dev->dev, "Status2: %04x\n", status2);
3633
		for (x = 0;x<wc->numspans;x++) {
3634
			status2 = t4_framer_in(wc, x, FRMR_FRS0);
3635
			dev_notice(&wc->dev->dev, "FRS0/%d: %04x\n", x,
3636
					status2);
3637
		}
3638
	}
3639
#endif
3640
	t4_do_counters(wc);
3641
3642
	x = wc->intcount & 15 /* 63 */;
3643
	switch(x) {
3644
	case 0:
3645
	case 1:
3646
	case 2:
3647
	case 3:
3648
		t4_check_sigbits(wc, x);
3649
		break;
3650
	case 4:
3651
	case 5:
3652
	case 6:
3653
	case 7:
3654
		t4_check_alarms(wc, x - 4);
3655
		break;
3656
	}
3657
3658
	spin_lock_irqsave(&wc->reglock, flags);
3659
3660
	__handle_leds(wc);
3661
3662
	if (test_bit(T4_CHECK_TIMING, &wc->checkflag))
3663
		__t4_set_timing_source_auto(wc);
3664
3665
	spin_unlock_irqrestore(&wc->reglock, flags);
3666
3667
	return IRQ_RETVAL(1);
3668
}
3669
#endif
3670
3671
static int t4_allocate_buffers(struct t4 *wc, int numbufs, volatile unsigned int **oldalloc, dma_addr_t *oldwritedma)
3672
{
3673
	volatile unsigned int *alloc;
3674
	dma_addr_t writedma;
3675
3676
	alloc =
3677
		/* 32 channels, Double-buffer, Read/Write, 4 spans */
3678
		(unsigned int *)pci_alloc_consistent(wc->dev, numbufs * T4_BASE_SIZE * 2, &writedma);
3679
3680
	if (!alloc) {
3681
		dev_notice(&wc->dev->dev, "wct%dxxp: Unable to allocate "
3682
				"DMA-able memory\n", wc->numspans);
3683
		return -ENOMEM;
3684
	}
3685
3686
	if (oldwritedma)
3687
		*oldwritedma = wc->writedma;
3688
	if (oldalloc)
3689
		*oldalloc = wc->writechunk;
3690
3691
	wc->writechunk = alloc;
3692
	wc->writedma = writedma;
3693
3694
	/* Read is after the whole write piece (in words) */
3695
	wc->readchunk = wc->writechunk + (T4_BASE_SIZE * numbufs) / 4;
3696
	
3697
	/* Same thing but in bytes...  */
3698
	wc->readdma = wc->writedma + (T4_BASE_SIZE * numbufs);
3699
3700
	wc->numbufs = numbufs;
3701
	
3702
	/* Initialize Write/Buffers to all blank data */
3703
	memset((void *)wc->writechunk,0x00, T4_BASE_SIZE * numbufs);
3704
	memset((void *)wc->readchunk,0xff, T4_BASE_SIZE * numbufs);
3705
3706
	dev_notice(&wc->dev->dev, "DMA memory base of size %d at %p.  Read: "
3707
		"%p and Write %p\n", numbufs * T4_BASE_SIZE * 2,
3708
		wc->writechunk, wc->readchunk, wc->writechunk);
3709
3710
	return 0;
3711
}
3712
3713
static void t4_increase_latency(struct t4 *wc, int newlatency)
3714
{
3715
	unsigned long flags;
3716
	volatile unsigned int *oldalloc;
3717
	dma_addr_t oldaddr;
3718
	int oldbufs;
3719
3720
	spin_lock_irqsave(&wc->reglock, flags);
3721
3722
	__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3723
	/* Acknowledge any pending interrupts */
3724
	__t4_pci_out(wc, WC_INTR, 0x00000000);
3725
3726
	__t4_pci_in(wc, WC_VERSION);
3727
3728
	oldbufs = wc->numbufs;
3729
3730
	if (t4_allocate_buffers(wc, newlatency, &oldalloc, &oldaddr)) {
3731
		dev_info(&wc->dev->dev, "Error allocating latency buffers for "
3732
				"latency of %d\n", newlatency);
3733
		__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3734
		spin_unlock_irqrestore(&wc->reglock, flags);
3735
		return;
3736
	}
3737
3738
	__t4_pci_out(wc, WC_RDADDR, wc->readdma);
3739
	__t4_pci_out(wc, WC_WRADDR, wc->writedma);
3740
3741
	__t4_pci_in(wc, WC_VERSION);
3742
3743
	__t4_pci_out(wc, 5, (ms_per_irq << 16) | newlatency);
3744
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3745
3746
	__t4_pci_in(wc, WC_VERSION);
3747
3748
	wc->rxident = 0;
3749
	wc->lastindex = 0;
3750
3751
	spin_unlock_irqrestore(&wc->reglock, flags);
3752
3753
	pci_free_consistent(wc->dev, T4_BASE_SIZE * oldbufs * 2, (void *)oldalloc, oldaddr);
3754
3755
	dev_info(&wc->dev->dev, "Increased latency to %d\n", newlatency);
3756
3757
}
3758
3759
static void t4_isr_bh(unsigned long data)
3760
{
3761
	struct t4 *wc = (struct t4 *)data;
3762
3763
	if (test_bit(T4_CHANGE_LATENCY, &wc->checkflag)) {
3764
		if (wc->needed_latency != wc->numbufs) {
3765
			t4_increase_latency(wc, wc->needed_latency);
3766
			clear_bit(T4_CHANGE_LATENCY, &wc->checkflag);
3767
		}
3768
	}
3769
#ifdef VPM_SUPPORT
3770
	if (wc->vpm) {
3771
		if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) {
3772
			if (wc->vpm450m) {
3773
				/* How stupid is it that the octasic can't generate an
3774
				   interrupt when there's a tone, in spite of what their
3775
				   documentation says? */
3776
				t4_check_vpm450(wc);
3777
			} else
3778
				t4_check_vpm400(wc, wc->vpm400checkstatus);
3779
		}
3780
	}
3781
#endif
3782
}
3783
3784
DAHDI_IRQ_HANDLER(t4_interrupt_gen2)
3785
{
3786
	struct t4 *wc = dev_id;
3787
	unsigned int status;
3788
	unsigned char rxident, expected;
3789
	
3790
	/* Check this first in case we get a spurious interrupt */
3791
	if (unlikely(test_bit(T4_STOP_DMA, &wc->checkflag))) {
3792
		/* Stop DMA cleanly if requested */
3793
		wc->dmactrl = 0x0;
3794
		t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3795
		/* Acknowledge any pending interrupts */
3796
		t4_pci_out(wc, WC_INTR, 0x00000000);
3797
		spin_lock(&wc->reglock);
3798
		__t4_set_sclk_src(wc, WC_SELF, 0, 0);
3799
		spin_unlock(&wc->reglock);
3800
		return IRQ_RETVAL(1);
3801
	}
3802
3803
	/* Make sure it's really for us */
3804
	status = __t4_pci_in(wc, WC_INTR);
3805
3806
	/* Ignore if it's not for us */
3807
	if (!(status & 0x7)) {
3808
		return IRQ_NONE;
3809
	}
3810
3811
#ifdef ENABLE_WORKQUEUES
3812
	__t4_pci_out(wc, WC_INTR, status & 0x00000008);
3813
#endif
3814
3815
	if (unlikely(!wc->spansstarted)) {
3816
		dev_info(&wc->dev->dev, "Not prepped yet!\n");
3817
		return IRQ_NONE;
3818
	}
3819
3820
	wc->intcount++;
3821
3822
	if ((wc->flags & FLAG_5THGEN) && (status & 0x2)) {
3823
		rxident = (status >> 16) & 0x7f;
3824
		expected = (wc->rxident + ms_per_irq) % 128;
3825
	
3826
		if ((rxident != expected) && !test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
3827
			int needed_latency;
3828
			int smallest_max;
3829
3830
			if (debug & DEBUG_MAIN)
3831
				dev_warn(&wc->dev->dev, "Missed interrupt.  "
3832
					"Expected ident of %d and got ident "
3833
					"of %d\n", expected, rxident);
3834
3835
			if (test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
3836
				dev_info(&wc->dev->dev,
3837
					"Should have ignored latency\n");
3838
			}
3839
			if (rxident > wc->rxident) {
3840
				needed_latency = rxident - wc->rxident;
3841
			} else {
3842
				needed_latency = (128 - wc->rxident) + rxident;
3843
			}
3844
3845
			needed_latency += 1;
3846
3847
			smallest_max = (max_latency >= GEN5_MAX_LATENCY) ? GEN5_MAX_LATENCY : max_latency;
3848
3849
			if (needed_latency > smallest_max) {
3850
				dev_info(&wc->dev->dev, "Truncating latency "
3851
					"request to %d instead of %d\n",
3852
					smallest_max, needed_latency);
3853
				needed_latency = smallest_max;
3854
			}
3855
3856
			if (needed_latency > wc->numbufs) {
3857
				int x;
3858
3859
				dev_info(&wc->dev->dev, "Need to increase "
3860
					"latency.  Estimated latency should "
3861
					"be %d\n", needed_latency);
3862
				for (x = 0; x < wc->numspans; x++)
3863
					wc->ddev->irqmisses++;
3864
				wc->needed_latency = needed_latency;
3865
				__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
3866
				set_bit(T4_CHANGE_LATENCY, &wc->checkflag);
3867
				goto out;
3868
			}
3869
		}
3870
	
3871
		wc->rxident = rxident;
3872
	}
3873
3874
	if (unlikely((wc->intcount < 20)))
3875
3876
		dev_info(&wc->dev->dev, "2G: Got interrupt, status = %08x, "
3877
			"CIS = %04x\n", status, t4_framer_in(wc, 0, FRMR_CIS));
3878
3879
	if (likely(status & 0x2)) {
3880
#ifdef ENABLE_WORKQUEUES
3881
		int cpus = num_online_cpus();
3882
		atomic_set(&wc->worklist, wc->numspans);
3883
		if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
3884
			t4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
3885
		else
3886
			atomic_dec(&wc->worklist);
3887
#else
3888
#if 1
3889
		unsigned int reg5 = __t4_pci_in(wc, 5);
3890
		if (wc->intcount < 20) {
3891
3892
			dev_info(&wc->dev->dev, "Reg 5 is %08x\n", reg5);
3893
		}
3894
#endif
3895
3896
		if (wc->flags & FLAG_5THGEN) {
3897
			unsigned int current_index = (reg5 >> 8) & 0x7f;
3898
3899
			while (((wc->lastindex + 1) % wc->numbufs) != current_index) {
3900
				wc->lastindex = (wc->lastindex + 1) % wc->numbufs;
3901
				setup_chunks(wc, wc->lastindex);
3902
				t4_prep_gen2(wc);
3903
			}
3904
		} else {
3905
			t4_prep_gen2(wc);
3906
		}
3907
3908
#endif
3909
		t4_do_counters(wc);
3910
		spin_lock(&wc->reglock);
3911
		__handle_leds(wc);
3912
		spin_unlock(&wc->reglock);
3913
3914
	}
3915
3916
	if (unlikely(status & 0x1)) {
3917
		unsigned char cis;
3918
3919
		cis = t4_framer_in(wc, 0, FRMR_CIS);
3920
		if (cis & FRMR_CIS_GIS1)
3921
			t4_framer_interrupt(wc, 0);
3922
		if (cis & FRMR_CIS_GIS2)
3923
			t4_framer_interrupt(wc, 1);
3924
		if (cis & FRMR_CIS_GIS3)
3925
			t4_framer_interrupt(wc, 2);
3926
		if (cis & FRMR_CIS_GIS4)
3927
			t4_framer_interrupt(wc, 3);
3928
	}
3929
3930
	if (wc->vpm && vpmdtmfsupport) {
3931
		if (wc->vpm450m) {
3932
			/* How stupid is it that the octasic can't generate an
3933
			   interrupt when there's a tone, in spite of what their
3934
			   documentation says? */
3935
			if (!(wc->intcount & 0xf)) {
3936
				set_bit(T4_CHECK_VPM, &wc->checkflag);
3937
			}
3938
		} else if ((status & 0xff00) != 0xff00) {
3939
			wc->vpm400checkstatus = (status & 0xff00) >> 8;
3940
			set_bit(T4_CHECK_VPM, &wc->checkflag);
3941
		}
3942
	}
3943
3944
	spin_lock(&wc->reglock);
3945
3946
	if (unlikely(test_bit(T4_CHECK_TIMING, &wc->checkflag))) {
3947
		__t4_set_timing_source_auto(wc);
3948
	}
3949
3950
	spin_unlock(&wc->reglock);
3951
3952
out:
3953
	if (unlikely(test_bit(T4_CHANGE_LATENCY, &wc->checkflag) || test_bit(T4_CHECK_VPM, &wc->checkflag)))
3954
		tasklet_schedule(&wc->t4_tlet);
3955
3956
#ifndef ENABLE_WORKQUEUES
3957
	__t4_pci_out(wc, WC_INTR, 0);
3958
#endif	
3959
3960
	return IRQ_RETVAL(1);
3961
}
3962
3963
#ifdef SUPPORT_GEN1
3964
static int t4_reset_dma(struct t4 *wc)
3965
{
3966
	/* Turn off DMA and such */
3967
	wc->dmactrl = 0x0;
3968
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3969
	t4_pci_out(wc, WC_COUNT, 0);
3970
	t4_pci_out(wc, WC_RDADDR, 0);
3971
	t4_pci_out(wc, WC_WRADDR, 0);
3972
	t4_pci_out(wc, WC_INTR, 0);
3973
	/* Turn it all back on */
3974
	t4_pci_out(wc, WC_RDADDR, wc->readdma);
3975
	t4_pci_out(wc, WC_WRADDR, wc->writedma);
3976
	t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
3977
	t4_pci_out(wc, WC_INTR, 0);
3978
#ifdef VPM_SUPPORT
3979
	wc->dmactrl = 0xc0000000 | (1 << 29) | wc->vpm;
3980
#else	
3981
	wc->dmactrl = 0xc0000000 | (1 << 29);
3982
#endif
3983
	if (noburst)
3984
		wc->dmactrl |= (1 << 26);
3985
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
3986
	return 0;
3987
}
3988
#endif
3989
3990
#ifdef VPM_SUPPORT
3991
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold)
3992
{
3993
	unsigned int x;
3994
3995
	for (x = 0; x < 8; x++) {
3996
		t4_vpm_out(wc, x, 0xC4, (threshold >> 8) & 0xFF);
3997
		t4_vpm_out(wc, x, 0xC5, (threshold & 0xFF));
3998
	}
3999
	dev_info(&wc->dev->dev, "VPM: DTMF threshold set to %d\n", threshold);
4000
}
4001
4002
static unsigned int t4_vpm_mask(int chip)
4003
{
4004
	unsigned int mask=0;
4005
	switch(vpmspans) {
4006
	case 4:
4007
		mask = 0x55555555 << (chip >> 2);
4008
		break;
4009
	case 2:
4010
		mask = 0x11111111 << (chip >> 1);
4011
		break;
4012
	case 1:
4013
		mask = 0x01010101 << chip;
4014
		break;
4015
	}
4016
	return mask;
4017
}
4018
4019
static int t4_vpm_spanno(int chip)
4020
{
4021
	int spanno = 0;
4022
	switch(vpmspans) {
4023
	case 4:
4024
		spanno = chip & 0x3;
4025
		break;
4026
	case 2:
4027
		spanno = chip & 0x1;
4028
		break;
4029
	/* Case 1 is implicit */
4030
	}
4031
	return spanno;
4032
}
4033
4034
static int t4_vpm_echotail(void)
4035
{
4036
	int echotail = 0x01ff;
4037
	switch(vpmspans) {
4038
	case 4:
4039
		echotail = 0x007f;
4040
		break;
4041
	case 2:
4042
		echotail = 0x00ff;
4043
		break;
4044
	/* Case 1 is implicit */
4045
	}
4046
	return echotail;
4047
}
4048
4049
static void t4_vpm450_init(struct t4 *wc)
4050
{
4051
	unsigned int check1, check2;
4052
	int laws[1] = { 0, };
4053
	int x;
4054
	unsigned int vpm_capacity;
4055
	struct firmware embedded_firmware;
4056
	const struct firmware *firmware = &embedded_firmware;
4057
#if !defined(HOTPLUG_FIRMWARE)
4058
	extern void _binary_dahdi_fw_oct6114_032_bin_size;
4059
	extern void _binary_dahdi_fw_oct6114_064_bin_size;
4060
	extern void _binary_dahdi_fw_oct6114_128_bin_size;
4061
	extern u8 _binary_dahdi_fw_oct6114_032_bin_start[];
4062
	extern u8 _binary_dahdi_fw_oct6114_064_bin_start[];
4063
	extern u8 _binary_dahdi_fw_oct6114_128_bin_start[];
4064
#else
4065
	static const char oct032_firmware[] = "dahdi-fw-oct6114-032.bin";
4066
	static const char oct064_firmware[] = "dahdi-fw-oct6114-064.bin";
4067
	static const char oct128_firmware[] = "dahdi-fw-oct6114-128.bin";
4068
#endif
4069
4070
	if (!vpmsupport) {
4071
		dev_info(&wc->dev->dev, "VPM450: Support Disabled\n");
4072
		return;
4073
	}
4074
4075
	/* Turn on GPIO/DATA mux if supported */
4076
	t4_gpio_setdir(wc, (1 << 24), (1 << 24));
4077
	__t4_raw_oct_out(wc, 0x000a, 0x5678);
4078
	__t4_raw_oct_out(wc, 0x0004, 0x1234);
4079
	check1 = __t4_raw_oct_in(wc, 0x0004);
4080
	check2 = __t4_raw_oct_in(wc, 0x000a);
4081
	if (debug)
4082
		dev_notice(&wc->dev->dev, "OCT Result: %04x/%04x\n",
4083
			__t4_raw_oct_in(wc, 0x0004),
4084
			__t4_raw_oct_in(wc, 0x000a));
4085
	if (__t4_raw_oct_in(wc, 0x0004) != 0x1234) {
4086
		dev_notice(&wc->dev->dev, "VPM450: Not Present\n");
4087
		return;
4088
	}
4089
4090
	/* Setup alaw vs ulaw rules */
4091
	for (x = 0;x < wc->numspans; x++) {
4092
		if (wc->tspans[x]->span.channels > 24)
4093
			laws[x] = 1;
4094
	}
4095
4096
	switch ((vpm_capacity = get_vpm450m_capacity(wc))) {
4097
	case 32:
4098
#if defined(HOTPLUG_FIRMWARE)
4099
		if ((request_firmware(&firmware, oct032_firmware, &wc->dev->dev) != 0) ||
4100
		    !firmware) {
4101
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4102
				"available from userspace\n", oct032_firmware);
4103
			return;
4104
		}
4105
#else
4106
		embedded_firmware.data = _binary_dahdi_fw_oct6114_032_bin_start;
4107
		/* Yes... this is weird. objcopy gives us a symbol containing
4108
		   the size of the firmware, not a pointer a variable containing
4109
		   the size. The only way we can get the value of the symbol
4110
		   is to take its address, so we define it as a pointer and
4111
		   then cast that value to the proper type.
4112
	      */
4113
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_032_bin_size;
4114
#endif
4115
		break;
4116
	case 64:
4117
#if defined(HOTPLUG_FIRMWARE)
4118
		if ((request_firmware(&firmware, oct064_firmware, &wc->dev->dev) != 0) ||
4119
		    !firmware) {
4120
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4121
				"available from userspace\n", oct064_firmware);
4122
			return;
4123
		}
4124
#else
4125
		embedded_firmware.data = _binary_dahdi_fw_oct6114_064_bin_start;
4126
		/* Yes... this is weird. objcopy gives us a symbol containing
4127
		   the size of the firmware, not a pointer a variable containing
4128
		   the size. The only way we can get the value of the symbol
4129
		   is to take its address, so we define it as a pointer and
4130
		   then cast that value to the proper type.
4131
	      */
4132
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_064_bin_size;
4133
#endif
4134
		break;
4135
	case 128:
4136
#if defined(HOTPLUG_FIRMWARE)
4137
		if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
4138
		    !firmware) {
4139
			dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
4140
				"available from userspace\n", oct128_firmware);
4141
			return;
4142
		}
4143
#else
4144
		embedded_firmware.data = _binary_dahdi_fw_oct6114_128_bin_start;
4145
		/* Yes... this is weird. objcopy gives us a symbol containing
4146
		   the size of the firmware, not a pointer a variable containing
4147
		   the size. The only way we can get the value of the symbol
4148
		   is to take its address, so we define it as a pointer and
4149
		   then cast that value to the proper type.
4150
		*/
4151
		embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_128_bin_size;
4152
#endif
4153
		break;
4154
	default:
4155
		dev_notice(&wc->dev->dev, "Unsupported channel capacity found "
4156
				"on VPM module (%d).\n", vpm_capacity);
4157
		return;
4158
	}
4159
4160
	if (!(wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) {
4161
		dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
4162
		if (firmware != &embedded_firmware)
4163
			release_firmware(firmware);
4164
		return;
4165
	}
4166
4167
	if (firmware != &embedded_firmware)
4168
		release_firmware(firmware);
4169
4170
	if (vpmdtmfsupport == -1) {
4171
		dev_notice(&wc->dev->dev, "VPM450: hardware DTMF disabled.\n");
4172
		vpmdtmfsupport = 0;
4173
	}
4174
4175
	wc->vpm = T4_VPM_PRESENT;
4176
	dev_info(&wc->dev->dev, "VPM450: Present and operational servicing %d "
4177
			"span(s)\n", wc->numspans);
4178
		
4179
}
4180
4181
static void t4_vpm400_init(struct t4 *wc)
4182
{
4183
	unsigned char reg;
4184
	unsigned int mask;
4185
	unsigned int ver;
4186
	unsigned int i, x, y, gen2vpm=0;
4187
4188
	if (!vpmsupport) {
4189
		dev_info(&wc->dev->dev, "VPM400: Support Disabled\n");
4190
		return;
4191
	}
4192
4193
	switch(vpmspans) {
4194
	case 4:
4195
	case 2:
4196
	case 1:
4197
		break;
4198
	default:
4199
		dev_notice(&wc->dev->dev, "VPM400: %d is not a valid vpmspans "
4200
				"value, using 4\n", vpmspans);
4201
		vpmspans = 1;
4202
	}
4203
4204
	for (x=0;x<8;x++) {
4205
		int spanno = t4_vpm_spanno(x);
4206
		struct t4_span *ts = wc->tspans[spanno];
4207
		int echotail = t4_vpm_echotail();
4208
4209
		ver = t4_vpm_in(wc, x, 0x1a0); /* revision */
4210
		if ((ver != 0x26) && (ver != 0x33)) {
4211
			if (x)
4212
				dev_notice(&wc->dev->dev,
4213
					"VPM400: Inoperable\n");
4214
			return;
4215
		}
4216
		if (ver == 0x33) {
4217
			if (x && !gen2vpm) {
4218
				dev_notice(&wc->dev->dev,
4219
					"VPM400: Inconsistent\n");
4220
				return;
4221
			}
4222
			ts->spanflags |= FLAG_VPM2GEN;
4223
			gen2vpm++;
4224
		} else if (gen2vpm) {
4225
			dev_notice(&wc->dev->dev,
4226
				"VPM400: Inconsistent\n");
4227
			return;
4228
		}
4229
4230
4231
		/* Setup GPIO's */
4232
		for (y=0;y<4;y++) {
4233
			t4_vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
4234
			t4_vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
4235
			t4_vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
4236
		}
4237
4238
		/* Setup TDM path - sets fsync and tdm_clk as inputs */
4239
		reg = t4_vpm_in(wc, x, 0x1a3); /* misc_con */
4240
		t4_vpm_out(wc, x, 0x1a3, reg & ~2);
4241
4242
		/* Setup timeslots */
4243
		t4_vpm_out(wc, x, 0x02f, 0x20 | (spanno << 3)); 
4244
4245
		/* Setup Echo length (128 taps) */
4246
		t4_vpm_out(wc, x, 0x022, (echotail >> 8));
4247
		t4_vpm_out(wc, x, 0x023, (echotail & 0xff));
4248
		
4249
		/* Setup the tdm channel masks for all chips*/
4250
		mask = t4_vpm_mask(x);
4251
		for (i = 0; i < 4; i++)
4252
			t4_vpm_out(wc, x, 0x30 + i, (mask >> (i << 3)) & 0xff);
4253
4254
		/* Setup convergence rate */
4255
		reg = t4_vpm_in(wc,x,0x20);
4256
		reg &= 0xE0;
4257
		if (ts->spantype == TYPE_E1) {
4258
			if (x < vpmspans)
4259
				dev_info(&wc->dev->dev, "VPM400: Span %d "
4260
						"A-law mode\n", spanno);
4261
			reg |= 0x01;
4262
		} else {
4263
			if (x < vpmspans)
4264
				dev_info(&wc->dev->dev, "VPM400: Span %d "
4265
						"U-law mode\n", spanno);
4266
			reg &= ~0x01;
4267
		}
4268
		t4_vpm_out(wc,x,0x20,(reg | 0x20));
4269
		
4270
		/* Initialize echo cans */
4271
		for (i = 0 ; i < MAX_TDM_CHAN; i++) {
4272
			if (mask & (0x00000001 << i))
4273
				t4_vpm_out(wc,x,i,0x00);
4274
		}
4275
4276
		wait_a_little();
4277
4278
		/* Put in bypass mode */
4279
		for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
4280
			if (mask & (0x00000001 << i)) {
4281
				t4_vpm_out(wc,x,i,0x01);
4282
			}
4283
		}
4284
4285
		/* Enable bypass */
4286
		for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
4287
			if (mask & (0x00000001 << i))
4288
				t4_vpm_out(wc,x,0x78 + i,0x01);
4289
		}
4290
      
4291
		/* set DTMF detection threshold */
4292
		t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
4293
4294
		/* Enable DTMF detectors (always DTMF detect all spans) */
4295
		for (i = 0; i < MAX_DTMF_DET; i++) {
4296
			t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 0 : 1));
4297
		}
4298
		for (i = 0x34; i < 0x38; i++)
4299
			t4_vpm_out(wc, x, i, 0x00);
4300
		for (i = 0x3C; i < 0x40; i++)
4301
			t4_vpm_out(wc, x, i, 0x00);
4302
4303
		for (i = 0x48; i < 0x4B; i++)
4304
			t4_vpm_out(wc, x, i, 0x00);
4305
		for (i = 0x50; i < 0x53; i++)
4306
			t4_vpm_out(wc, x, i, 0x00);
4307
		for (i = 0xB8; i < 0xBE; i++)
4308
			t4_vpm_out(wc, x, i, 0xFF);
4309
		if (gen2vpm) {
4310
			for (i = 0xBE; i < 0xC0; i++)
4311
				t4_vpm_out(wc, x, i, 0xFF);
4312
		} else {
4313
			for (i = 0xBE; i < 0xC0; i++)
4314
				t4_vpm_out(wc, x, i, 0x00);
4315
		}
4316
		for (i = 0xC0; i < 0xC4; i++)
4317
			t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA);
4318
4319
	} 
4320
	if (vpmdtmfsupport == -1) {
4321
		dev_info(&wc->dev->dev, "VPM400: hardware DTMF enabled.\n");
4322
		vpmdtmfsupport = 0;
4323
	}
4324
	dev_info(&wc->dev->dev, "VPM400%s: Present and operational servicing "
4325
		"%d span(s)\n", (gen2vpm ? " (2nd Gen)" : ""), wc->numspans);
4326
	wc->vpm = T4_VPM_PRESENT;
4327
}
4328
4329
#endif
4330
4331
static void t4_tsi_reset(struct t4 *wc) 
4332
{
4333
	int x;
4334
	for (x=0;x<128;x++) {
4335
		wc->dmactrl &= ~0x00007fff;
4336
		wc->dmactrl |= (0x00004000 | (x << 7));
4337
		t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4338
	}
4339
	wc->dmactrl &= ~0x00007fff;
4340
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4341
}
4342
4343
/* Note that channels here start from 1 */
4344
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan)
4345
{
4346
	unsigned long flags;
4347
	int fromts, tots;
4348
4349
	fromts = (fromspan << 5) |(fromchan);
4350
	tots = (tospan << 5) | (tochan);
4351
4352
	if (!wc->t1e1) {
4353
		fromts += 4;
4354
		tots += 4;
4355
	}
4356
	spin_lock_irqsave(&wc->reglock, flags);
4357
	wc->dmactrl &= ~0x00007fff;
4358
	wc->dmactrl |= (0x00004000 | (tots << 7) | (fromts));
4359
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4360
	wc->dmactrl &= ~0x00007fff;
4361
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4362
	spin_unlock_irqrestore(&wc->reglock, flags);
4363
}
4364
4365
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan)
4366
{
4367
	unsigned long flags;
4368
	int tots;
4369
4370
	tots = (tospan << 5) | (tochan);
4371
4372
	if (!wc->t1e1) 
4373
		tots += 4;
4374
	spin_lock_irqsave(&wc->reglock, flags);
4375
	wc->dmactrl &= ~0x00007fff;
4376
	wc->dmactrl |= (0x00004000 | (tots << 7));
4377
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4378
	if (debug & DEBUG_TSI)
4379
		dev_notice(&wc->dev->dev, "Sending '%08x\n", wc->dmactrl);
4380
	wc->dmactrl &= ~0x00007fff;
4381
	__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4382
	spin_unlock_irqrestore(&wc->reglock, flags);
4383
}
4384
#ifdef CONFIG_EXTENDED_RESET
4385
static void t4_extended_reset(struct t4 *wc)
4386
{
4387
	unsigned int oldreg = t4_pci_in(wc, 0x4);
4388
4389
	udelay(1000);
4390
4391
	t4_pci_out(wc, 0x4, 0x42000000);
4392
	t4_pci_out(wc, 0xa, 0x42000000);
4393
	t4_pci_out(wc, 0xa, 0x00080000);
4394
	t4_pci_out(wc, 0xa, 0x00080000);
4395
	t4_pci_out(wc, 0xa, 0x00080000);
4396
	t4_pci_out(wc, 0xa, 0x00180000);
4397
	t4_pci_out(wc, 0xa, 0x00080000);
4398
	t4_pci_out(wc, 0xa, 0x00180000);
4399
	t4_pci_out(wc, 0xa, 0x00080000);
4400
	t4_pci_out(wc, 0xa, 0x00180000);
4401
	t4_pci_out(wc, 0xa, 0x00080000);
4402
	t4_pci_out(wc, 0xa, 0x00180000);
4403
	t4_pci_out(wc, 0xa, 0x00080000);
4404
	t4_pci_out(wc, 0xa, 0x00180000);
4405
	t4_pci_out(wc, 0xa, 0x00080000);
4406
	t4_pci_out(wc, 0xa, 0x00180000);
4407
	t4_pci_out(wc, 0x4, oldreg);
4408
4409
	udelay(1000);
4410
}
4411
#endif
4412
4413
static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
4414
{
4415
	unsigned int version;
4416
4417
	version = t4_pci_in(wc, WC_VERSION);
4418
	dev_info(&wc->dev->dev, "Firmware Version: %08x\n", version);
4419
	dev_info(&wc->dev->dev, "Burst Mode: %s\n",
4420
		(!(cardflags & FLAG_BURST) && noburst) ? "Off" : "On");
4421
#ifdef ENABLE_WORKQUEUES
4422
	dev_info(&wc->dev->dev, "Work Queues: Enabled\n");
4423
#endif
4424
4425
#ifdef CONFIG_EXTENDED_RESET
4426
	t4_extended_reset(wc);
4427
#endif
4428
4429
	/* Make sure DMA engine is not running and interrupts are acknowledged */
4430
	wc->dmactrl = 0x0;
4431
	t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
4432
	/* Reset Framer and friends */
4433
	t4_pci_out(wc, WC_LEDS, 0x00000000);
4434
4435
	/* Set DMA addresses */
4436
	t4_pci_out(wc, WC_RDADDR, wc->readdma);
4437
	t4_pci_out(wc, WC_WRADDR, wc->writedma);
4438
4439
	/* Setup counters, interrupt flags (ignored in Gen2) */
4440
	if (cardflags & FLAG_2NDGEN) {
4441
		t4_tsi_reset(wc);
4442
	} else {
4443
		t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
4444
	}
4445
	
4446
	/* Reset pending interrupts */
4447
	t4_pci_out(wc, WC_INTR, 0x00000000);
4448
4449
	/* Read T1/E1 status */
4450
	if (t1e1override > -1)
4451
		wc->t1e1 = t1e1override;
4452
	else
4453
		wc->t1e1 = ((t4_pci_in(wc, WC_LEDS)) & 0x0f00) >> 8;
4454
	wc->order = ((t4_pci_in(wc, WC_LEDS)) & 0xf0000000) >> 28;
4455
	order_index[wc->order]++;
4456
	return 0;
4457
}
4458
4459
static int t4_hardware_init_2(struct t4 *wc)
4460
{
4461
	int x;
4462
	unsigned int regval;
4463
4464
	if (t4_pci_in(wc, WC_VERSION) >= 0xc01a0165) {
4465
		wc->tspans[0]->spanflags |= FLAG_OCTOPT;
4466
		dev_info(&wc->dev->dev, "Octasic Optimizations: Enabled\n");
4467
	}
4468
	/* Setup LEDS, take out of reset */
4469
	t4_pci_out(wc, WC_LEDS, 0x000000ff);
4470
	t4_activate(wc);
4471
4472
	/* 
4473
	 * In order to find out the QFALC framer version, we have to temporarily term off compat
4474
	 * mode and take a peak at VSTR.  We turn compat back on when we are done.
4475
	 */
4476
	if (t4_framer_in(wc, 0, 0x4a) != 0x05)
4477
		dev_info(&wc->dev->dev, "WARNING: FALC framer not intialized "
4478
				"in compatibility mode.\n");
4479
	regval = t4_framer_in(wc, 0 ,0xd6);
4480
	regval |= (1 << 5); /* set COMP_DIS*/
4481
	t4_framer_out(wc, 0, 0xd6, regval);
4482
	regval = t4_framer_in(wc, 0, 0x4a);
4483
	if (regval == 0x05)
4484
		dev_info(&wc->dev->dev, "FALC Framer Version: 2.1 or "
4485
				"earlier\n");
4486
	else if (regval == 0x20) {
4487
		dev_info(&wc->dev->dev, "FALC Framer Version: 3.1\n");
4488
		wc->falc31 = 1;
4489
	} else
4490
		dev_info(&wc->dev->dev, "FALC Framer Version: Unknown "
4491
				"(VSTR = 0x%02x)\n", regval);
4492
	regval = t4_framer_in(wc, 0 ,0xd6);
4493
	regval &= ~(1 << 5); /* clear COMP_DIS*/
4494
	t4_framer_out(wc, 0, 0xd6, regval);
4495
	
4496
	t4_framer_out(wc, 0, 0x4a, 0xaa);
4497
	dev_info(&wc->dev->dev, "Board ID: %02x\n", wc->order);
4498
4499
	for (x=0;x< 11;x++)
4500
		dev_info(&wc->dev->dev, "Reg %d: 0x%08x\n", x,
4501
				t4_pci_in(wc, x));
4502
	return 0;
4503
}
4504
4505
static int __devinit t4_launch(struct t4 *wc)
4506
{
4507
	int x;
4508
	unsigned long flags;
4509
	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &wc->tspans[0]->span.flags))
4510
		return 0;
4511
	dev_info(&wc->dev->dev, "opvxd115: Launching card: %d\n",
4512
			wc->order);
4513
4514
	/* Setup serial parameters and system interface */
4515
	for (x=0;x<PORTS_PER_FRAMER;x++)
4516
		t4_serial_setup(wc, x);
4517
4518
	for (x = 0; x < wc->numspans; ++x) {
4519
		list_add_tail(&wc->tspans[x]->span.device_node,
4520
			      &wc->ddev->spans);
4521
	}
4522
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
4523
		dev_err(&wc->dev->dev, "Unable to register span %s\n",
4524
				wc->tspans[0]->span.name);
4525
		return -1;
4526
	}
4527
	set_bit(T4_CHECK_TIMING, &wc->checkflag);
4528
	spin_lock_irqsave(&wc->reglock, flags);
4529
	__t4_set_sclk_src(wc, WC_SELF, 0, 0);
4530
	spin_unlock_irqrestore(&wc->reglock, flags);
4531
	tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
4532
	return 0;
4533
}
4534
4535
static void free_wc(struct t4 *wc)
4536
{
4537
	unsigned int x, y;
4538
4539
	for (x = 0; x < sizeof(wc->tspans)/sizeof(wc->tspans[0]); x++) {
4540
		if (!wc->tspans[x]) {
4541
			continue;
4542
		}
4543
4544
		for (y = 0; y < sizeof(wc->tspans[x]->chans)/sizeof(wc->tspans[x]->chans[0]); y++) {
4545
			if (wc->tspans[x]->chans[y]) {
4546
				kfree(wc->tspans[x]->chans[y]);
4547
			}
4548
			if (wc->tspans[x]->ec[y])
4549
				kfree(wc->tspans[x]->ec[y]);
4550
		}
4551
		kfree(wc->tspans[x]);
4552
	}
4553
	kfree(wc);
4554
}
4555
4556
static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
4557
{
4558
	struct t4 *wc;
4559
	struct devtype *dt;
4560
	unsigned int x, f;
4561
	int init_latency;
4562
	
4563
	if (pci_enable_device(pdev)) {
4564
		return -EIO;
4565
	}
4566
4567
	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
4568
		return -ENOMEM;
4569
	}
4570
4571
	memset(wc, 0x0, sizeof(*wc));
4572
	spin_lock_init(&wc->reglock);
4573
	dt = (struct devtype *) (ent->driver_data);
4574
4575
	wc->flags = dt->flags;
4576
4577
	wc->numspans = 1;
4578
	
4579
	wc->variety = dt->desc;
4580
	
4581
	wc->memaddr = pci_resource_start(pdev, 0);
4582
	wc->memlen = pci_resource_len(pdev, 0);
4583
	wc->membase = ioremap(wc->memaddr, wc->memlen);
4584
	/* This rids of the Double missed interrupt message after loading */
4585
	wc->last0 = 1;
4586
#if 0
4587
	if (!request_mem_region(wc->memaddr, wc->memlen, wc->variety))
4588
		dev_info(&wc->dev->dev, "opvxd115: Unable to request memory "
4589
				"region :(, using anyway...\n");
4590
#endif
4591
	if (pci_request_regions(pdev, wc->variety))
4592
		dev_info(&pdev->dev, "opvxd115: Unable to request regions\n");
4593
	
4594
	dev_info(&pdev->dev, "Found opvxd115 at base address %08lx, remapped "
4595
			"to %p\n", wc->memaddr, wc->membase);
4596
	
4597
	wc->dev = pdev;
4598
	
4599
	/* Enable bus mastering */
4600
	pci_set_master(pdev);
4601
4602
	/* Keep track of which device we are */
4603
	pci_set_drvdata(pdev, wc);
4604
4605
	if (wc->flags & FLAG_5THGEN) {
4606
		if ((ms_per_irq > 1) && (latency <= ((ms_per_irq) << 1))) {
4607
			init_latency = ms_per_irq << 1;
4608
		} else {
4609
			if (latency > 2)
4610
				init_latency = latency;
4611
			else
4612
				init_latency = 2;
4613
		}
4614
		dev_info(&wc->dev->dev, "5th gen card with initial latency of "
4615
			"%d and %d ms per IRQ\n", init_latency, ms_per_irq);
4616
	} else {
4617
		if (wc->flags & FLAG_2NDGEN)
4618
			init_latency = 1;
4619
		else
4620
			init_latency = 2;
4621
	}
4622
4623
	if (max_latency < init_latency) {
4624
		printk(KERN_INFO "maxlatency must be set to something greater than %d ms, increasing it to %d\n", init_latency, init_latency);
4625
		max_latency = init_latency;
4626
	}
4627
	
4628
	if (t4_allocate_buffers(wc, init_latency, NULL, NULL)) {
4629
		return -ENOMEM;
4630
	}
4631
4632
	/* Initialize hardware */
4633
	t4_hardware_init_1(wc, wc->flags);
4634
	
4635
	for(x = 0; x < MAX_T4_CARDS; x++) {
4636
		if (!cards[x])
4637
			break;
4638
	}
4639
	
4640
	if (x >= MAX_T4_CARDS) {
4641
		dev_notice(&wc->dev->dev, "No cards[] slot available!!\n");
4642
		kfree(wc);
4643
		return -ENOMEM;
4644
	}
4645
	
4646
	wc->num = x;
4647
	cards[x] = wc;
4648
	
4649
#ifdef ENABLE_WORKQUEUES
4650
	if (wc->flags & FLAG_2NDGEN) {
4651
		char tmp[20];
4652
4653
		sprintf(tmp, "opvxd115");
4654
		wc->workq = create_workqueue(tmp);
4655
	}
4656
#endif			
4657
4658
	/* Allocate pieces we need here */
4659
	for (x = 0; x < PORTS_PER_FRAMER; x++) {
4660
		if (!(wc->tspans[x] = kmalloc(sizeof(*wc->tspans[x]), GFP_KERNEL))) {
4661
			free_wc(wc);
4662
			return -ENOMEM;
4663
		}
4664
4665
		memset(wc->tspans[x], 0, sizeof(*wc->tspans[x]));
4666
4667
		if (wc->t1e1 & (1 << x)) {
4668
			wc->tspans[x]->spantype = TYPE_E1;
4669
		} else {
4670
			if (j1mode)
4671
				wc->tspans[x]->spantype = TYPE_J1;
4672
			else
4673
				wc->tspans[x]->spantype = TYPE_T1;
4674
		}
4675
4676
		for (f = 0; f < (wc->tspans[x]->spantype == TYPE_E1 ? 31 : 24); f++) {
4677
			if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
4678
				free_wc(wc);
4679
				return -ENOMEM;
4680
			}
4681
			memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
4682
			if (!(wc->tspans[x]->ec[f] = kmalloc(sizeof(*wc->tspans[x]->ec[f]), GFP_KERNEL))) {
4683
				free_wc(wc);
4684
				return -ENOMEM;
4685
			}
4686
			memset(wc->tspans[x]->ec[f], 0, sizeof(*wc->tspans[x]->ec[f]));
4687
		}
4688
4689
#ifdef ENABLE_WORKQUEUES
4690
		INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
4691
#endif				
4692
		wc->tspans[x]->spanflags |= wc->flags;
4693
	}
4694
	
4695
	/* Continue hardware intiialization */
4696
	t4_hardware_init_2(wc);
4697
	
4698
#ifdef SUPPORT_GEN1
4699
	if (request_irq(pdev->irq, (wc->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, DAHDI_IRQ_SHARED_DISABLED, "opvxd115", wc)) 
4700
#else
4701
		if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
4702
			dev_notice(&wc->dev->dev, "This driver does not "
4703
					"support 1st gen modules\n");
4704
			free_wc(wc);
4705
			return -ENODEV;
4706
		}	
4707
			if (request_irq(pdev->irq, t4_interrupt_gen2, DAHDI_IRQ_SHARED_DISABLED, "opvxd115", wc)) 
4708
#endif
4709
	{
4710
		dev_notice(&wc->dev->dev, "opvxd115: Unable to request IRQ %d\n",
4711
				pdev->irq);
4712
		free_wc(wc);
4713
		return -EIO;
4714
	}
4715
	
4716
	init_spans(wc);
4717
	/* get the current number of probed cards and run a slice of a tail
4718
	 * insertion sort */
4719
	for (x = 0; x < MAX_T4_CARDS; x++) {
4720
		if (!cards[x+1])
4721
			break;
4722
	}
4723
	for ( ; x > 0; x--) {
4724
		if (cards[x]->order < cards[x-1]->order) {
4725
			struct t4 *tmp = cards[x];
4726
			cards[x] = cards[x-1];
4727
			cards[x-1] = tmp;
4728
		} else {
4729
			/* if we're not moving it, we won't move any more
4730
			 * since all cards are sorted on addition */
4731
			break;
4732
		}
4733
	}
4734
	
4735
	dev_info(&wc->dev->dev, "Found an OpenVox Card: %s\n", wc->variety);
4736
	wc->gpio = 0x00000000;
4737
	t4_pci_out(wc, WC_GPIO, wc->gpio);
4738
	t4_gpio_setdir(wc, (1 << 17), (1 << 17));
4739
	t4_gpio_setdir(wc, (0xff), (0xff));
4740
4741
	create_sysfs_files(wc);
4742
	
4743
#if 0
4744
	for (x=0;x<0x10000;x++) {
4745
		__t4_raw_oct_out(wc, 0x0004, x);
4746
		__t4_raw_oct_out(wc, 0x000a, x ^ 0xffff);
4747
		if (__t4_raw_oct_in(wc, 0x0004) != x) 
4748
			dev_notice(&wc->dev->dev, "Register 4 failed %04x\n",
4749
					x);
4750
		if (__t4_raw_oct_in(wc, 0x000a) != (x ^ 0xffff))
4751
			dev_notice(&wc->dev->dev, "Register 10 failed %04x\n",
4752
					x);
4753
	}
4754
#endif
4755
4756
	return 0;
4757
}
4758
4759
static int t4_hardware_stop(struct t4 *wc)
4760
{
4761
4762
	/* Turn off DMA, leave interrupts enabled */
4763
	set_bit(T4_STOP_DMA, &wc->checkflag);
4764
4765
	/* Wait for interrupts to stop */
4766
	msleep(25);
4767
4768
	/* Turn off counter, address, etc */
4769
	if (wc->tspans[0]->spanflags & FLAG_2NDGEN) {
4770
		t4_tsi_reset(wc);
4771
	} else {
4772
		t4_pci_out(wc, WC_COUNT, 0x000000);
4773
	}
4774
	t4_pci_out(wc, WC_RDADDR, 0x0000000);
4775
	t4_pci_out(wc, WC_WRADDR, 0x0000000);
4776
	wc->gpio = 0x00000000;
4777
	t4_pci_out(wc, WC_GPIO, wc->gpio);
4778
	t4_pci_out(wc, WC_LEDS, 0x00000000);
4779
4780
	dev_notice(&wc->dev->dev, "\nStopped opvxd115, Turned off DMA\n");
4781
	return 0;
4782
}
4783
4784
static void __devexit t4_remove_one(struct pci_dev *pdev)
4785
{
4786
	struct t4 *wc = pci_get_drvdata(pdev);
4787
	int basesize;
4788
4789
	if (!wc) {
4790
		return;
4791
	}
4792
4793
	remove_sysfs_files(wc);
4794
4795
	/* Stop hardware */
4796
	t4_hardware_stop(wc);
4797
	
4798
	/* Release vpm450m */
4799
	if (wc->vpm450m)
4800
		release_vpm450m(wc->vpm450m);
4801
	wc->vpm450m = NULL;
4802
	/* Unregister spans */
4803
4804
	basesize = DAHDI_MAX_CHUNKSIZE * 32 * 4;
4805
	if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN))
4806
		basesize = basesize * 2;
4807
4808
	dahdi_unregister_device(wc->ddev);
4809
	kfree(wc->ddev->location);
4810
	kfree(wc->ddev->devicetype);
4811
	dahdi_free_device(wc->ddev);
4812
#ifdef ENABLE_WORKQUEUES
4813
	if (wc->workq) {
4814
		flush_workqueue(wc->workq);
4815
		destroy_workqueue(wc->workq);
4816
	}
4817
#endif			
4818
	
4819
	free_irq(pdev->irq, wc);
4820
	
4821
	if (wc->membase)
4822
		iounmap(wc->membase);
4823
	
4824
	pci_release_regions(pdev);		
4825
	
4826
	/* Immediately free resources */
4827
	pci_free_consistent(pdev, T4_BASE_SIZE * wc->numbufs * 2, (void *)wc->writechunk, wc->writedma);
4828
	
4829
	order_index[wc->order]--;
4830
	
4831
	cards[wc->num] = NULL;
4832
	pci_set_drvdata(pdev, NULL);
4833
	free_wc(wc);
4834
}
4835
4836
4837
static struct pci_device_id t4_pci_tbl[] __devinitdata =
4838
{
4839
	{ 0x1b74, 0x0115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd115 }, /* OpenVox D115P/D115E */
4840
	{ 0x1b74, 0xd130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd130 }, /* OpenVox D130P/D130E */
4841
	{ 0, }
4842
};
4843
4844
static struct pci_driver t4_driver = {
4845
	.name = "opvxd115",
4846
	.probe = t4_init_one,
4847
	.remove = __devexit_p(t4_remove_one),
4848
	.id_table = t4_pci_tbl,
4849
};
4850
4851
static int __init t4_init(void)
4852
{
4853
	int res;
4854
	res = dahdi_pci_module(&t4_driver);
4855
	if (res)
4856
		return -ENODEV;
4857
	/* initialize cards since we have all of them */
4858
	/* warn for missing zero and duplicate numbers */
4859
	if (cards[0] && cards[0]->order != 0) {
4860
		printk(KERN_NOTICE "opvxd115: Ident of first card is not zero (%d)\n",
4861
			cards[0]->order);
4862
	}
4863
	for (res = 0; cards[res]; res++) {
4864
		/* warn the user of duplicate ident values it is probably
4865
		 * unintended */
4866
		if (debug && res < 15 && cards[res+1] &&
4867
		    cards[res]->order == cards[res+1]->order) {
4868
			printk(KERN_NOTICE "opvxd115: Duplicate ident value found (%d)\n",
4869
				cards[res]->order);
4870
		}
4871
		t4_launch(cards[res]);
4872
	}
4873
	return 0;
4874
}
4875
4876
static void __exit t4_cleanup(void)
4877
{
4878
	pci_unregister_driver(&t4_driver);
4879
}
4880
4881
4882
MODULE_AUTHOR("mark.liu <mark.liu@openvox.cn>");
4883
MODULE_DESCRIPTION("Unified OpenVox Single T1/E1/J1 Card Driver");
4884
MODULE_ALIAS("opvxd115");
4885
MODULE_LICENSE("GPL v2");
4886
4887
module_param(pedanticpci, int, 0600);
4888
module_param(debug, int, 0600);
4889
module_param(noburst, int, 0600);
4890
module_param(timingcable, int, 0600);
4891
module_param(t1e1override, int, 0600);
4892
module_param(alarmdebounce, int, 0600);
4893
module_param(losalarmdebounce, int, 0600);
4894
module_param(aisalarmdebounce, int, 0600);
4895
module_param(yelalarmdebounce, int, 0600);
4896
module_param(max_latency, int, 0600);
4897
module_param(j1mode, int, 0600);
4898
module_param(sigmode, int, 0600);
4899
module_param(latency, int, 0600);
4900
module_param(ms_per_irq, int, 0600);
4901
#ifdef VPM_SUPPORT
4902
module_param(vpmsupport, int, 0600);
4903
module_param(vpmdtmfsupport, int, 0600);
4904
module_param(vpmspans, int, 0600);
4905
module_param(dtmfthreshold, int, 0600);
4906
#endif
4907
4908
MODULE_DEVICE_TABLE(pci, t4_pci_tbl);
4909
4910
module_init(t4_init);
4911
module_exit(t4_cleanup);
(-)dahdi-linux-2.6.1.ORIG/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 $(shell $(src)/../oct612x/octasic-helper objects ../oct612x)
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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/drivers/dahdi/wcopenpci.c (+1868 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
56
57
58
/* Compatibility helpers */
59
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
60
 #include <linux/interrupt.h>
61
#else
62
 typedef void irqreturn_t;
63
 #define IRQ_NONE
64
 #define IRQ_HANDLED
65
 #define IRQ_RETVAL(x)
66
 #define __devexit_p(x) x
67
#endif
68
69
// Centos4.3 uses a modified 2.6.9 kernel, with no indication that
70
// it is different from the mainstream (or even Centos4.2 2.6.9)
71
// kernel, so we must crowbar off the dunce-hat manually here.
72
#if !defined CENTOS4_3 && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
73
 typedef int gfp_t;
74
 static inline void *kzalloc( size_t n, gfp_t flags ){
75
	void *p = kmalloc(n,flags);
76
	if (p) memset(p, 0, n);
77
	return p;
78
 }
79
#endif
80
81
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
82
 #define DEFINE_MUTEX(x)		DECLARE_MUTEX(x)
83
 #define mutex_init(x)			init_MUTEX(x)
84
 #define mutex_lock(x)			down(x)
85
 #define mutex_lock_interruptible(x)	down_interruptible(x)
86
 #define mutex_trylock(x)		down_trylock(x)
87
 #define mutex_unlock(x)		up(x)
88
#else
89
 #include <linux/mutex.h>
90
#endif
91
92
93
static struct fxo_mode {
94
	char *name;
95
	int ohs;
96
	int ohs2;
97
	int rz;
98
	int rt;
99
	int ilim;
100
	int dcv;
101
	int mini;
102
	int acim;
103
	int ring_osc;
104
	int ring_x;
105
} fxo_modes[] =
106
{
107
	{ "FCC", 0, 0, 0, 1, 0, 0x3, 0, 0, }, 	/* US, Canada */
108
	{ "TBR21", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0x7e6c, 0x023a, },
109
		/* Austria, Belgium, Denmark, Finland, France, Germany, 
110
		   Greece, Iceland, Ireland, Italy, Luxembourg, Netherlands,
111
		   Norway, Portugal, Spain, Sweden, Switzerland, and UK */
112
	{ "ARGENTINA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
113
	{ "AUSTRALIA", 1, 0, 0, 0, 0, 0, 0x3, 0x3, },
114
	{ "AUSTRIA", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
115
	{ "BAHRAIN", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
116
	{ "BELGIUM", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
117
	{ "BRAZIL", 0, 0, 0, 0, 0, 0, 0x3, 0, },
118
	{ "BULGARIA", 0, 0, 0, 0, 1, 0x3, 0x0, 0x3, },
119
	{ "CANADA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
120
	{ "CHILE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
121
	{ "CHINA", 0, 0, 0, 0, 0, 0, 0x3, 0xf, },
122
	{ "COLUMBIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
123
	{ "CROATIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
124
	{ "CYRPUS", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
125
	{ "CZECH", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
126
	{ "DENMARK", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
127
	{ "ECUADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
128
	{ "EGYPT", 0, 0, 0, 0, 0, 0, 0x3, 0, },
129
	{ "ELSALVADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
130
	{ "FINLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
131
	{ "FRANCE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
132
	{ "GERMANY", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
133
	{ "GREECE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
134
	{ "GUAM", 0, 0, 0, 0, 0, 0x3, 0, 0, },
135
	{ "HONGKONG", 0, 0, 0, 0, 0, 0x3, 0, 0, },
136
	{ "HUNGARY", 0, 0, 0, 0, 0, 0x3, 0, 0, },
137
	{ "ICELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
138
	{ "INDIA", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
139
	{ "INDONESIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
140
	{ "IRELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
141
	{ "ISRAEL", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
142
	{ "ITALY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
143
	{ "JAPAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
144
	{ "JORDAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
145
	{ "KAZAKHSTAN", 0, 0, 0, 0, 0, 0x3, 0, },
146
	{ "KUWAIT", 0, 0, 0, 0, 0, 0x3, 0, 0, },
147
	{ "LATVIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
148
	{ "LEBANON", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
149
	{ "LUXEMBOURG", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
150
	{ "MACAO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
151
	{ "MALAYSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },	/* Current loop >= 20ma */
152
	{ "MALTA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
153
	{ "MEXICO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
154
	{ "MOROCCO", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
155
	{ "NETHERLANDS", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
156
	{ "NEWZEALAND", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
157
	{ "NIGERIA", 0, 0, 0, 0, 0x1, 0x3, 0, 0x2, },
158
	{ "NORWAY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
159
	{ "OMAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
160
	{ "PAKISTAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
161
	{ "PERU", 0, 0, 0, 0, 0, 0x3, 0, 0, },
162
	{ "PHILIPPINES", 0, 0, 0, 0, 0, 0, 0x3, 0, },
163
	{ "POLAND", 0, 0, 1, 1, 0, 0x3, 0, 0, },
164
	{ "PORTUGAL", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
165
	{ "ROMANIA", 0, 0, 0, 0, 0, 3, 0, 0, },
166
	{ "RUSSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
167
	{ "SAUDIARABIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
168
	{ "SINGAPORE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
169
	{ "SLOVAKIA", 0, 0, 0, 0, 0, 0x3, 0, 0x3, },
170
	{ "SLOVENIA", 0, 0, 0, 0, 0, 0x3, 0, 0x2, },
171
	{ "SOUTHAFRICA", 1, 0, 1, 0, 0, 0x3, 0, 0x3, },
172
	{ "SOUTHKOREA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
173
	{ "SPAIN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
174
	{ "SWEDEN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
175
	{ "SWITZERLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
176
	{ "SYRIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
177
	{ "TAIWAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
178
	{ "THAILAND", 0, 0, 0, 0, 0, 0, 0x3, 0, },
179
	{ "UAE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
180
	{ "UK", 0, 1, 0, 0, 1, 0x3, 0, 0x5, },
181
	{ "USA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
182
	{ "YEMEN", 0, 0, 0, 0, 0, 0x3, 0, 0, },
183
};
184
185
static struct ps_country_reg {
186
	const char *country;
187
	unsigned short value;
188
} ps_country_regs[] = {
189
	{"ARGENTINA",  0x8},
190
	{"AUSTRALIA",  0xD},
191
	{"AUSTRIA",    0xD},
192
	{"BAHRAIN",    0xC},
193
	{"BELGIUM",    0xC},
194
	{"BRAZIL",     0x8},
195
	{"BULGARIA",   0xD},
196
	{"CANADA",     0x8},
197
	{"CHILE",      0x8},
198
	{"CHINA",      0xC},
199
	{"COLOMBIA",   0x8},
200
	{"CROATIA",    0xC},
201
	{"CYPRUS",     0xC},
202
	{"CZECH",      0xC},
203
	{"DENMARK",    0xC},
204
	{"ECUADOR",    0x8},
205
	{"EGYPT",      0x8},
206
	{"ELSALVADOR", 0x8},
207
	{"FINLAND",    0xC},
208
	{"FRANCE",     0xC},
209
	{"GERMANY",    0xD},
210
	{"GREECE",     0xC},
211
	{"GUAM",       0x8},
212
	{"HONGKONG",   0x8},
213
	{"HUNGARY",    0x8},
214
	{"ICELAND",    0xC},
215
	{"INDIA",      0xF},
216
	{"INDONESIA",  0x8},
217
	{"IRELAND",    0xC},
218
	{"ISRAEL",     0xC},
219
	{"ITALY",      0xC},
220
	{"JAPAN",      0x8},
221
	{"JORDAN",     0x8},
222
	{"KAZAKHSTAN", 0x8},
223
	{"KUWAIT",     0x8},
224
	{"LATVIA",     0xC},
225
	{"LEBANON",    0xC},
226
	{"LUXEMBOURG", 0xC},
227
	{"MACAO",      0x8},
228
	{"MALAYSIA",   0x8},
229
	{"MALTA",      0xC},
230
	{"MEXICO",     0x8},
231
	{"MOROCCO",    0xC},
232
	{"NETHERLANDS",0xC},
233
	{"NEWZEALAND", 0xF},
234
	{"NIGERIA",    0xC},
235
	{"NORWAY",     0xC},
236
	{"OMAN",       0x8},
237
	{"PAKISTAN",   0x8},
238
	{"PERU",       0x8},
239
	{"PHILIPPINES",0x8},
240
	{"POLAND",     0x8},
241
	{"PORTUGAL",   0xC},
242
	{"ROMANIA",    0x8},
243
	{"RUSSIA",     0x8},
244
	{"SAUDIARABIA",0x8},
245
	{"SINGAPORE",  0x8},
246
	{"SLOVAKIA",   0xE},
247
	{"SLOVENIA",   0xE},
248
	{"SOUTHAFRICA",0xE},
249
	{"SOUTHKOREA", 0x8},
250
	{"SPAIN",      0xC},
251
	{"SWEDEN",     0xC},
252
	{"SWITZERLAND",0xC},
253
	{"SYRIA",      0x8},
254
	{"TAIWAN",     0x8},
255
	{"THAILAND",   0x8},
256
	{"UAE",        0x8},
257
	{"UK",         0xC},
258
	{"USA",        0x8},
259
	{"YEMEN",      0x8}
260
};
261
262
#define INOUT 2
263
264
/* Allocate enough memory for two zt chunks, receive and transmit.  Each sample uses
265
   32 bits.  Allocate an extra set just for control too */
266
#define VT_PCIDMA_BLOCKSIZE (DAHDI_MAX_CHUNKSIZE * INOUT * MAX_PORTS * 2 * 2)
267
#define VT_PCIDMA_MIDDLE    (DAHDI_MAX_CHUNKSIZE * MAX_PORTS - 4)
268
#define VT_PCIDMA_END       (DAHDI_MAX_CHUNKSIZE * MAX_PORTS * 2 - 4)
269
270
#define ID_DATA_MAXSIZE         30
271
272
#define NUM_CAL_REGS 12
273
#define NUM_FXO_REGS 60
274
275
#define TREG(addr)      (wc->ioaddr + addr)
276
277
#define TJ_CNTL         TREG(0x00)
278
#define TJ_OPER         TREG(0x01)
279
#define TJ_AUXC         TREG(0x02)
280
#define TJ_AUXD         TREG(0x03)
281
#define TJ_MASK0        TREG(0x04)
282
#define TJ_MASK1        TREG(0x05)
283
#define TJ_INTSTAT      TREG(0x06)
284
#define TJ_AUXR         TREG(0x07)
285
286
#define TJ_DMAWS        TREG(0x08)
287
#define TJ_DMAWI        TREG(0x0c)
288
#define TJ_DMAWE        TREG(0x10)
289
#define TJ_DMAWC        TREG(0x14)
290
#define TJ_DMARS        TREG(0x18)
291
#define TJ_DMARI        TREG(0x1c)
292
#define TJ_DMARE        TREG(0x20)
293
#define TJ_DMARC        TREG(0x24)
294
295
#define TJ_AUXINTPOL    TREG(0x2A)
296
297
#define TJ_AUXFUNC      TREG(0x2b)
298
#define TJ_SFDELAY      TREG(0x2c)
299
#define TJ_SERCTL       TREG(0x2d)
300
#define TJ_SFLC         TREG(0x2e)
301
#define TJ_FSCDELAY     TREG(0x2f)
302
303
#define TJ_REGBASE      TREG(0xc0)
304
305
#define PIB(addr)       (TJ_REGBASE + addr * 4)
306
307
#define HTXF_READY      (inb(PIB(0)) & 0x10)
308
#define HRXF_READY      (inb(PIB(0)) & 0x20)
309
310
311
#define VT_PORT_EMPTY	0
312
#define VT_PORT_VDAA	1   /* Voice DAA - FXO */
313
#define VT_PORT_PROSLIC	2   /* ProSLIC - FXS */
314
315
#define VBAT 0xC7
316
317
#define HKMODE_FWDACT   1
318
#define HKMODE_FWDONACT	2
319
#define HKMODE_RINGING	4
320
321
#define HOOK_ONHOOK     0
322
#define HOOK_OFFHOOK    1
323
324
#define	DSP_CODEC_RING		12	/* RING rising edge detected		*/
325
#define	DSP_CODEC_HKOFF		22	/* station port off hook                */
326
#define	DSP_CODEC_HKON		23	/* station port on hook                 */
327
#define	DSP_RING_OFF		24	/* RING falling edge detected		*/
328
#define DSP_DROP		25
329
330
#define	DSP_CODEC_FLASH		26	/* station port hook flash              */
331
332
#define DSP_LOOP_OFFHOOK	38	/* Loop Off hook from OpenPCI           */
333
#define DSP_LOOP_ONHOOK		39	/* Loop On hook from OpenPCI            */
334
#define DSP_LOOP_POLARITY	40	/* Loop Polarity from OpenPCI           */
335
#define DSP_LOOP_NOBATT		41
336
337
#define DSP_PROSLIC_SANITY	50	/* Sanity alert from a ProSLIC port 	*/
338
#define DSP_PROSLIC_PWR_ALARM	51	/* Power Alarm from a ProSLIC port 	*/
339
#define DSP_VDAA_ISO_FRAME_E	52	/* ISO-cap frame sync lost on VDAA port*/
340
341
#if VERBOSE_TIMING
342
 #define REPORT_WAIT(n,x)						    \
343
	 cardinfo(card->cardnum, #n " wait at %d, " #x " = %d", __LINE__, x )
344
#else
345
 #define REPORT_WAIT(n,x)
346
#endif
347
348
#define BUSY_WAIT(countvar,cond,delay,iter,failret)			    \
349
	countvar=0;							    \
350
	while(cond){							    \
351
	    udelay(delay);						    \
352
	    if(++countvar > iter){					    \
353
		cardcrit(wc->boardnum, "busy wait FAILED at %d", __LINE__); \
354
		return failret;						    \
355
	    }								    \
356
	}								    \
357
	REPORT_WAIT(busy,i)
358
359
#define LOCKED_WAIT(countvar,cond,delay,iter,failret)			    \
360
	countvar=0;							    \
361
	while(cond){							    \
362
	    udelay(delay);						    \
363
	    if(++countvar > iter){					    \
364
		dbginfo(wc->boardnum,"busy wait failed at %d",__LINE__);    \
365
		spin_unlock_irqrestore(&wc->lock, flags);		    \
366
		return failret;						    \
367
	    }								    \
368
	}								    \
369
	REPORT_WAIT(locked,i)
370
371
#define HTXF_WAIT()                 BUSY_WAIT(i,HTXF_READY,5,500,RET_FAIL)
372
#define HRXF_WAIT()                 BUSY_WAIT(i,!HRXF_READY,5,70000,RET_FAIL)
373
#define HTXF_WAIT_RET(failret)      BUSY_WAIT(i,HTXF_READY,5,500,failret)
374
#define HRXF_WAIT_RET(failret)      BUSY_WAIT(i,!HRXF_READY,5,1000,failret)
375
376
#define HTXF_WAIT_LOCKED()	    LOCKED_WAIT(i,HTXF_READY,5,500,RET_FAIL)
377
#define HRXF_WAIT_LOCKED()	    LOCKED_WAIT(i,!HRXF_READY,5,1000,RET_FAIL)
378
#define HTXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,HTXF_READY,5,500,failret)
379
#define HRXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,!HRXF_READY,5,1000,failret)
380
381
382
struct openpci {
383
	struct pci_dev *dev;
384
	char *variety;
385
	int boardnum;
386
	int portcount;
387
	int porttype[MAX_PORTS];
388
389
        int firmware;
390
        char serial[ID_DATA_MAXSIZE];
391
392
	spinlock_t lock;
393
394
	//XXX Replace these with proper try_module_get locking in the dahdi driver.
395
	//int usecount;	//XXX
396
	//int dead;	//XXX
397
	union {
398
		struct {
399
			int offhook;
400
		} fxo;
401
		struct {
402
			int ohttimer;
403
			int idletxhookstate;  /* IDLE changing hook state */
404
			int lasttxhook;
405
		} fxs;
406
	} mod[MAX_PORTS];
407
408
	unsigned long		ioaddr;
409
	dma_addr_t		readdma;
410
	dma_addr_t		writedma;
411
	volatile unsigned int  *writechunk;  /* Double-word aligned write memory */
412
	volatile unsigned int  *readchunk;   /* Double-word aligned read memory */
413
414
	struct dahdi_chan _chans[MAX_PORTS];
415
	struct dahdi_chan *chans[MAX_PORTS];
416
	struct dahdi_device *ddev;
417
	struct dahdi_span span;
418
} *cards[MAX_CARDS];
419
420
// You must hold this lock anytime you access or modify the cards[] array.
421
DEFINE_MUTEX(cards_mutex);
422
423
static unsigned char fxo_port_lookup[8] = { 0x0, 0x8, 0x4, 0xc, 0x10, 0x18, 0x14, 0x1c};
424
static unsigned char fxs_port_lookup[8] = { 0x0, 0x1, 0x2, 0x3, 0x10, 0x11, 0x12, 0x13};
425
static char wcopenpci[] = "Voicetronix OpenPCI";
426
427
static char *country = DEFAULT_COUNTRY;
428
static int reversepolarity;  // = 0
429
static int debug;            // = 0
430
431
module_param(country, charp, 0444);
432
module_param(debug, int, 0600);
433
module_param(reversepolarity, int, 0600);
434
MODULE_PARM_DESC(country, "Set the default country name");
435
MODULE_PARM_DESC(debug, "Enable verbose logging");
436
437
//#define DEBUG_LOOP_VOLTAGE 1
438
#ifdef DEBUG_LOOP_VOLTAGE
439
 // This param is a 32 bit bitfield where bit 1 << cardnum * 8 << portnum
440
 // will enable voltage monitoring on that port (fxo only presently)
441
 static int voltmeter;        // = 0
442
 module_param(voltmeter, int, 0600);
443
 MODULE_PARM_DESC(voltmeter, "Enable loop voltage metering");
444
#endif
445
446
447
/* boolean return values */
448
#define RET_OK   1
449
#define RET_FAIL 0
450
451
/* Convenience macros for logging */
452
#define info(format,...) printk(KERN_INFO NAME ": " format "\n" , ## __VA_ARGS__)
453
#define warn(format,...) printk(KERN_WARNING NAME ": " format "\n" , ## __VA_ARGS__)
454
#define crit(format,...) printk(KERN_CRIT NAME ": " format "\n" , ## __VA_ARGS__)
455
#define cardinfo(cardnum,format,...) info("[%02d] " format, cardnum , ## __VA_ARGS__)
456
#define cardwarn(cardnum,format,...) warn("[%02d] " format, cardnum , ## __VA_ARGS__)
457
#define cardcrit(cardnum,format,...) crit("[%02d] " format, cardnum , ## __VA_ARGS__)
458
#define dbginfo(cardnum,format,...) if(debug) info("[%02d] " format, cardnum , ## __VA_ARGS__)
459
460
461
static inline const char *porttype(struct openpci *wc, int port)
462
{ //{{{
463
	switch( wc->porttype[port] ) {
464
	    case VT_PORT_VDAA:    return "VDAA";
465
	    case VT_PORT_PROSLIC: return "ProSLIC";
466
	    case VT_PORT_EMPTY:   return "empty port";
467
	    default:              return "unknown type";
468
	}
469
} //}}}
470
471
472
static int __read_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
473
{ //{{{
474
	unsigned char portadr = fxo_port_lookup[port];
475
	int i;
476
477
	if (HRXF_READY) *value = inb(PIB(1));
478
479
	outb(0x11, PIB(1));    HTXF_WAIT();
480
	outb(0x2, PIB(1));     HTXF_WAIT();
481
	outb(portadr, PIB(1)); HTXF_WAIT();
482
	outb(reg, PIB(1));     HTXF_WAIT();
483
	HRXF_WAIT(); *value = inb(PIB(1));
484
485
	return RET_OK;
486
} //}}}
487
488
static int read_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
489
{ //{{{
490
	unsigned long flags;
491
492
	spin_lock_irqsave(&wc->lock, flags);
493
	if( __read_reg_fxo(wc, port, reg, value) ){
494
		spin_unlock_irqrestore(&wc->lock, flags);
495
		return RET_OK;
496
	}
497
	spin_unlock_irqrestore(&wc->lock, flags);
498
	cardcrit(wc->boardnum, "FXO port %d, reg %d, read failed!", port, reg);
499
	return RET_FAIL;
500
} //}}}
501
502
static int __read_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
503
{ //{{{
504
	unsigned char portadr = fxs_port_lookup[port];
505
	int i;
506
507
	if (HRXF_READY) *value = inb(PIB(1));
508
509
	outb(0x13, PIB(1));    HTXF_WAIT();
510
	outb(0x2, PIB(1));     HTXF_WAIT();
511
	outb(portadr, PIB(1)); HTXF_WAIT();
512
	outb(reg, PIB(1));     HTXF_WAIT();
513
	HRXF_WAIT(); *value = inb(PIB(1));
514
515
	return RET_OK;
516
} //}}}
517
518
static int read_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char *value)
519
{ //{{{
520
	unsigned long flags;
521
522
	spin_lock_irqsave(&wc->lock, flags);
523
	if( __read_reg_fxs(wc, port, reg, value) ) {
524
		spin_unlock_irqrestore(&wc->lock, flags);
525
		return RET_OK;
526
	}
527
	spin_unlock_irqrestore(&wc->lock, flags);
528
	cardcrit(wc->boardnum, "FXS port %d, reg %d, read failed!", port, reg);
529
	return RET_FAIL;
530
} //}}}
531
532
static int __write_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char value)
533
{ //{{{
534
	unsigned char portadr = fxo_port_lookup[port];
535
	int i;
536
537
        outb(0x10, PIB(1) );   HTXF_WAIT();
538
        outb(0x3, PIB(1));     HTXF_WAIT();
539
        outb(portadr, PIB(1)); HTXF_WAIT();
540
        outb(reg, PIB(1));     HTXF_WAIT();
541
        outb(value, PIB(1));   HTXF_WAIT();
542
543
	return RET_OK;
544
} //}}}
545
546
static int write_reg_fxo(struct openpci *wc, int port, unsigned char reg, unsigned char value)
547
{ //{{{
548
	unsigned long flags;
549
550
	spin_lock_irqsave(&wc->lock, flags);
551
	if( __write_reg_fxo(wc, port, reg, value) ){
552
		spin_unlock_irqrestore(&wc->lock, flags);
553
		return RET_OK;
554
	}
555
	spin_unlock_irqrestore(&wc->lock, flags);
556
	cardcrit(wc->boardnum, "FXO port %d, reg %d, write(%d) failed!", port, reg, value);
557
	return RET_FAIL;
558
} //}}}
559
560
static int __write_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char value)
561
{ //{{{
562
	unsigned char portadr = fxs_port_lookup[port];
563
	int i;
564
565
        outb(0x12, PIB(1) );   HTXF_WAIT();
566
        outb(0x3, PIB(1));     HTXF_WAIT();
567
        outb(portadr, PIB(1)); HTXF_WAIT();
568
        outb(reg, PIB(1));     HTXF_WAIT();
569
        outb(value, PIB(1));   HTXF_WAIT();
570
571
	return RET_OK;
572
} //}}}
573
574
static int write_reg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned char value)
575
{ //{{{
576
	unsigned long flags;
577
578
	spin_lock_irqsave(&wc->lock, flags);
579
	if( __write_reg_fxs(wc, port, reg, value) ){
580
		spin_unlock_irqrestore(&wc->lock, flags);
581
		return RET_OK;
582
	}
583
	spin_unlock_irqrestore(&wc->lock, flags);
584
	cardcrit(wc->boardnum, "FXS port %d, reg %d, write(%d) failed!", port, reg, value);
585
	return RET_FAIL;
586
} //}}}
587
588
static int __wait_indreg_fxs(struct openpci *wc, int port)
589
{ //{{{
590
	unsigned char value;
591
	int count = 100;
592
593
	while (--count)
594
	{
595
		if( __read_reg_fxs(wc, port, I_STATUS, &value) ){
596
			if( value == 0 )
597
				return RET_OK;
598
		} else {
599
			cardcrit(wc->boardnum,
600
				 "failed to read port %d PS_IND_ADDR_ST, retrying...",
601
				 port);
602
		}
603
		udelay(5);
604
	}
605
	cardcrit(wc->boardnum, "Failed to wait for indirect reg write to port %d", port);
606
	return RET_FAIL;
607
} //}}}
608
609
static int write_indreg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned short value)
610
{ //{{{
611
	unsigned long flags;
612
613
	spin_lock_irqsave(&wc->lock, flags);
614
	if( __wait_indreg_fxs(wc, port)
615
	 && __write_reg_fxs(wc, port, IDA_LO, value & 0xff)
616
	 && __write_reg_fxs(wc, port, IDA_HI, (value & 0xff00)>>8)
617
	 && __write_reg_fxs(wc, port, IAA, reg)
618
	 && __wait_indreg_fxs(wc, port) )
619
	{
620
		spin_unlock_irqrestore(&wc->lock, flags);
621
		return RET_OK;
622
	}
623
	spin_unlock_irqrestore(&wc->lock, flags);
624
	cardcrit(wc->boardnum, "FXS indreg %d write failed on port %d", reg, port);
625
	return RET_FAIL;
626
} //}}}
627
628
static int read_indreg_fxs(struct openpci *wc, int port, unsigned char reg, unsigned short *value)
629
{ //{{{
630
	unsigned long flags;
631
	unsigned char lo, hi;
632
633
	spin_lock_irqsave(&wc->lock, flags);
634
	if( __wait_indreg_fxs(wc, port)
635
	 && __write_reg_fxs(wc, port, IAA, reg)
636
	 && __wait_indreg_fxs(wc, port)
637
	 && __read_reg_fxs(wc, port, IDA_LO, &lo)
638
	 && __read_reg_fxs(wc, port, IDA_HI, &hi) )
639
	{
640
		*value = lo | hi << 8;
641
		spin_unlock_irqrestore(&wc->lock, flags);
642
		return RET_OK;
643
	}
644
	spin_unlock_irqrestore(&wc->lock, flags);
645
	return RET_FAIL;
646
} //}}}
647
648
static void start_dma(struct openpci *wc)
649
{ //{{{
650
	outb(0x0f, TJ_CNTL);
651
	set_current_state(TASK_INTERRUPTIBLE);
652
	schedule_timeout(1);
653
	outb(0x01, TJ_CNTL);
654
	outb(0x01, TJ_OPER);
655
} //}}}
656
657
static void restart_dma(struct openpci *wc)
658
{ //{{{
659
	/* Reset Master and TDM */
660
	outb(0x01, TJ_CNTL);
661
	outb(0x01, TJ_OPER);
662
} //}}}
663
664
/* You must hold the card spinlock to call this function */
665
static int __ping_arm(struct openpci *wc)
666
{ //{{{
667
	int i;
668
	int pong=0;
669
670
	while(pong != 0x02){
671
		outb(0x02, PIB(1)); HTXF_WAIT();
672
		HRXF_WAIT(); pong = inb(PIB(1));
673
		dbginfo(wc->boardnum, "ping_arm returned %x", pong);
674
	}
675
	while(pong == 0x02){
676
		// Poke no-ops into the arm while it is still returning data,
677
		// if 500 usec elapses with no further response from it then
678
		// the message queue is should be completely cleared.
679
		outb(0x00, PIB(1)); HTXF_WAIT();
680
		i = 100;
681
		while( !HRXF_READY && --i ) udelay(5);
682
		if( i == 0 ) break;
683
		pong = inb(PIB(1));
684
		dbginfo(wc->boardnum, "ping_arm returned %x.", pong);
685
	}
686
	return RET_OK;
687
} //}}}
688
689
static void arm_event(struct openpci *wc, char *msg)
690
{ //{{{
691
	int port = msg[0];
692
693
	switch(msg[1]){
694
		case DSP_LOOP_OFFHOOK:
695
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
696
			dbginfo(wc->boardnum, "Port %d Loop OffHook", port);
697
			break;
698
699
		case DSP_LOOP_ONHOOK:
700
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
701
			dbginfo(wc->boardnum, "Port %d Loop OnHook", port);
702
			break;
703
704
		case DSP_LOOP_POLARITY:
705
			dahdi_qevent_lock(wc->chans[port], DAHDI_EVENT_POLARITY);
706
			dbginfo(wc->boardnum, "Port %d Loop Polarity", port);
707
			break;
708
709
		case DSP_CODEC_RING:
710
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_RING);
711
			dbginfo(wc->boardnum, "Port %d Ring On", port);
712
			break;
713
714
		case DSP_RING_OFF:
715
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
716
			dbginfo(wc->boardnum, "Port %d Ring Off", port);
717
			break;
718
719
		case DSP_CODEC_HKOFF:
720
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_OFFHOOK);
721
			dbginfo(wc->boardnum, "Port %d Station OffHook", port);
722
			if (reversepolarity)
723
				wc->mod[port].fxs.idletxhookstate = 5;
724
			else
725
				wc->mod[port].fxs.idletxhookstate = 1;
726
			break;
727
728
		case DSP_CODEC_HKON:
729
			dahdi_hooksig(wc->chans[port], DAHDI_RXSIG_ONHOOK);
730
			dbginfo(wc->boardnum, "Port %d Station OnHook", port);
731
			if (reversepolarity)
732
				wc->mod[port].fxs.idletxhookstate = 6;
733
			else
734
				wc->mod[port].fxs.idletxhookstate = 2;
735
			break;
736
737
		case DSP_CODEC_FLASH:
738
			dahdi_qevent_lock(wc->chans[port], DAHDI_EVENT_WINKFLASH);
739
			dbginfo(wc->boardnum, "Port %d Station Flash", port);
740
			break;
741
742
		case DSP_DROP:
743
		case DSP_LOOP_NOBATT:
744
			break;
745
746
			//XXX What to do to recover from these?
747
		case DSP_PROSLIC_SANITY:
748
			dbginfo(wc->boardnum, "Port %d ProSlic has gone insane!", port);
749
			break;
750
751
		case DSP_PROSLIC_PWR_ALARM:
752
		{
753
			char errbuf[32] = " Unknown", *p = errbuf;
754
			int i = 49;
755
756
			msg[2] >>= 2;
757
			for(; i < 55; ++i, msg[2] >>= 1 )
758
			    if(msg[2] & 1){ *(++p)='Q'; *(++p)=i; *(++p)=','; }
759
			if( p != errbuf ) *p = '\0';
760
			cardcrit(wc->boardnum,"%d: ProSlic power ALARM:%s",msg[0],errbuf);
761
			//write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook );
762
			return;
763
		}
764
765
		case DSP_VDAA_ISO_FRAME_E:
766
			dbginfo(wc->boardnum, "Port %d VDAA has lost ISO-Cap frame lock", port);
767
			break;
768
769
		default:
770
			cardwarn(wc->boardnum, "Unknown message from Arm[%d] for port %d",
771
						msg[1], port);
772
			break;
773
	}
774
} //}}}
775
776
/* You must hold the card spinlock to call this function */
777
static inline int __read_arm_byte( struct openpci *wc, unsigned char *msg )
778
{ //{{{
779
	int i;
780
781
	HRXF_WAIT(); *msg = inb(PIB(1));
782
	return RET_OK;
783
} //}}}
784
785
static inline int read_arm_msg( struct openpci *wc, unsigned char *msg )
786
{ //{{{
787
	unsigned long flags;
788
	int i, d, count;
789
	int ret = RET_OK;
790
791
	spin_lock_irqsave(&wc->lock, flags);
792
	outb(0x08, PIB(1)); HTXF_WAIT_LOCKED();
793
	//XXX Do we need to clear the interrupt flag even if this fails?
794
	HRXF_WAIT_LOCKED(); count = inb(PIB(1));
795
	if( count == 0 ){
796
		ret = RET_FAIL;
797
	} else if( count < 3 || count > 4 ){
798
		cardcrit(wc->boardnum, "BOGUS arm message size %d, flushing queue", count);
799
		// NB: This may take a while (up to 500usec or more) to complete
800
		//     and we are in the isr at present when this is called, so
801
		//     we may miss an interrupt or two while this is done in the
802
		//     bottom half, but we are already in trouble, so...
803
		d = debug; debug = 5; __ping_arm( wc ); debug = d;
804
		ret = RET_FAIL;
805
	} else while( --count ){
806
		if( ! __read_arm_byte(wc, msg) ){
807
			cardcrit(wc->boardnum,
808
				 "Failed to read arm message %d more bytes expected",
809
				 count);
810
			ret = RET_FAIL;
811
			break;
812
		}
813
		++msg;
814
	}
815
	outb(0x09, PIB(1)); HTXF_WAIT_LOCKED();
816
	spin_unlock_irqrestore(&wc->lock, flags);
817
	return ret;
818
} //}}}
819
820
static void openpci_arm_work( void *cardptr )
821
{ //{{{
822
	struct openpci *wc = (struct openpci*)cardptr;
823
	unsigned char armmsg[4];
824
825
	if( read_arm_msg(wc, armmsg) ) arm_event(wc, armmsg);
826
} //}}}
827
828
829
static inline void openpci_write(struct openpci *wc, unsigned char flags)
830
{ //{{{
831
	int x,y;
832
	volatile unsigned int *writechunk;
833
834
	if (flags & 0x01)
835
		writechunk = wc->writechunk;
836
	else if (flags & 0x02)
837
		writechunk = wc->writechunk + DAHDI_CHUNKSIZE*2;
838
	else {
839
		cardcrit(wc->boardnum, "bad write interrupt flags %x, at %x",
840
					flags, inb(TJ_DMAWC) );
841
		return;
842
	}
843
	/* get data */
844
	dahdi_transmit(&wc->span);
845
	for (y=0,x=0;x<DAHDI_CHUNKSIZE;++x) {
846
		/* Send a sample, as a 32-bit word */
847
#ifdef __BIG_ENDIAN
848
#warning No big endian support (yet)
849
#else
850
		/* transmit second 4 ports */
851
		writechunk[y]=0;
852
		if (wc->porttype[4])
853
			writechunk[y] |= (wc->chans[4]->writechunk[x] << 24);
854
		else
855
			writechunk[y] |= (0x01 << 24);
856
		if (wc->porttype[5])
857
			writechunk[y] |= (wc->chans[5]->writechunk[x] << 16);
858
		if (wc->porttype[6])
859
			writechunk[y] |= (wc->chans[6]->writechunk[x] << 8);
860
		if (wc->porttype[7])
861
			writechunk[y] |= (wc->chans[7]->writechunk[x]);
862
		++y;
863
864
		/* transmit first 4 ports */
865
		writechunk[y]=0x01000000;
866
		/* Make sure first port doesnt equal 0x00 */
867
		if (wc->porttype[0]){
868
			if (wc->chans[0]->writechunk[x] == 0)
869
				writechunk[y] |= (0x01 << 24);
870
			else
871
				writechunk[y] |= (wc->chans[0]->writechunk[x] << 24);
872
		}
873
		//else writechunk[y] |= (0x00 << 24);
874
		if (wc->porttype[1])
875
			writechunk[y] |= (wc->chans[1]->writechunk[x] << 16);
876
		if (wc->porttype[2])
877
			writechunk[y] |= (wc->chans[2]->writechunk[x] << 8);
878
		if (wc->porttype[3])
879
			writechunk[y] |= (wc->chans[3]->writechunk[x]);
880
		++y;
881
#endif
882
	}
883
} //}}}
884
885
static inline void openpci_read(struct openpci *wc, unsigned char flags)
886
{ //{{{
887
	int x,y;
888
	volatile unsigned int *readchunk;
889
890
	if (flags & 0x08)
891
		readchunk = wc->readchunk + DAHDI_CHUNKSIZE*2;
892
	else if (flags & 0x04)
893
		readchunk = wc->readchunk;
894
	else {
895
		cardcrit(wc->boardnum, "bad read interrupt flags %x, at %x",
896
					flags, inb(TJ_DMARC));
897
		return;
898
	}
899
900
	for (y=0,x=0;x<DAHDI_CHUNKSIZE;++x) {
901
#ifdef __BIG_ENDIAN
902
#warning No big endian support (yet)
903
#else
904
		/* Receive first 4 ports */
905
906
		if (wc->porttype[0])
907
			wc->chans[0]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
908
		if (wc->porttype[1])
909
			wc->chans[1]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
910
		if (wc->porttype[2])
911
			wc->chans[2]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
912
		if (wc->porttype[3])
913
			wc->chans[3]->readchunk[x] = (readchunk[y]) & 0xff;
914
		++y;
915
		/* Receive second 4 ports */
916
		if (wc->porttype[4])
917
			wc->chans[4]->readchunk[x] = (readchunk[y] >> 24) & 0xff;
918
		if (wc->porttype[5])
919
			wc->chans[5]->readchunk[x] = (readchunk[y] >> 16) & 0xff;
920
		if (wc->porttype[6])
921
			wc->chans[6]->readchunk[x] = (readchunk[y] >> 8) & 0xff;
922
		if (wc->porttype[7])
923
			wc->chans[7]->readchunk[x] = (readchunk[y]) & 0xff;
924
		++y;
925
#endif
926
	}
927
	/* XXX We're wasting 8 taps.  We should get closer :( */
928
	for (x = 0; x < MAX_PORTS; x++) {
929
		if (wc->porttype[x])
930
			dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
931
	}
932
	dahdi_receive(&wc->span);
933
} //}}}
934
935
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
936
static irqreturn_t openpci_isr(int irq, void *dev_id, struct pt_regs *regs)
937
#else
938
static irqreturn_t openpci_isr(int irq, void *dev_id)
939
#endif
940
{ //{{{
941
	struct openpci *wc = dev_id;
942
	unsigned long flags;
943
	unsigned char status;
944
945
	spin_lock_irqsave(&wc->lock, flags);
946
	status = inb(TJ_INTSTAT);
947
	outb(status, TJ_INTSTAT);
948
949
	if (!status) {
950
		if(inb(TJ_AUXR) & 0x02) {
951
			spin_unlock_irqrestore(&wc->lock, flags);
952
			return IRQ_NONE;
953
		}
954
		spin_unlock_irqrestore(&wc->lock, flags);
955
		openpci_arm_work(wc);
956
		return IRQ_HANDLED;
957
	}
958
	if (status & 0x10){
959
		/* PCI Master abort */
960
		cardcrit(wc->boardnum, "PCI Master Abort.");
961
		/* Stop DMA, wait for watchdog */
962
		outb(0x00, TJ_OPER);
963
		spin_unlock_irqrestore(&wc->lock, flags);
964
		return IRQ_HANDLED;
965
	}
966
	spin_unlock_irqrestore(&wc->lock, flags);
967
968
	if (status & 0x20){
969
		/* PCI Target abort */
970
		cardcrit(wc->boardnum, "PCI Target Abort.");
971
		return IRQ_HANDLED;
972
	}
973
	if (status & 0x03){
974
		openpci_write(wc, status);
975
	}
976
	if (status & 0x0c){
977
	    #ifdef DEBUG_LOOP_VOLTAGE
978
	    //{{{
979
		static int counter[MAX_CARDS];
980
		int card = wc->boardnum;
981
		int port = ++counter[card] & 0x07;
982
		int ignore = counter[card] & 0xf0;
983
984
		if( ! ignore && (voltmeter & ((1 << (card * 8)) << port)) ) {
985
			unsigned char lv;
986
			if( wc->porttype[port] == VT_PORT_VDAA && read_reg_fxo(wc, port, 29, &lv) )
987
				cardinfo(wc->boardnum, "Port %d loop voltage %d",
988
							port, lv < 128 ? lv : lv - 256);
989
		}
990
	    //}}}
991
	    #endif
992
		openpci_read(wc, status);
993
	}
994
995
	return IRQ_HANDLED;
996
} //}}}
997
998
static int openpci_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
999
{ //{{{
1000
	struct wctdm_stats stats;
1001
	struct wctdm_regs regs;
1002
	struct wctdm_regop regop;
1003
	struct wctdm_echo_coefs echoregs;
1004
	struct openpci *wc = chan->pvt;
1005
	int port = chan->chanpos - 1;
1006
	int x;
1007
1008
	switch (cmd) {
1009
	case DAHDI_ONHOOKTRANSFER:
1010
		if (wc->porttype[port] != VT_PORT_PROSLIC)
1011
			return -EINVAL;
1012
		if (get_user(x, (int *)data))
1013
			return -EFAULT;
1014
		wc->mod[port].fxs.ohttimer = x << 3;
1015
		if (reversepolarity)
1016
			wc->mod[port].fxs.idletxhookstate = 0x6;	/* OHT mode when idle */
1017
		else
1018
			wc->mod[port].fxs.idletxhookstate = 0x2;
1019
		switch(wc->mod[port].fxs.lasttxhook) {
1020
		    case 0x1:
1021
		    case 0x5:
1022
			if (reversepolarity)
1023
				wc->mod[port].fxs.lasttxhook = 0x6;
1024
			else
1025
				wc->mod[port].fxs.lasttxhook = 0x2;
1026
			if( ! write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook) )
1027
				return -EIO;
1028
		}
1029
		break;
1030
	case DAHDI_SETPOLARITY:
1031
		if (get_user(x, (int *)data))
1032
			return -EFAULT;
1033
		if (wc->porttype[port] != VT_PORT_PROSLIC)
1034
			return -EINVAL;
1035
		/* Can't change polarity while ringing or when open */
1036
		if ((wc->mod[port].fxs.lasttxhook == 0x04) ||
1037
		    (wc->mod[port].fxs.lasttxhook == 0x00))
1038
			return -EINVAL;
1039
1040
		if ((x && !reversepolarity) || (!x && reversepolarity))
1041
			wc->mod[port].fxs.lasttxhook |= 0x04;
1042
		else
1043
			wc->mod[port].fxs.lasttxhook &= ~0x04;
1044
		if( ! write_reg_fxs(wc, port, 64, wc->mod[port].fxs.lasttxhook) )
1045
			return -EIO;
1046
		break;
1047
	case WCTDM_GET_STATS:
1048
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
1049
			unsigned char	linevolt;
1050
			if( read_reg_fxs(wc, port, 80, &linevolt) )
1051
				stats.tipvolt = linevolt * -376;
1052
			else
1053
				return -EIO;
1054
			if( read_reg_fxs(wc, port, 81, &linevolt) )
1055
				stats.ringvolt = linevolt * -376;
1056
			else
1057
				return -EIO;
1058
			if( read_reg_fxs(wc, port, 82, &linevolt) )
1059
				stats.batvolt = linevolt * -376;
1060
			else
1061
				return -EIO;
1062
		} else if (wc->porttype[port] == VT_PORT_VDAA) {
1063
			unsigned char	linevolt;
1064
			if( read_reg_fxo(wc, port, 29, &linevolt) )
1065
				stats.tipvolt = stats.ringvolt = stats.batvolt = linevolt * 1000;
1066
			else
1067
				return -EIO;
1068
		} else
1069
			return -EINVAL;
1070
		if (copy_to_user((struct wctdm_stats *)data, &stats, sizeof(stats)))
1071
			return -EFAULT;
1072
		break;
1073
	case WCTDM_GET_REGS:
1074
		if (wc->porttype[port] == VT_PORT_PROSLIC) {
1075
			for (x=0;x<NUM_INDIRECT_REGS;x++)
1076
				if( ! read_indreg_fxs(wc, port, x, &regs.indirect[x]) )
1077
					return -EIO;
1078
			for (x=0;x<NUM_REGS;x++)
1079
				if( ! read_reg_fxs(wc, port, x, &regs.direct[x]) )
1080
					return -EIO;
1081
		} else {
1082
			memset(&regs, 0, sizeof(regs));
1083
			for (x=0;x<NUM_FXO_REGS;x++){
1084
				if( ! read_reg_fxo(wc, port, x, &regs.direct[x]) )
1085
					return -EIO;
1086
			}
1087
		}
1088
		if (copy_to_user((struct wctdm_regs *)data, &regs, sizeof(regs)))
1089
			return -EFAULT;
1090
		break;
1091
	case WCTDM_SET_REG:
1092
		if (copy_from_user(&regop, (struct wctdm_regop *)data, sizeof(regop)))
1093
			return -EFAULT;
1094
		if (regop.indirect) {
1095
			if (wc->porttype[port] != VT_PORT_PROSLIC)
1096
				return -EINVAL;
1097
			printk("Setting indirect %d to 0x%04x on %d\n",
1098
				regop.reg, regop.val, chan->chanpos);
1099
			if( ! write_indreg_fxs(wc, port, regop.reg, regop.val) )
1100
				return -EIO;
1101
		} else {
1102
			regop.val &= 0xff;
1103
			printk("Setting direct %d to %04x on %d\n",
1104
				regop.reg, regop.val, chan->chanpos);
1105
			if (wc->porttype[port] == VT_PORT_PROSLIC) {
1106
				if( ! write_reg_fxs(wc, port, regop.reg, regop.val) )
1107
					return -EIO;
1108
			} else {
1109
				if( ! write_reg_fxo(wc, port, regop.reg, regop.val) )
1110
					return -EIO;
1111
			}
1112
		}
1113
		break;
1114
	case WCTDM_SET_ECHOTUNE:
1115
		cardinfo(wc->boardnum, "Setting echo registers");
1116
		if (copy_from_user(&echoregs, (struct wctdm_echo_coefs*)data, sizeof(echoregs)))
1117
			return -EFAULT;
1118
1119
		if (wc->porttype[port] == VT_PORT_VDAA) {
1120
			/* Set the ACIM and digital echo canceller registers */
1121
			if( ! write_reg_fxo(wc, port, 30, echoregs.acim)
1122
			 || ! write_reg_fxo(wc, port, 45, echoregs.coef1)
1123
			 || ! write_reg_fxo(wc, port, 46, echoregs.coef2)
1124
			 || ! write_reg_fxo(wc, port, 47, echoregs.coef3)
1125
			 || ! write_reg_fxo(wc, port, 48, echoregs.coef4)
1126
			 || ! write_reg_fxo(wc, port, 49, echoregs.coef5)
1127
			 || ! write_reg_fxo(wc, port, 50, echoregs.coef6)
1128
			 || ! write_reg_fxo(wc, port, 51, echoregs.coef7)
1129
			 || ! write_reg_fxo(wc, port, 52, echoregs.coef8) )
1130
			{
1131
				cardcrit(wc->boardnum, "Failed to set echo registers");
1132
				return -EIO;
1133
			}
1134
			break;
1135
		} else {
1136
			return -EINVAL;
1137
		}
1138
		break;
1139
	default:
1140
		return -ENOTTY;
1141
	}
1142
	return 0;
1143
} //}}}
1144
1145
static int openpci_open(struct dahdi_chan *chan)
1146
{
1147
	struct openpci *wc = chan->pvt;
1148
	if( ! wc->porttype[chan->chanpos-1] )
1149
		return -ENODEV;
1150
1151
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1152
	//    as the owner of the span that holds the pointer to this function,
1153
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1154
	//    fatal call to an invalid pointer is made.
1155
	//if( wc->dead ) return -ENODEV;
1156
	//wc->usecount++;
1157
	try_module_get(THIS_MODULE);  //XXX
1158
1159
	return 0;
1160
}
1161
1162
static inline struct openpci* openpci_from_span(struct dahdi_span *span) {
1163
	return container_of(span, struct openpci, span);
1164
}
1165
1166
static int openpci_watchdog(struct dahdi_span *span, int event)
1167
{
1168
	info("TDM: Restarting DMA");
1169
	restart_dma(openpci_from_span(span));
1170
	return 0;
1171
}
1172
1173
static int openpci_close(struct dahdi_chan *chan)
1174
{
1175
	struct openpci *wc = chan->pvt;
1176
	int port = chan->chanpos - 1;
1177
1178
	//XXX wc->usecount--;
1179
	//XXX This is WRONG and can prang in a race.  We must pass THIS_MODULE
1180
	//    as the owner of the span that holds the pointer to this function,
1181
	//    then bump the refcount in the dahdi code _BEFORE_ the potentially
1182
	//    fatal call to an invalid pointer is made.
1183
	module_put(THIS_MODULE);
1184
	if (wc->porttype[port] == VT_PORT_PROSLIC) {
1185
		if (reversepolarity)
1186
			wc->mod[port].fxs.idletxhookstate = 5;
1187
		else
1188
			wc->mod[port].fxs.idletxhookstate = 1;
1189
	}
1190
	/* If we're dead, release us now */
1191
	//XXX if (!wc->usecount && wc->dead) openpci_release(wc);
1192
1193
	return 0;
1194
}
1195
1196
static int openpci_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
1197
{ //{{{
1198
	struct openpci *wc = chan->pvt;
1199
	int port = chan->chanpos - 1;
1200
	int new_hk_state;
1201
1202
	dbginfo(wc->boardnum, "Setting %s port %d hook state %s",
1203
		 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1204
		 port,
1205
		 txsig == 0 ? "ONHOOK" :
1206
		 txsig == 1 ? "OFFHOOK" :
1207
		 txsig == 2 ? "START" :
1208
		 txsig == 3 ? "KEWL" : "UNKNOWN" );
1209
1210
	switch(wc->porttype[port]) {
1211
	    case VT_PORT_VDAA:
1212
		switch(txsig) {
1213
		    case DAHDI_TXSIG_START:
1214
		    case DAHDI_TXSIG_OFFHOOK:
1215
			if( write_reg_fxo(wc, port, 5, 0x9)
1216
			 && write_reg_fxo(wc, port, 0x20, 0x0) )
1217
				wc->mod[port].fxo.offhook = 1;
1218
			else
1219
				cardcrit(wc->boardnum, "Failed set fxo off-hook");
1220
			break;
1221
1222
		    case DAHDI_TXSIG_ONHOOK:
1223
			if( write_reg_fxo(wc, port, 5, 0x8)
1224
			 && write_reg_fxo(wc, port, 0x20, 0x3) )
1225
				wc->mod[port].fxo.offhook = 0;
1226
			else
1227
				cardcrit(wc->boardnum, "Failed set fxo on-hook");
1228
			break;
1229
1230
		    default:
1231
			cardcrit(wc->boardnum,
1232
				 "Can't set FXO port %d tx state to %d",
1233
				 port, txsig);
1234
		}
1235
		break;
1236
1237
	    case VT_PORT_PROSLIC:
1238
		new_hk_state = wc->mod[port].fxs.lasttxhook;
1239
		switch(txsig) {
1240
		    case DAHDI_TXSIG_ONHOOK:
1241
			switch(chan->sig) {
1242
			case DAHDI_SIG_EM:
1243
			case DAHDI_SIG_FXOKS:
1244
			case DAHDI_SIG_FXOLS:
1245
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1246
				break;
1247
			case DAHDI_SIG_FXOGS:
1248
				new_hk_state = 3;
1249
				break;
1250
			}
1251
			break;
1252
1253
		    case DAHDI_TXSIG_OFFHOOK:
1254
			switch(chan->sig) {
1255
			case DAHDI_SIG_EM:
1256
				new_hk_state = 5;
1257
				break;
1258
			default:
1259
				new_hk_state = wc->mod[port].fxs.idletxhookstate;
1260
				break;
1261
			}
1262
			break;
1263
1264
		    case DAHDI_TXSIG_START:
1265
			new_hk_state = 4;
1266
			break;
1267
1268
		    case DAHDI_TXSIG_KEWL:
1269
			new_hk_state = 0;
1270
			break;
1271
1272
		    default:
1273
			cardinfo(wc->boardnum,
1274
				 "Can't set FXS port %d tx state to %d",
1275
				 port, txsig);
1276
		}
1277
		dbginfo(wc->boardnum, "%s port %d hook state old %d, new %d",
1278
			 wc->porttype[port] == VT_PORT_VDAA ? "FXO" : "FXS",
1279
			 port, wc->mod[port].fxs.lasttxhook, new_hk_state );
1280
1281
		if (new_hk_state != wc->mod[port].fxs.lasttxhook){
1282
			if( write_reg_fxs(wc, port, 64, new_hk_state) )
1283
				wc->mod[port].fxs.lasttxhook = new_hk_state;
1284
			else
1285
				cardcrit(wc->boardnum,
1286
					 "Failed to set port %d fxs hookstate from %d to %d",
1287
					 port, wc->mod[port].fxs.lasttxhook, new_hk_state);
1288
		}
1289
		break;
1290
1291
	    default:
1292
		cardcrit(wc->boardnum,
1293
			 "Unknown module type %d in openpci_hooksig",
1294
			 wc->porttype[port] );
1295
	}
1296
	return 0;
1297
} //}}}
1298
1299
static const struct dahdi_span_ops openpci_span_ops = {
1300
	.owner = THIS_MODULE,
1301
	.hooksig = openpci_hooksig,
1302
	.open = openpci_open,
1303
	.close = openpci_close,
1304
	.ioctl = openpci_ioctl,
1305
	.watchdog = openpci_watchdog
1306
};
1307
1308
static int span_initialize(struct openpci *wc)
1309
{ //{{{
1310
	int x;
1311
1312
	wc->ddev = dahdi_create_device();
1313
	//XXX Set a THIS_MODULE as the owner of the span...
1314
	/* Zapata stuff */
1315
	sprintf(wc->span.name, "WCTDM/%d", wc->boardnum);
1316
	sprintf(wc->span.desc, "%s Board %d", wc->variety, wc->boardnum + 1);
1317
	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
1318
				      wc->dev->bus->number,
1319
				      PCI_SLOT(wc->dev->devfn) + 1);
1320
	if (!wc->ddev->location)
1321
		return -ENOMEM;
1322
	for (x = 0; x < MAX_PORTS; x++) {
1323
		struct dahdi_chan *chan = &wc->_chans[x];
1324
		wc->chans[x] = chan;
1325
		sprintf(chan->name, "WCTDM/%d/%d", wc->boardnum, x);
1326
		chan->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS
1327
				    | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
1328
		chan->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
1329
		chan->chanpos = x+1;
1330
		chan->pvt = wc;
1331
	}
1332
	wc->ddev->manufacturer = "Voicetronix";
1333
	wc->ddev->devicetype = wc->variety;
1334
	wc->span.deflaw = DAHDI_LAW_MULAW;
1335
	wc->span.chans = wc->chans;
1336
	wc->span.channels = MAX_PORTS;
1337
	wc->span.flags = DAHDI_FLAG_RBS;
1338
	wc->span.ops = &openpci_span_ops;
1339
1340
	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
1341
	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
1342
		cardcrit(wc->boardnum, "Unable to register device with dahdi");
1343
		return RET_FAIL;
1344
	}
1345
	return RET_OK;
1346
} //}}}
1347
1348
static int get_port_type(struct openpci *wc, int port)
1349
{ //{{{
1350
	int i, type;
1351
	unsigned long flags;
1352
1353
	spin_lock_irqsave(&wc->lock, flags);
1354
	outb(0x20, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1355
	outb(port, PIB(1)); HTXF_WAIT_LOCKED_RET(VT_PORT_EMPTY);
1356
	HRXF_WAIT_LOCKED_RET(VT_PORT_EMPTY); type = inb(PIB(1));
1357
	spin_unlock_irqrestore(&wc->lock, flags);
1358
1359
	return type;
1360
} //}}}
1361
1362
static int check_ports(struct openpci *wc)
1363
{ //{{{
1364
	int i = 0;
1365
1366
	wc->portcount = 0;
1367
	for(; i < MAX_PORTS; ++i ){
1368
		wc->porttype[i] = get_port_type(wc, i);
1369
		dbginfo(wc->boardnum,"%d: %s", i, porttype(wc,i));
1370
1371
		switch( wc->porttype[i] ) {
1372
		    case VT_PORT_PROSLIC:
1373
			/* By default, don't send on hook */
1374
			if (reversepolarity)
1375
				wc->mod[i].fxs.idletxhookstate = 5;
1376
			else
1377
				wc->mod[i].fxs.idletxhookstate = 1;
1378
1379
		    case VT_PORT_VDAA:
1380
			++wc->portcount;
1381
		}
1382
	}
1383
	// we 'succeed' if any ports were discovered.
1384
	return wc->portcount ? RET_OK : RET_FAIL;
1385
} //}}}
1386
1387
static int configure_vdaa_country(struct openpci *wc, int port, char *name)
1388
{ //{{{
1389
	unsigned char value;
1390
	int i;
1391
1392
	for (i=0; i < sizeof(fxo_modes)/sizeof(struct fxo_mode); ++i){
1393
		if(!strcmp(fxo_modes[i].name, name)){
1394
			dbginfo(wc->boardnum, "%d: Setting country to %s", port, name);
1395
			goto part2;
1396
		}
1397
	}
1398
	i = 3;
1399
	cardinfo(wc->boardnum, "Using default country %s", fxo_modes[i].name);
1400
1401
    part2:
1402
	value  = (fxo_modes[i].ohs << 6);
1403
	value |= (fxo_modes[i].rz << 1);
1404
	value |= (fxo_modes[i].rt << 0);
1405
	if( ! write_reg_fxo(wc, port, 16, value) ) goto hell;
1406
1407
	/* DC Termination Control - Register 26 */
1408
	value  = (fxo_modes[i].dcv << 6);
1409
	value |= (fxo_modes[i].mini << 4);
1410
	value |= (fxo_modes[i].ilim << 1);
1411
	if( ! write_reg_fxo(wc, port, 26, value) ) goto hell;
1412
1413
	/* AC Termination Control - Register 30 */
1414
	value = (fxo_modes[i].acim << 0);
1415
	if( ! write_reg_fxo(wc, port, 30, value) ) goto hell;
1416
1417
	/* DAA Control 5 - Register 31 */
1418
	msleep(1);
1419
	if( ! read_reg_fxo(wc, port, 31, &value) ) goto hell;
1420
1421
	value = (value & 0xf7) | (fxo_modes[i].ohs2 << 3);
1422
	value = value | 0x02;
1423
	if( ! write_reg_fxo(wc, port, 31, value) ) goto hell;
1424
1425
	return RET_OK;
1426
1427
    hell:
1428
	cardcrit(wc->boardnum, "port %d failed configure vdaa country", port);
1429
	return RET_FAIL;
1430
} //}}}
1431
1432
// Do not call this from an interrupt context, it may sleep.
1433
static void configure_vdaa_port(struct openpci *wc, int port)
1434
{ //{{{
1435
	/* Set Country - default to Australia */
1436
	if( configure_vdaa_country(wc, port, country) )
1437
		++wc->portcount;
1438
	else {
1439
		cardcrit(wc->boardnum, "FAILED to configure vdaa port %d.  Disabled.", port);
1440
		wc->porttype[port] = VT_PORT_EMPTY;
1441
	}
1442
} //}}}
1443
1444
static int configure_proslic_country(struct openpci *wc, int port, const char *name)
1445
{ //{{{
1446
	int i;
1447
1448
	for(i=0; i < sizeof(ps_country_regs)/sizeof(struct ps_country_reg); ++i) {
1449
		if(!strcmp(ps_country_regs[i].country, name)){
1450
			dbginfo(wc->boardnum, "%d: Setting country to %s", port, name);
1451
			goto part2;
1452
		}
1453
	}
1454
	return -EINVAL;
1455
1456
    part2:
1457
1458
	if( ! write_reg_fxs(wc, port, 10, ps_country_regs[i].value) ){
1459
		cardcrit(wc->boardnum,"%d: failed to write PS_IMPEDANCE", port);
1460
		return -EIO;
1461
	}
1462
	return 0;
1463
} //}}}
1464
1465
// Do not call this from an interrupt context, it may sleep.
1466
static void configure_proslic_port(struct openpci *wc, int port)
1467
{ //{{{
1468
	/* Set Country - default to Australia */
1469
	switch( configure_proslic_country(wc, port, country) ){
1470
	    case 0:
1471
		break;
1472
1473
	    case -EINVAL:
1474
		cardwarn(wc->boardnum,"%d: Country '%s' unknown, using default", port, country);
1475
		if( configure_proslic_country(wc, port, DEFAULT_COUNTRY) == 0 )
1476
			goto hell;
1477
1478
	    default:
1479
		goto hell;
1480
	}
1481
1482
	++wc->portcount;
1483
	return;
1484
1485
    hell:
1486
	cardcrit(wc->boardnum, "FAILED to configure proslic port %d.  Disabled.", port);
1487
	wc->porttype[port] = VT_PORT_EMPTY;
1488
} //}}}
1489
1490
// Do not call this from an interrupt context, it may (indirectly) sleep.
1491
static int configure_ports(struct openpci *wc)
1492
{ //{{{
1493
	unsigned long flags;
1494
	int i;
1495
1496
	wc->portcount = 0;
1497
	for(i=0; i < MAX_PORTS; ++i){
1498
		switch (wc->porttype[i]){
1499
		    case VT_PORT_VDAA:    configure_vdaa_port(wc,i);    break;
1500
		    case VT_PORT_PROSLIC: configure_proslic_port(wc,i); break;
1501
		}
1502
	}
1503
1504
	spin_lock_irqsave(&wc->lock, flags);
1505
	outb(0x2c, PIB(1)); HTXF_WAIT_LOCKED();
1506
	outb(0xff, PIB(1)); HTXF_WAIT_LOCKED();
1507
	spin_unlock_irqrestore(&wc->lock, flags);
1508
1509
	// otherwise we 'succeed' if any ports were configured successfully.
1510
	return wc->portcount ? RET_OK : RET_FAIL;
1511
} //}}}
1512
1513
static int __get_arm_id(struct openpci *wc, int field, char *value)
1514
{ //{{{
1515
	int i;
1516
	int x=0;
1517
	int count=0;
1518
1519
	outb(0x01, PIB(1));  HTXF_WAIT();
1520
	outb(field, PIB(1)); HTXF_WAIT();
1521
	HRXF_WAIT(); count = inb(PIB(1));
1522
	if (count > ID_DATA_MAXSIZE){
1523
		cardcrit(wc->boardnum, "Too many bytes of id(%d) data %d/%d",
1524
					 field, count, ID_DATA_MAXSIZE);
1525
		return RET_FAIL;
1526
	}
1527
	//cardinfo(wc->boardnum, "get_arm_id(%d): byte count %d",field,count);
1528
	for(; x < count; ++x){
1529
		HRXF_WAIT(); *value = inb(PIB(1));
1530
		//cardinfo(wc->boardnum, "get_arm_id(%d): byte %d => 0x%02x",field,x,tmp);
1531
		++value;
1532
	}
1533
	return RET_OK;
1534
} //}}}
1535
1536
static void enable_interrupts(struct openpci *wc)
1537
{ //{{{
1538
	outb(0x3f, TJ_MASK0);
1539
	outb(0x02, TJ_MASK1);
1540
} //}}}
1541
1542
static void disable_interrupts(struct openpci *wc)
1543
{ //{{{
1544
	outb(0x00, TJ_MASK0);
1545
	outb(0x00, TJ_MASK1);
1546
} //}}}
1547
1548
// Do not call this from an interrupt context, it may sleep.
1549
static int check_arm(struct openpci *wc)
1550
{ //{{{
1551
	char model[ID_DATA_MAXSIZE+1] = { 0 };
1552
	char date[ID_DATA_MAXSIZE+1]  = { 0 };
1553
	unsigned long flags;
1554
	int i=0;
1555
	int tmp=0;
1556
1557
	spin_lock_irqsave(&wc->lock, flags);
1558
	while ((tmp != 0x88)&&(++i<100)){
1559
		outb(0x88, PIB(0));
1560
		msleep(1);
1561
		tmp = inb(PIB(1));
1562
	}
1563
	if (i>=1000) goto limbo;
1564
	dbginfo(wc->boardnum, "Arm responded on attempt %d",i);
1565
1566
	// Flush out the queue if we sent several pings before a response.
1567
	if(i>1)	__ping_arm(wc);
1568
1569
	if( ! __get_arm_id(wc, 0, model) )  goto hell;
1570
	sscanf(model, "OpenPCI8.%02d", &(wc->firmware));
1571
	cardinfo(wc->boardnum, "  model: %s", model);
1572
1573
	if( ! __get_arm_id(wc, 1, date) )   goto hell;
1574
	cardinfo(wc->boardnum, "  date: %s", date);
1575
1576
	if( ! __get_arm_id(wc, 2, wc->serial) ) goto hell;
1577
	cardinfo(wc->boardnum, "  serial: %s", wc->serial);
1578
1579
	spin_unlock_irqrestore(&wc->lock, flags);
1580
	return RET_OK;
1581
1582
    hell:
1583
	spin_unlock_irqrestore(&wc->lock, flags);
1584
        cardwarn(wc->boardnum, "Found ARM processor, dumb firmware.");
1585
	return RET_OK;
1586
1587
    limbo:
1588
	spin_unlock_irqrestore(&wc->lock, flags);
1589
	return RET_FAIL;
1590
} //}}}
1591
1592
static int arm_monitor(struct openpci *wc, int on)
1593
{ //{{{
1594
	int i;
1595
	outb( on ? 0x06 : 0x07, PIB(1) ); HTXF_WAIT();
1596
	return RET_OK;
1597
} //}}}
1598
1599
static int __devinit openpci_probe_board(struct pci_dev *pdev, const struct pci_device_id *ent)
1600
{ //{{{
1601
	struct openpci *wc;
1602
	int boardnum = 0;
1603
	int failret = -ENOMEM;
1604
	int tmp = 0;
1605
	int i;
1606
	unsigned long flags;
1607
1608
	if( ent->driver_data != (kernel_ulong_t)&wcopenpci )
1609
	{
1610
	    info("Probe of non-OpenPCI card, ignoring.");
1611
	    return -EINVAL;
1612
	}
1613
	wc = kzalloc(sizeof(struct openpci), GFP_KERNEL);
1614
	if (!wc){
1615
		return -ENOMEM;
1616
	}
1617
1618
	mutex_lock(&cards_mutex);
1619
	for (; boardnum < MAX_CARDS && cards[boardnum]; ++boardnum);
1620
	if (boardnum >= MAX_CARDS){
1621
		crit("Too many OpenPCI cards(%d), max is %d.", boardnum, MAX_CARDS);
1622
		mutex_unlock(&cards_mutex);
1623
		goto hell;
1624
	}
1625
	cards[boardnum] = wc;
1626
	mutex_unlock(&cards_mutex);
1627
1628
	spin_lock_init(&wc->lock);
1629
	pci_set_drvdata(pdev, wc);
1630
1631
	wc->boardnum = boardnum;
1632
	wc->dev      = pdev;
1633
	wc->variety  = wcopenpci;
1634
1635
	cardinfo(boardnum, "Initialising card");
1636
	if (pci_enable_device(pdev)) {
1637
		failret = -EIO;
1638
		goto hell_2;
1639
	}
1640
	wc->ioaddr = pci_resource_start(pdev, 0);
1641
	if( ! request_region(wc->ioaddr, 0xff, NAME) ){
1642
                cardcrit(boardnum, "Failed to lock IO region, another driver already using it");
1643
		failret = -EBUSY;
1644
		goto hell_2;
1645
	}
1646
1647
	spin_lock_irqsave(&wc->lock, flags);
1648
	outb(0xff, TJ_AUXD);            /* Set up TJ to access the ARM */
1649
	outb(0x78, TJ_AUXC);            /* Set up for Jtag */
1650
	outb(0x00, TJ_CNTL);            /* pull ERST low */
1651
	spin_unlock_irqrestore(&wc->lock, flags);
1652
	msleep(1);	                /* Wait a bit */
1653
1654
	dbginfo(boardnum,"Starting ARM");
1655
	spin_lock_irqsave(&wc->lock, flags);
1656
	outb(0x01, TJ_CNTL);            /* pull ERST high again */
1657
	spin_unlock_irqrestore(&wc->lock, flags);
1658
	msleep(100);                    /* Give it all a chance to boot */
1659
1660
	if( ! check_arm(wc) ){
1661
		cardcrit(boardnum, "Couldnt find ARM processor");
1662
		failret = -EIO;
1663
		goto hell_3;
1664
	}
1665
	if( wc->firmware < 11 ){
1666
		cardcrit(boardnum,
1667
			 "Firmware version %d not supported by this driver",
1668
			 wc->firmware);
1669
		cardcrit(boardnum, " contact Voicetronix to have it updated");
1670
		failret = -ENODEV;
1671
		goto hell_3;
1672
	}
1673
	if( ! check_ports(wc) ){
1674
		cardcrit(boardnum, "Couldnt find ports!");
1675
		failret = -EIO;
1676
		goto hell_3;
1677
	}
1678
1679
	wc->writechunk = pci_alloc_consistent(pdev, VT_PCIDMA_BLOCKSIZE, &wc->writedma);
1680
	if (!wc->writechunk) {
1681
		cardcrit(boardnum, "Couldnt get DMA memory.");
1682
		goto hell_3;
1683
	}
1684
	wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE * (MAX_PORTS*2 / sizeof(int));
1685
	wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_PORTS*2);
1686
1687
	memset((void*)wc->writechunk,0,VT_PCIDMA_BLOCKSIZE);
1688
1689
	spin_lock_irqsave(&wc->lock, flags);
1690
	outb(0xc1, TJ_SERCTL);
1691
	outb(0x0, TJ_FSCDELAY);
1692
1693
	outl(wc->writedma,                    TJ_DMAWS);
1694
	outl(wc->writedma + VT_PCIDMA_MIDDLE, TJ_DMAWI);
1695
	outl(wc->writedma + VT_PCIDMA_END,    TJ_DMAWE);
1696
	outl(wc->readdma,                     TJ_DMARS);
1697
	outl(wc->readdma + VT_PCIDMA_MIDDLE,  TJ_DMARI);
1698
	outl(wc->readdma + VT_PCIDMA_END,     TJ_DMARE);
1699
1700
	/* Clear interrupts */
1701
	outb(0xff, TJ_INTSTAT);
1702
	spin_unlock_irqrestore(&wc->lock, flags);
1703
1704
	if( ! arm_monitor(wc, 1) ){
1705
		cardcrit(boardnum, "failed to start arm monitoring");
1706
		failret = -EIO;
1707
		goto hell_4;
1708
	}
1709
	msleep(1000);
1710
1711
	i = 0;
1712
	while(tmp != 0x88 && ++i < 1000) {
1713
		outb(0x88, PIB(0));
1714
		msleep(250);
1715
		tmp = inb(PIB(1));
1716
	}
1717
	if(i>=1000) {
1718
		cardcrit(boardnum, "FAILED to initialise board");
1719
		goto hell_4;
1720
	}
1721
1722
	if( ! check_ports(wc) ) {
1723
		cardcrit(boardnum, "FAILED to initialise ports");
1724
		failret = -EIO;
1725
		goto hell_4;
1726
	}
1727
	if( ! configure_ports(wc) ){
1728
		cardcrit(boardnum, "Failed to configure ports.");
1729
		failret = -EIO;
1730
		goto hell_4;
1731
	}
1732
	cardinfo(wc->boardnum, "have %d configured ports", wc->portcount);
1733
1734
	if( ! span_initialize(wc) ) {
1735
		cardcrit(boardnum, "Failed to register with dahdi driver");
1736
		failret = -EFAULT;
1737
		goto hell_4;
1738
	}
1739
1740
	/* Finalize signalling  */
1741
	for (i=0; i < MAX_PORTS; ++i) {
1742
		if (wc->porttype[i] == VT_PORT_VDAA)
1743
		    wc->chans[i]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS
1744
					| DAHDI_SIG_CLEAR | DAHDI_SIG_SF;
1745
		else if (wc->porttype[i] == VT_PORT_PROSLIC)
1746
		    wc->chans[i]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS
1747
					| DAHDI_SIG_FXOGS | DAHDI_SIG_SF
1748
					| DAHDI_SIG_CLEAR | DAHDI_SIG_EM;
1749
		else if (wc->porttype[i])
1750
		    cardcrit(wc->boardnum, "Port %d has unknown type (%d)",
1751
					   i, wc->porttype[i]);
1752
	}
1753
1754
	/* Enable bus mastering */
1755
	pci_set_master(pdev);
1756
1757
	if (request_irq(pdev->irq, openpci_isr, DAHDI_IRQ_SHARED, NAME, wc)) {
1758
		cardcrit(boardnum, "Cant get IRQ!");
1759
		failret = -EIO;
1760
		goto hell_5;
1761
	}
1762
	cardinfo(boardnum, "Got IRQ %d", pdev->irq);
1763
1764
	enable_interrupts(wc);
1765
	start_dma(wc);
1766
1767
	cardinfo(boardnum,"Initialised card.");
1768
	return 0;
1769
1770
    hell_5:
1771
	dahdi_unregister_device(wc->ddev);
1772
    hell_4:
1773
	if (wc->writechunk){
1774
		pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE,
1775
				    (void*)wc->writechunk, wc->writedma);
1776
	}
1777
    hell_3:
1778
	outb(0x00, TJ_CNTL);
1779
	release_region(wc->ioaddr, 0xff);
1780
    hell_2:
1781
	cards[boardnum] = NULL;
1782
    hell:
1783
	kfree(wc->ddev->location);
1784
	dahdi_free_device(wc->ddev);
1785
	kfree(wc);
1786
	return failret;
1787
} //}}}
1788
1789
static void __devexit openpci_remove_board(struct pci_dev *pdev)
1790
{ //{{{
1791
	struct openpci *wc = pci_get_drvdata(pdev);
1792
1793
	if(!wc) return;
1794
1795
	arm_monitor(wc,0);
1796
1797
	/* Stop DMA */
1798
	outb(0x00, TJ_OPER);
1799
	disable_interrupts(wc);
1800
1801
	//XXX Replace this usecount business...
1802
	//    and do this BEFORE we invalidate everything above...
1803
	//    check that we wont try to write to it in the meantime.
1804
	/* Release span, possibly delayed */
1805
	//XXX if (!wc->usecount) openpci_release(wc); else wc->dead = 1;
1806
1807
	dahdi_unregister_device(wc->ddev);
1808
	outb(0x00, TJ_CNTL);
1809
1810
	pci_free_consistent(pdev, VT_PCIDMA_BLOCKSIZE, (void *)wc->writechunk, wc->writedma);
1811
	free_irq(pdev->irq, wc);
1812
1813
	release_region(wc->ioaddr, 0xff);
1814
1815
	mutex_lock(&cards_mutex);
1816
	cards[wc->boardnum] = NULL;
1817
	mutex_unlock(&cards_mutex);
1818
1819
	kfree(wc->ddev->location);
1820
	dahdi_free_device(wc->ddev);
1821
	kfree(wc);
1822
	cardinfo(wc->boardnum, "Removed OpenPCI card.");
1823
} //}}}
1824
1825
static struct pci_device_id openpci_pci_tbl[] = {
1826
	{ 0xe159, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t) &wcopenpci },
1827
	{ 0 }
1828
};
1829
1830
MODULE_DEVICE_TABLE(pci, openpci_pci_tbl);
1831
1832
static struct pci_driver openpci_driver = {
1833
	name: 	  NAME,
1834
	probe: 	  openpci_probe_board,
1835
	remove:	  __devexit_p(openpci_remove_board),
1836
	suspend:  NULL,
1837
	resume:	  NULL,
1838
	id_table: openpci_pci_tbl,
1839
};
1840
1841
static int __init openpci_init(void)
1842
{
1843
#ifdef __BIG_ENDIAN
1844
	warn("No big endian support (yet)");
1845
	return -ENODEV;
1846
#endif
1847
1848
	if( dahdi_pci_module(&openpci_driver) )
1849
		return -ENODEV;
1850
1851
	info("Module loaded %s", debug ? "with debug enabled" : "");
1852
	return 0;
1853
}
1854
1855
static void __exit openpci_cleanup(void)
1856
{
1857
	pci_unregister_driver(&openpci_driver);
1858
	info("Module exit");
1859
}
1860
1861
module_init(openpci_init);
1862
module_exit(openpci_cleanup);
1863
1864
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
1865
MODULE_AUTHOR(DRIVER_AUTHOR);
1866
MODULE_VERSION(DAHDI_VERSION);
1867
MODULE_LICENSE("GPL");
1868
(-)dahdi-linux-2.6.1.ORIG/drivers/dahdi/hfcs/base.c (+1741 lines)
Line 0 Link Here
1
/*
2
 * dahdi_hfcs.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) 2011, Raoul Bönisch
8
 * Copyright (C) 2009, Jose A. Deniz
9
 * Copyright (C) 2006, headiisue GmbH; Jens Wilke
10
 * Copyright (C) 2004 Daniele Orlandi
11
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
12
 *
13
 * Jens Wilke <jw_vzaphfc@headissue.com>
14
 *
15
 * Original author of this code is
16
 * Daniele "Vihai" Orlandi <daniele@orlandi.com>
17
 *
18
 * Major rewrite of the driver made by
19
 * Klaus-Peter Junghanns <kpj@junghanns.net>
20
 *
21
 * This program is free software and may be modified and
22
 * distributed under the terms of the GNU Public License.
23
 *
24
 * Please read the README file for important infos.
25
 */
26
27
#include <linux/spinlock.h>
28
#include <linux/init.h>
29
#include <linux/pci.h>
30
#include <linux/interrupt.h>
31
#include <linux/module.h>
32
#include <linux/moduleparam.h>
33
#include <linux/version.h>
34
#include <linux/kernel.h>
35
#include <linux/delay.h>
36
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
37
#include <linux/sched.h>
38
#endif
39
#include <linux/proc_fs.h>
40
#include <linux/if_arp.h>
41
42
#include <dahdi/kernel.h>
43
44
#include "dahdi_hfcs.h"
45
#include "fifo.h"
46
47
#if CONFIG_PCI
48
49
#define DAHDI_B1 0
50
#define DAHDI_B2 1
51
#define DAHDI_D 2
52
53
#define D 0
54
#define B1 1
55
#define B2 2
56
57
/*
58
 * Mode Te for all
59
 */
60
static int modes;
61
static int nt_modes[hfc_MAX_BOARDS];
62
static int nt_modes_count;
63
static int force_l1_up;
64
static struct proc_dir_entry *hfc_proc_dahdi_hfcs_dir;
65
66
#define DEBUG
67
#ifdef DEBUG
68
int debug_level;
69
#endif
70
71
#ifndef FALSE
72
#define FALSE 0
73
#endif
74
#ifndef TRUE
75
#define TRUE (!FALSE)
76
#endif
77
78
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
79
#define	SET_PROC_DIRENTRY_OWNER(p)	do { (p)->owner = THIS_MODULE; } while(0);
80
#else
81
#define	SET_PROC_DIRENTRY_OWNER(p)	do { } while(0);
82
#endif
83
84
static DEFINE_PCI_DEVICE_TABLE(hfc_pci_ids) = {
85
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0,
86
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000,
88
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006,
90
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
91
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007,
92
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
93
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008,
94
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
95
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009,
96
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
97
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A,
98
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
99
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B,
100
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
101
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C,
102
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
103
	{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100,
104
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
105
	{PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1,
106
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
107
	{PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675,
108
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
109
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT,
110
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
111
	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T,
112
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
113
	{PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575,
114
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
115
	{PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0,
116
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
117
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,
118
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,
120
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
121
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,
122
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
123
	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,
124
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
125
	{PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_3069,
126
		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
127
	{0,}
128
};
129
130
MODULE_DEVICE_TABLE(pci, hfc_pci_ids);
131
132
static int __devinit hfc_probe(struct pci_dev *dev
133
			, const struct pci_device_id *ent);
134
static void __devexit hfc_remove(struct pci_dev *dev);
135
136
static struct pci_driver hfc_driver = {
137
	.name     = hfc_DRIVER_NAME,
138
	.id_table = hfc_pci_ids,
139
	.probe    = hfc_probe,
140
	.remove   = __devexit_p(hfc_remove),
141
};
142
143
/******************************************
144
 * HW routines
145
 ******************************************/
146
147
static void hfc_softreset(struct hfc_card *card)
148
{
149
	printk(KERN_INFO hfc_DRIVER_PREFIX
150
		"card %d: "
151
		"resetting\n",
152
		card->cardnum);
153
154
/*
155
 * Softreset procedure. Put it on, wait and off again
156
 */
157
	hfc_outb(card, hfc_CIRM, hfc_CIRM_RESET);
158
	udelay(6);
159
	hfc_outb(card, hfc_CIRM, 0);
160
161
	set_current_state(TASK_UNINTERRUPTIBLE);
162
	schedule_timeout((hfc_RESET_DELAY * HZ) / 1000);
163
}
164
165
static void hfc_resetCard(struct hfc_card *card)
166
{
167
	card->regs.m1 = 0;
168
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
169
170
	card->regs.m2 = 0;
171
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
172
173
	hfc_softreset(card);
174
175
	card->regs.trm = 0;
176
	hfc_outb(card, hfc_TRM, card->regs.trm);
177
178
	/*
179
	 * Select the non-capacitive line mode for the S/T interface
180
	 */
181
	card->regs.sctrl = hfc_SCTRL_NONE_CAP;
182
183
	if (card->nt_mode) {
184
		/*
185
		 * ST-Bit delay for NT-Mode
186
		 */
187
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_NT);
188
189
		card->regs.sctrl |= hfc_SCTRL_MODE_NT;
190
	} else {
191
		/*
192
		 * ST-Bit delay for TE-Mode
193
		 */
194
		hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_TE);
195
196
		card->regs.sctrl |= hfc_SCTRL_MODE_TE;
197
	}
198
199
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
200
201
	/*
202
	 * S/T Auto awake
203
	 */
204
	card->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
205
	hfc_outb(card, hfc_SCTRL_E, card->regs.sctrl_e);
206
207
	/*
208
	 * No B-channel enabled at startup
209
	 */
210
	card->regs.sctrl_r = 0;
211
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
212
213
	/*
214
	 * HFC Master Mode
215
	 */
216
	hfc_outb(card, hfc_MST_MODE, hfc_MST_MODE_MASTER);
217
218
	/*
219
	 * Connect internal blocks
220
	 */
221
	card->regs.connect =
222
		hfc_CONNECT_B1_HFC_from_ST |
223
		hfc_CONNECT_B1_ST_from_HFC |
224
		hfc_CONNECT_B1_GCI_from_HFC |
225
		hfc_CONNECT_B2_HFC_from_ST |
226
		hfc_CONNECT_B2_ST_from_HFC |
227
		hfc_CONNECT_B2_GCI_from_HFC;
228
	hfc_outb(card, hfc_CONNECT, card->regs.connect);
229
230
	/*
231
	 * All bchans are HDLC by default, not useful, actually
232
	 * since mode is set during open()
233
	 */
234
	hfc_outb(card, hfc_CTMT, 0);
235
236
	/*
237
	 * bit order
238
	 */
239
	hfc_outb(card, hfc_CIRM, 0);
240
241
	/*
242
	 * Enable D-rx FIFO. At least one FIFO must be enabled (by specs)
243
	 */
244
	card->regs.fifo_en = hfc_FIFOEN_DRX;
245
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
246
247
	card->late_irqs = 0;
248
249
	/*
250
	 * Clear already pending ints
251
	 */
252
	hfc_inb(card, hfc_INT_S1);
253
	hfc_inb(card, hfc_INT_S2);
254
255
	/*
256
	 * Enable IRQ output
257
	 */
258
	card->regs.m1 = hfc_INTS_DREC | hfc_INTS_L1STATE | hfc_INTS_TIMER;
259
	hfc_outb(card, hfc_INT_M1, card->regs.m1);
260
261
	card->regs.m2 = hfc_M2_IRQ_ENABLE;
262
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
263
264
	/*
265
	 * Unlocks the states machine
266
	 */
267
	hfc_outb(card, hfc_STATES, 0);
268
269
	/*
270
	 * There's no need to explicitly activate L1 now.
271
	 * Activation is managed inside the interrupt routine.
272
	 */
273
}
274
275
static void hfc_update_fifo_state(struct hfc_card *card)
276
{
277
	/*
278
	 * I'm not sure if irqsave is needed but there could be a race
279
	 * condition since hfc_update_fifo_state could be called from
280
	 * both the IRQ handler and the *_(open|close) functions
281
	 */
282
283
	unsigned long flags;
284
	spin_lock_irqsave(&card->chans[B1].lock, flags);
285
	if (!card->fifo_suspended &&
286
		(card->chans[B1].status == open_framed ||
287
		card->chans[B1].status == open_voice)) {
288
289
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1RX)) {
290
			card->regs.fifo_en |= hfc_FIFOEN_B1RX;
291
			hfc_clear_fifo_rx(&card->chans[B1].rx);
292
		}
293
294
		if (!(card->regs.fifo_en & hfc_FIFOEN_B1TX)) {
295
			card->regs.fifo_en |= hfc_FIFOEN_B1TX;
296
			hfc_clear_fifo_tx(&card->chans[B1].tx);
297
		}
298
	} else {
299
		if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
300
			card->regs.fifo_en &= ~hfc_FIFOEN_B1RX;
301
		if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
302
			card->regs.fifo_en &= ~hfc_FIFOEN_B1TX;
303
	}
304
	spin_unlock_irqrestore(&card->chans[B1].lock, flags);
305
306
	spin_lock_irqsave(&card->chans[B2].lock, flags);
307
	if (!card->fifo_suspended &&
308
		(card->chans[B2].status == open_framed ||
309
		card->chans[B2].status == open_voice ||
310
		card->chans[B2].status == sniff_aux)) {
311
312
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2RX)) {
313
			card->regs.fifo_en |= hfc_FIFOEN_B2RX;
314
			hfc_clear_fifo_rx(&card->chans[B2].rx);
315
		}
316
317
		if (!(card->regs.fifo_en & hfc_FIFOEN_B2TX)) {
318
			card->regs.fifo_en |= hfc_FIFOEN_B2TX;
319
			hfc_clear_fifo_tx(&card->chans[B2].tx);
320
		}
321
	} else {
322
		if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
323
			card->regs.fifo_en &= ~hfc_FIFOEN_B2RX;
324
		if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
325
			card->regs.fifo_en &= ~hfc_FIFOEN_B2TX;
326
	}
327
	spin_unlock_irqrestore(&card->chans[B2].lock, flags);
328
329
	spin_lock_irqsave(&card->chans[D].lock, flags);
330
	if (!card->fifo_suspended &&
331
		card->chans[D].status == open_framed) {
332
333
		if (!(card->regs.fifo_en & hfc_FIFOEN_DTX)) {
334
			card->regs.fifo_en |= hfc_FIFOEN_DTX;
335
336
			card->chans[D].tx.ugly_framebuf_size = 0;
337
			card->chans[D].tx.ugly_framebuf_off = 0;
338
		}
339
	} else {
340
		if (card->regs.fifo_en & hfc_FIFOEN_DTX)
341
			card->regs.fifo_en &= ~hfc_FIFOEN_DTX;
342
	}
343
	spin_unlock_irqrestore(&card->chans[D].lock, flags);
344
345
	hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
346
}
347
348
static inline void hfc_suspend_fifo(struct hfc_card *card)
349
{
350
	card->fifo_suspended = TRUE;
351
352
	hfc_update_fifo_state(card);
353
354
	/*
355
	 * When L1 goes down D rx receives garbage; it is nice to
356
	 * clear it to avoid a CRC error on reactivation
357
	 * udelay is needed because the FIFO deactivation happens
358
	 * in 250us
359
	 */
360
	udelay(250);
361
	hfc_clear_fifo_rx(&card->chans[D].rx);
362
363
#ifdef DEBUG
364
	if (debug_level >= 3) {
365
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
366
			"card %d: "
367
			"FIFOs suspended\n",
368
			card->cardnum);
369
	}
370
#endif
371
}
372
373
static inline void hfc_resume_fifo(struct hfc_card *card)
374
{
375
	card->fifo_suspended = FALSE;
376
377
	hfc_update_fifo_state(card);
378
379
#ifdef DEBUG
380
	if (debug_level >= 3) {
381
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
382
			"card %d: "
383
			"FIFOs resumed\n",
384
			card->cardnum);
385
	}
386
#endif
387
}
388
389
static void hfc_check_l1_up(struct hfc_card *card)
390
{
391
	if ((!card->nt_mode && card->l1_state != 7)
392
		|| (card->nt_mode && card->l1_state != 3)) {
393
394
		hfc_outb(card, hfc_STATES, hfc_STATES_DO_ACTION |
395
			hfc_STATES_ACTIVATE|
396
				hfc_STATES_NT_G2_G3);
397
398
	/*
399
	 * 0 because this is quite verbose when an inferface is unconnected, jaw
400
	 */
401
#if 0
402
		if (debug_level >= 1) {
403
			printk(KERN_DEBUG hfc_DRIVER_PREFIX
404
				"card %d: "
405
				"L1 is down, bringing up L1.\n",
406
				card->cardnum);
407
		}
408
#endif
409
	}
410
}
411
412
413
/*******************
414
 * Dahdi interface *
415
 *******************/
416
417
static int hfc_dahdi_open(struct dahdi_chan *dahdi_chan)
418
{
419
	struct hfc_chan_duplex *chan = dahdi_chan->pvt;
420
	struct hfc_card *card = chan->card;
421
422
	spin_lock(&chan->lock);
423
424
	switch (chan->number) {
425
	case D:
426
		if (chan->status != free &&
427
			chan->status != open_framed) {
428
			spin_unlock(&chan->lock);
429
			return -EBUSY;
430
		}
431
		chan->status = open_framed;
432
	break;
433
434
	case B1:
435
	case B2:
436
		if (chan->status != free) {
437
			spin_unlock(&chan->lock);
438
			return -EBUSY;
439
		}
440
		chan->status = open_voice;
441
	break;
442
	}
443
444
	chan->open_by_dahdi = TRUE;
445
	try_module_get(THIS_MODULE);
446
	spin_unlock(&chan->lock);
447
448
	switch (chan->number) {
449
	case D:
450
	break;
451
452
	case B1:
453
		card->regs.m2 |= hfc_M2_PROC_TRANS;
454
		/*
455
		 * Enable transparent mode
456
		 */
457
		card->regs.ctmt |= hfc_CTMT_TRANSB1;
458
		/*
459
		* Reversed bit order
460
		*/
461
		card->regs.cirm |= hfc_CIRM_B1_REV;
462
		/*
463
		 * Enable transmission
464
		 */
465
		card->regs.sctrl |= hfc_SCTRL_B1_ENA;
466
		/*
467
		 * Enable reception
468
		 */
469
		card->regs.sctrl_r |= hfc_SCTRL_R_B1_ENA;
470
	break;
471
472
	case B2:
473
		card->regs.m2 |= hfc_M2_PROC_TRANS;
474
		card->regs.ctmt |= hfc_CTMT_TRANSB2;
475
		card->regs.cirm |= hfc_CIRM_B2_REV;
476
		card->regs.sctrl |= hfc_SCTRL_B2_ENA;
477
		card->regs.sctrl_r |= hfc_SCTRL_R_B2_ENA;
478
	break;
479
480
	}
481
482
	/*
483
	 * If not already enabled, enable processing transition (8KHz)
484
	 * interrupt
485
	 */
486
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
487
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
488
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
489
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
490
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
491
492
	hfc_update_fifo_state(card);
493
494
	printk(KERN_INFO hfc_DRIVER_PREFIX
495
		"card %d: "
496
		"chan %s opened as %s.\n",
497
		card->cardnum,
498
		chan->name,
499
		dahdi_chan->name);
500
501
	return 0;
502
}
503
504
static int hfc_dahdi_close(struct dahdi_chan *dahdi_chan)
505
{
506
	struct hfc_chan_duplex *chan = dahdi_chan->pvt;
507
	struct hfc_card *card = chan->card;
508
509
	if (!card) {
510
		printk(KERN_CRIT hfc_DRIVER_PREFIX
511
			"hfc_dahdi_close called with NULL card\n");
512
		return -1;
513
	}
514
515
	spin_lock(&chan->lock);
516
517
	if (chan->status == free) {
518
		spin_unlock(&chan->lock);
519
		return -EINVAL;
520
	}
521
522
	chan->status = free;
523
	chan->open_by_dahdi = FALSE;
524
525
	spin_unlock(&chan->lock);
526
527
	switch (chan->number) {
528
	case D:
529
	break;
530
531
	case B1:
532
		card->regs.ctmt &= ~hfc_CTMT_TRANSB1;
533
		card->regs.cirm &= ~hfc_CIRM_B1_REV;
534
		card->regs.sctrl &= ~hfc_SCTRL_B1_ENA;
535
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B1_ENA;
536
	break;
537
538
	case B2:
539
		card->regs.ctmt &= ~hfc_CTMT_TRANSB2;
540
		card->regs.cirm &= ~hfc_CIRM_B2_REV;
541
		card->regs.sctrl &= ~hfc_SCTRL_B2_ENA;
542
		card->regs.sctrl_r &= ~hfc_SCTRL_R_B2_ENA;
543
	break;
544
	}
545
546
	if (card->chans[B1].status == free &&
547
		card->chans[B2].status == free)
548
		card->regs.m2 &= ~hfc_M2_PROC_TRANS;
549
550
	hfc_outb(card, hfc_INT_M2, card->regs.m2);
551
	hfc_outb(card, hfc_CTMT, card->regs.ctmt);
552
	hfc_outb(card, hfc_CIRM, card->regs.cirm);
553
	hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
554
	hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
555
556
	hfc_update_fifo_state(card);
557
558
	module_put(THIS_MODULE);
559
560
	printk(KERN_INFO hfc_DRIVER_PREFIX
561
		"card %d: "
562
		"chan %s closed as %s.\n",
563
		card->cardnum,
564
		chan->name,
565
		dahdi_chan->name);
566
567
	return 0;
568
}
569
570
static int hfc_dahdi_rbsbits(struct dahdi_chan *chan, int bits)
571
{
572
	return 0;
573
}
574
575
static int hfc_dahdi_ioctl(struct dahdi_chan *chan,
576
		unsigned int cmd, unsigned long data)
577
{
578
	switch (cmd) {
579
580
	default:
581
		return -ENOTTY;
582
	}
583
584
	return 0;
585
}
586
587
static void hfc_hdlc_hard_xmit(struct dahdi_chan *d_chan)
588
{
589
	struct hfc_chan_duplex *chan = d_chan->pvt;
590
	struct hfc_card *card = chan->card;
591
	struct dahdi_hfc *hfccard = card->dahdi_dev;
592
593
	atomic_inc(&hfccard->hdlc_pending);
594
595
}
596
597
static int hfc_dahdi_startup(struct file *file, struct dahdi_span *span)
598
{
599
    struct dahdi_hfc *dahdi_hfcs = dahdi_hfc_from_span(span);
600
    struct hfc_card *hfctmp = dahdi_hfcs->card;
601
    int alreadyrunning;
602
603
	if (!hfctmp) {
604
		printk(KERN_INFO hfc_DRIVER_PREFIX
605
			"card %d: "
606
			"no card for span at startup!\n",
607
			hfctmp->cardnum);
608
	}
609
610
	alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
611
612
	if (!alreadyrunning)
613
		span->flags |= DAHDI_FLAG_RUNNING;
614
615
	return 0;
616
}
617
618
static int hfc_dahdi_shutdown(struct dahdi_span *span)
619
{
620
	return 0;
621
}
622
623
static int hfc_dahdi_maint(struct dahdi_span *span, int cmd)
624
{
625
	return 0;
626
}
627
628
static int hfc_dahdi_chanconfig(struct file *file, struct dahdi_chan *d_chan, int sigtype)
629
{
630
	struct hfc_chan_duplex *chan = d_chan->pvt;
631
	struct hfc_card *card = chan->card;
632
	struct dahdi_hfc *hfccard = card->dahdi_dev;
633
634
	if ((sigtype == DAHDI_SIG_HARDHDLC) && (hfccard->sigchan == d_chan)) {
635
		hfccard->sigactive = 0;
636
		atomic_set(&hfccard->hdlc_pending, 0);
637
	}
638
639
	return 0;
640
}
641
642
static int hfc_dahdi_spanconfig(struct file *file, struct dahdi_span *span,
643
		struct dahdi_lineconfig *lc)
644
{
645
	span->lineconfig = lc->lineconfig;
646
647
	return 0;
648
}
649
650
static const struct dahdi_span_ops hfc_dahdi_span_ops = {
651
       .owner = THIS_MODULE,
652
       .chanconfig = hfc_dahdi_chanconfig,
653
       .spanconfig = hfc_dahdi_spanconfig,
654
       .startup = hfc_dahdi_startup,
655
       .shutdown = hfc_dahdi_shutdown,
656
       .maint = hfc_dahdi_maint,
657
       .rbsbits = hfc_dahdi_rbsbits,
658
       .open = hfc_dahdi_open,
659
       .close = hfc_dahdi_close,
660
       .ioctl = hfc_dahdi_ioctl,
661
       .hdlc_hard_xmit = hfc_hdlc_hard_xmit
662
};
663
664
static int hfc_dahdi_initialize(struct dahdi_hfc *hfccard)
665
{
666
	 struct hfc_card *hfctmp = hfccard->card;
667
	int i;
668
669
	hfccard->ddev = dahdi_create_device();
670
	if (!hfccard->ddev)
671
		return -ENOMEM;
672
673
	memset(&hfccard->span, 0x0, sizeof(struct dahdi_span));
674
675
		/*
676
		 * ZTHFC
677
		 *
678
		 * Cards' and channels' names shall contain "ZTHFC"
679
		 * as the dahdi-tools look for this string to guess framing.
680
		 * We don't want to modify dahdi-tools only in order to change this.
681
		 *
682
		 * So we choose for a span name: DAHDI HFC-S formerly known as ZTHFC. :-)
683
		 */
684
685
	sprintf(hfccard->span.name, "DAHDI_HFCS_FKA_ZTHFC%d", hfctmp->cardnum + 1);
686
	sprintf(hfccard->span.desc,
687
			"HFC-S PCI A ISDN card %d [%s] ",
688
			hfctmp->cardnum,
689
			hfctmp->nt_mode ? "NT" : "TE");
690
	hfccard->span.spantype = hfctmp->nt_mode ? "NT" : "TE";
691
	hfccard->ddev->manufacturer = "Cologne Chips";
692
	hfccard->span.flags = 0;
693
	hfccard->span.ops = &hfc_dahdi_span_ops;
694
	hfccard->ddev->devicetype = kasprintf(GFP_KERNEL, "HFC-S PCI-A ISDN");
695
	hfccard->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
696
			hfctmp->pcidev->bus->number,
697
			PCI_SLOT(hfctmp->pcidev->devfn) + 1);
698
	hfccard->span.chans = hfccard->_chans;
699
	hfccard->span.channels = 3;
700
	for (i = 0; i < hfccard->span.channels; i++)
701
		hfccard->_chans[i] = &hfccard->chans[i];
702
	hfccard->span.deflaw = DAHDI_LAW_ALAW;
703
	hfccard->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS;
704
	hfccard->span.offset = 0;
705
706
	for (i = 0; i < hfccard->span.channels; i++) {
707
		memset(&hfccard->chans[i], 0x0, sizeof(struct dahdi_chan));
708
709
		sprintf(hfccard->chans[i].name,
710
				"DAHDI_HFCS_FKA_ZTHFC%d/%d/%d",
711
				hfctmp->cardnum + 1, 0, i + 1);
712
713
		printk(KERN_INFO hfc_DRIVER_PREFIX
714
			"card %d: "
715
			"registered %s\n",
716
			hfctmp->cardnum,
717
			hfccard->chans[i].name);
718
719
		if (i == hfccard->span.channels - 1) {
720
			hfccard->chans[i].sigcap = DAHDI_SIG_HARDHDLC;
721
			hfccard->sigchan = &hfccard->chans[DAHDI_D];
722
			hfccard->sigactive = 0;
723
			atomic_set(&hfccard->hdlc_pending, 0);
724
		} else {
725
			hfccard->chans[i].sigcap =
726
				DAHDI_SIG_CLEAR | DAHDI_SIG_DACS;
727
		}
728
729
		hfccard->chans[i].chanpos = i + 1;
730
	}
731
732
	hfccard->chans[DAHDI_D].readchunk  =
733
		hfctmp->chans[D].rx.dahdi_buffer;
734
735
	hfccard->chans[DAHDI_D].writechunk =
736
		hfctmp->chans[D].tx.dahdi_buffer;
737
738
	hfccard->chans[DAHDI_D].pvt = &hfctmp->chans[D];
739
740
	hfccard->chans[DAHDI_B1].readchunk  =
741
		hfctmp->chans[B1].rx.dahdi_buffer;
742
743
	hfccard->chans[DAHDI_B1].writechunk =
744
		hfctmp->chans[B1].tx.dahdi_buffer;
745
746
	hfccard->chans[DAHDI_B1].pvt = &hfctmp->chans[B1];
747
748
	hfccard->chans[DAHDI_B2].readchunk  =
749
		hfctmp->chans[B2].rx.dahdi_buffer;
750
751
	hfccard->chans[DAHDI_B2].writechunk =
752
		hfctmp->chans[B2].tx.dahdi_buffer;
753
754
	hfccard->chans[DAHDI_B2].pvt = &hfctmp->chans[B2];
755
756
	list_add_tail(&hfccard->span.device_node, &hfccard->ddev->spans);
757
	if (dahdi_register_device(hfccard->ddev, &hfccard->card->pcidev->dev)) {
758
		printk(KERN_NOTICE "Unable to register device with DAHDI\n");
759
		return -1;
760
	}
761
762
	return 0;
763
}
764
765
static void hfc_dahdi_transmit(struct hfc_chan_simplex *chan)
766
{
767
	hfc_fifo_put(chan, chan->dahdi_buffer, DAHDI_CHUNKSIZE);
768
}
769
770
static void hfc_dahdi_receive(struct hfc_chan_simplex *chan)
771
{
772
	hfc_fifo_get(chan, chan->dahdi_buffer, DAHDI_CHUNKSIZE);
773
}
774
775
/******************************************
776
 * Interrupt Handler
777
 ******************************************/
778
779
static void hfc_handle_timer_interrupt(struct hfc_card *card);
780
static void hfc_handle_state_interrupt(struct hfc_card *card);
781
static void hfc_handle_processing_interrupt(struct hfc_card *card);
782
static void hfc_frame_arrived(struct hfc_chan_duplex *chan);
783
static void hfc_handle_voice(struct hfc_card *card);
784
785
#if (KERNEL_VERSION(2, 6, 24) < LINUX_VERSION_CODE)
786
static irqreturn_t hfc_interrupt(int irq, void *dev_id)
787
#else
788
static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
789
#endif
790
{
791
	struct hfc_card *card = dev_id;
792
	unsigned long flags;
793
	u8 status, s1, s2;
794
795
	if (!card) {
796
		printk(KERN_CRIT hfc_DRIVER_PREFIX
797
			"spurious interrupt (IRQ %d)\n",
798
			irq);
799
		return IRQ_NONE;
800
	}
801
802
	spin_lock_irqsave(&card->lock, flags);
803
	status = hfc_inb(card, hfc_STATUS);
804
	if (!(status & hfc_STATUS_ANYINT)) {
805
		/*
806
		 * maybe we are sharing the irq
807
		 */
808
		spin_unlock_irqrestore(&card->lock, flags);
809
		return IRQ_NONE;
810
	}
811
812
	/* We used to ingore the IRQ when the card was in processing
813
	 * state but apparently there is no restriction to access the
814
	 * card in such state:
815
	 *
816
	 * Joerg Ciesielski wrote:
817
	 * > There is no restriction for the IRQ handler to access
818
	 * > HFC-S PCI during processing phase. A IRQ latency of 375 us
819
	 * > is also no problem since there are no interrupt sources in
820
	 * > HFC-S PCI which must be handled very fast.
821
	 * > Due to its deep fifos the IRQ latency can be several ms with
822
	 * > out the risk of loosing data. Even the S/T state interrupts
823
	 * > must not be handled with a latency less than <5ms.
824
	 * >
825
	 * > The processing phase only indicates that HFC-S PCI is
826
	 * > processing the Fifos as PCI master so that data is read and
827
	 * > written in the 32k memory window. But there is no restriction
828
	 * > to access data in the memory window during this time.
829
	 *
830
	 * // if (status & hfc_STATUS_PCI_PROC) {
831
	 * // return IRQ_HANDLED;
832
	 * // }
833
	 */
834
835
	s1 = hfc_inb(card, hfc_INT_S1);
836
	s2 = hfc_inb(card, hfc_INT_S2);
837
838
	if (s1 != 0) {
839
		if (s1 & hfc_INTS_TIMER) {
840
			/*
841
			 * timer (bit 7)
842
			 */
843
			hfc_handle_timer_interrupt(card);
844
		}
845
846
		if (s1 & hfc_INTS_L1STATE) {
847
			/*
848
			 * state machine (bit 6)
849
			 */
850
			hfc_handle_state_interrupt(card);
851
		}
852
853
		if (s1 & hfc_INTS_DREC) {
854
			/*
855
			 * D chan RX (bit 5)
856
			 */
857
			hfc_frame_arrived(&card->chans[D]);
858
		}
859
860
		if (s1 & hfc_INTS_B1REC) {
861
			/*
862
			 * B1 chan RX (bit 3)
863
			 */
864
			hfc_frame_arrived(&card->chans[B1]);
865
		}
866
867
		if (s1 & hfc_INTS_B2REC) {
868
			/*
869
			 * B2 chan RX (bit 4)
870
			 */
871
			hfc_frame_arrived(&card->chans[B2]);
872
		}
873
874
		if (s1 & hfc_INTS_DTRANS) {
875
			/*
876
			 * D chan TX (bit 2)
877
			 */
878
		}
879
880
		if (s1 & hfc_INTS_B1TRANS) {
881
			/*
882
			 * B1 chan TX (bit 0)
883
			 */
884
		}
885
886
		if (s1 & hfc_INTS_B2TRANS) {
887
			/*
888
			 * B2 chan TX (bit 1)
889
			 */
890
		}
891
892
	}
893
894
	if (s2 != 0) {
895
		if (s2 & hfc_M2_PMESEL) {
896
			/*
897
			 * kaboom irq (bit 7)
898
			 *
899
			 * CologneChip says:
900
			 *
901
			 * the meaning of this fatal error bit is that HFC-S
902
			 * PCI as PCI master could not access the PCI bus
903
			 * within 125us to finish its data processing. If this
904
			 * happens only very seldom it does not cause big
905
			 * problems but of course some B-channel or D-channel
906
			 * data will be corrupted due to this event.
907
			 *
908
			 * Unfortunately this bit is only set once after the
909
			 * problem occurs and can only be reseted by a
910
			 * software reset. That means it is not easily
911
			 * possible to check how often this fatal error
912
			 * happens.
913
			 *
914
			 */
915
916
			if (!card->sync_loss_reported) {
917
				printk(KERN_CRIT hfc_DRIVER_PREFIX
918
					"card %d: "
919
					"sync lost, pci performance too low!\n",
920
					card->cardnum);
921
922
				card->sync_loss_reported = TRUE;
923
			}
924
		}
925
926
		if (s2 & hfc_M2_GCI_MON_REC) {
927
			/*
928
			 * RxR monitor channel (bit 2)
929
			 */
930
		}
931
932
		if (s2 & hfc_M2_GCI_I_CHG) {
933
			/*
934
			 * GCI I-change  (bit 1)
935
			 */
936
		}
937
938
		if (s2 & hfc_M2_PROC_TRANS) {
939
			/*
940
			 * processing/non-processing transition  (bit 0)
941
			 */
942
			hfc_handle_processing_interrupt(card);
943
		}
944
945
	}
946
947
	spin_unlock_irqrestore(&card->lock, flags);
948
949
	return IRQ_HANDLED;
950
}
951
952
static void hfc_handle_timer_interrupt(struct hfc_card *card)
953
{
954
	if (card->ignore_first_timer_interrupt) {
955
		card->ignore_first_timer_interrupt = FALSE;
956
		return;
957
	}
958
959
	if ((card->nt_mode && card->l1_state == 3) ||
960
		(!card->nt_mode && card->l1_state == 7)) {
961
962
		card->regs.ctmt &= ~hfc_CTMT_TIMER_MASK;
963
		hfc_outb(card, hfc_CTMT, card->regs.ctmt);
964
965
		hfc_resume_fifo(card);
966
	}
967
}
968
969
static void hfc_handle_state_interrupt(struct hfc_card *card)
970
{
971
	u8 new_state = hfc_inb(card, hfc_STATES)  & hfc_STATES_STATE_MASK;
972
973
#ifdef DEBUG
974
	if (debug_level >= 1) {
975
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
976
			"card %d: "
977
			"layer 1 state = %c%d\n",
978
			card->cardnum,
979
			card->nt_mode ? 'G' : 'F',
980
			new_state);
981
	}
982
#endif
983
984
	if (card->nt_mode) {
985
		/*
986
		 * NT mode
987
		 */
988
989
		if (new_state == 3) {
990
			/*
991
			 * fix to G3 state (see specs)
992
			 */
993
			hfc_outb(card, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
994
		}
995
996
		if (new_state == 3 && card->l1_state != 3)
997
			hfc_resume_fifo(card);
998
999
		if (new_state != 3 && card->l1_state == 3)
1000
			hfc_suspend_fifo(card);
1001
1002
	} else {
1003
		if (new_state == 3) {
1004
			/*
1005
			 * Keep L1 up... zaptel & libpri expects
1006
			 * a always up L1...
1007
			 * Enable only  when using an unpatched libpri
1008
			 *
1009
			 * Are we still using unpatched libpri? Is this tested at runtime???
1010
			 * Does it only affect zaptel or DAHDI, too?
1011
			 */
1012
1013
			if (force_l1_up) {
1014
				hfc_outb(card, hfc_STATES,
1015
					hfc_STATES_DO_ACTION |
1016
					hfc_STATES_ACTIVATE|
1017
					hfc_STATES_NT_G2_G3);
1018
			}
1019
		}
1020
1021
		if (new_state == 7 && card->l1_state != 7) {
1022
			/*
1023
			 * TE is now active, schedule FIFO activation after
1024
			 * some time, otherwise the first frames are lost
1025
			 */
1026
1027
			card->regs.ctmt |= hfc_CTMT_TIMER_50 |
1028
				hfc_CTMT_TIMER_CLEAR;
1029
			hfc_outb(card, hfc_CTMT, card->regs.ctmt);
1030
1031
			/*
1032
			 * Activating the timer firest an
1033
			 * interrupt immediately, we
1034
			 * obviously need to ignore it
1035
			 */
1036
			card->ignore_first_timer_interrupt = TRUE;
1037
		}
1038
1039
		if (new_state != 7 && card->l1_state == 7) {
1040
			/*
1041
			 * TE has become inactive, disable FIFO
1042
			 */
1043
			hfc_suspend_fifo(card);
1044
		}
1045
	}
1046
1047
	card->l1_state = new_state;
1048
}
1049
1050
static void hfc_handle_processing_interrupt(struct hfc_card *card)
1051
{
1052
	int available_bytes = 0;
1053
1054
	/*
1055
	 * Synchronize with the first enabled channel
1056
	 */
1057
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1058
		available_bytes = hfc_fifo_used_rx(&card->chans[B1].rx);
1059
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1060
		available_bytes = hfc_fifo_used_rx(&card->chans[B2].rx);
1061
	else
1062
		available_bytes = -1;
1063
1064
	if ((available_bytes == -1 && card->ticks == 8) ||
1065
		available_bytes >= DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD) {
1066
		card->ticks = 0;
1067
1068
		if (available_bytes > DAHDI_CHUNKSIZE*2 + hfc_RX_FIFO_PRELOAD) {
1069
			card->late_irqs++;
1070
			/*
1071
			 * we are out of sync, clear fifos, jaw
1072
			 */
1073
			hfc_clear_fifo_rx(&card->chans[B1].rx);
1074
			hfc_clear_fifo_tx(&card->chans[B1].tx);
1075
			hfc_clear_fifo_rx(&card->chans[B2].rx);
1076
			hfc_clear_fifo_tx(&card->chans[B2].tx);
1077
1078
#ifdef DEBUG
1079
			if (debug_level >= 4) {
1080
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1081
					"card %d: "
1082
					"late IRQ, %d bytes late\n",
1083
					card->cardnum,
1084
					available_bytes -
1085
						(DAHDI_CHUNKSIZE +
1086
						 hfc_RX_FIFO_PRELOAD));
1087
			}
1088
#endif
1089
		} else {
1090
			hfc_handle_voice(card);
1091
		}
1092
	}
1093
1094
	card->ticks++;
1095
}
1096
1097
1098
static void hfc_handle_voice(struct hfc_card *card)
1099
{
1100
	struct dahdi_hfc *hfccard = card->dahdi_dev;
1101
	int frame_left, res;
1102
	unsigned char buf[hfc_HDLC_BUF_LEN];
1103
	unsigned int size = sizeof(buf) / sizeof(buf[0]);
1104
1105
1106
	if (card->chans[B1].status != open_voice &&
1107
		card->chans[B2].status != open_voice)
1108
		return;
1109
1110
	dahdi_transmit(&hfccard->span);
1111
1112
	if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
1113
		hfc_dahdi_transmit(&card->chans[B1].tx);
1114
	if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
1115
		hfc_dahdi_transmit(&card->chans[B2].tx);
1116
1117
	/*
1118
	 * dahdi hdlc frame tx
1119
	 */
1120
1121
	if (atomic_read(&hfccard->hdlc_pending)) {
1122
		hfc_check_l1_up(card);
1123
		res = dahdi_hdlc_getbuf(hfccard->sigchan, buf, &size);
1124
			if (size > 0) {
1125
				hfccard->sigactive = 1;
1126
				memcpy(card->chans[D].tx.ugly_framebuf +
1127
				card->chans[D].tx.ugly_framebuf_size,
1128
				buf, size);
1129
				card->chans[D].tx.ugly_framebuf_size += size;
1130
			if (res != 0) {
1131
					hfc_fifo_put_frame(&card->chans[D].tx,
1132
					card->chans[D].tx.ugly_framebuf,
1133
					card->chans[D].tx.ugly_framebuf_size);
1134
					++hfccard->frames_out;
1135
					hfccard->sigactive = 0;
1136
					card->chans[D].tx.ugly_framebuf_size
1137
						= 0;
1138
					atomic_dec(&hfccard->hdlc_pending);
1139
				}
1140
			}
1141
	}
1142
	/*
1143
	 * dahdi hdlc frame tx done
1144
	 */
1145
1146
	if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1147
		hfc_dahdi_receive(&card->chans[B1].rx);
1148
	else
1149
		memset(&card->chans[B1].rx.dahdi_buffer, 0x7f,
1150
			sizeof(card->chans[B1].rx.dahdi_buffer));
1151
1152
	if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1153
		hfc_dahdi_receive(&card->chans[B2].rx);
1154
	else
1155
		memset(&card->chans[B2].rx.dahdi_buffer, 0x7f,
1156
			sizeof(card->chans[B1].rx.dahdi_buffer));
1157
1158
	/*
1159
	 * Echo cancellation
1160
	 */
1161
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B1],
1162
			card->chans[B1].rx.dahdi_buffer,
1163
			card->chans[B1].tx.dahdi_buffer);
1164
	dahdi_ec_chunk(&hfccard->chans[DAHDI_B2],
1165
			card->chans[B2].rx.dahdi_buffer,
1166
			card->chans[B2].tx.dahdi_buffer);
1167
1168
	/*
1169
	 * dahdi hdlc frame rx
1170
	 */
1171
	if (hfc_fifo_has_frames(&card->chans[D].rx))
1172
		hfc_frame_arrived(&card->chans[D]);
1173
1174
	if (card->chans[D].rx.ugly_framebuf_size) {
1175
		frame_left = card->chans[D].rx.ugly_framebuf_size -
1176
			card->chans[D].rx.ugly_framebuf_off ;
1177
		if (frame_left > hfc_HDLC_BUF_LEN) {
1178
			dahdi_hdlc_putbuf(hfccard->sigchan,
1179
					card->chans[D].rx.ugly_framebuf +
1180
					card->chans[D].rx.ugly_framebuf_off,
1181
					hfc_HDLC_BUF_LEN);
1182
			card->chans[D].rx.ugly_framebuf_off +=
1183
				hfc_HDLC_BUF_LEN;
1184
		} else {
1185
			dahdi_hdlc_putbuf(hfccard->sigchan,
1186
					card->chans[D].rx.ugly_framebuf +
1187
					card->chans[D].rx.ugly_framebuf_off,
1188
					frame_left);
1189
			dahdi_hdlc_finish(hfccard->sigchan);
1190
			card->chans[D].rx.ugly_framebuf_size = 0;
1191
			card->chans[D].rx.ugly_framebuf_off = 0;
1192
		}
1193
	}
1194
	/*
1195
	 * dahdi hdlc frame rx done
1196
	 */
1197
1198
	if (hfccard->span.flags & DAHDI_FLAG_RUNNING)
1199
		dahdi_receive(&hfccard->span);
1200
1201
}
1202
1203
static void hfc_frame_arrived(struct hfc_chan_duplex *chan)
1204
{
1205
	struct hfc_card *card = chan->card;
1206
	int antiloop = 16;
1207
	struct sk_buff *skb;
1208
1209
	while (hfc_fifo_has_frames(&chan->rx) && --antiloop) {
1210
		int frame_size = hfc_fifo_get_frame_size(&chan->rx);
1211
1212
		if (frame_size < 3) {
1213
#ifdef DEBUG
1214
			if (debug_level >= 2)
1215
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1216
					"card %d: "
1217
					"chan %s: "
1218
					"invalid frame received, "
1219
					"just %d bytes\n",
1220
					card->cardnum,
1221
					chan->name,
1222
					frame_size);
1223
#endif
1224
1225
			hfc_fifo_drop_frame(&chan->rx);
1226
1227
1228
			continue;
1229
		} else if (frame_size == 3) {
1230
#ifdef DEBUG
1231
			if (debug_level >= 2)
1232
				printk(KERN_DEBUG hfc_DRIVER_PREFIX
1233
					"card %d: "
1234
					"chan %s: "
1235
					"empty frame received\n",
1236
					card->cardnum,
1237
					chan->name);
1238
#endif
1239
1240
			hfc_fifo_drop_frame(&chan->rx);
1241
1242
1243
			continue;
1244
		}
1245
1246
		if (chan->open_by_dahdi &&
1247
			card->chans[D].rx.ugly_framebuf_size) {
1248
1249
				/*
1250
				 * We have to wait for Dahdi to transmit the
1251
				 * frame... wait for next time
1252
				 */
1253
1254
				 break;
1255
		}
1256
1257
		skb = dev_alloc_skb(frame_size - 3);
1258
1259
		if (!skb) {
1260
			printk(KERN_ERR hfc_DRIVER_PREFIX
1261
				"card %d: "
1262
				"chan %s: "
1263
				"cannot allocate skb: frame dropped\n",
1264
				card->cardnum,
1265
				chan->name);
1266
1267
			hfc_fifo_drop_frame(&chan->rx);
1268
1269
1270
			continue;
1271
		}
1272
1273
1274
		/*
1275
		* HFC does the checksum
1276
		*/
1277
#ifndef CHECKSUM_HW
1278
		skb->ip_summed = CHECKSUM_COMPLETE;
1279
#else
1280
		skb->ip_summed = CHECKSUM_HW;
1281
#endif
1282
1283
		if (chan->open_by_dahdi) {
1284
			card->chans[D].rx.ugly_framebuf_size = frame_size - 1;
1285
1286
			if (hfc_fifo_get_frame(&card->chans[D].rx,
1287
				card->chans[D].rx.ugly_framebuf,
1288
				frame_size - 1) == -1) {
1289
				dev_kfree_skb(skb);
1290
				continue;
1291
			}
1292
1293
			memcpy(skb_put(skb, frame_size - 3),
1294
				card->chans[D].rx.ugly_framebuf,
1295
				frame_size - 3);
1296
		} else {
1297
			if (hfc_fifo_get_frame(&chan->rx,
1298
				skb_put(skb, frame_size - 3),
1299
				frame_size - 3) == -1) {
1300
				dev_kfree_skb(skb);
1301
				continue;
1302
			}
1303
		}
1304
	}
1305
1306
	if (!antiloop)
1307
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1308
			"card %d: "
1309
			"Infinite loop detected\n",
1310
			card->cardnum);
1311
}
1312
1313
/******************************************
1314
 * Module initialization and cleanup
1315
 ******************************************/
1316
1317
static int __devinit hfc_probe(struct pci_dev *pci_dev,
1318
	const struct pci_device_id *ent)
1319
{
1320
	static int cardnum;
1321
	int err;
1322
	int i;
1323
1324
	struct hfc_card *card = NULL;
1325
	struct dahdi_hfc *dahdi_hfcs = NULL;
1326
	card = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
1327
	if (!card) {
1328
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1329
			"unable to kmalloc!\n");
1330
		err = -ENOMEM;
1331
		goto err_alloc_hfccard;
1332
	}
1333
1334
	memset(card, 0x00, sizeof(struct hfc_card));
1335
	card->cardnum = cardnum;
1336
	card->pcidev = pci_dev;
1337
	spin_lock_init(&card->lock);
1338
1339
	pci_set_drvdata(pci_dev, card);
1340
1341
	err = pci_enable_device(pci_dev);
1342
	if (err)
1343
		goto err_pci_enable_device;
1344
1345
	err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT);
1346
	if (err) {
1347
		printk(KERN_ERR hfc_DRIVER_PREFIX
1348
			"card %d: "
1349
			"No suitable DMA configuration available.\n",
1350
			card->cardnum);
1351
		goto err_pci_set_dma_mask;
1352
	}
1353
1354
	pci_write_config_word(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
1355
	err = pci_request_regions(pci_dev, hfc_DRIVER_NAME);
1356
	if (err) {
1357
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1358
			"card %d: "
1359
			"cannot request I/O memory region\n",
1360
			card->cardnum);
1361
		goto err_pci_request_regions;
1362
	}
1363
1364
	pci_set_master(pci_dev);
1365
1366
	if (!pci_dev->irq) {
1367
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1368
			"card %d: "
1369
			"no irq!\n",
1370
			card->cardnum);
1371
		err = -ENODEV;
1372
		goto err_noirq;
1373
	}
1374
1375
	card->io_bus_mem = pci_resource_start(pci_dev, 1);
1376
	if (!card->io_bus_mem) {
1377
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1378
			"card %d: "
1379
			"no iomem!\n",
1380
			card->cardnum);
1381
		err = -ENODEV;
1382
		goto err_noiobase;
1383
	}
1384
1385
	card->io_mem = ioremap(card->io_bus_mem, hfc_PCI_MEM_SIZE);
1386
	if (!(card->io_mem)) {
1387
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1388
			"card %d: "
1389
			"cannot ioremap I/O memory\n",
1390
			card->cardnum);
1391
		err = -ENODEV;
1392
		goto err_ioremap;
1393
	}
1394
1395
	/*
1396
	 * pci_alloc_consistent guarantees alignment
1397
	 * (Documentation/DMA-mapping.txt)
1398
	 */
1399
	card->fifo_mem = pci_alloc_consistent(pci_dev,
1400
			hfc_FIFO_SIZE, &card->fifo_bus_mem);
1401
	if (!card->fifo_mem) {
1402
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1403
			"card %d: "
1404
			"unable to allocate FIFO DMA memory!\n",
1405
			card->cardnum);
1406
		err = -ENOMEM;
1407
		goto err_alloc_fifo;
1408
	}
1409
1410
	memset(card->fifo_mem, 0x00, hfc_FIFO_SIZE);
1411
1412
	card->fifos = card->fifo_mem;
1413
1414
	pci_write_config_dword(card->pcidev, hfc_PCI_MWBA, card->fifo_bus_mem);
1415
1416
	err = request_irq(card->pcidev->irq, &hfc_interrupt,
1417
1418
#if (KERNEL_VERSION(2, 6, 23) < LINUX_VERSION_CODE)
1419
		IRQF_SHARED, hfc_DRIVER_NAME, card);
1420
#else
1421
		SA_SHIRQ, hfc_DRIVER_NAME, card);
1422
#endif
1423
1424
	if (err) {
1425
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1426
			"card %d: "
1427
			"unable to register irq\n",
1428
			card->cardnum);
1429
		goto err_request_irq;
1430
	}
1431
1432
	card->nt_mode = FALSE;
1433
1434
	if (modes & (1 << card->cardnum))
1435
		card->nt_mode = TRUE;
1436
1437
	for (i = 0; i < nt_modes_count; i++) {
1438
		if (nt_modes[i] == card->cardnum)
1439
			card->nt_mode = TRUE;
1440
	}
1441
1442
	/*
1443
	 * D Channel
1444
	 */
1445
	card->chans[D].card = card;
1446
	card->chans[D].name = "D";
1447
	card->chans[D].status = free;
1448
	card->chans[D].number = D;
1449
	spin_lock_init(&card->chans[D].lock);
1450
1451
	card->chans[D].rx.chan      = &card->chans[D];
1452
	card->chans[D].rx.fifo_base = card->fifos + 0x4000;
1453
	card->chans[D].rx.z_base    = card->fifos + 0x4000;
1454
	card->chans[D].rx.z1_base   = card->fifos + 0x6080;
1455
	card->chans[D].rx.z2_base   = card->fifos + 0x6082;
1456
	card->chans[D].rx.z_min     = 0x0000;
1457
	card->chans[D].rx.z_max     = 0x01FF;
1458
	card->chans[D].rx.f_min     = 0x10;
1459
	card->chans[D].rx.f_max     = 0x1F;
1460
	card->chans[D].rx.f1        = card->fifos + 0x60a0;
1461
	card->chans[D].rx.f2        = card->fifos + 0x60a1;
1462
	card->chans[D].rx.fifo_size = card->chans[D].rx.z_max
1463
		- card->chans[D].rx.z_min + 1;
1464
	card->chans[D].rx.f_num     = card->chans[D].rx.f_max
1465
		- card->chans[D].rx.f_min + 1;
1466
1467
	card->chans[D].tx.chan      = &card->chans[D];
1468
	card->chans[D].tx.fifo_base = card->fifos + 0x0000;
1469
	card->chans[D].tx.z_base    = card->fifos + 0x0000;
1470
	card->chans[D].tx.z1_base   = card->fifos + 0x2080;
1471
	card->chans[D].tx.z2_base   = card->fifos + 0x2082;
1472
	card->chans[D].tx.z_min     = 0x0000;
1473
	card->chans[D].tx.z_max     = 0x01FF;
1474
	card->chans[D].tx.f_min     = 0x10;
1475
	card->chans[D].tx.f_max     = 0x1F;
1476
	card->chans[D].tx.f1        = card->fifos + 0x20a0;
1477
	card->chans[D].tx.f2        = card->fifos + 0x20a1;
1478
	card->chans[D].tx.fifo_size = card->chans[D].tx.z_max -
1479
		card->chans[D].tx.z_min + 1;
1480
	card->chans[D].tx.f_num     = card->chans[D].tx.f_max -
1481
		card->chans[D].tx.f_min + 1;
1482
1483
	/*
1484
	 * B1 Channel
1485
	 */
1486
	card->chans[B1].card = card;
1487
	card->chans[B1].name = "B1";
1488
	card->chans[B1].status = free;
1489
	card->chans[B1].number = B1;
1490
	card->chans[B1].protocol = 0;
1491
	spin_lock_init(&card->chans[B1].lock);
1492
1493
	card->chans[B1].rx.chan      = &card->chans[B1];
1494
	card->chans[B1].rx.fifo_base = card->fifos + 0x4200;
1495
	card->chans[B1].rx.z_base    = card->fifos + 0x4000;
1496
	card->chans[B1].rx.z1_base   = card->fifos + 0x6000;
1497
	card->chans[B1].rx.z2_base   = card->fifos + 0x6002;
1498
	card->chans[B1].rx.z_min     = 0x0200;
1499
	card->chans[B1].rx.z_max     = 0x1FFF;
1500
	card->chans[B1].rx.f_min     = 0x00;
1501
	card->chans[B1].rx.f_max     = 0x1F;
1502
	card->chans[B1].rx.f1        = card->fifos + 0x6080;
1503
	card->chans[B1].rx.f2        = card->fifos + 0x6081;
1504
	card->chans[B1].rx.fifo_size = card->chans[B1].rx.z_max -
1505
		card->chans[B1].rx.z_min + 1;
1506
	card->chans[B1].rx.f_num     = card->chans[B1].rx.f_max -
1507
		card->chans[B1].rx.f_min + 1;
1508
1509
	card->chans[B1].tx.chan      = &card->chans[B1];
1510
	card->chans[B1].tx.fifo_base = card->fifos + 0x0200;
1511
	card->chans[B1].tx.z_base    = card->fifos + 0x0000;
1512
	card->chans[B1].tx.z1_base   = card->fifos + 0x2000;
1513
	card->chans[B1].tx.z2_base   = card->fifos + 0x2002;
1514
	card->chans[B1].tx.z_min     = 0x0200;
1515
	card->chans[B1].tx.z_max     = 0x1FFF;
1516
	card->chans[B1].tx.f_min     = 0x00;
1517
	card->chans[B1].tx.f_max     = 0x1F;
1518
	card->chans[B1].tx.f1        = card->fifos + 0x2080;
1519
	card->chans[B1].tx.f2        = card->fifos + 0x2081;
1520
	card->chans[B1].tx.fifo_size = card->chans[B1].tx.z_max -
1521
		card->chans[B1].tx.z_min + 1;
1522
	card->chans[B1].tx.f_num     = card->chans[B1].tx.f_max -
1523
		card->chans[B1].tx.f_min + 1;
1524
1525
	/*
1526
	 * B2 Channel
1527
	 */
1528
	card->chans[B2].card = card;
1529
	card->chans[B2].name = "B2";
1530
	card->chans[B2].status = free;
1531
	card->chans[B2].number = B2;
1532
	card->chans[B2].protocol = 0;
1533
	spin_lock_init(&card->chans[B2].lock);
1534
1535
	card->chans[B2].rx.chan      = &card->chans[B2];
1536
	card->chans[B2].rx.fifo_base = card->fifos + 0x6200,
1537
	card->chans[B2].rx.z_base    = card->fifos + 0x6000;
1538
	card->chans[B2].rx.z1_base   = card->fifos + 0x6100;
1539
	card->chans[B2].rx.z2_base   = card->fifos + 0x6102;
1540
	card->chans[B2].rx.z_min     = 0x0200;
1541
	card->chans[B2].rx.z_max     = 0x1FFF;
1542
	card->chans[B2].rx.f_min     = 0x00;
1543
	card->chans[B2].rx.f_max     = 0x1F;
1544
	card->chans[B2].rx.f1        = card->fifos + 0x6180;
1545
	card->chans[B2].rx.f2        = card->fifos + 0x6181;
1546
	card->chans[B2].rx.fifo_size = card->chans[B2].rx.z_max -
1547
		card->chans[B2].rx.z_min + 1;
1548
	card->chans[B2].rx.f_num     = card->chans[B2].rx.f_max -
1549
		card->chans[B2].rx.f_min + 1;
1550
1551
	card->chans[B2].tx.chan      = &card->chans[B2];
1552
	card->chans[B2].tx.fifo_base = card->fifos + 0x2200;
1553
	card->chans[B2].tx.z_base    = card->fifos + 0x2000;
1554
	card->chans[B2].tx.z1_base   = card->fifos + 0x2100;
1555
	card->chans[B2].tx.z2_base   = card->fifos + 0x2102;
1556
	card->chans[B2].tx.z_min     = 0x0200;
1557
	card->chans[B2].tx.z_max     = 0x1FFF;
1558
	card->chans[B2].tx.f_min     = 0x00;
1559
	card->chans[B2].tx.f_max     = 0x1F;
1560
	card->chans[B2].tx.f1        = card->fifos + 0x2180;
1561
	card->chans[B2].tx.f2        = card->fifos + 0x2181;
1562
	card->chans[B2].tx.fifo_size = card->chans[B2].tx.z_max -
1563
		card->chans[B2].tx.z_min + 1;
1564
	card->chans[B2].tx.f_num     = card->chans[B2].tx.f_max -
1565
		card->chans[B2].tx.f_min + 1;
1566
1567
	/*
1568
	 * All done
1569
	 */
1570
1571
	dahdi_hfcs = kmalloc(sizeof(struct dahdi_hfc), GFP_KERNEL);
1572
	if (!dahdi_hfcs) {
1573
		printk(KERN_CRIT hfc_DRIVER_PREFIX
1574
			"unable to kmalloc!\n");
1575
		goto err_request_irq;
1576
	}
1577
	memset(dahdi_hfcs, 0x0, sizeof(struct dahdi_hfc));
1578
1579
	dahdi_hfcs->card = card;
1580
	hfc_dahdi_initialize(dahdi_hfcs);
1581
	card->dahdi_dev = dahdi_hfcs;
1582
1583
	snprintf(card->proc_dir_name,
1584
			sizeof(card->proc_dir_name),
1585
			"%d", card->cardnum);
1586
	card->proc_dir = proc_mkdir(card->proc_dir_name, hfc_proc_dahdi_hfcs_dir);
1587
	SET_PROC_DIRENTRY_OWNER(card->proc_dir);
1588
1589
	hfc_resetCard(card);
1590
1591
	printk(KERN_INFO hfc_DRIVER_PREFIX
1592
		"card %d configured for %s mode at mem %#lx (0x%p) IRQ %u\n",
1593
		card->cardnum,
1594
		card->nt_mode ? "NT" : "TE",
1595
		card->io_bus_mem,
1596
		card->io_mem,
1597
		card->pcidev->irq);
1598
1599
	cardnum++;
1600
1601
	return 0;
1602
1603
err_request_irq:
1604
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1605
		card->fifo_mem, card->fifo_bus_mem);
1606
err_alloc_fifo:
1607
	iounmap(card->io_mem);
1608
err_ioremap:
1609
err_noiobase:
1610
err_noirq:
1611
	pci_release_regions(pci_dev);
1612
err_pci_request_regions:
1613
err_pci_set_dma_mask:
1614
err_pci_enable_device:
1615
	kfree(card);
1616
err_alloc_hfccard:
1617
	return err;
1618
}
1619
1620
static void __devexit hfc_remove(struct pci_dev *pci_dev)
1621
{
1622
	struct hfc_card *card = pci_get_drvdata(pci_dev);
1623
1624
1625
	printk(KERN_INFO hfc_DRIVER_PREFIX
1626
		"card %d: "
1627
		"shutting down card at %p.\n",
1628
		card->cardnum,
1629
		card->io_mem);
1630
1631
	if (!card) {
1632
		return;
1633
	}
1634
1635
	hfc_softreset(card);
1636
1637
	dahdi_unregister_device(card->dahdi_dev->ddev);
1638
1639
1640
	/*
1641
	 * disable memio and bustmaster
1642
	 */
1643
	pci_write_config_word(pci_dev, PCI_COMMAND, 0);
1644
1645
/*
1646
BUG: these proc entries just cause Call traces, so removed.
1647
	remove_proc_entry("bufs", card->proc_dir);
1648
	remove_proc_entry("fifos", card->proc_dir);
1649
	remove_proc_entry("info", card->proc_dir);
1650
*/
1651
	remove_proc_entry(card->proc_dir_name, hfc_proc_dahdi_hfcs_dir);
1652
1653
	free_irq(pci_dev->irq, card);
1654
1655
	pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1656
		card->fifo_mem, card->fifo_bus_mem);
1657
1658
	iounmap(card->io_mem);
1659
1660
	pci_release_regions(pci_dev);
1661
1662
	pci_disable_device(pci_dev);
1663
1664
	kfree(card);
1665
}
1666
1667
/******************************************
1668
 * Module stuff
1669
 ******************************************/
1670
1671
static int __init hfc_init_module(void)
1672
{
1673
	int ret;
1674
1675
	printk(KERN_INFO hfc_DRIVER_PREFIX
1676
		hfc_DRIVER_STRING " loading\n");
1677
#ifdef DEBUG
1678
printk(KERN_INFO hfc_DRIVER_PREFIX "Check /var/log/kern-debug.log for debugging output level %d.", debug_level);
1679
printk(KERN_DEBUG hfc_DRIVER_PREFIX "base.c is debugging.");
1680
#endif
1681
1682
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1683
	hfc_proc_dahdi_hfcs_dir = proc_mkdir(hfc_DRIVER_NAME, NULL);
1684
#else
1685
	hfc_proc_dahdi_hfcs_dir = proc_mkdir(hfc_DRIVER_NAME, proc_root_driver);
1686
#endif
1687
1688
	ret = dahdi_pci_module(&hfc_driver);
1689
	return ret;
1690
}
1691
1692
module_init(hfc_init_module);
1693
1694
static void __exit hfc_module_exit(void)
1695
{
1696
	pci_unregister_driver(&hfc_driver);
1697
1698
#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1699
	remove_proc_entry(hfc_DRIVER_NAME, NULL);
1700
#else
1701
	remove_proc_entry(hfc_DRIVER_NAME, proc_root_driver);
1702
#endif
1703
1704
	printk(KERN_INFO hfc_DRIVER_PREFIX
1705
		hfc_DRIVER_STRING " unloaded\n");
1706
}
1707
1708
module_exit(hfc_module_exit);
1709
1710
#endif
1711
1712
MODULE_DESCRIPTION(hfc_DRIVER_DESCR);
1713
MODULE_AUTHOR("Jens Wilke <jw_vzaphfc@headissue.com>, "
1714
		"Daniele (Vihai) Orlandi <daniele@orlandi.com>, "
1715
		"Jose A. Deniz <odicha@hotmail.com>");
1716
MODULE_ALIAS("dahdi_hfcs");
1717
#ifdef MODULE_LICENSE
1718
MODULE_LICENSE("GPL");
1719
#endif
1720
1721
1722
module_param(modes, int, 0444);
1723
1724
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
1725
module_param_array(nt_modes, int, &nt_modes_count, 0444);
1726
#else
1727
module_param_array(nt_modes, int, nt_modes_count, 0444);
1728
#endif
1729
1730
module_param(force_l1_up, int, 0444);
1731
#ifdef DEBUG
1732
module_param(debug_level, int, 0444);
1733
#endif
1734
1735
MODULE_PARM_DESC(modes, "[Deprecated] bit-mask to configure NT mode");
1736
MODULE_PARM_DESC(nt_modes,
1737
		"Comma-separated list of card IDs to configure in NT mode");
1738
MODULE_PARM_DESC(force_l1_up, "Don't allow L1 to go down");
1739
#ifdef DEBUG
1740
MODULE_PARM_DESC(debug_level, "Debug verbosity level");
1741
#endif
(-)dahdi-linux-2.6.1.ORIG/drivers/dahdi/hfcs/dahdi_hfcs.h (+419 lines)
Line 0 Link Here
1
/*
2
 * dahdi_hfcs.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 "dahdi_hfcs"
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 dahdi_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_dahdi;
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 *dahdi_dev;
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
403
} dahdi_hfc;
404
405
static inline struct dahdi_hfc* dahdi_hfc_from_span(struct dahdi_span *span) {
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.6.1.ORIG/drivers/dahdi/hfcs/fifo.c (+380 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
#define DEBUG
17
#ifdef DEBUG
18
extern int debug_level;
19
#endif
20
21
#include <linux/kernel.h>
22
23
#include <dahdi/kernel.h>
24
25
#include "fifo.h"
26
27
static void hfc_fifo_mem_read(struct hfc_chan_simplex *chan,
28
	int z_start,
29
	void *data, int size)
30
{
31
	int bytes_to_boundary = chan->z_max - z_start + 1;
32
	if (bytes_to_boundary >= size) {
33
		memcpy(data,
34
			chan->z_base + z_start,
35
			size);
36
	} else {
37
		/*
38
		 * Buffer wrap
39
		 */
40
		memcpy(data,
41
			chan->z_base + z_start,
42
			bytes_to_boundary);
43
44
		memcpy(data + bytes_to_boundary,
45
			chan->fifo_base,
46
			size - bytes_to_boundary);
47
	}
48
}
49
50
static void hfc_fifo_mem_write(struct hfc_chan_simplex *chan,
51
	void *data, int size)
52
{
53
	int bytes_to_boundary = chan->z_max - *Z1_F1(chan) + 1;
54
	if (bytes_to_boundary >= size) {
55
		memcpy(chan->z_base + *Z1_F1(chan),
56
			data,
57
			size);
58
	} else {
59
		/*
60
		 * FIFO wrap
61
		 */
62
63
		memcpy(chan->z_base + *Z1_F1(chan),
64
			data,
65
			bytes_to_boundary);
66
67
		memcpy(chan->fifo_base,
68
			data + bytes_to_boundary,
69
			size - bytes_to_boundary);
70
	}
71
}
72
73
int hfc_fifo_get(struct hfc_chan_simplex *chan,
74
		void *data, int size)
75
{
76
	int available_bytes;
77
78
	/*
79
	 * Some useless statistic
80
	 */
81
	chan->bytes += size;
82
83
	available_bytes = hfc_fifo_used_rx(chan);
84
85
	if (available_bytes < size && !chan->fifo_underrun++) {
86
		/*
87
		 * print the warning only once
88
		 */
89
		printk(KERN_WARNING hfc_DRIVER_PREFIX
90
			"card %d: "
91
			"chan %s: "
92
			"RX FIFO not enough (%d) bytes to receive!\n",
93
			chan->chan->card->cardnum,
94
			chan->chan->name,
95
			available_bytes);
96
		return -1;
97
	}
98
99
	hfc_fifo_mem_read(chan, *Z2_F2(chan), data, size);
100
	*Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size);
101
	return available_bytes - size;
102
}
103
104
void hfc_fifo_put(struct hfc_chan_simplex *chan,
105
			void *data, int size)
106
{
107
	struct hfc_card *card = chan->chan->card;
108
	int used_bytes = hfc_fifo_used_tx(chan);
109
	int free_bytes = hfc_fifo_free_tx(chan);
110
111
	if (!used_bytes && !chan->fifo_underrun++) {
112
		/*
113
		 * print warning only once, to make timing not worse
114
		 */
115
		printk(KERN_WARNING hfc_DRIVER_PREFIX
116
			"card %d: "
117
			"chan %s: "
118
			"TX FIFO has become empty\n",
119
			card->cardnum,
120
			chan->chan->name);
121
	}
122
	if (free_bytes < size) {
123
		printk(KERN_CRIT hfc_DRIVER_PREFIX
124
			"card %d: "
125
			"chan %s: "
126
			"TX FIFO full!\n",
127
			chan->chan->card->cardnum,
128
			chan->chan->name);
129
		chan->fifo_full++;
130
		hfc_clear_fifo_tx(chan);
131
	}
132
133
	hfc_fifo_mem_write(chan, data, size);
134
	chan->bytes += size;
135
	*Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size);
136
}
137
138
int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size)
139
{
140
	int frame_size;
141
	u16 newz2 ;
142
143
	if (*chan->f1 == *chan->f2) {
144
		/*
145
		 * nothing received, strange uh?
146
		 */
147
		printk(KERN_WARNING hfc_DRIVER_PREFIX
148
			"card %d: "
149
			"chan %s: "
150
			"get_frame called with no frame in FIFO.\n",
151
			chan->chan->card->cardnum,
152
			chan->chan->name);
153
154
		return -1;
155
	}
156
157
	/*
158
	 * frame_size includes CRC+CRC+STAT
159
	 */
160
	frame_size = hfc_fifo_get_frame_size(chan);
161
162
#ifdef DEBUG
163
	if (debug_level == 3) {
164
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
165
			"card %d: "
166
			"chan %s: "
167
			"RX len %2d: ",
168
			chan->chan->card->cardnum,
169
			chan->chan->name,
170
			frame_size);
171
	} else if (debug_level >= 4) {
172
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
173
			"card %d: "
174
			"chan %s: "
175
			"RX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
176
			chan->chan->card->cardnum,
177
			chan->chan->name,
178
			*chan->f1, *chan->f2, *Z1_F2(chan), *Z2_F2(chan),
179
			frame_size);
180
	}
181
182
	if (debug_level >= 3) {
183
		int i;
184
		for (i = 0; i < frame_size; i++) {
185
			printk("%02x", hfc_fifo_u8(chan,
186
				Z_inc(chan, *Z2_F2(chan), i)));
187
		}
188
189
		printk("\n");
190
	}
191
#endif
192
193
	if (frame_size <= 0) {
194
#ifdef DEBUG
195
		if (debug_level >= 2) {
196
			printk(KERN_DEBUG hfc_DRIVER_PREFIX
197
				"card %d: "
198
				"chan %s: "
199
				"invalid (empty) frame received.\n",
200
				chan->chan->card->cardnum,
201
				chan->chan->name);
202
		}
203
#endif
204
205
		hfc_fifo_drop_frame(chan);
206
		return -1;
207
	}
208
209
	/*
210
	 * STAT is not really received
211
	 */
212
	chan->bytes += frame_size - 1;
213
214
	/*
215
	 * Calculate beginning of the next frame
216
	 */
217
	newz2 = Z_inc(chan, *Z2_F2(chan), frame_size);
218
219
	/*
220
	 * We cannot use hfc_fifo_get because of different semantic of
221
	 * "available bytes" and to avoid useless increment of Z2
222
	 */
223
	hfc_fifo_mem_read(chan, *Z2_F2(chan), data,
224
		frame_size < max_size ? frame_size : max_size);
225
226
	if (hfc_fifo_u8(chan, Z_inc(chan, *Z2_F2(chan),
227
		frame_size - 1)) != 0x00) {
228
		/*
229
		 * CRC not ok, frame broken, skipping
230
		 */
231
#ifdef DEBUG
232
		if (debug_level >= 2) {
233
			printk(KERN_WARNING hfc_DRIVER_PREFIX
234
				"card %d: "
235
				"chan %s: "
236
				"Received frame with wrong CRC\n",
237
				chan->chan->card->cardnum,
238
				chan->chan->name);
239
		}
240
#endif
241
242
		chan->crc++;
243
244
		hfc_fifo_drop_frame(chan);
245
		return -1;
246
	}
247
248
	chan->frames++;
249
250
	*chan->f2 = F_inc(chan, *chan->f2, 1);
251
252
	/*
253
	 * Set Z2 for the next frame we're going to receive
254
	 */
255
	*Z2_F2(chan) = newz2;
256
257
	return frame_size;
258
}
259
260
void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan)
261
{
262
	int available_bytes;
263
	u16 newz2;
264
265
	if (*chan->f1 == *chan->f2) {
266
		/*
267
		 * nothing received, strange eh?
268
		 */
269
		printk(KERN_WARNING hfc_DRIVER_PREFIX
270
			"card %d: "
271
			"chan %s: "
272
			"skip_frame called with no frame in FIFO.\n",
273
			chan->chan->card->cardnum,
274
			chan->chan->name);
275
276
		return;
277
	}
278
279
	available_bytes = hfc_fifo_used_rx(chan) + 1;
280
281
	/*
282
	 * Calculate beginning of the next frame
283
	 */
284
	newz2 = Z_inc(chan, *Z2_F2(chan), available_bytes);
285
286
	*chan->f2 = F_inc(chan, *chan->f2, 1);
287
288
	/*
289
	 * Set Z2 for the next frame we're going to receive
290
	 */
291
	*Z2_F2(chan) = newz2;
292
}
293
294
void hfc_fifo_put_frame(struct hfc_chan_simplex *chan,
295
		 void *data, int size)
296
{
297
	u16 newz1;
298
	int available_frames;
299
300
#ifdef DEBUG
301
	if (debug_level == 3) {
302
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
303
			"card %d: "
304
			"chan %s: "
305
			"TX len %2d: ",
306
			chan->chan->card->cardnum,
307
			chan->chan->name,
308
			size);
309
	} else if (debug_level >= 4) {
310
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
311
			"card %d: "
312
			"chan %s: "
313
			"TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
314
			chan->chan->card->cardnum,
315
			chan->chan->name,
316
			*chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan),
317
			size);
318
	}
319
320
	if (debug_level >= 3) {
321
		int i;
322
		for (i = 0; i < size; i++)
323
			printk("%02x", ((u8 *)data)[i]);
324
325
		printk("\n");
326
	}
327
#endif
328
329
	available_frames = hfc_fifo_free_frames(chan);
330
331
	if (available_frames >= chan->f_num) {
332
		printk(KERN_CRIT hfc_DRIVER_PREFIX
333
			"card %d: "
334
			"chan %s: "
335
			"TX FIFO total number of frames exceeded!\n",
336
			chan->chan->card->cardnum,
337
			chan->chan->name);
338
339
		chan->fifo_full++;
340
341
		return;
342
	}
343
344
	hfc_fifo_put(chan, data, size);
345
346
	newz1 = *Z1_F1(chan);
347
348
	*chan->f1 = F_inc(chan, *chan->f1, 1);
349
350
	*Z1_F1(chan) = newz1;
351
352
	chan->frames++;
353
}
354
355
void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan)
356
{
357
	*chan->f2 = *chan->f1;
358
	*Z2_F2(chan) = *Z1_F2(chan);
359
}
360
361
void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan)
362
{
363
	*chan->f1 = *chan->f2;
364
	*Z1_F1(chan) = *Z2_F1(chan);
365
366
	if (chan->chan->status == open_voice) {
367
		/*
368
		 * Make sure that at least hfc_TX_FIFO_PRELOAD bytes are
369
		 * present in the TX FIFOs
370
		 * Create hfc_TX_FIFO_PRELOAD bytes of empty data
371
		 * (0x7f is mute audio)
372
		 */
373
		u8 empty_fifo[hfc_TX_FIFO_PRELOAD +
374
			DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD];
375
		memset(empty_fifo, 0x7f, sizeof(empty_fifo));
376
377
		hfc_fifo_put(chan, empty_fifo, sizeof(empty_fifo));
378
	}
379
}
380
(-)dahdi-linux-2.6.1.ORIG/drivers/dahdi/hfcs/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 "dahdi_hfcs.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.6.1.ORIG/drivers/dahdi/hfcs/Kbuild (+10 lines)
Line 0 Link Here
1
obj-m += dahdi_hfcs.o
2
3
EXTRA_CFLAGS := -I$(src)/.. -Wno-undef
4
5
dahdi_hfcs-objs := base.o fifo.o
6
7
$(obj)/base.o: $(src)/dahdi_hfcs.h
8
$(obj)/fifo.o: $(src)/fifo.h
9
10
(-)dahdi-linux-2.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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.6.1.ORIG/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 480148