summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
blob: 46c6c2e313fb9d376393a5deac7b9b6008a1256e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/*
 * Wildcard TDM2400P TDM FXS/FXO Interface Driver for DAHDI Telephony interface
 *
 * Written by Mark Spencer <markster@digium.com>
 * Support for TDM800P and VPM150M by Matthew Fredrickson <creslin@digium.com>
 *
 * Copyright (C) 2005-2010 Digium, Inc.
 *
 * All rights reserved.
 *
 */

/*
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2 as published by the
 * Free Software Foundation. See the LICENSE file included with
 * this program for more details.
 */

#ifndef _WCTDM24XXP_H
#define _WCTDM24XXP_H

#include <dahdi/kernel.h>

#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#include <linux/semaphore.h>
#else
#include <asm/semaphore.h>
#endif

#include "voicebus/voicebus.h"

#define NUM_FXO_REGS 60

#define WC_MAX_IFACES 128

/*!
 * \brief Default ringer debounce (in ms)
 */
#define DEFAULT_RING_DEBOUNCE	1024

#define POLARITY_DEBOUNCE	64		/* Polarity debounce (in ms) */

#define OHT_TIMER		6000	/* How long after RING to retain OHT */

#define FLAG_3215	(1 << 0)
#define FLAG_EXPRESS	(1 << 1)

#define EFRAME_SIZE 108L
#define EFRAME_GAP 20L
#define SFRAME_SIZE ((EFRAME_SIZE * DAHDI_CHUNKSIZE) + (EFRAME_GAP * (DAHDI_CHUNKSIZE - 1)))

#define MAX_ALARMS 10

#define MOD_TYPE_NONE		0
#define MOD_TYPE_FXS		1
#define MOD_TYPE_FXO		2
#define MOD_TYPE_FXSINIT	3
#define MOD_TYPE_QRV		5
#define MOD_TYPE_BRI		7

#define MINPEGTIME	10 * 8		/* 30 ms peak to peak gets us no more than 100 Hz */
#define PEGTIME		50 * 8		/* 50ms peak to peak gets us rings of 10 Hz or more */
#define PEGCOUNT	5		/* 5 cycles of pegging means RING */

#define SDI_CLK		(0x00010000)
#define SDI_DOUT	(0x00020000)
#define SDI_DREAD	(0x00040000)
#define SDI_DIN		(0x00080000)

#define __CMD_RD   (1 << 20)		/* Read Operation */
#define __CMD_WR   (1 << 21)		/* Write Operation */
#define __CMD_FIN  (1 << 22)		/* Has finished receive */
#define __CMD_TX   (1 << 23)		/* Has been transmitted */

#define CMD_WR(a,b) (((a) << 8) | (b) | __CMD_WR)
#define CMD_RD(a) (((a) << 8) | __CMD_RD)

#if 0
#define CMD_BYTE(card,bit,altcs) (((((card) & 0x3) * 3 + (bit)) * 7) \
			+ ((card) >> 2) + (altcs) + ((altcs) ? -21 : 0))
#endif
#define NUM_MODULES		24
#define NUM_SLOTS		6
#define MAX_SPANS		9

#define NUM_CAL_REGS		12

#define USER_COMMANDS		8
#define ISR_COMMANDS		2
#define QRV_DEBOUNCETIME	20

#define MAX_COMMANDS		(USER_COMMANDS + ISR_COMMANDS)

#define VPM150M_HPI_CONTROL	0x00
#define VPM150M_HPI_ADDRESS	0x02
#define VPM150M_HPI_DATA	0x03

#define VPM_SUPPORT
#define VPM150M_SUPPORT

#ifdef VPM150M_SUPPORT
#include "voicebus/GpakCust.h"
#endif

struct calregs {
	unsigned char vals[NUM_CAL_REGS];
};

struct cmdq {
	unsigned int cmds[MAX_COMMANDS];
	unsigned char isrshadow[ISR_COMMANDS];
};

enum battery_state {
	BATTERY_UNKNOWN = 0,
	BATTERY_PRESENT,
	BATTERY_LOST,
};

/**
 * struct wctdm_span -
 * @span:		dahdi_span to register.
 * @timing_priority:	What the priority of this span is relative to the other
 * 			spans.
 * @spanno:		Which span on the card this is.
 *
 * NOTE:  spanno would normally be taken care of by dahdi_span.offset, but
 * appears to have meaning in xhfc.c, and that needs to be audited before
 * changing. !!!TODO!!!
 *
 */
struct wctdm_span {
	struct dahdi_span span;
	int timing_priority;
	int spanno;
	struct wctdm *wc;
	struct b400m_span *bspan;
};

