summaryrefslogtreecommitdiff
path: root/xhfc/xhfc.h
blob: a598d4c738510a84aa87cb7b1d6f04e4968b945d (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
/* BRI support on XiVO IPBX OpenHardware with Cologne Chip's XHFC
 *
 * Copyright (C) 2010,2012  Avencall
 * Authors:
 *	Noe Rubinstein <nrubinstein@proformatique.com>
 *	Guillaume Knispel <gknispel@proformatique.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __XHFC_H__
#define __XHFC_H__

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

#ifdef AUDIO
# include <tdm/xivo_tdm_api.h>
# define XIVO_XHFC_TDM_PORT	0
#endif

#include "xhfc24sucd.h"

#define DRIVER_NAME "xivoxhfc"

#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

#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 */
#define DEBUG_REGS 		(1 << 2)
/* 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_SPAN(xhfc_span)	((1 << xhfc_span->port) & dbg_spanfilter)

#define CORRUPTED_FRAME 	(-1)

#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

#define V_SU_ACT_ACTIVATE	3
#define V_SU_ACT_DEACTIVATE	2

#define NOT_RUNNING		0	/* timer not running */

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

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;
	struct dahdi_chan* sigchan;
	atomic_t hdlc_pending; /* read and dec'd in interrupt context 
				* inc'd in xhfc_hdlc_hard_xmit called by DAHDI
				* in user context */

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

	u8 state, prev_state;
	unsigned long activation_timer, f6_f7_transition; // timers; 0 when deactivated
};

struct xhfc {
	struct xhfc_pi	*pi;		/* backpointer to xhfc_pi */

	struct xhfc_span spans[SPANS_PER_CHIP];

	int		running;
	unsigned long	ticks;
};

struct xhfc_pi {

	struct tlp_leb_regs __iomem *regs;	/* own ioremap */
	u8 __iomem *cs_n0;			/* own ioremap */
	u8 __iomem *cs_n1;			/* don't own ioremap */
	u8 soft_conf_byte;
	int irq;

	struct xhfc 	xhfc;		/* mem for one XHFC */

	struct pci_dev *pci_dev;

	/* maybe should be in struct xhfc but mainly used to retrieve the irq,
	 * so for now it ends up here */
	struct pnp_dev *pnp_dev;

#ifdef AUDIO
	struct xivo_tdm_port *tdm_port;
#endif
};

#define dchan_fifo(span) ((span)->port * 4 + 2)
#define portno(span) ((span)->port + 1)	/* used for traces */

void start_state_machine(struct xhfc_span* s);
void activate_request(struct xhfc_span* s);
void deactivate_request(struct xhfc_span* s);
void handle_state_change(struct xhfc_span* s);
void handle_st_timers(struct xhfc_span* s);

extern uint debug;
extern uint dbg_spanfilter;

#endif