void __init initW6692(struct IsdnCardState *cs, int part) { if (part & 1) { cs->tqueue.routine = (void *) (void *) W6692_bh; cs->setstack_d = setstack_W6692; cs->DC_Close = DC_Close_W6692; cs->dbusytimer.function = (void *) dbusy_timer_handler; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); resetW6692(cs); ph_command(cs, W_L1CMD_RST); cs->dc.w6692.ph_state = W_L1CMD_RST; W6692_new_ph(cs); ph_command(cs, W_L1CMD_ECK); cs->bcs[0].BC_SetStack = setstack_w6692; cs->bcs[1].BC_SetStack = setstack_w6692; cs->bcs[0].BC_Close = close_w6692state; cs->bcs[1].BC_Close = close_w6692state; W6692Bmode(cs->bcs, 0, 0); W6692Bmode(cs->bcs + 1, 0, 0); } if (part & 2) { /* Reenable all IRQ */ cs->writeW6692(cs, W_IMASK, 0x18); cs->writeW6692(cs, W_D_EXIM, 0x00); cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00); cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00); /* Reset D-chan receiver and transmitter */ cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); } }
void initW6692(struct w6692_hw *card) { u8 val; card->dch.timer.function = (void *)dbusy_timer_handler; card->dch.timer.data = (u_long)&card->dch; init_timer(&card->dch.timer); w6692_mode(&card->bc[0], ISDN_P_NONE); w6692_mode(&card->bc[1], ISDN_P_NONE); WriteW6692(card, W_D_CTL, 0x00); disable_hwirq(card); WriteW6692(card, W_D_SAM, 0xff); WriteW6692(card, W_D_TAM, 0xff); WriteW6692(card, W_D_MODE, W_D_MODE_RACT); card->state = W_L1CMD_RST; ph_command(card, W_L1CMD_RST); ph_command(card, W_L1CMD_ECK); /* enable all IRQ but extern */ card->imask = 0x18; WriteW6692(card, W_D_EXIM, 0x00); WriteW6692B(&card->bc[0], W_B_EXIM, 0); WriteW6692B(&card->bc[1], W_B_EXIM, 0); /* Reset D-chan receiver and transmitter */ WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); /* Reset B-chan receiver and transmitter */ WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); /* enable peripheral */ if (card->subtype == W6692_USR) { /* seems that USR implemented some power control features * Pin 79 is connected to the oscilator circuit so we * have to handle it here */ card->pctl = 0x80; card->xdata = 0; WriteW6692(card, W_PCTL, card->pctl); WriteW6692(card, W_XDATA, card->xdata); } else { card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 | W_PCTL_OE1 | W_PCTL_OE0; card->xaddr = 0x00;/* all sw off */ if (card->fmask & pots) card->xdata |= 0x06; /* POWER UP/ LED OFF / ALAW */ if (card->fmask & led) card->xdata |= 0x04; /* LED OFF */ if ((card->fmask & pots) || (card->fmask & led)) { WriteW6692(card, W_PCTL, card->pctl); WriteW6692(card, W_XADDR, card->xaddr); WriteW6692(card, W_XDATA, card->xdata); val = ReadW6692(card, W_XADDR); if (debug & DEBUG_HW) pr_notice("%s: W_XADDR=%02x\n", card->name, val); } } }
void initW6692(struct w6692_hw *card) { u8 val; card->dch.timer.function = (void *)dbusy_timer_handler; card->dch.timer.data = (u_long)&card->dch; init_timer(&card->dch.timer); w6692_mode(&card->bc[0], ISDN_P_NONE); w6692_mode(&card->bc[1], ISDN_P_NONE); WriteW6692(card, W_D_CTL, 0x00); disable_hwirq(card); WriteW6692(card, W_D_SAM, 0xff); WriteW6692(card, W_D_TAM, 0xff); WriteW6692(card, W_D_MODE, W_D_MODE_RACT); card->state = W_L1CMD_RST; ph_command(card, W_L1CMD_RST); ph_command(card, W_L1CMD_ECK); card->imask = 0x18; WriteW6692(card, W_D_EXIM, 0x00); WriteW6692B(&card->bc[0], W_B_EXIM, 0); WriteW6692B(&card->bc[1], W_B_EXIM, 0); WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); if (card->subtype == W6692_USR) { card->pctl = 0x80; card->xdata = 0; WriteW6692(card, W_PCTL, card->pctl); WriteW6692(card, W_XDATA, card->xdata); } else { card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 | W_PCTL_OE1 | W_PCTL_OE0; card->xaddr = 0x00; if (card->fmask & pots) card->xdata |= 0x06; if (card->fmask & led) card->xdata |= 0x04; if ((card->fmask & pots) || (card->fmask & led)) { WriteW6692(card, W_PCTL, card->pctl); WriteW6692(card, W_XADDR, card->xaddr); WriteW6692(card, W_XDATA, card->xdata); val = ReadW6692(card, W_XADDR); if (debug & DEBUG_HW) pr_notice("%s: W_XADDR=%02x\n", card->name, val); } } }
static void icc_new_ph(struct IsdnCardState *cs) { switch (cs->dc.icc.ph_state) { case (ICC_IND_EI1): ph_command(cs, ICC_CMD_DI); l1_msg(cs, HW_RESET | INDICATION, NULL); break; case (ICC_IND_DC): l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); break; case (ICC_IND_DR): l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); break; case (ICC_IND_PU): l1_msg(cs, HW_POWERUP | CONFIRM, NULL); break; case (ICC_IND_FJ): l1_msg(cs, HW_RSYNC | INDICATION, NULL); break; case (ICC_IND_AR): l1_msg(cs, HW_INFO2 | INDICATION, NULL); break; case (ICC_IND_AI): l1_msg(cs, HW_INFO4 | INDICATION, NULL); break; default: break; } }
static void W6692_new_ph(struct IsdnCardState *cs) { switch (cs->dc.w6692.ph_state) { case (W_L1CMD_RST): ph_command(cs, W_L1CMD_DRC); l1_msg(cs, HW_RESET | INDICATION, NULL); /* fallthru */ case (W_L1IND_CD): l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); break; case (W_L1IND_DRD): l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); break; case (W_L1IND_CE): l1_msg(cs, HW_POWERUP | CONFIRM, NULL); break; case (W_L1IND_LD): l1_msg(cs, HW_RSYNC | INDICATION, NULL); break; case (W_L1IND_ARD): l1_msg(cs, HW_INFO2 | INDICATION, NULL); break; case (W_L1IND_AI8): l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); break; case (W_L1IND_AI10): l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL); break; default: break; } }
static void l1_timer3(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; ph_command(isac, ISAC_CMD_DI); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); }
static void l1_ar8(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmRestartTimer(&isac->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); ph_command(isac, ISAC_CMD_AR8); }
static void l1_go_f3pend(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_F3_PEND_DEACT); ph_command(isac, ISAC_CMD_DI); }
static void l1_di(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_RESET); ph_command(isac, ISAC_CMD_DI); }
static void W6692_new_ph(struct w6692_hw *card) { if (card->state == W_L1CMD_RST) ph_command(card, W_L1CMD_DRC); schedule_event(&card->dch, FLG_PHCHANGE); }
static void isac_new_ph(struct IsdnCardState *cs) { switch (cs->dc.isac.ph_state) { case (ISAC_IND_RS): case (ISAC_IND_EI): ph_command(cs, ISAC_CMD_DUI); l1_msg(cs, HW_RESET | INDICATION, NULL); break; case (ISAC_IND_DID): l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); break; case (ISAC_IND_DR): l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); break; case (ISAC_IND_PU): l1_msg(cs, HW_POWERUP | CONFIRM, NULL); break; case (ISAC_IND_RSY): l1_msg(cs, HW_RSYNC | INDICATION, NULL); break; case (ISAC_IND_ARD): l1_msg(cs, HW_INFO2 | INDICATION, NULL); break; case (ISAC_IND_AI8): l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); break; case (ISAC_IND_AI10): l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL); break; default: break; } }
static void l1_go_f3pend_deact_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_F3_PEND_DEACT); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); ph_command(isac, ISAC_CMD_DI); }
static void l1_go_f7_act_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmDelTimer(&isac->timer, 0); FsmChangeState(fi, ST_L1_F7); ph_command(isac, ISAC_CMD_AR8); D_L1L2(isac, PH_ACTIVATE | INDICATION, NULL); }
static void isac_ph_state_change(struct isac_hw *isac) { switch (isac->state) { case (ISAC_IND_RS): case (ISAC_IND_EI): ph_command(isac, ISAC_CMD_DUI); } schedule_event(&isac->dch, FLG_PHCHANGE); }
static void W6692_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; int val; switch (pr) { case (PH_DATA | REQUEST): if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb); #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); #endif } else { cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); #endif W6692_fill_fifo(cs); } break; case (PH_PULL | INDICATION): if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); break; } if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); #endif W6692_fill_fifo(cs); break; case (PH_PULL | REQUEST): #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); #endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (HW_RESET | REQUEST): if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) ph_command(cs, W_L1CMD_ECK); else { ph_command(cs, W_L1CMD_RST); cs->dc.w6692.ph_state = W_L1CMD_RST; W6692_new_ph(cs); } break; case (HW_ENABLE | REQUEST): ph_command(cs, W_L1CMD_ECK); break; case (HW_INFO3 | REQUEST): ph_command(cs, W_L1CMD_AR8); break; case (HW_TESTLOOP | REQUEST): val = 0; if (1 & (long) arg) val |= 0x0c; if (2 & (long) arg) val |= 0x3; /* !!! not implemented yet */ break; case (HW_DEACTIVATE | RESPONSE): skb_queue_purge(&cs->rq); skb_queue_purge(&cs->sq); if (cs->tx_skb) { dev_kfree_skb_any(cs->tx_skb); cs->tx_skb = NULL; } if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) del_timer(&cs->dbusytimer); if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) W6692_sched_event(cs, D_CLEARBUSY); break; default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "W6692_l1hw unknown %04x", pr); break; } }
static int w6692_l1callback(struct dchannel *dch, u32 cmd) { struct w6692_hw *card = container_of(dch, struct w6692_hw, dch); u_long flags; pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state); switch (cmd) { case INFO3_P8: spin_lock_irqsave(&card->lock, flags); ph_command(card, W_L1CMD_AR8); spin_unlock_irqrestore(&card->lock, flags); break; case INFO3_P10: spin_lock_irqsave(&card->lock, flags); ph_command(card, W_L1CMD_AR10); spin_unlock_irqrestore(&card->lock, flags); break; case HW_RESET_REQ: spin_lock_irqsave(&card->lock, flags); if (card->state != W_L1IND_DRD) ph_command(card, W_L1CMD_RST); ph_command(card, W_L1CMD_ECK); spin_unlock_irqrestore(&card->lock, flags); break; case HW_DEACT_REQ: skb_queue_purge(&dch->squeue); if (dch->tx_skb) { dev_kfree_skb(dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { dev_kfree_skb(dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) del_timer(&dch->timer); break; case HW_POWERUP_REQ: spin_lock_irqsave(&card->lock, flags); ph_command(card, W_L1CMD_ECK); spin_unlock_irqrestore(&card->lock, flags); break; case PH_ACTIVATE_IND: test_and_set_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; case PH_DEACTIVATE_IND: test_and_clear_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; default: pr_debug("%s: %s unknown command %x\n", card->name, __func__, cmd); return -1; } return 0; }