struct wctdm_chan {
	struct dahdi_chan chan;
	struct dahdi_echocan_state ec;
	int timeslot;
};

struct wctdm {
	const struct wctdm_desc *desc;
	char board_name[80];
	int usecount;
	int pos;				/* card number in system */

	spinlock_t frame_list_lock;
	struct list_head frame_list;

	unsigned int intcount;
	unsigned char txident;
	unsigned char rxident;

	int flags[NUM_MODULES];			/* bitmap of board-specific + module-specific flags */
	u8 ctlreg;
	u8 tdm410leds;

	int mods_per_board;			/* maximum number of modules for this board */
	int digi_mods;				/* number of digital modules present */
	int avchannels;				/* active "voice" (voice, B and D) channels */
	int modmap;				/* Bit-map of present cards (1=present) */

	int altcs[NUM_MODULES];

/* FIXME: why are all of these QRV-only members part of the main card structure? */
	char qrvhook[NUM_MODULES];
	unsigned short qrvdebtime[NUM_MODULES];
	int radmode[NUM_MODULES];
#define	RADMODE_INVERTCOR 1
#define	RADMODE_IGNORECOR 2
#define	RADMODE_EXTTONE 4
#define	RADMODE_EXTINVERT 8
#define	RADMODE_IGNORECT 16
#define	RADMODE_PREEMP	32
#define	RADMODE_DEEMP 64
	unsigned short debouncetime[NUM_MODULES];
	signed short rxgain[NUM_MODULES];
	signed short txgain[NUM_MODULES];

	spinlock_t reglock;			/* held when accessing anything affecting the module array */
	wait_queue_head_t regq;			/* for schluffen() */

	union {
		struct fxo {
			int wasringing;
			int lastrdtx;
			int lastrdtx_count;
			int ringdebounce;
			int offhook;
			int battdebounce;
			int battalarm;
			enum battery_state battery;
			int lastpol;
			int polarity;
			int polaritydebounce;
			int neonmwi_state;
			int neonmwi_last_voltage;
			unsigned int neonmwi_debounce;
			unsigned int neonmwi_offcounter;
		} fxo;
		struct fxs {
			int oldrxhook;
			int debouncehook;
			int lastrxhook;
			int debounce;
			int ohttimer;
			int idletxhookstate;	/* IDLE changing hook state */
	/* lasttxhook reflects the last value written to the proslic's reg
	* 64 (LINEFEED_CONTROL) in bits 0-2.  Bit 4 indicates if the last
	* write is pending i.e. it is in process of being written to the
	* register
	* NOTE: in order for this value to actually be written to the
	* proslic, the appropriate matching value must be written into the
	* sethook variable so that it gets queued and handled by the
	* voicebus ISR.
	*/
			int lasttxhook;
			int oppending_ms;
			spinlock_t lasttxhooklock;
			int palarms;
			struct dahdi_vmwi_info vmwisetting;
			int vmwi_active_messages;
			int vmwi_linereverse;
			int reversepolarity;	/* polarity reversal */
			struct calregs calregs;
		} fxs;
		struct b400m *bri;
	} mods[NUM_MODULES];

	struct cmdq cmdq[NUM_MODULES];
	int modtype[NUM_MODULES]; /* type of module (FXO/FXS/QRV/etc.) */
	int sethook[NUM_MODULES]; /* pending hook state command */
	int dacssrc[NUM_MODULES];

	struct vpmadt032 *vpmadt032;

	struct voicebus vb;
	struct wctdm_span *aspan;			/* pointer to the spans[] holding the analog span */
	struct wctdm_span *spans[MAX_SPANS];
	struct wctdm_chan *chans[NUM_MODULES];
#ifdef CONFIG_VOICEBUS_ECREFERENCE
	struct dahdi_fifo *ec_reference[NUM_MODULES];
#endif

	/* Only care about digital spans here */
	/* int span_timing_prio[MAX_SPANS - 1]; */
	struct semaphore syncsem;
	int oldsync;

	int initialized;				/* =1 when the entire card is ready to go */
	unsigned long checkflag;			/* Internal state flags and task bits */
	int companding;
};

/* Atomic flag bits for checkflag field */
#define WCTDM_CHECK_TIMING	0

int schluffen(wait_queue_head_t *q);
void wait_just_a_bit(int foo);
int wctdm_getreg(struct wctdm *wc, int card, int addr);
int wctdm_setreg(struct wctdm *wc, int card, int addr, int val);

extern struct semaphore ifacelock;
extern struct wctdm *ifaces[WC_MAX_IFACES];

#endif