linux/drivers/isdn/hisax/jade.c
<<
>>
Prefs
   1/* $Id: jade.c,v 1.9.2.4 2004/01/14 16:04:48 keil Exp $
   2 *
   3 * JADE stuff (derived from original hscx.c)
   4 *
   5 * Author       Roland Klabunde
   6 * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.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
  14#include <linux/init.h>
  15#include "hisax.h"
  16#include "hscx.h"
  17#include "jade.h"
  18#include "isdnl1.h"
  19#include <linux/interrupt.h>
  20#include <linux/slab.h>
  21
  22
  23int
  24JadeVersion(struct IsdnCardState *cs, char *s)
  25{
  26        int ver;
  27        int to = 50;
  28        cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
  29        while (to) {
  30                udelay(1);
  31                ver = cs->BC_Read_Reg(cs, -1, 0x60);
  32                to--;
  33                if (ver)
  34                        break;
  35                if (!to) {
  36                        printk(KERN_INFO "%s JADE version not obtainable\n", s);
  37                        return (0);
  38                }
  39        }
  40        /* Wait for the JADE */
  41        udelay(10);
  42        /* Read version */
  43        ver = cs->BC_Read_Reg(cs, -1, 0x60);
  44        printk(KERN_INFO "%s JADE version: %d\n", s, ver);
  45        return (1);
  46}
  47
  48/* Write to indirect accessible jade register set */
  49static void
  50jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
  51{
  52        int to = 50;
  53        u_char ret;
  54
  55        /* Write the data */
  56        cs->BC_Write_Reg(cs, -1, COMM_JADE + 1, value);
  57        /* Say JADE we wanna write indirect reg 'reg' */
  58        cs->BC_Write_Reg(cs, -1, COMM_JADE, reg);
  59        to = 50;
  60        /* Wait for RDY goes high */
  61        while (to) {
  62                udelay(1);
  63                ret = cs->BC_Read_Reg(cs, -1, COMM_JADE);
  64                to--;
  65                if (ret & 1)
  66                        /* Got acknowledge */
  67                        break;
  68                if (!to) {
  69                        printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value);
  70                        return;
  71                }
  72        }
  73}
  74
  75
  76
  77static void
  78modejade(struct BCState *bcs, int mode, int bc)
  79{
  80        struct IsdnCardState *cs = bcs->cs;
  81        int jade = bcs->hw.hscx.hscx;
  82
  83        if (cs->debug & L1_DEB_HSCX) {
  84                debugl1(cs, "jade %c mode %d ichan %d", 'A' + jade, mode, bc);
  85        }
  86        bcs->mode = mode;
  87        bcs->channel = bc;
  88
  89        cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO : 0x00));
  90        cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU | jadeCCR0_ITF));
  91        cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
  92
  93        jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
  94        jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
  95        jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
  96        jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
  97
  98        cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
  99        cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
 100
 101        if (bc == 0) {
 102                cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
 103                cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
 104        } else {
 105                cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
 106                cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
 107        }
 108        switch (mode) {
 109        case (L1_MODE_NULL):
 110                cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO);
 111                break;
 112        case (L1_MODE_TRANS):
 113                cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO | jadeMODE_RAC | jadeMODE_XAC));
 114                break;
 115        case (L1_MODE_HDLC):
 116                cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC | jadeMODE_XAC));
 117                break;
 118        }
 119        if (mode) {
 120                cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES | jadeRCMD_RMC));
 121                cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
 122                /* Unmask ints */
 123                cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
 124        }
 125        else
 126                /* Mask ints */
 127                cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
 128}
 129
 130static void
 131jade_l2l1(struct PStack *st, int pr, void *arg)
 132{
 133        struct BCState *bcs = st->l1.bcs;
 134        struct sk_buff *skb = arg;
 135        u_long flags;
 136
 137        switch (pr) {
 138        case (PH_DATA | REQUEST):
 139                spin_lock_irqsave(&bcs->cs->lock, flags);
 140                if (bcs->tx_skb) {
 141                        skb_queue_tail(&bcs->squeue, skb);
 142                } else {
 143                        bcs->tx_skb = skb;
 144                        test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
 145                        bcs->hw.hscx.count = 0;
 146                        bcs->cs->BC_Send_Data(bcs);
 147                }
 148                spin_unlock_irqrestore(&bcs->cs->lock, flags);
 149                break;
 150        case (PH_PULL | INDICATION):
 151                spin_lock_irqsave(&bcs->cs->lock, flags);
 152                if (bcs->tx_skb) {
 153                        printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n");
 154                } else {
 155                        test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
 156                        bcs->tx_skb = skb;
 157                        bcs->hw.hscx.count = 0;
 158                        bcs->cs->BC_Send_Data(bcs);
 159                }
 160                spin_unlock_irqrestore(&bcs->cs->lock, flags);
 161                break;
 162        case (PH_PULL | REQUEST):
 163                if (!bcs->tx_skb) {
 164                        test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 165                        st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
 166                } else
 167                        test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 168                break;
 169        case (PH_ACTIVATE | REQUEST):
 170                spin_lock_irqsave(&bcs->cs->lock, flags);
 171                test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
 172                modejade(bcs, st->l1.mode, st->l1.bc);
 173                spin_unlock_irqrestore(&bcs->cs->lock, flags);
 174                l1_msg_b(st, pr, arg);
 175                break;
 176        case (PH_DEACTIVATE | REQUEST):
 177                l1_msg_b(st, pr, arg);
 178                break;
 179        case (PH_DEACTIVATE | CONFIRM):
 180                spin_lock_irqsave(&bcs->cs->lock, flags);
 181                test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
 182                test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 183                modejade(bcs, 0, st->l1.bc);
 184                spin_unlock_irqrestore(&bcs->cs->lock, flags);
 185                st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
 186                break;
 187        }
 188}
 189
 190static void
 191close_jadestate(struct BCState *bcs)
 192{
 193        modejade(bcs, 0, bcs->channel);
 194        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
 195                kfree(bcs->hw.hscx.rcvbuf);
 196                bcs->hw.hscx.rcvbuf = NULL;
 197                kfree(bcs->blog);
 198                bcs->blog = NULL;
 199                skb_queue_purge(&bcs->rqueue);
 200                skb_queue_purge(&bcs->squeue);
 201                if (bcs->tx_skb) {
 202                        dev_kfree_skb_any(bcs->tx_skb);
 203                        bcs->tx_skb = NULL;
 204                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 205                }
 206        }
 207}
 208
 209static int
 210open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
 211{
 212        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
 213                if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
 214                        printk(KERN_WARNING
 215                               "HiSax: No memory for hscx.rcvbuf\n");
 216                        test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
 217                        return (1);
 218                }
 219                if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
 220                        printk(KERN_WARNING
 221                               "HiSax: No memory for bcs->blog\n");
 222                        test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
 223                        kfree(bcs->hw.hscx.rcvbuf);
 224                        bcs->hw.hscx.rcvbuf = NULL;
 225                        return (2);
 226                }
 227                skb_queue_head_init(&bcs->rqueue);
 228                skb_queue_head_init(&bcs->squeue);
 229        }
 230        bcs->tx_skb = NULL;
 231        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 232        bcs->event = 0;
 233        bcs->hw.hscx.rcvidx = 0;
 234        bcs->tx_cnt = 0;
 235        return (0);
 236}
 237
 238
 239static int
 240setstack_jade(struct PStack *st, struct BCState *bcs)
 241{
 242        bcs->channel = st->l1.bc;
 243        if (open_jadestate(st->l1.hardware, bcs))
 244                return (-1);
 245        st->l1.bcs = bcs;
 246        st->l2.l2l1 = jade_l2l1;
 247        setstack_manager(st);
 248        bcs->st = st;
 249        setstack_l1_B(st);
 250        return (0);
 251}
 252
 253void
 254clear_pending_jade_ints(struct IsdnCardState *cs)
 255{
 256        int val;
 257
 258        cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
 259        cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
 260
 261        val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR);
 262        debugl1(cs, "jade B ISTA %x", val);
 263        val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR);
 264        debugl1(cs, "jade A ISTA %x", val);
 265        val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR);
 266        debugl1(cs, "jade B STAR %x", val);
 267        val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR);
 268        debugl1(cs, "jade A STAR %x", val);
 269        /* Unmask ints */
 270        cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8);
 271        cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8);
 272}
 273
 274void
 275initjade(struct IsdnCardState *cs)
 276{
 277        cs->bcs[0].BC_SetStack = setstack_jade;
 278        cs->bcs[1].BC_SetStack = setstack_jade;
 279        cs->bcs[0].BC_Close = close_jadestate;
 280        cs->bcs[1].BC_Close = close_jadestate;
 281        cs->bcs[0].hw.hscx.hscx = 0;
 282        cs->bcs[1].hw.hscx.hscx = 1;
 283
 284        /* Stop DSP audio tx/rx */
 285        jade_write_indirect(cs, 0x11, 0x0f);
 286        jade_write_indirect(cs, 0x17, 0x2f);
 287
 288        /* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */
 289        cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO);
 290        cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO);
 291        /* Power down, 1-Idle, RxTx least significant bit first */
 292        cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00);
 293        cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00);
 294        /* Mask all interrupts */
 295        cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR,  0x00);
 296        cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR,  0x00);
 297        /* Setup host access to hdlc controller */
 298        jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1 | jadeINDIRECT_HAH2));
 299        /* Unmask HDLC int (don't forget DSP int later on)*/
 300        cs->BC_Write_Reg(cs, -1, jade_INT, (jadeINT_HDLC1 | jadeINT_HDLC2));
 301
 302        /* once again TRANSPARENT */
 303        modejade(cs->bcs, 0, 0);
 304        modejade(cs->bcs + 1, 0, 0);
 305}
 306