aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax/st5481.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/isdn/hisax/st5481.h
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/isdn/hisax/st5481.h')
-rw-r--r--drivers/isdn/hisax/st5481.h535
1 files changed, 535 insertions, 0 deletions
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
new file mode 100644
index 000000000000..e8177b017b1d
--- /dev/null
+++ b/drivers/isdn/hisax/st5481.h
@@ -0,0 +1,535 @@
1/*
2 * Driver for ST5481 USB ISDN modem
3 *
4 * Author Frode Isaksen
5 * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com>
6 * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de>
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 *
11 */
12
13#ifndef _ST5481_H_
14#define _ST5481_H_
15
16#include <linux/config.h>
17
18// USB IDs, the Product Id is in the range 0x4810-0x481F
19
20#define ST_VENDOR_ID 0x0483
21#define ST5481_PRODUCT_ID 0x4810
22#define ST5481_PRODUCT_ID_MASK 0xFFF0
23
24// ST5481 endpoints when using alternative setting 3 (2B+D).
25// To get the endpoint address, OR with 0x80 for IN endpoints.
26
27#define EP_CTRL 0x00U /* Control endpoint */
28#define EP_INT 0x01U /* Interrupt endpoint */
29#define EP_B1_OUT 0x02U /* B1 channel out */
30#define EP_B1_IN 0x03U /* B1 channel in */
31#define EP_B2_OUT 0x04U /* B2 channel out */
32#define EP_B2_IN 0x05U /* B2 channel in */
33#define EP_D_OUT 0x06U /* D channel out */
34#define EP_D_IN 0x07U /* D channel in */
35
36// Number of isochronous packets. With 20 packets we get
37// 50 interrupts/sec for each endpoint.
38
39#define NUM_ISO_PACKETS_D 20
40#define NUM_ISO_PACKETS_B 20
41
42// Size of each isochronous packet.
43// In outgoing direction we need to match ISDN data rates:
44// D: 2 bytes / msec -> 16 kbit / s
45// B: 16 bytes / msec -> 64 kbit / s
46#define SIZE_ISO_PACKETS_D_IN 16
47#define SIZE_ISO_PACKETS_D_OUT 2
48#define SIZE_ISO_PACKETS_B_IN 32
49#define SIZE_ISO_PACKETS_B_OUT 8
50
51// If we overrun/underrun, we send one packet with +/- 2 bytes
52#define B_FLOW_ADJUST 2
53
54// Registers that are written using vendor specific device request
55// on endpoint 0.
56
57#define LBA 0x02 /* S loopback */
58#define SET_DEFAULT 0x06 /* Soft reset */
59#define LBB 0x1D /* S maintenance loopback */
60#define STT 0x1e /* S force transmission signals */
61#define SDA_MIN 0x20 /* SDA-sin minimal value */
62#define SDA_MAX 0x21 /* SDA-sin maximal value */
63#define SDELAY_VALUE 0x22 /* Delay between Tx and Rx clock */
64#define IN_D_COUNTER 0x36 /* D receive channel fifo counter */
65#define OUT_D_COUNTER 0x37 /* D transmit channel fifo counter */
66#define IN_B1_COUNTER 0x38 /* B1 receive channel fifo counter */
67#define OUT_B1_COUNTER 0x39 /* B1 transmit channel fifo counter */
68#define IN_B2_COUNTER 0x3a /* B2 receive channel fifo counter */
69#define OUT_B2_COUNTER 0x3b /* B2 transmit channel fifo counter */
70#define FFCTRL_IN_D 0x3C /* D receive channel fifo threshold low */
71#define FFCTRH_IN_D 0x3D /* D receive channel fifo threshold high */
72#define FFCTRL_OUT_D 0x3E /* D transmit channel fifo threshold low */
73#define FFCTRH_OUT_D 0x3F /* D transmit channel fifo threshold high */
74#define FFCTRL_IN_B1 0x40 /* B1 receive channel fifo threshold low */
75#define FFCTRH_IN_B1 0x41 /* B1 receive channel fifo threshold high */
76#define FFCTRL_OUT_B1 0x42 /* B1 transmit channel fifo threshold low */
77#define FFCTRH_OUT_B1 0x43 /* B1 transmit channel fifo threshold high */
78#define FFCTRL_IN_B2 0x44 /* B2 receive channel fifo threshold low */
79#define FFCTRH_IN_B2 0x45 /* B2 receive channel fifo threshold high */
80#define FFCTRL_OUT_B2 0x46 /* B2 transmit channel fifo threshold low */
81#define FFCTRH_OUT_B2 0x47 /* B2 transmit channel fifo threshold high */
82#define MPMSK 0x4A /* Multi purpose interrupt MASK register */
83#define FFMSK_D 0x4c /* D fifo interrupt MASK register */
84#define FFMSK_B1 0x4e /* B1 fifo interrupt MASK register */
85#define FFMSK_B2 0x50 /* B2 fifo interrupt MASK register */
86#define GPIO_DIR 0x52 /* GPIO pins direction registers */
87#define GPIO_OUT 0x53 /* GPIO pins output register */
88#define GPIO_IN 0x54 /* GPIO pins input register */
89#define TXCI 0x56 /* CI command to be transmitted */
90
91
92// Format of the interrupt packet received on endpoint 1:
93//
94// +--------+--------+--------+--------+--------+--------+
95// !MPINT !FFINT_D !FFINT_B1!FFINT_B2!CCIST !GPIO_INT!
96// +--------+--------+--------+--------+--------+--------+
97
98// Offsets in the interrupt packet
99
100#define MPINT 0
101#define FFINT_D 1
102#define FFINT_B1 2
103#define FFINT_B2 3
104#define CCIST 4
105#define GPIO_INT 5
106#define INT_PKT_SIZE 6
107
108// MPINT
109#define LSD_INT 0x80 /* S line activity detected */
110#define RXCI_INT 0x40 /* Indicate primitive arrived */
111#define DEN_INT 0x20 /* Signal enabling data out of D Tx fifo */
112#define DCOLL_INT 0x10 /* D channel collision */
113#define AMIVN_INT 0x04 /* AMI violation number reached 2 */
114#define INFOI_INT 0x04 /* INFOi changed */
115#define DRXON_INT 0x02 /* Reception channel active */
116#define GPCHG_INT 0x01 /* GPIO pin value changed */
117
118// FFINT_x
119#define IN_OVERRUN 0x80 /* In fifo overrun */
120#define OUT_UNDERRUN 0x40 /* Out fifo underrun */
121#define IN_UP 0x20 /* In fifo thresholdh up-crossed */
122#define IN_DOWN 0x10 /* In fifo thresholdl down-crossed */
123#define OUT_UP 0x08 /* Out fifo thresholdh up-crossed */
124#define OUT_DOWN 0x04 /* Out fifo thresholdl down-crossed */
125#define IN_COUNTER_ZEROED 0x02 /* In down-counter reached 0 */
126#define OUT_COUNTER_ZEROED 0x01 /* Out down-counter reached 0 */
127
128#define ANY_REC_INT (IN_OVERRUN+IN_UP+IN_DOWN+IN_COUNTER_ZEROED)
129#define ANY_XMIT_INT (OUT_UNDERRUN+OUT_UP+OUT_DOWN+OUT_COUNTER_ZEROED)
130
131
132// Level 1 commands that are sent using the TXCI device request
133#define ST5481_CMD_DR 0x0 /* Deactivation Request */
134#define ST5481_CMD_RES 0x1 /* state machine RESet */
135#define ST5481_CMD_TM1 0x2 /* Test Mode 1 */
136#define ST5481_CMD_TM2 0x3 /* Test Mode 2 */
137#define ST5481_CMD_PUP 0x7 /* Power UP */
138#define ST5481_CMD_AR8 0x8 /* Activation Request class 1 */
139#define ST5481_CMD_AR10 0x9 /* Activation Request class 2 */
140#define ST5481_CMD_ARL 0xA /* Activation Request Loopback */
141#define ST5481_CMD_PDN 0xF /* Power DoWn */
142
143// Turn on/off the LEDs using the GPIO device request.
144// To use the B LEDs, number_of_leds must be set to 4
145#define B1_LED 0x10U
146#define B2_LED 0x20U
147#define GREEN_LED 0x40U
148#define RED_LED 0x80U
149
150// D channel out states
151enum {
152 ST_DOUT_NONE,
153
154 ST_DOUT_SHORT_INIT,
155 ST_DOUT_SHORT_WAIT_DEN,
156
157 ST_DOUT_LONG_INIT,
158 ST_DOUT_LONG_WAIT_DEN,
159 ST_DOUT_NORMAL,
160
161 ST_DOUT_WAIT_FOR_UNDERRUN,
162 ST_DOUT_WAIT_FOR_NOT_BUSY,
163 ST_DOUT_WAIT_FOR_STOP,
164 ST_DOUT_WAIT_FOR_RESET,
165};
166
167#define DOUT_STATE_COUNT (ST_DOUT_WAIT_FOR_RESET + 1)
168
169// D channel out events
170enum {
171 EV_DOUT_START_XMIT,
172 EV_DOUT_COMPLETE,
173 EV_DOUT_DEN,
174 EV_DOUT_RESETED,
175 EV_DOUT_STOPPED,
176 EV_DOUT_COLL,
177 EV_DOUT_UNDERRUN,
178};
179
180#define DOUT_EVENT_COUNT (EV_DOUT_UNDERRUN + 1)
181
182// ----------------------------------------------------------------------
183
184enum {
185 ST_L1_F3,
186 ST_L1_F4,
187 ST_L1_F6,
188 ST_L1_F7,
189 ST_L1_F8,
190};
191
192#define L1_STATE_COUNT (ST_L1_F8+1)
193
194// The first 16 entries match the Level 1 indications that
195// are found at offset 4 (CCIST) in the interrupt packet
196
197enum {
198 EV_IND_DP, // 0000 Deactivation Pending
199 EV_IND_1, // 0001
200 EV_IND_2, // 0010
201 EV_IND_3, // 0011
202 EV_IND_RSY, // 0100 ReSYnchronizing
203 EV_IND_5, // 0101
204 EV_IND_6, // 0110
205 EV_IND_7, // 0111
206 EV_IND_AP, // 1000 Activation Pending
207 EV_IND_9, // 1001
208 EV_IND_10, // 1010
209 EV_IND_11, // 1011
210 EV_IND_AI8, // 1100 Activation Indication class 8
211 EV_IND_AI10,// 1101 Activation Indication class 10
212 EV_IND_AIL, // 1110 Activation Indication Loopback
213 EV_IND_DI, // 1111 Deactivation Indication
214 EV_PH_ACTIVATE_REQ,
215 EV_PH_DEACTIVATE_REQ,
216 EV_TIMER3,
217};
218
219#define L1_EVENT_COUNT (EV_TIMER3 + 1)
220
221#define ERR(format, arg...) \
222printk(KERN_ERR "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg)
223
224#define WARN(format, arg...) \
225printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg)
226
227#define INFO(format, arg...) \
228printk(KERN_INFO "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg)
229
230#include "isdnhdlc.h"
231#include "fsm.h"
232#include "hisax_if.h"
233#include <linux/skbuff.h>
234
235/* ======================================================================
236 * FIFO handling
237 */
238
239/* Generic FIFO structure */
240struct fifo {
241 u_char r,w,count,size;
242 spinlock_t lock;
243};
244
245/*
246 * Init an FIFO
247 */
248static inline void fifo_init(struct fifo *fifo, int size)
249{
250 fifo->r = fifo->w = fifo->count = 0;
251 fifo->size = size;
252 spin_lock_init(&fifo->lock);
253}
254
255/*
256 * Add an entry to the FIFO
257 */
258static inline int fifo_add(struct fifo *fifo)
259{
260 unsigned long flags;
261 int index;
262
263 if (!fifo) {
264 return -1;
265 }
266
267 spin_lock_irqsave(&fifo->lock, flags);
268 if (fifo->count == fifo->size) {
269 // FIFO full
270 index = -1;
271 } else {
272 // Return index where to get the next data to add to the FIFO
273 index = fifo->w++ & (fifo->size-1);
274 fifo->count++;
275 }
276 spin_unlock_irqrestore(&fifo->lock, flags);
277 return index;
278}
279
280/*
281 * Remove an entry from the FIFO with the index returned.
282 */
283static inline int fifo_remove(struct fifo *fifo)
284{
285 unsigned long flags;
286 int index;
287
288 if (!fifo) {
289 return -1;
290 }
291
292 spin_lock_irqsave(&fifo->lock, flags);
293 if (!fifo->count) {
294 // FIFO empty
295 index = -1;
296 } else {
297 // Return index where to get the next data from the FIFO
298 index = fifo->r++ & (fifo->size-1);
299 fifo->count--;
300 }
301 spin_unlock_irqrestore(&fifo->lock, flags);
302
303 return index;
304}
305
306/* ======================================================================
307 * control pipe
308 */
309typedef void (*ctrl_complete_t)(void *);
310
311typedef struct ctrl_msg {
312 struct usb_ctrlrequest dr;
313 ctrl_complete_t complete;
314 void *context;
315} ctrl_msg;
316
317/* FIFO of ctrl messages waiting to be sent */
318#define MAX_EP0_MSG 16
319struct ctrl_msg_fifo {
320 struct fifo f;
321 struct ctrl_msg data[MAX_EP0_MSG];
322};
323
324#define MAX_DFRAME_LEN_L1 300
325#define HSCX_BUFMAX 4096
326
327struct st5481_ctrl {
328 struct ctrl_msg_fifo msg_fifo;
329 unsigned long busy;
330 struct urb *urb;
331};
332
333struct st5481_intr {
334 // struct evt_fifo evt_fifo;
335 struct urb *urb;
336};
337
338struct st5481_d_out {
339 struct isdnhdlc_vars hdlc_state;
340 struct urb *urb[2]; /* double buffering */
341 unsigned long busy;
342 struct sk_buff *tx_skb;
343 struct FsmInst fsm;
344};
345
346struct st5481_b_out {
347 struct isdnhdlc_vars hdlc_state;
348 struct urb *urb[2]; /* double buffering */
349 u_char flow_event;
350 u_long busy;
351 struct sk_buff *tx_skb;
352};
353
354struct st5481_in {
355 struct isdnhdlc_vars hdlc_state;
356 struct urb *urb[2]; /* double buffering */
357 int mode;
358 int bufsize;
359 unsigned int num_packets;
360 unsigned int packet_size;
361 unsigned char ep, counter;
362 unsigned char *rcvbuf;
363 struct st5481_adapter *adapter;
364 struct hisax_if *hisax_if;
365};
366
367int st5481_setup_in(struct st5481_in *in);
368void st5481_release_in(struct st5481_in *in);
369void st5481_in_mode(struct st5481_in *in, int mode);
370
371struct st5481_bcs {
372 struct hisax_b_if b_if;
373 struct st5481_adapter *adapter;
374 struct st5481_in b_in;
375 struct st5481_b_out b_out;
376 int channel;
377 int mode;
378};
379
380struct st5481_adapter {
381 struct list_head list;
382 int number_of_leds;
383 struct usb_device *usb_dev;
384 struct hisax_d_if hisax_d_if;
385
386 struct st5481_ctrl ctrl;
387 struct st5481_intr intr;
388 struct st5481_in d_in;
389 struct st5481_d_out d_out;
390
391 unsigned char leds;
392 unsigned int led_counter;
393
394 unsigned long event;
395
396 struct FsmInst l1m;
397 struct FsmTimer timer;
398
399 struct st5481_bcs bcs[2];
400};
401
402#define TIMER3_VALUE 7000
403
404/* ======================================================================
405 *
406 */
407
408/*
409 * Submit an URB with error reporting. This is a macro so
410 * the __FUNCTION__ returns the caller function name.
411 */
412#define SUBMIT_URB(urb, mem_flags) \
413({ \
414 int status; \
415 if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \
416 WARN("usb_submit_urb failed,status=%d", status); \
417 } \
418 status; \
419})
420
421/*
422 * USB double buffering, return the URB index (0 or 1).
423 */
424static inline int get_buf_nr(struct urb *urbs[], struct urb *urb)
425{
426 return (urbs[0]==urb ? 0 : 1);
427}
428
429/* ---------------------------------------------------------------------- */
430
431/* B Channel */
432
433int st5481_setup_b(struct st5481_bcs *bcs);
434void st5481_release_b(struct st5481_bcs *bcs);
435void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg);
436
437/* D Channel */
438
439int st5481_setup_d(struct st5481_adapter *adapter);
440void st5481_release_d(struct st5481_adapter *adapter);
441void st5481_b_l2l1(struct hisax_if *b_if, int pr, void *arg);
442int st5481_d_init(void);
443void st5481_d_exit(void);
444
445/* USB */
446void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command);
447int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
448 unsigned int pipe, int num_packets,
449 int packet_size, int buf_size,
450 usb_complete_t complete, void *context);
451void st5481_release_isocpipes(struct urb* urb[2]);
452
453int st5481_isoc_flatten(struct urb *urb);
454void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
455 u_char pipe, ctrl_complete_t complete, void *context);
456void st5481_usb_ctrl_msg(struct st5481_adapter *adapter,
457 u8 request, u8 requesttype, u16 value, u16 index,
458 ctrl_complete_t complete, void *context);
459void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
460 u8 request, u16 value,
461 ctrl_complete_t complete, void *context);
462int st5481_setup_usb(struct st5481_adapter *adapter);
463void st5481_release_usb(struct st5481_adapter *adapter);
464void st5481_start(struct st5481_adapter *adapter);
465void st5481_stop(struct st5481_adapter *adapter);
466
467// ----------------------------------------------------------------------
468// debugging macros
469
470#define __debug_variable st5481_debug
471#include "hisax_debug.h"
472
473#ifdef CONFIG_HISAX_DEBUG
474
475extern int st5481_debug;
476
477#define DBG_ISO_PACKET(level,urb) \
478 if (level & __debug_variable) dump_iso_packet(__FUNCTION__,urb)
479
480static void __attribute__((unused))
481dump_iso_packet(const char *name, struct urb *urb)
482{
483 int i,j;
484 int len,ofs;
485 u_char *data;
486
487 printk(KERN_DEBUG "%s: packets=%d,errors=%d\n",
488 name,urb->number_of_packets,urb->error_count);
489 for (i = 0; i < urb->number_of_packets; ++i) {
490 if (urb->pipe & USB_DIR_IN) {
491 len = urb->iso_frame_desc[i].actual_length;
492 } else {
493 len = urb->iso_frame_desc[i].length;
494 }
495 ofs = urb->iso_frame_desc[i].offset;
496 printk(KERN_DEBUG "len=%.2d,ofs=%.3d ",len,ofs);
497 if (len) {
498 data = urb->transfer_buffer+ofs;
499 for (j=0; j < len; j++) {
500 printk ("%.2x", data[j]);
501 }
502 }
503 printk("\n");
504 }
505}
506
507static inline const char *ST5481_CMD_string(int evt)
508{
509 static char s[16];
510
511 switch (evt) {
512 case ST5481_CMD_DR: return "DR";
513 case ST5481_CMD_RES: return "RES";
514 case ST5481_CMD_TM1: return "TM1";
515 case ST5481_CMD_TM2: return "TM2";
516 case ST5481_CMD_PUP: return "PUP";
517 case ST5481_CMD_AR8: return "AR8";
518 case ST5481_CMD_AR10: return "AR10";
519 case ST5481_CMD_ARL: return "ARL";
520 case ST5481_CMD_PDN: return "PDN";
521 };
522
523 sprintf(s,"0x%x",evt);
524 return s;
525}
526
527#else
528
529#define DBG_ISO_PACKET(level,urb) do {} while (0)
530
531#endif
532
533
534
535#endif