void snd_opl3_interrupt(snd_hwdep_t * hw) { unsigned char status; opl3_t *opl3; snd_timer_t *timer; if (hw == NULL) return; opl3 = snd_magic_cast(opl3_t, hw->private_data, return); status = inb(opl3->l_port); #if 0 snd_printk("AdLib IRQ status = 0x%x\n", status); #endif if (!(status & 0x80)) return; if (status & 0x40) { timer = opl3->timer1; snd_timer_interrupt(timer, timer->sticks); } if (status & 0x20) { timer = opl3->timer2; snd_timer_interrupt(timer, timer->sticks); } }
void snd_opl3_interrupt(struct snd_hwdep * hw) { unsigned char status; struct snd_opl3 *opl3; struct snd_timer *timer; if (hw == NULL) return; opl3 = hw->private_data; status = inb(opl3->l_port); #if 0 snd_mprintk("AdLib IRQ status = 0x%x\n", status); // MJR #endif if (!(status & 0x80)) return; if (status & 0x40) { timer = opl3->timer1; snd_timer_interrupt(timer, timer->sticks); } if (status & 0x20) { timer = opl3->timer2; snd_timer_interrupt(timer, timer->sticks); } }
static void snd_gf1_interrupt_timer2(snd_gus_card_t * gus) { snd_timer_t *timer = gus->gf1.timer2; if (timer == NULL) return; snd_timer_interrupt(timer, timer->sticks); }
static void snd_gf1_interrupt_timer1(struct snd_gus_card * gus) { struct snd_timer *timer = gus->gf1.timer1; if (timer == NULL) return; snd_timer_interrupt(timer, timer->sticks); }
static void lsm_event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; struct snd_pcm_substream *substream = prtd->substream; uint16_t status = 0; uint16_t payload_size = 0; uint16_t index = 0; pr_debug("%s: Opcode 0x%x\n", __func__, opcode); switch (opcode) { case LSM_SESSION_EVENT_DETECTION_STATUS: status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[2]; index = 4; pr_debug("%s: event detect status = %d payload size = %d\n", __func__, status , payload_size); break; case LSM_SESSION_EVENT_DETECTION_STATUS_V2: status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; pr_debug("%s: event detect status = %d payload size = %d\n", __func__, status , payload_size); break; default: pr_debug("%s: Unsupported Event opcode 0x%x\n", __func__, opcode); break; } if (opcode == LSM_SESSION_EVENT_DETECTION_STATUS || opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2) { spin_lock_irqsave(&prtd->event_lock, flags); prtd->event_status = krealloc(prtd->event_status, sizeof(struct snd_lsm_event_status) + payload_size, GFP_ATOMIC); prtd->event_status->status = status; prtd->event_status->payload_size = payload_size; if (likely(prtd->event_status)) { memcpy(prtd->event_status->payload, &((uint8_t *)payload)[index], payload_size); prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); wake_up(&prtd->event_wait); } else { spin_unlock_irqrestore(&prtd->event_lock, flags); pr_err("%s: Couldn't allocate %d bytes of memory\n", __func__, payload_size); } if (substream->timer_running) snd_timer_interrupt(substream->timer, 1); } }
static void lsm_event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) { unsigned long flags; struct snd_lsm_event_status *event_status; struct lsm_priv *prtd = priv; struct snd_pcm_substream *substream = prtd->substream; pr_debug("%s: enter opcode 0x%x\n", __func__, opcode); switch (opcode) { case LSM_SESSION_EVENT_DETECTION_STATUS: event_status = payload; spin_lock_irqsave(&prtd->event_lock, flags); prtd->event_status = krealloc(prtd->event_status, sizeof(*event_status) + event_status->payload_size, GFP_ATOMIC); if (likely(prtd->event_status)) { memcpy(prtd->event_status, event_status, sizeof(*event_status) + event_status->payload_size); prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); wake_up(&prtd->event_wait); } else { spin_unlock_irqrestore(&prtd->event_lock, flags); pr_err("%s: Couldn't allocate %d bytes of memory\n", __func__, event_status->payload_size); } if (substream->timer_running) snd_timer_interrupt(substream->timer, 1); break; default: pr_debug("%s: Unsupported Event opcode 0x%x\n", __func__, opcode); break; } }
static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id) { struct snd_ad1816a *chip = dev_id; unsigned char status; spin_lock(&chip->lock); status = snd_ad1816a_in(chip, AD1816A_INTERRUPT_STATUS); spin_unlock(&chip->lock); if ((status & AD1816A_PLAYBACK_IRQ_PENDING) && chip->playback_substream) snd_pcm_period_elapsed(chip->playback_substream); if ((status & AD1816A_CAPTURE_IRQ_PENDING) && chip->capture_substream) snd_pcm_period_elapsed(chip->capture_substream); if ((status & AD1816A_TIMER_IRQ_PENDING) && chip->timer) snd_timer_interrupt(chip->timer, chip->timer->sticks); spin_lock(&chip->lock); snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00); spin_unlock(&chip->lock); return IRQ_HANDLED; }
static void rtctimer_tasklet(unsigned long data) { snd_timer_interrupt((struct snd_timer *)data, 1); }
irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) { struct snd_emu10k1 *emu = dev_id; unsigned int status, status2, orig_status, orig_status2; int handled = 0; int timeout = 0; while (((status = inl(emu->port + IPR)) != 0) && (timeout < 1000)) { timeout++; orig_status = status; handled = 1; if ((status & 0xffffffff) == 0xffffffff) { ; break; } if (status & IPR_PCIERROR) { ; snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE); status &= ~IPR_PCIERROR; } if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) { if (emu->hwvol_interrupt) emu->hwvol_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE); status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE); } if (status & IPR_CHANNELLOOP) { int voice; int voice_max = status & IPR_CHANNELNUMBERMASK; u32 val; struct snd_emu10k1_voice *pvoice = emu->voices; val = snd_emu10k1_ptr_read(emu, CLIPL, 0); for (voice = 0; voice <= voice_max; voice++) { if (voice == 0x20) val = snd_emu10k1_ptr_read(emu, CLIPH, 0); if (val & 1) { if (pvoice->use && pvoice->interrupt != NULL) { pvoice->interrupt(emu, pvoice); snd_emu10k1_voice_intr_ack(emu, voice); } else { snd_emu10k1_voice_intr_disable(emu, voice); } } val >>= 1; pvoice++; } val = snd_emu10k1_ptr_read(emu, HLIPL, 0); for (voice = 0; voice <= voice_max; voice++) { if (voice == 0x20) val = snd_emu10k1_ptr_read(emu, HLIPH, 0); if (val & 1) { if (pvoice->use && pvoice->interrupt != NULL) { pvoice->interrupt(emu, pvoice); snd_emu10k1_voice_half_loop_intr_ack(emu, voice); } else { snd_emu10k1_voice_half_loop_intr_disable(emu, voice); } } val >>= 1; pvoice++; } status &= ~IPR_CHANNELLOOP; } status &= ~IPR_CHANNELNUMBERMASK; if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) { if (emu->capture_interrupt) emu->capture_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE); status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL); } if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) { if (emu->capture_mic_interrupt) emu->capture_mic_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE); status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL); } if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) { if (emu->capture_efx_interrupt) emu->capture_efx_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE); status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL); } if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) { if (emu->midi.interrupt) emu->midi.interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE); status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY); } if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) { if (emu->midi2.interrupt) emu->midi2.interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2); status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2); } if (status & IPR_INTERVALTIMER) { if (emu->timer) snd_timer_interrupt(emu->timer, emu->timer->sticks); else snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB); status &= ~IPR_INTERVALTIMER; } if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) { if (emu->spdif_interrupt) emu->spdif_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE); status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE); } if (status & IPR_FXDSP) { if (emu->dsp_interrupt) emu->dsp_interrupt(emu); else snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE); status &= ~IPR_FXDSP; } if (status & IPR_P16V) { while ((status2 = inl(emu->port + IPR2)) != 0) { u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]); struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice); ; orig_status2 = status2; if(status2 & mask) { if(pvoice->use) { snd_pcm_period_elapsed(pvoice->epcm->substream); } else { ; } } if(status2 & 0x110000) { ; if(cvoice->use) { ; snd_pcm_period_elapsed(cvoice->epcm->substream); } } outl(orig_status2, emu->port + IPR2); /* ack all */ } status &= ~IPR_P16V; } if (status) { unsigned int bits; ; //make sure any interrupts we don't handle are disabled: bits = INTE_FXDSPENABLE | INTE_PCIERRORENABLE | INTE_VOLINCRENABLE | INTE_VOLDECRENABLE | INTE_MUTEENABLE | INTE_MICBUFENABLE | INTE_ADCBUFENABLE | INTE_EFXBUFENABLE | INTE_GPSPDIFENABLE | INTE_CDSPDIFENABLE | INTE_INTERVALTIMERENB | INTE_MIDITXENABLE | INTE_MIDIRXENABLE; if (emu->audigy) bits |= INTE_A_MIDITXENABLE2 | INTE_A_MIDIRXENABLE2; snd_emu10k1_intr_disable(emu, bits); } outl(orig_status, emu->port + IPR); /* ack all */ }
irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { emu10k1_t *emu = dev_id; unsigned int status, status2, orig_status, orig_status2; int handled = 0; while ((status = inl(emu->port + IPR)) != 0) { // printk("irq - status = 0x%x\n", status); orig_status = status; handled = 1; if (status & IPR_PCIERROR) { snd_printk("interrupt: PCI error\n"); snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE); status &= ~IPR_PCIERROR; } if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) { if (emu->hwvol_interrupt) emu->hwvol_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE); status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE); } if (status & IPR_CHANNELLOOP) { int voice; int voice_max = status & IPR_CHANNELNUMBERMASK; u32 val; emu10k1_voice_t *pvoice = emu->voices; val = snd_emu10k1_ptr_read(emu, CLIPL, 0); for (voice = 0; voice <= voice_max; voice++) { if (voice == 0x20) val = snd_emu10k1_ptr_read(emu, CLIPH, 0); if (val & 1) { if (pvoice->use && pvoice->interrupt != NULL) { pvoice->interrupt(emu, pvoice); snd_emu10k1_voice_intr_ack(emu, voice); } else { snd_emu10k1_voice_intr_disable(emu, voice); } } val >>= 1; pvoice++; } val = snd_emu10k1_ptr_read(emu, HLIPL, 0); for (voice = 0; voice <= voice_max; voice++) { if (voice == 0x20) val = snd_emu10k1_ptr_read(emu, HLIPH, 0); if (val & 1) { if (pvoice->use && pvoice->interrupt != NULL) { pvoice->interrupt(emu, pvoice); snd_emu10k1_voice_half_loop_intr_ack(emu, voice); } else { snd_emu10k1_voice_half_loop_intr_disable(emu, voice); } } val >>= 1; pvoice++; } status &= ~IPR_CHANNELLOOP; } status &= ~IPR_CHANNELNUMBERMASK; if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) { if (emu->capture_interrupt) emu->capture_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE); status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL); } if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) { if (emu->capture_mic_interrupt) emu->capture_mic_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE); status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL); } if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) { if (emu->capture_efx_interrupt) emu->capture_efx_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE); status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL); } if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) { if (emu->midi.interrupt) emu->midi.interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE); status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY); } if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) { if (emu->midi2.interrupt) emu->midi2.interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2); status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2); } if (status & IPR_INTERVALTIMER) { if (emu->timer) snd_timer_interrupt(emu->timer, emu->timer->sticks); else snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB); status &= ~IPR_INTERVALTIMER; } if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) { if (emu->spdif_interrupt) emu->spdif_interrupt(emu, status); else snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE); status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE); } if (status & IPR_FXDSP) { if (emu->dsp_interrupt) emu->dsp_interrupt(emu); else snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE); status &= ~IPR_FXDSP; } if (status) { unsigned int bits; //snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status); //make sure any interrupts we don't handle are disabled: bits = INTE_FXDSPENABLE | INTE_PCIERRORENABLE | INTE_VOLINCRENABLE | INTE_VOLDECRENABLE | INTE_MUTEENABLE | INTE_MICBUFENABLE | INTE_ADCBUFENABLE | INTE_EFXBUFENABLE | INTE_GPSPDIFENABLE | INTE_CDSPDIFENABLE | INTE_INTERVALTIMERENB | INTE_MIDITXENABLE | INTE_MIDIRXENABLE; if (emu->audigy) bits |= INTE_A_MIDITXENABLE2 | INTE_A_MIDIRXENABLE2; snd_emu10k1_intr_disable(emu, bits); } outl(orig_status, emu->port + IPR); /* ack all */ }
static void lsm_event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; struct snd_pcm_substream *substream = prtd->substream; uint16_t status = 0; uint16_t payload_size = 0; uint16_t index = 0; pr_debug("%s: Opcode 0x%x\n", __func__, opcode); switch (opcode) { case LSM_DATA_EVENT_READ_DONE: { int rc; struct lsm_cmd_read_done *read_done = payload; int buf_index = 0; if (prtd->lsm_client->session != token || !read_done) { pr_err("%s: EVENT_READ_DONE invalid callback client session %d callback sesson %d payload %p", __func__, prtd->lsm_client->session, token, read_done); return; } if (atomic_read(&prtd->read_abort)) { pr_info("%s: read abort set skip data\n", __func__); return; } if (!lsm_lab_buffer_sanity(prtd, read_done, &buf_index)) { pr_debug("%s: process read done index %d\n", __func__, buf_index); if (buf_index >= prtd->lsm_client->hw_params.period_count) { pr_err("%s: Invalid index %d buf_index max cnt %d\n" , __func__, buf_index, prtd->lsm_client->hw_params.period_count); return; } prtd->dma_write += read_done->total_size; atomic_inc(&prtd->buf_count); snd_pcm_period_elapsed(substream); wake_up(&prtd->period_wait); /* queue the next period buffer */ buf_index = (buf_index + 1) % prtd->lsm_client->hw_params.period_count; rc = msm_lsm_queue_lab_buffer(prtd, buf_index); if (rc) pr_err("%s: error in queuing the lab buffer rc %d\n", __func__, rc); } else pr_err("%s: Invalid lab buffer returned by dsp\n", __func__); break; } case LSM_SESSION_EVENT_DETECTION_STATUS: status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[2]; index = 4; pr_debug("%s: event detect status = %d payload size = %d\n", __func__, status , payload_size); break; case LSM_SESSION_EVENT_DETECTION_STATUS_V2: status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; pr_debug("%s: event detect status = %d payload size = %d\n", __func__, status , payload_size); break; default: pr_debug("%s: Unsupported Event opcode 0x%x\n", __func__, opcode); break; } if (opcode == LSM_SESSION_EVENT_DETECTION_STATUS || opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2) { spin_lock_irqsave(&prtd->event_lock, flags); prtd->event_status = krealloc(prtd->event_status, sizeof(struct snd_lsm_event_status) + payload_size, GFP_ATOMIC); prtd->event_status->status = status; prtd->event_status->payload_size = payload_size; if (likely(prtd->event_status)) { memcpy(prtd->event_status->payload, &((uint8_t *)payload)[index], payload_size); prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); wake_up(&prtd->event_wait); } else { spin_unlock_irqrestore(&prtd->event_lock, flags); pr_err("%s: Couldn't allocate %d bytes of memory\n", __func__, payload_size); } if (substream->timer_running) snd_timer_interrupt(substream->timer, 1); } }
/* * interrupt */ static void rtctimer_interrupt(void *private_data) { snd_timer_interrupt(private_data, 1); }