diff options
Diffstat (limited to 'sound')
95 files changed, 3769 insertions, 3042 deletions
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 115313ef54d..f5ded640b39 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -991,6 +991,8 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) gpio_direction_output(pdata->reset_pin, 1); chip->reset_pin = pdata->reset_pin; } + } else { + chip->reset_pin = -EINVAL; } snd_card_set_dev(card, &pdev->dev); diff --git a/sound/core/jack.c b/sound/core/jack.c index 471e1e3b0a9..a06b1651fcb 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -155,7 +155,7 @@ EXPORT_SYMBOL(snd_jack_new); * @jack: The jack to configure * @parent: The device to set as parent for the jack. * - * Set the parent for the jack input device in the device tree. This + * Set the parent for the jack devices in the device tree. This * function is only valid prior to registration of the jack. If no * parent is configured then the parent device will be the sound card. */ @@ -179,6 +179,9 @@ EXPORT_SYMBOL(snd_jack_set_parent); * mapping is provided but keys are enabled in the jack type then * BTN_n numeric buttons will be reported. * + * If jacks are not reporting via the input API this call will have no + * effect. + * * Note that this is intended to be use by simple devices with small * numbers of keys that can be reported. It is also possible to * access the input device directly - devices with complex input diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 4d18941178e..faedb1481b2 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1894,6 +1894,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t xfer = 0; snd_pcm_uframes_t offset = 0; + snd_pcm_uframes_t avail; int err = 0; if (size == 0) @@ -1917,13 +1918,12 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, } runtime->twake = runtime->control->avail_min ? : 1; + if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) + snd_pcm_update_hw_ptr(substream); + avail = snd_pcm_playback_avail(runtime); while (size > 0) { snd_pcm_uframes_t frames, appl_ptr, appl_ofs; - snd_pcm_uframes_t avail; snd_pcm_uframes_t cont; - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) - snd_pcm_update_hw_ptr(substream); - avail = snd_pcm_playback_avail(runtime); if (!avail) { if (nonblock) { err = -EAGAIN; @@ -1971,6 +1971,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, offset += frames; size -= frames; xfer += frames; + avail -= frames; if (runtime->status->state == SNDRV_PCM_STATE_PREPARED && snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { err = snd_pcm_start(substream); @@ -2111,6 +2112,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t xfer = 0; snd_pcm_uframes_t offset = 0; + snd_pcm_uframes_t avail; int err = 0; if (size == 0) @@ -2141,13 +2143,12 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, } runtime->twake = runtime->control->avail_min ? : 1; + if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) + snd_pcm_update_hw_ptr(substream); + avail = snd_pcm_capture_avail(runtime); while (size > 0) { snd_pcm_uframes_t frames, appl_ptr, appl_ofs; - snd_pcm_uframes_t avail; snd_pcm_uframes_t cont; - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) - snd_pcm_update_hw_ptr(substream); - avail = snd_pcm_capture_avail(runtime); if (!avail) { if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { @@ -2202,6 +2203,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, offset += frames; size -= frames; xfer += frames; + avail -= frames; } _end_unlock: runtime->twake = 0; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 3fe99e644eb..53b5ada8f7c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1360,7 +1360,14 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream, static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) { - substream->runtime->trigger_master = substream; + struct snd_pcm_runtime *runtime = substream->runtime; + switch (runtime->status->state) { + case SNDRV_PCM_STATE_OPEN: + case SNDRV_PCM_STATE_DISCONNECTED: + case SNDRV_PCM_STATE_SUSPENDED: + return -EBADFD; + } + runtime->trigger_master = substream; return 0; } @@ -1379,6 +1386,9 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) case SNDRV_PCM_STATE_RUNNING: runtime->status->state = SNDRV_PCM_STATE_DRAINING; break; + case SNDRV_PCM_STATE_XRUN: + runtime->status->state = SNDRV_PCM_STATE_SETUP; + break; default: break; } diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index c7009204306..e9528333e36 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -35,7 +35,7 @@ #include <linux/sound.h> #include <linux/mutex.h> -#define SNDRV_OSS_MINORS 128 +#define SNDRV_OSS_MINORS 256 static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; static DEFINE_MUTEX(sound_oss_mutex); @@ -111,7 +111,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, int register1 = -1, register2 = -1; struct device *carddev = snd_card_get_device_link(card); - if (card && card->number >= 8) + if (card && card->number >= SNDRV_MINOR_OSS_DEVICES) return 0; /* ignore silently */ if (minor < 0) return minor; @@ -170,7 +170,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) int track2 = -1; struct snd_minor *mptr; - if (card && card->number >= 8) + if (card && card->number >= SNDRV_MINOR_OSS_DEVICES) return 0; if (minor < 0) return minor; diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index ad079b63b8b..8b5c36f4d30 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -117,6 +117,7 @@ struct loopback_pcm { /* timer stuff */ unsigned int irq_pos; /* fractional IRQ position */ unsigned int period_size_frac; + unsigned int last_drift; unsigned long last_jiffies; struct timer_list timer; }; @@ -264,6 +265,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) return err; dpcm->last_jiffies = jiffies; dpcm->pcm_rate_shift = 0; + dpcm->last_drift = 0; spin_lock(&cable->lock); cable->running |= stream; cable->pause &= ~stream; @@ -444,34 +446,30 @@ static void copy_play_buf(struct loopback_pcm *play, } } -#define BYTEPOS_UPDATE_POSONLY 0 -#define BYTEPOS_UPDATE_CLEAR 1 -#define BYTEPOS_UPDATE_COPY 2 - -static void loopback_bytepos_update(struct loopback_pcm *dpcm, - unsigned int delta, - unsigned int cmd) +static inline unsigned int bytepos_delta(struct loopback_pcm *dpcm, + unsigned int jiffies_delta) { - unsigned int count; unsigned long last_pos; + unsigned int delta; last_pos = byte_pos(dpcm, dpcm->irq_pos); - dpcm->irq_pos += delta * dpcm->pcm_bps; - count = byte_pos(dpcm, dpcm->irq_pos) - last_pos; - if (!count) - return; - if (cmd == BYTEPOS_UPDATE_CLEAR) - clear_capture_buf(dpcm, count); - else if (cmd == BYTEPOS_UPDATE_COPY) - copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK], - dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE], - count); - dpcm->buf_pos += count; - dpcm->buf_pos %= dpcm->pcm_buffer_size; + dpcm->irq_pos += jiffies_delta * dpcm->pcm_bps; + delta = byte_pos(dpcm, dpcm->irq_pos) - last_pos; + if (delta >= dpcm->last_drift) + delta -= dpcm->last_drift; + dpcm->last_drift = 0; if (dpcm->irq_pos >= dpcm->period_size_frac) { dpcm->irq_pos %= dpcm->period_size_frac; dpcm->period_update_pending = 1; } + return delta; +} + +static inline void bytepos_finish(struct loopback_pcm *dpcm, + unsigned int delta) +{ + dpcm->buf_pos += delta; + dpcm->buf_pos %= dpcm->pcm_buffer_size; } static unsigned int loopback_pos_update(struct loopback_cable *cable) @@ -481,7 +479,7 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable) struct loopback_pcm *dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE]; unsigned long delta_play = 0, delta_capt = 0; - unsigned int running; + unsigned int running, count1, count2; unsigned long flags; spin_lock_irqsave(&cable->lock, flags); @@ -500,12 +498,13 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable) goto unlock; if (delta_play > delta_capt) { - loopback_bytepos_update(dpcm_play, delta_play - delta_capt, - BYTEPOS_UPDATE_POSONLY); + count1 = bytepos_delta(dpcm_play, delta_play - delta_capt); + bytepos_finish(dpcm_play, count1); delta_play = delta_capt; } else if (delta_play < delta_capt) { - loopback_bytepos_update(dpcm_capt, delta_capt - delta_play, - BYTEPOS_UPDATE_CLEAR); |