diff options
Diffstat (limited to 'sound/drivers')
-rw-r--r-- | sound/drivers/dummy.c | 126 |
1 files changed, 47 insertions, 79 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 64ef7f62851d..8dfe5d49eafc 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -172,47 +172,33 @@ typedef struct snd_card_dummy_pcm { static snd_card_t *snd_dummy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; -static void snd_card_dummy_pcm_timer_start(snd_pcm_substream_t * substream) +static inline void snd_card_dummy_pcm_timer_start(snd_card_dummy_pcm_t *dpcm) { - snd_pcm_runtime_t *runtime = substream->runtime; - snd_card_dummy_pcm_t *dpcm = runtime->private_data; - dpcm->timer.expires = 1 + jiffies; add_timer(&dpcm->timer); } -static void snd_card_dummy_pcm_timer_stop(snd_pcm_substream_t * substream) +static inline void snd_card_dummy_pcm_timer_stop(snd_card_dummy_pcm_t *dpcm) { - snd_pcm_runtime_t *runtime = substream->runtime; - snd_card_dummy_pcm_t *dpcm = runtime->private_data; - del_timer(&dpcm->timer); } -static int snd_card_dummy_playback_trigger(snd_pcm_substream_t * substream, - int cmd) +static int snd_card_dummy_pcm_trigger(snd_pcm_substream_t *substream, int cmd) { - if (cmd == SNDRV_PCM_TRIGGER_START) { - snd_card_dummy_pcm_timer_start(substream); - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - snd_card_dummy_pcm_timer_stop(substream); - } else { - return -EINVAL; - } - return 0; -} + snd_pcm_runtime_t *runtime = substream->runtime; + snd_dummy_card_pcm_t *dpcm = runtime->private_data; + int err = 0; -static int snd_card_dummy_capture_trigger(snd_pcm_substream_t * substream, - int cmd) -{ + spin_lock(&dpcm->lock); if (cmd == SNDRV_PCM_TRIGGER_START) { - snd_card_dummy_pcm_timer_start(substream); + snd_card_dummy_pcm_timer_start(dpcm); } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - snd_card_dummy_pcm_timer_stop(substream); + snd_card_dummy_pcm_timer_stop(dpcm); } else { - return -EINVAL; + err = -EINVAL; } - return 0; + spin_unlock(&dpcm->lock); + return err; } static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream) @@ -235,42 +221,26 @@ static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream) return 0; } -static int snd_card_dummy_playback_prepare(snd_pcm_substream_t * substream) -{ - return snd_card_dummy_pcm_prepare(substream); -} - -static int snd_card_dummy_capture_prepare(snd_pcm_substream_t * substream) -{ - return snd_card_dummy_pcm_prepare(substream); -} - static void snd_card_dummy_pcm_timer_function(unsigned long data) { snd_card_dummy_pcm_t *dpcm = (snd_card_dummy_pcm_t *)data; + spin_lock(&dpcm->lock); dpcm->timer.expires = 1 + jiffies; add_timer(&dpcm->timer); - spin_lock_irq(&dpcm->lock); dpcm->pcm_irq_pos += dpcm->pcm_jiffie; dpcm->pcm_buf_pos += dpcm->pcm_jiffie; dpcm->pcm_buf_pos %= dpcm->pcm_size; if (dpcm->pcm_irq_pos >= dpcm->pcm_count) { dpcm->pcm_irq_pos %= dpcm->pcm_count; + spin_unlock(&dpcm->lock); snd_pcm_period_elapsed(dpcm->substream); + spin_lock(&dpcm->lock); } - spin_unlock_irq(&dpcm->lock); + spin_unlock(&dpcm->lock); } -static snd_pcm_uframes_t snd_card_dummy_playback_pointer(snd_pcm_substream_t * substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - snd_card_dummy_pcm_t *dpcm = runtime->private_data; - - return bytes_to_frames(runtime, dpcm->pcm_buf_pos); -} - -static snd_pcm_uframes_t snd_card_dummy_capture_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(snd_pcm_substream_t * substream) { snd_pcm_runtime_t *runtime = substream->runtime; snd_card_dummy_pcm_t *dpcm = runtime->private_data; @@ -316,8 +286,7 @@ static snd_pcm_hardware_t snd_card_dummy_capture = static void snd_card_dummy_runtime_free(snd_pcm_runtime_t *runtime) { - snd_card_dummy_pcm_t *dpcm = runtime->private_data; - kfree(dpcm); + kfree(runtime->private_data); } static int snd_card_dummy_hw_params(snd_pcm_substream_t * substream, @@ -331,20 +300,29 @@ static int snd_card_dummy_hw_free(snd_pcm_substream_t * substream) return snd_pcm_lib_free_pages(substream); } -static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream) +static snd_card_dummy_pcm_t *new_pcm_stream(snd_pcm_substream_t *substream) { - snd_pcm_runtime_t *runtime = substream->runtime; snd_card_dummy_pcm_t *dpcm; - int err; dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); - if (dpcm == NULL) - return -ENOMEM; + if (! dpcm) + return dpcm; init_timer(&dpcm->timer); dpcm->timer.data = (unsigned long) dpcm; dpcm->timer.function = snd_card_dummy_pcm_timer_function; spin_lock_init(&dpcm->lock); dpcm->substream = substream; + return dpcm; +} + +static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + snd_card_dummy_pcm_t *dpcm; + int err; + + if ((dpcm = new_pcm_stream(substream)) == NULL) + return -ENOMEM; runtime->private_data = dpcm; runtime->private_free = snd_card_dummy_runtime_free; runtime->hw = snd_card_dummy_playback; @@ -368,14 +346,8 @@ static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream) snd_card_dummy_pcm_t *dpcm; int err; - dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); - if (dpcm == NULL) + if ((dpcm = new_pcm_stream(substream)) == NULL) return -ENOMEM; - init_timer(&dpcm->timer); - dpcm->timer.data = (unsigned long) dpcm; - dpcm->timer.function = snd_card_dummy_pcm_timer_function; - spin_lock_init(&dpcm->lock); - dpcm->substream = substream; runtime->private_data = dpcm; runtime->private_free = snd_card_dummy_runtime_free; runtime->hw = snd_card_dummy_capture; @@ -409,9 +381,9 @@ static snd_pcm_ops_t snd_card_dummy_playback_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_card_dummy_hw_params, .hw_free = snd_card_dummy_hw_free, - .prepare = snd_card_dummy_playback_prepare, - .trigger = snd_card_dummy_playback_trigger, - .pointer = snd_card_dummy_playback_pointer, + .prepare = snd_card_dummy_pcm_prepare, + .trigger = snd_card_dummy_pcm_trigger, + .pointer = snd_card_dummy_pcm_pointer, }; static snd_pcm_ops_t snd_card_dummy_capture_ops = { @@ -420,9 +392,9 @@ static snd_pcm_ops_t snd_card_dummy_capture_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_card_dummy_hw_params, .hw_free = snd_card_dummy_hw_free, - .prepare = snd_card_dummy_capture_prepare, - .trigger = snd_card_dummy_capture_trigger, - .pointer = snd_card_dummy_capture_pointer, + .prepare = snd_card_dummy_pcm_prepare, + .trigger = snd_card_dummy_pcm_trigger, + .pointer = snd_card_dummy_pcm_pointer, }; static int __init snd_card_dummy_pcm(snd_card_dummy_t *dummy, int device, int substreams) @@ -461,20 +433,18 @@ static int snd_dummy_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t static int snd_dummy_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); - unsigned long flags; int addr = kcontrol->private_value; - spin_lock_irqsave(&dummy->mixer_lock, flags); + spin_lock_irq(&dummy->mixer_lock); ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0]; ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1]; - spin_unlock_irqrestore(&dummy->mixer_lock, flags); + spin_unlock_irq(&dummy->mixer_lock); return 0; } static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); - unsigned long flags; int change, addr = kcontrol->private_value; int left, right; @@ -488,12 +458,12 @@ static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t right = -50; if (right > 100) right = 100; - spin_lock_irqsave(&dummy->mixer_lock, flags); + spin_lock_irq(&dummy->mixer_lock); change = dummy->mixer_volume[addr][0] != left || dummy->mixer_volume[addr][1] != right; dummy->mixer_volume[addr][0] = left; dummy->mixer_volume[addr][1] = right; - spin_unlock_irqrestore(&dummy->mixer_lock, flags); + spin_unlock_irq(&dummy->mixer_lock); return change; } @@ -515,31 +485,29 @@ static int snd_dummy_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t static int snd_dummy_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); - unsigned long flags; int addr = kcontrol->private_value; - spin_lock_irqsave(&dummy->mixer_lock, flags); + spin_lock_irq(&dummy->mixer_lock); ucontrol->value.integer.value[0] = dummy->capture_source[addr][0]; ucontrol->value.integer.value[1] = dummy->capture_source[addr][1]; - spin_unlock_irqrestore(&dummy->mixer_lock, flags); + spin_unlock_irq(&dummy->mixer_lock); return 0; } static int snd_dummy_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); - unsigned long flags; int change, addr = kcontrol->private_value; int left, right; left = ucontrol->value.integer.value[0] & 1; right = ucontrol->value.integer.value[1] & 1; - spin_lock_irqsave(&dummy->mixer_lock, flags); + spin_lock_irq(&dummy->mixer_lock); change = dummy->capture_source[addr][0] != left && dummy->capture_source[addr][1] != right; dummy->capture_source[addr][0] = left; dummy->capture_source[addr][1] = right; - spin_unlock_irqrestore(&dummy->mixer_lock, flags); + spin_unlock_irq(&dummy->mixer_lock); return change; } |