linux/drivers/isdn/hisax/st5481.h
<<
>>
Prefs
   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
  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
 150enum {
 151        ST_DOUT_NONE,
 152
 153        ST_DOUT_SHORT_INIT,
 154        ST_DOUT_SHORT_WAIT_DEN,
 155
 156        ST_DOUT_LONG_INIT,
 157        ST_DOUT_LONG_WAIT_DEN,
 158        ST_DOUT_NORMAL,
 159
 160        ST_DOUT_WAIT_FOR_UNDERRUN,
 161        ST_DOUT_WAIT_FOR_NOT_BUSY,
 162        ST_DOUT_WAIT_FOR_STOP,
 163        ST_DOUT_WAIT_FOR_RESET,
 164};
 165
 166#define DOUT_STATE_COUNT (ST_DOUT_WAIT_FOR_RESET + 1)
 167
 168// D channel out events
 169enum {
 170        EV_DOUT_START_XMIT,
 171        EV_DOUT_COMPLETE,
 172        EV_DOUT_DEN,
 173        EV_DOUT_RESETED,
 174        EV_DOUT_STOPPED,
 175        EV_DOUT_COLL,
 176        EV_DOUT_UNDERRUN,
 177};
 178
 179#define DOUT_EVENT_COUNT (EV_DOUT_UNDERRUN + 1)
 180
 181// ----------------------------------------------------------------------
 182
 183enum {
 184        ST_L1_F3,
 185        ST_L1_F4,
 186        ST_L1_F6,
 187        ST_L1_F7,
 188        ST_L1_F8,
 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
 196enum {
 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
 213        EV_PH_ACTIVATE_REQ,
 214        EV_PH_DEACTIVATE_REQ,
 215        EV_TIMER3,
 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 */
 239struct fifo {
 240        u_char r, w, count, size;
 241        spinlock_t lock;
 242};
 243
 244/*
 245 * Init an FIFO
 246 */
 247static 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 */
 257static 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 */
 282static 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 */
 308typedef void (*ctrl_complete_t)(void *);
 309
 310typedef struct ctrl_msg {
 311        struct usb_ctrlrequest dr;
 312        ctrl_complete_t complete;
 313        void *context;
 314} ctrl_msg;
 315
 316/* FIFO of ctrl messages waiting to be sent */
 317#define MAX_EP0_MSG 16
 318struct ctrl_msg_fifo {
 319        struct fifo f;
 320        struct ctrl_msg data[MAX_EP0_MSG];
 321};
 322
 323#define MAX_DFRAME_LEN_L1       300
 324#define HSCX_BUFMAX     4096
 325
 326struct st5481_ctrl {
 327        struct ctrl_msg_fifo msg_fifo;
 328        unsigned long busy;
 329        struct urb *urb;
 330};
 331
 332struct st5481_intr {
 333        //      struct evt_fifo evt_fifo;
 334        struct urb *urb;
 335};
 336
 337struct st5481_d_out {
 338        struct isdnhdlc_vars hdlc_state;
 339        struct urb *urb[2]; /* double buffering */
 340        unsigned long busy;
 341        struct sk_buff *tx_skb;
 342        struct FsmInst fsm;
 343};
 344
 345struct st5481_b_out {
 346        struct isdnhdlc_vars hdlc_state;
 347        struct urb *urb[2]; /* double buffering */
 348        u_char flow_event;
 349        u_long busy;
 350        struct sk_buff *tx_skb;
 351};
 352
 353struct st5481_in {
 354        struct isdnhdlc_vars hdlc_state;
 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;
 362        struct st5481_adapter *adapter;
 363        struct hisax_if *hisax_if;
 364};
 365
 366int st5481_setup_in(struct st5481_in *in);
 367void st5481_release_in(struct st5481_in *in);
 368void st5481_in_mode(struct st5481_in *in, int mode);
 369
 370struct st5481_bcs {
 371        struct hisax_b_if b_if;
 372        struct st5481_adapter *adapter;
 373        struct st5481_in b_in;
 374        struct st5481_b_out b_out;
 375        int channel;
 376        int mode;
 377};
 378
 379struct st5481_adapter {
 380        int number_of_leds;
 381        struct usb_device *usb_dev;
 382        struct hisax_d_if hisax_d_if;
 383
 384        struct st5481_ctrl ctrl;
 385        struct st5481_intr intr;
 386        struct st5481_in d_in;
 387        struct st5481_d_out d_out;
 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 */
 422static 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
 431int  st5481_setup_b(struct st5481_bcs *bcs);
 432void st5481_release_b(struct st5481_bcs *bcs);
 433void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg);
 434
 435/* D Channel */
 436
 437int  st5481_setup_d(struct st5481_adapter *adapter);
 438void st5481_release_d(struct st5481_adapter *adapter);
 439void st5481_b_l2l1(struct hisax_if *b_if, int pr, void *arg);
 440int  st5481_d_init(void);
 441void st5481_d_exit(void);
 442
 443/* USB */
 444void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command);
 445int 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);
 449void st5481_release_isocpipes(struct urb *urb[2]);
 450
 451void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
 452                           u_char pipe, ctrl_complete_t complete, void *context);
 453void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
 454                                u8 request, u16 value,
 455                                ctrl_complete_t complete, void *context);
 456int  st5481_setup_usb(struct st5481_adapter *adapter);
 457void st5481_release_usb(struct st5481_adapter *adapter);
 458void st5481_start(struct st5481_adapter *adapter);
 459void st5481_stop(struct st5481_adapter *adapter);
 460
 461// ----------------------------------------------------------------------
 462// debugging macros
 463
 464#define __debug_variable st5481_debug
 465#include "hisax_debug.h"
 466
 467extern 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
 474static void __attribute__((unused))
 475dump_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
 501static 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
 530