summaryrefslogtreecommitdiff
path: root/xhfc/xhfc.h
blob: 53c99bc0d92edf6760eeebcc88fd9c944a6c4e4e (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
#ifndef __XHFC_H__
#define __XHFC_H__

#include <linux/interrupt.h>
#include <linux/pci.h>
#include <dahdi/kernel.h>
#include "xhfc24sucd.h"

#define DRIVER_NAME "xhfc"

#ifndef CHIP_ID_2S4U
#define CHIP_ID_2S4U	0x62
#endif
#ifndef CHIP_ID_4SU
#define CHIP_ID_4SU	0x63
#endif
#ifndef CHIP_ID_1SU
#define CHIP_ID_1SU	0x60
#endif
#ifndef CHIP_ID_2SU
#define CHIP_ID_2SU	0x61
#endif

#define SPANS_PER_CHIP		4
#define CHANS_PER_SPAN		3

#define XHFC_ZMIN 0x00
#define XHFC_ZMAX 0x3F /*for V_FIFO_MD = 00*/
#define XHFC_FMIN 0x00
#define XHFC_FMAX 0x07

enum { XHFC_T1, XHFC_T2, XHFC_T3, XHFC_T4 };

#if (DAHDI_CHUNKSIZE != 8)
#error Sorry, the XHFC driver module does not support chunksize != 8
#endif

/* general debug messages */
#define DEBUG_GENERAL 		(1 << 0)
/* emit register read/write, but only if the kernel's DEBUG is defined */
#define DEBUG_REGS 		(1 << 2) // not used
/* emit file operation messages */
#define DEBUG_FOPS  		(1 << 3)
#define DEBUG_ECHOCAN 		(1 << 4)
/* S/T state machine */
#define DEBUG_ST_STATE		(1 << 5)
/* HDLC controller */
#define DEBUG_HDLC		(1 << 6)
#define DEBUG_VERBOSE_HDLC	(1 << 7)
/* Timing related changes */
#define DEBUG_TIMING		(1 << 8)
/* alarm changes */
#define DEBUG_ALARM		(1 << 9)

#define DBG			(debug & DEBUG_GENERAL)
#define DBG_DTMF		(debug & DEBUG_DTMF)
#define DBG_REGS		(debug & DEBUG_REGS)
#define DBG_FOPS		(debug & DEBUG_FOPS)
#define DBG_EC			(debug & DEBUG_ECHOCAN)
#define DBG_ST			(debug & DEBUG_ST_STATE)
#define DBG_HDLC		(debug & DEBUG_HDLC)
#define DBG_VERBOSE_HDLC	(debug & DEBUG_VERBOSE_HDLC)
#define DBG_ALARM		(debug & DEBUG_ALARM)
#define DBG_TIMING		(debug & DEBUG_TIMING)

#define DBG_SPANFILTER		((1 << xhfc_span->port) & dbg_spanfilter)

#define CORRUPTED_FRAME 	(-1)
#define USE_FIFO_IRQ 		0

#define HDLC_BUF_LEN		128	/* "arbitrary", or so say DAHDI's drivers */

#ifndef MAX
# define MAX(a, b)		(((a) > (b))? (a) : (b))
#endif
#ifndef MIN
# define MIN(a, b)		(((a) < (b))? (a) : (b))
#endif

enum data_dir { TRANSMIT = 0, RECEIVE = 1 };

#define xhfc_info(x, format, arg...)         \
	dev_info(&(x)->pi->pci_dev->dev, format, ## arg)

enum { XHFC_PCM_MASTER = 1, XHFC_PCM_SLAVE = 0 };

/* some forward declaration */
struct xhfc_pi;
struct xhfc_span;
struct xhfc;

struct xhfc_span {

	struct xhfc* xhfc;

	struct dahdi_chan* chans[CHANS_PER_SPAN]; /* B1, B2, D */
	struct dahdi_chan _chans[CHANS_PER_SPAN]; /* B1, B2, D */
	unsigned char writechunk[CHANS_PER_SPAN * DAHDI_CHUNKSIZE]; // looks strange
	unsigned char readchunk[CHANS_PER_SPAN * DAHDI_CHUNKSIZE];  // looks strange
	/* Same as in DAHDI's for sameness reasons XXX which are??? */

	struct dahdi_span span;
	int ts;		/* PCM timeslot 			*/
	atomic_t hdlc_pending;

	int port;	/* (physical) S/T port number */
	int nt;		/* 1 if the port is nt, 0 if it's TE	*/

	int running;
	int shutdown;

	/* Got the following from DAHDI */
	int oldstate;
	int newalarm;
	unsigned long alarmtimer;
	struct dahdi_chan* sigchan;
	int sigactive;
	unsigned long hfc_timers[4];	/* T1, T2, T3, T4 */
	int hfc_timer_on[4]; 		/* 1=timer active */

	unsigned long non_rx_cnt;
};

struct xhfc {
	char 		*name;
	__u8 		chipidx;	/* index in pi->xhfcs[NUM_XHFCS] */
	struct xhfc_pi	*pi;		/* backpointer to xhfc_pi */

	struct xhfc_span spans[SPANS_PER_CHIP];

	/* from DAHDI */
	int running;
	unsigned long ticks;
	int setsyncspan;			/* Span reported from HFC for sync on this card */
	int reportedsyncspan;			/* Span reported from HFC for sync on this card */
};

struct xhfc_pi {

	struct tlp_leb_regs __iomem *regs;
	u8 __iomem *cs_n0;
	int irq;

	char 		name[16]; 	/* 'XHFC_PI0' = ProcessorInterface no. 0 */
	struct xhfc 	xhfc;		/* mem for one XHFC */

	struct pci_dev *pci_dev;
};

#define dchan_fifo(span) (span->port * 4 + 2)

void xhfc_flush_fifo(struct xhfc* x, int fifo);
int xhfc_hdlc_init(struct xhfc* x);
int xhfc_hdlc_interrupt(struct xhfc* x);

void xhfc_waitbusy(struct xhfc * xhfc);
void xhfc_selfifo(struct xhfc * xhfc, int fifo, int receive);
void xhfc_inc_f(struct xhfc * xhfc);
int xhfc_reset(struct xhfc * xhfc);
int xhfc_chipid(struct xhfc * xhfc);
int xhfc_cfg_pcm(struct xhfc * xhfc, __u8 pcm);

void hfc_handle_state(struct xhfc_span *s);
void hfc_update_st_timers(struct xhfc *x);
void hfc_start_st(struct xhfc_span *s);

int __devinit xhfc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
void __devexit xhfc_remove_one(struct pci_dev *pdev);
void xhfc_shutdown(struct pci_dev *pdev);

extern uint debug;
extern uint dbg_spanfilter;

#endif