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