int msnd_enable_irq(multisound_dev_t *dev) { unsigned long flags; if (dev->irq_ref++) return 0; printk(KERN_DEBUG LOGNAME ": Enabling IRQ\n"); spin_lock_irqsave(&dev->lock, flags); if (msnd_wait_TXDE(dev) == 0) { msnd_outb(msnd_inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR); if (dev->type == msndClassic) msnd_outb(dev->irqid, dev->io + HP_IRQM); msnd_outb(msnd_inb(dev->io + HP_ICR) & ~HPICR_TREQ, dev->io + HP_ICR); msnd_outb(msnd_inb(dev->io + HP_ICR) | HPICR_RREQ, dev->io + HP_ICR); enable_irq(dev->irq); msnd_init_queue(dev->DSPQ, dev->dspq_data_buff, dev->dspq_buff_size); spin_unlock_irqrestore(&dev->lock, flags); return 0; } spin_unlock_irqrestore(&dev->lock, flags); printk(KERN_DEBUG LOGNAME ": Enable IRQ failed\n"); return -EIO; }
int msnd_disable_irq(multisound_dev_t *dev) { unsigned long flags; if (--dev->irq_ref > 0) return 0; if (dev->irq_ref < 0) printk(KERN_DEBUG LOGNAME ": IRQ ref count is %d\n", dev->irq_ref); printk(KERN_DEBUG LOGNAME ": Disabling IRQ\n"); spin_lock_irqsave(&dev->lock, flags); if (msnd_wait_TXDE(dev) == 0) { msnd_outb(msnd_inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR); if (dev->type == msndClassic) msnd_outb(HPIRQ_NONE, dev->io + HP_IRQM); disable_irq(dev->irq); spin_unlock_irqrestore(&dev->lock, flags); return 0; } spin_unlock_irqrestore(&dev->lock, flags); printk(KERN_DEBUG LOGNAME ": Disable IRQ failed\n"); return -EIO; }
int msnd_disable_irq(multisound_dev_t *dev) { unsigned long flags; if (--dev->irq_ref > 0) return 0; if (dev->irq_ref < 0) ; ; spin_lock_irqsave(&dev->lock, flags); if (msnd_wait_TXDE(dev) == 0) { msnd_outb(msnd_inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR); if (dev->type == msndClassic) msnd_outb(HPIRQ_NONE, dev->io + HP_IRQM); disable_irq(dev->irq); spin_unlock_irqrestore(&dev->lock, flags); return 0; } spin_unlock_irqrestore(&dev->lock, flags); ; return -EIO; }
int msnd_upload_host(multisound_dev_t *dev, char *bin, int len) { int i; if (len % 3 != 0) { printk(KERN_WARNING LOGNAME ": Upload host data not multiple of 3!\n"); return -EINVAL; } for (i = 0; i < len; i += 3) if (msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2]) != 0) return -EIO; msnd_inb(dev->io + HP_RXL); msnd_inb(dev->io + HP_CVR); return 0; }
int msnd_upload_host(multisound_dev_t *dev, char *bin, int len) { int i; if (len % 3 != 0) { ; return -EINVAL; } for (i = 0; i < len; i += 3) if (msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2]) != 0) return -EIO; msnd_inb(dev->io + HP_RXL); msnd_inb(dev->io + HP_CVR); return 0; }
static int msnd_wait_HC0(multisound_dev_t *dev) { register unsigned int io = dev->io; register int timeout = 1000; while(timeout-- > 0) if (!(msnd_inb(io + HP_CVR) & HPCVR_HC)) return 0; return -EIO; }
static int msnd_wait_TXDE(multisound_dev_t *dev) { register unsigned int io = dev->io; register int timeout = 1000; while(timeout-- > 0) if (msnd_inb(io + HP_ISR) & HPISR_TXDE) return 0; return -EIO; }