diff options
-rw-r--r-- | include/sound/emu10k1.h | 3 | ||||
-rw-r--r-- | sound/pci/emu10k1/irq.c | 32 | ||||
-rw-r--r-- | sound/pci/emu10k1/p16v.c | 111 |
3 files changed, 50 insertions, 96 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index a1ea022bcdc8..ba2d48b38710 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1735,8 +1735,6 @@ struct snd_emu10k1 { spinlock_t i2c_lock; /* serialises access to i2c port */ struct snd_emu10k1_voice voices[NUM_G]; - struct snd_emu10k1_voice p16v_voices[4]; - struct snd_emu10k1_voice p16v_capture_voice; int p16v_device_offset; u32 p16v_capture_source; u32 p16v_capture_channel; @@ -1756,6 +1754,7 @@ struct snd_emu10k1 { void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status); void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status); void (*dsp_interrupt)(struct snd_emu10k1 *emu); + void (*p16v_interrupt)(struct snd_emu10k1 *emu); struct snd_pcm_substream *pcm_capture_substream; struct snd_pcm_substream *pcm_capture_mic_substream; diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c index ebb2275efb6c..dfb44e5e69a7 100644 --- a/sound/pci/emu10k1/irq.c +++ b/sound/pci/emu10k1/irq.c @@ -18,7 +18,7 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) { struct snd_emu10k1 *emu = dev_id; - unsigned int status, status2, orig_status, orig_status2; + unsigned int status, orig_status; int handled = 0; int timeout = 0; @@ -139,32 +139,10 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) 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); - - /* dev_dbg(emu->card->dev, "status2=0x%x\n", status2); */ - orig_status2 = status2; - if(status2 & mask) { - if(pvoice->use) { - snd_pcm_period_elapsed(pvoice->epcm->substream); - } else { - dev_err(emu->card->dev, - "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", - status2, mask, pvoice, - pvoice->use); - } - } - if(status2 & 0x110000) { - /* dev_info(emu->card->dev, "capture int found\n"); */ - if(cvoice->use) { - /* dev_info(emu->card->dev, "capture period_elapsed\n"); */ - snd_pcm_period_elapsed(cvoice->epcm->substream); - } - } - outl(orig_status2, emu->port + IPR2); /* ack all */ - } + if (emu->p16v_interrupt) + emu->p16v_interrupt(emu); + else + outl(0, emu->port + INTE2); status &= ~IPR_P16V; } diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index f5e0972187a7..ce4d3450959c 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -149,41 +149,19 @@ static const struct snd_pcm_hardware snd_p16v_capture_hw = { .fifo_size = 0, }; -static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime) -{ - struct snd_emu10k1_pcm *epcm = runtime->private_data; - - kfree(epcm); -} - /* open_playback callback */ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id) { - struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); - struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]); - struct snd_emu10k1_pcm *epcm; struct snd_pcm_runtime *runtime = substream->runtime; int err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); - /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */ - - if (epcm == NULL) - return -ENOMEM; - epcm->emu = emu; - epcm->substream = substream; /* dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id); */ - runtime->private_data = epcm; - runtime->private_free = snd_p16v_pcm_free_substream; runtime->hw = snd_p16v_playback_hw; - channel->number = channel_id; - - channel->use=1; #if 0 /* debug */ dev_dbg(emu->card->dev, "p16v: open channel_id=%d, channel=%p, use=0x%x\n", @@ -192,7 +170,6 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea channel_id, chip, channel); #endif /* debug */ /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */ - channel->epcm = epcm; err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) return err; @@ -204,43 +181,20 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea return 0; } + /* open_capture callback */ static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id) { - struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); - struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice); - struct snd_emu10k1_pcm *epcm; struct snd_pcm_runtime *runtime = substream->runtime; int err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); - /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */ - - if (epcm == NULL) - return -ENOMEM; - epcm->emu = emu; - epcm->substream = substream; /* dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id); */ - runtime->private_data = epcm; - runtime->private_free = snd_p16v_pcm_free_substream; runtime->hw = snd_p16v_capture_hw; - channel->number = channel_id; - - channel->use=1; -#if 0 /* debug */ - dev_dbg(emu->card->dev, - "p16v: open channel_id=%d, channel=%p, use=0x%x\n", - channel_id, channel, channel->use); - dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n", - channel_id, chip, channel); -#endif /* debug */ - /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */ - channel->epcm = epcm; err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) return err; @@ -252,22 +206,12 @@ static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream /* close callback */ static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream) { - struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); - //struct snd_pcm_runtime *runtime = substream->runtime; - //struct snd_emu10k1_pcm *epcm = runtime->private_data; - emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0; - /* FIXME: maybe zero others */ return 0; } /* close callback */ static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream) { - struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); - //struct snd_pcm_runtime *runtime = substream->runtime; - //struct snd_emu10k1_pcm *epcm = runtime->private_data; - emu->p16v_capture_voice.use = 0; - /* FIXME: maybe zero others */ return 0; } @@ -409,13 +353,48 @@ static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb) spin_unlock_irqrestore(&emu->emu_lock, flags); } +static void snd_p16v_interrupt(struct snd_emu10k1 *emu) +{ + unsigned int status; + + while ((status = inl(emu->port + IPR2)) != 0) { + u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ + + /* dev_dbg(emu->card->dev, "p16v status=0x%x\n", status); */ + if (status & mask) { + struct snd_pcm_substream *substream = + emu->pcm_p16v->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct snd_pcm_runtime *runtime = substream->runtime; + + if (runtime && runtime->private_data) { + snd_pcm_period_elapsed(substream); + } else { + dev_err(emu->card->dev, + "p16v: status: 0x%08x, mask=0x%08x\n", + status, mask); + } + } + if (status & 0x110000) { + struct snd_pcm_substream *substream = + emu->pcm_p16v->streams[SNDRV_PCM_STREAM_CAPTURE].substream; + struct snd_pcm_runtime *runtime = substream->runtime; + + /* dev_info(emu->card->dev, "capture int found\n"); */ + if (runtime && runtime->private_data) { + /* dev_info(emu->card->dev, "capture period_elapsed\n"); */ + snd_pcm_period_elapsed(substream); + } + } + outl(status, emu->port + IPR2); /* ack all */ + } +} + /* trigger_playback callback */ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, int cmd) { struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime; - struct snd_emu10k1_pcm *epcm; int channel; int result = 0; struct snd_pcm_substream *s; @@ -437,10 +416,9 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, s->stream != SNDRV_PCM_STREAM_PLAYBACK) continue; runtime = s->runtime; - epcm = runtime->private_data; channel = substream->pcm->device-emu->p16v_device_offset; /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */ - epcm->running = running; + runtime->private_data = (void *)(ptrdiff_t)running; basic |= (0x1<<channel); inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel); snd_pcm_trigger_done(s, substream); @@ -469,7 +447,6 @@ static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream, { struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_emu10k1_pcm *epcm = runtime->private_data; int channel = 0; int result = 0; u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP; @@ -478,13 +455,13 @@ static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: snd_p16v_intr_enable(emu, inte); snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel)); - epcm->running = 1; + runtime->private_data = (void *)1; break; case SNDRV_PCM_TRIGGER_STOP: snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel)); snd_p16v_intr_disable(emu, inte); //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel)); - epcm->running = 0; + runtime->private_data = NULL; break; default: result = -EINVAL; @@ -499,10 +476,10 @@ snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream) { struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_emu10k1_pcm *epcm = runtime->private_data; snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; int channel = substream->pcm->device - emu->p16v_device_offset; - if (!epcm->running) + + if (!runtime->private_data) return 0; ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel); @@ -524,11 +501,10 @@ snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream) { struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_emu10k1_pcm *epcm = runtime->private_data; snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; int channel = 0; - if (!epcm->running) + if (!runtime->private_data) return 0; ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel); @@ -589,6 +565,7 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device) pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; strcpy(pcm->name, "p16v"); emu->pcm_p16v = pcm; + emu->p16v_interrupt = snd_p16v_interrupt; for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; |