static int __devinit setup_speedfax(struct sfax_hw *sf) { u_long flags; if (!request_region(sf->cfg, 256, sf->name)) { pr_info("mISDN: %s config port %x-%x already in use\n", sf->name, sf->cfg, sf->cfg + 255); return -EIO; } outb(0xff, sf->cfg); outb(0, sf->cfg); outb(0xdd, sf->cfg + TIGER_AUX_CTRL); outb(0, sf->cfg + TIGER_AUX_IRQMASK); sf->isac.type = IPAC_TYPE_ISAC; sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR; sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC; sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR; sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR; ASSIGN_FUNC(IND, ISAC, sf->isac); ASSIGN_FUNC(IND, ISAR, sf->isar); spin_lock_irqsave(&sf->lock, flags); reset_speedfax(sf); disable_hwirq(sf); spin_unlock_irqrestore(&sf->lock, flags); return 0; }
static int init_card(struct w6692_hw *card) { int cnt = 3; u_long flags; spin_lock_irqsave(&card->lock, flags); disable_hwirq(card); spin_unlock_irqrestore(&card->lock, flags); if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) { pr_info("%s: couldn't get interrupt %d\n", card->name, card->irq); return -EIO; } while (cnt--) { spin_lock_irqsave(&card->lock, flags); initW6692(card); enable_hwirq(card); spin_unlock_irqrestore(&card->lock, flags); msleep_interruptible(10); if (debug & DEBUG_HW) pr_notice("%s: IRQ %d count %d\n", card->name, card->irq, card->irqcnt); if (!card->irqcnt) { pr_info("%s: IRQ(%d) getting no IRQs during init %d\n", card->name, card->irq, 3 - cnt); reset_w6692(card); } else return 0; } free_irq(card->irq, card); return -EIO; }
static void release_card(struct w6692_hw *card) { u_long flags; spin_lock_irqsave(&card->lock, flags); disable_hwirq(card); w6692_mode(&card->bc[0], ISDN_P_NONE); w6692_mode(&card->bc[1], ISDN_P_NONE); if ((card->fmask & led) || card->subtype == W6692_USR) { card->xdata |= 0x04; WriteW6692(card, W_XDATA, card->xdata); } spin_unlock_irqrestore(&card->lock, flags); free_irq(card->irq, card); l1_event(card->dch.l1, CLOSE_CHANNEL); mISDN_unregister_device(&card->dch.dev); release_region(card->addr, 256); mISDN_freebchannel(&card->bc[1].bch); mISDN_freebchannel(&card->bc[0].bch); mISDN_freedchannel(&card->dch); write_lock_irqsave(&card_lock, flags); list_del(&card->list); write_unlock_irqrestore(&card_lock, flags); pci_disable_device(card->pdev); pci_set_drvdata(card->pdev, NULL); kfree(card); }
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 release_card(struct sfax_hw *card) { u_long flags; spin_lock_irqsave(&card->lock, flags); disable_hwirq(card); spin_unlock_irqrestore(&card->lock, flags); card->isac.release(&card->isac); free_irq(card->irq, card); card->isar.release(&card->isar); mISDN_unregister_device(&card->isac.dch.dev); release_region(card->cfg, 256); pci_disable_device(card->pdev); pci_set_drvdata(card->pdev, NULL); write_lock_irqsave(&card_lock, flags); list_del(&card->list); write_unlock_irqrestore(&card_lock, flags); kfree(card); sfax_cnt--; }
static int __devinit setup_instance(struct sfax_hw *card) { const struct firmware *firmware; int i, err; u_long flags; snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1); write_lock_irqsave(&card_lock, flags); list_add_tail(&card->list, &Cards); write_unlock_irqrestore(&card_lock, flags); _set_debug(card); spin_lock_init(&card->lock); card->isac.hwlock = &card->lock; card->isar.hwlock = &card->lock; card->isar.ctrl = (void *)&sfax_ctrl; card->isac.name = card->name; card->isar.name = card->name; card->isar.owner = THIS_MODULE; err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev); if (err < 0) { pr_info("%s: firmware request failed %d\n", card->name, err); goto error_fw; } if (debug & DEBUG_HW) pr_notice("%s: got firmware %zu bytes\n", card->name, firmware->size); mISDNisac_init(&card->isac, card); card->isac.dch.dev.D.ctrl = sfax_dctrl; card->isac.dch.dev.Bprotocols = mISDNisar_init(&card->isar, card); for (i = 0; i < 2; i++) { set_channelmap(i + 1, card->isac.dch.dev.channelmap); list_add(&card->isar.ch[i].bch.ch.list, &card->isac.dch.dev.bchannels); } err = setup_speedfax(card); if (err) goto error_setup; err = card->isar.init(&card->isar); if (err) goto error; err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev, card->name); if (err) goto error; err = init_card(card); if (err) goto error_init; err = card->isar.firmware(&card->isar, firmware->data, firmware->size); if (!err) { release_firmware(firmware); sfax_cnt++; pr_notice("SpeedFax %d cards installed\n", sfax_cnt); return 0; } disable_hwirq(card); free_irq(card->irq, card); error_init: mISDN_unregister_device(&card->isac.dch.dev); error: release_region(card->cfg, 256); error_setup: card->isac.release(&card->isac); card->isar.release(&card->isar); release_firmware(firmware); error_fw: pci_disable_device(card->pdev); write_lock_irqsave(&card_lock, flags); list_del(&card->list); write_unlock_irqrestore(&card_lock, flags); kfree(card); return err; }