0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/time.h>
0015 #include <sound/core.h>
0016 #include <sound/emu10k1.h>
0017
0018 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id)
0019 {
0020 struct snd_emu10k1 *emu = dev_id;
0021 unsigned int status, status2, orig_status, orig_status2;
0022 int handled = 0;
0023 int timeout = 0;
0024
0025 while (((status = inl(emu->port + IPR)) != 0) && (timeout < 1000)) {
0026 timeout++;
0027 orig_status = status;
0028 handled = 1;
0029 if ((status & 0xffffffff) == 0xffffffff) {
0030 dev_info(emu->card->dev,
0031 "Suspected sound card removal\n");
0032 break;
0033 }
0034 if (status & IPR_PCIERROR) {
0035 dev_err(emu->card->dev, "interrupt: PCI error\n");
0036 snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
0037 status &= ~IPR_PCIERROR;
0038 }
0039 if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) {
0040 if (emu->hwvol_interrupt)
0041 emu->hwvol_interrupt(emu, status);
0042 else
0043 snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE);
0044 status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE);
0045 }
0046 if (status & IPR_CHANNELLOOP) {
0047 int voice;
0048 int voice_max = status & IPR_CHANNELNUMBERMASK;
0049 u32 val;
0050 struct snd_emu10k1_voice *pvoice = emu->voices;
0051
0052 val = snd_emu10k1_ptr_read(emu, CLIPL, 0);
0053 for (voice = 0; voice <= voice_max; voice++) {
0054 if (voice == 0x20)
0055 val = snd_emu10k1_ptr_read(emu, CLIPH, 0);
0056 if (val & 1) {
0057 if (pvoice->use && pvoice->interrupt != NULL) {
0058 pvoice->interrupt(emu, pvoice);
0059 snd_emu10k1_voice_intr_ack(emu, voice);
0060 } else {
0061 snd_emu10k1_voice_intr_disable(emu, voice);
0062 }
0063 }
0064 val >>= 1;
0065 pvoice++;
0066 }
0067 val = snd_emu10k1_ptr_read(emu, HLIPL, 0);
0068 for (voice = 0; voice <= voice_max; voice++) {
0069 if (voice == 0x20)
0070 val = snd_emu10k1_ptr_read(emu, HLIPH, 0);
0071 if (val & 1) {
0072 if (pvoice->use && pvoice->interrupt != NULL) {
0073 pvoice->interrupt(emu, pvoice);
0074 snd_emu10k1_voice_half_loop_intr_ack(emu, voice);
0075 } else {
0076 snd_emu10k1_voice_half_loop_intr_disable(emu, voice);
0077 }
0078 }
0079 val >>= 1;
0080 pvoice++;
0081 }
0082 status &= ~IPR_CHANNELLOOP;
0083 }
0084 status &= ~IPR_CHANNELNUMBERMASK;
0085 if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) {
0086 if (emu->capture_interrupt)
0087 emu->capture_interrupt(emu, status);
0088 else
0089 snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE);
0090 status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL);
0091 }
0092 if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) {
0093 if (emu->capture_mic_interrupt)
0094 emu->capture_mic_interrupt(emu, status);
0095 else
0096 snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE);
0097 status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL);
0098 }
0099 if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) {
0100 if (emu->capture_efx_interrupt)
0101 emu->capture_efx_interrupt(emu, status);
0102 else
0103 snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE);
0104 status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL);
0105 }
0106 if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
0107 if (emu->midi.interrupt)
0108 emu->midi.interrupt(emu, status);
0109 else
0110 snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
0111 status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY);
0112 }
0113 if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) {
0114 if (emu->midi2.interrupt)
0115 emu->midi2.interrupt(emu, status);
0116 else
0117 snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2);
0118 status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
0119 }
0120 if (status & IPR_INTERVALTIMER) {
0121 if (emu->timer)
0122 snd_timer_interrupt(emu->timer, emu->timer->sticks);
0123 else
0124 snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
0125 status &= ~IPR_INTERVALTIMER;
0126 }
0127 if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) {
0128 if (emu->spdif_interrupt)
0129 emu->spdif_interrupt(emu, status);
0130 else
0131 snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE);
0132 status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE);
0133 }
0134 if (status & IPR_FXDSP) {
0135 if (emu->dsp_interrupt)
0136 emu->dsp_interrupt(emu);
0137 else
0138 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
0139 status &= ~IPR_FXDSP;
0140 }
0141 if (status & IPR_P16V) {
0142 while ((status2 = inl(emu->port + IPR2)) != 0) {
0143 u32 mask = INTE2_PLAYBACK_CH_0_LOOP;
0144 struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]);
0145 struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice);
0146
0147
0148 orig_status2 = status2;
0149 if(status2 & mask) {
0150 if(pvoice->use) {
0151 snd_pcm_period_elapsed(pvoice->epcm->substream);
0152 } else {
0153 dev_err(emu->card->dev,
0154 "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n",
0155 status2, mask, pvoice,
0156 pvoice->use);
0157 }
0158 }
0159 if(status2 & 0x110000) {
0160
0161 if(cvoice->use) {
0162
0163 snd_pcm_period_elapsed(cvoice->epcm->substream);
0164 }
0165 }
0166 outl(orig_status2, emu->port + IPR2);
0167 }
0168 status &= ~IPR_P16V;
0169 }
0170
0171 if (status) {
0172 unsigned int bits;
0173 dev_err(emu->card->dev,
0174 "unhandled interrupt: 0x%08x\n", status);
0175
0176 bits = INTE_FXDSPENABLE |
0177 INTE_PCIERRORENABLE |
0178 INTE_VOLINCRENABLE |
0179 INTE_VOLDECRENABLE |
0180 INTE_MUTEENABLE |
0181 INTE_MICBUFENABLE |
0182 INTE_ADCBUFENABLE |
0183 INTE_EFXBUFENABLE |
0184 INTE_GPSPDIFENABLE |
0185 INTE_CDSPDIFENABLE |
0186 INTE_INTERVALTIMERENB |
0187 INTE_MIDITXENABLE |
0188 INTE_MIDIRXENABLE;
0189 if (emu->audigy)
0190 bits |= INTE_A_MIDITXENABLE2 | INTE_A_MIDIRXENABLE2;
0191 snd_emu10k1_intr_disable(emu, bits);
0192 }
0193 outl(orig_status, emu->port + IPR);
0194 }
0195 if (timeout == 1000)
0196 dev_info(emu->card->dev, "emu10k1 irq routine failure\n");
0197
0198 return IRQ_RETVAL(handled);
0199 }