summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-11-01 11:11:07 +0100
committerTakashi Iwai <tiwai@suse.de>2009-11-01 11:11:07 +0100
commite87a3dd33eab30b4db539500064a9584867e4f2c (patch)
tree2f7ad16e46ae30518ff63bb5391b63f7f7cc74dd /sound
parentb14f5de731ae657d498d18d713c6431bfbeefb4b (diff)
parent3d00941371a765779c4e3509214c7e5793cce1fe (diff)
downloadlinux-3.10-e87a3dd33eab30b4db539500064a9584867e4f2c.tar.gz
linux-3.10-e87a3dd33eab30b4db539500064a9584867e4f2c.tar.bz2
linux-3.10-e87a3dd33eab30b4db539500064a9584867e4f2c.zip
Merge branch 'fix/misc' into topic/misc
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/tas.c9
-rw-r--r--sound/arm/aaci.c1
-rw-r--r--sound/arm/pxa2xx-ac97.c20
-rw-r--r--sound/core/pcm.c5
-rw-r--r--sound/core/pcm_native.c81
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/drivers/opl3/opl3_midi.c28
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c65
-rw-r--r--sound/drivers/pcsp/pcsp_mixer.c2
-rw-r--r--sound/mips/hal2.c2
-rw-r--r--sound/mips/sgio2audio.c2
-rw-r--r--sound/oss/swarm_cs4297a.c3
-rw-r--r--sound/oss/sys_timer.c3
-rw-r--r--sound/parisc/harmony.c6
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/bt87x.c2
-rw-r--r--sound/pci/ctxfi/ctatc.c4
-rw-r--r--sound/pci/echoaudio/echoaudio.c30
-rw-r--r--sound/pci/echoaudio/mia.c1
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_analog.c139
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_nvhdmi.c31
-rw-r--r--sound/pci/hda/patch_realtek.c335
-rw-r--r--sound/pci/hda/patch_sigmatel.c49
-rw-r--r--sound/pci/ice1712/amp.c8
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1724.c8
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/lx6464es/lx6464es.h2
-rw-r--r--sound/pci/lx6464es/lx_core.c98
-rw-r--r--sound/pci/via82xx.c86
-rw-r--r--sound/ppc/keywest.c14
-rw-r--r--sound/soc/blackfin/Kconfig98
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c8
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h2
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c30
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.h2
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c2
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c8
-rw-r--r--sound/soc/codecs/ad1836.c3
-rw-r--r--sound/soc/codecs/ad1938.c2
-rw-r--r--sound/soc/codecs/wm8350.c4
-rw-r--r--sound/soc/codecs/wm8753.c1
-rw-r--r--sound/soc/codecs/wm8940.c2
-rw-r--r--sound/soc/codecs/wm9081.c2
-rw-r--r--sound/soc/davinci/davinci-i2s.c37
-rw-r--r--sound/soc/davinci/davinci-mcasp.c104
-rw-r--r--sound/soc/davinci/davinci-mcasp.h7
-rw-r--r--sound/soc/davinci/davinci-pcm.c13
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
-rw-r--r--sound/soc/imx/mxc-ssi.c8
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/pxa/pxa-ssp.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/soc-dapm.c5
-rw-r--r--sound/sound_core.c4
-rw-r--r--sound/usb/caiaq/audio.c16
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/usbmixer.c23
-rw-r--r--sound/usb/usx2y/us122l.c2
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c2
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
63 files changed, 888 insertions, 573 deletions
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index f0ebc971c68..1dd66ddffca 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter,
client = i2c_new_device(adapter, &info);
if (!client)
return -ENODEV;
+ /*
+ * We know the driver is already loaded, so the device should be
+ * already bound. If not it means binding failed, and then there
+ * is no point in keeping the device instantiated.
+ */
+ if (!client->driver) {
+ i2c_unregister_device(client);
+ return -ENODEV;
+ }
/*
* Let i2c-core delete that device on driver removal.
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index dc78272fc39..1f0f8213e2d 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -937,6 +937,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
struct snd_ac97 *ac97;
int ret;
+ writel(0, aaci->base + AC97_POWERDOWN);
/*
* Assert AACIRESET for 2us
*/
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 4e34d19ddbc..b4b48afb6de 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -137,9 +137,9 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card)
return 0;
}
-static int pxa2xx_ac97_suspend(struct platform_device *dev, pm_message_t state)
+static int pxa2xx_ac97_suspend(struct device *dev)
{
- struct snd_card *card = platform_get_drvdata(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
int ret = 0;
if (card)
@@ -148,9 +148,9 @@ static int pxa2xx_ac97_suspend(struct platform_device *dev, pm_message_t state)
return ret;
}
-static int pxa2xx_ac97_resume(struct platform_device *dev)
+static int pxa2xx_ac97_resume(struct device *dev)
{
- struct snd_card *card = platform_get_drvdata(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
int ret = 0;
if (card)
@@ -159,9 +159,10 @@ static int pxa2xx_ac97_resume(struct platform_device *dev)
return ret;
}
-#else
-#define pxa2xx_ac97_suspend NULL
-#define pxa2xx_ac97_resume NULL
+static struct dev_pm_ops pxa2xx_ac97_pm_ops = {
+ .suspend = pxa2xx_ac97_suspend,
+ .resume = pxa2xx_ac97_resume,
+};
#endif
static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
@@ -241,11 +242,12 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev)
static struct platform_driver pxa2xx_ac97_driver = {
.probe = pxa2xx_ac97_probe,
.remove = __devexit_p(pxa2xx_ac97_remove),
- .suspend = pxa2xx_ac97_suspend,
- .resume = pxa2xx_ac97_resume,
.driver = {
.name = "pxa2xx-ac97",
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &pxa2xx_ac97_pm_ops,
+#endif
},
};
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 0c1440121c2..c69c60b2a48 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -953,11 +953,12 @@ static int snd_pcm_dev_register(struct snd_device *device)
struct snd_pcm_substream *substream;
struct snd_pcm_notify *notify;
char str[16];
- struct snd_pcm *pcm = device->device_data;
+ struct snd_pcm *pcm;
struct device *dev;
- if (snd_BUG_ON(!pcm || !device))
+ if (snd_BUG_ON(!device || !device->device_data))
return -ENXIO;
+ pcm = device->device_data;
mutex_lock(&register_mutex);
err = snd_pcm_add(pcm);
if (err) {
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 59e5fbe6af5..ab73edf2c89 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1387,11 +1387,6 @@ static struct action_ops snd_pcm_action_drain_init = {
.post_action = snd_pcm_post_drain_init
};
-struct drain_rec {
- struct snd_pcm_substream *substream;
- wait_queue_t wait;
-};
-
static int snd_pcm_drop(struct snd_pcm_substream *substream);
/*
@@ -1407,10 +1402,9 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
struct snd_card *card;
struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *s;
+ wait_queue_t wait;
int result = 0;
- int i, num_drecs;
int nonblock = 0;
- struct drain_rec *drec, drec_tmp, *d;
card = substream->pcm->card;
runtime = substream->runtime;
@@ -1433,38 +1427,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
} else if (substream->f_flags & O_NONBLOCK)
nonblock = 1;
- if (nonblock)
- goto lock; /* no need to allocate waitqueues */
-
- /* allocate temporary record for drain sync */
down_read(&snd_pcm_link_rwsem);
- if (snd_pcm_stream_linked(substream)) {
- drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL);
- if (! drec) {
- up_read(&snd_pcm_link_rwsem);
- snd_power_unlock(card);
- return -ENOMEM;
- }
- } else
- drec = &drec_tmp;
-
- /* count only playback streams */
- num_drecs = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- runtime = s->runtime;
- if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- d = &drec[num_drecs++];
- d->substream = s;
- init_waitqueue_entry(&d->wait, current);
- add_wait_queue(&runtime->sleep, &d->wait);
- }
- }
- up_read(&snd_pcm_link_rwsem);
-
- lock:
snd_pcm_stream_lock_irq(substream);
/* resume pause */
- if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED)
+ if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, 0);
/* pre-start/stop - all running streams are changed to DRAINING state */
@@ -1479,25 +1445,35 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
for (;;) {
long tout;
+ struct snd_pcm_runtime *to_check;
if (signal_pending(current)) {
result = -ERESTARTSYS;
break;
}
- /* all finished? */
- for (i = 0; i < num_drecs; i++) {
- runtime = drec[i].substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
+ /* find a substream to drain */
+ to_check = NULL;
+ snd_pcm_group_for_each_entry(s, substream) {
+ if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ continue;
+ runtime = s->runtime;
+ if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
+ to_check = runtime;
break;
+ }
}
- if (i == num_drecs)
- break; /* yes, all drained */
-
+ if (!to_check)
+ break; /* all drained */
+ init_waitqueue_entry(&wait, current);
+ add_wait_queue(&to_check->sleep, &wait);
set_current_state(TASK_INTERRUPTIBLE);
snd_pcm_stream_unlock_irq(substream);
+ up_read(&snd_pcm_link_rwsem);
snd_power_unlock(card);
tout = schedule_timeout(10 * HZ);
snd_power_lock(card);
+ down_read(&snd_pcm_link_rwsem);
snd_pcm_stream_lock_irq(substream);
+ remove_wait_queue(&to_check->sleep, &wait);
if (tout == 0) {
if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
result = -ESTRPIPE;
@@ -1512,16 +1488,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
unlock:
snd_pcm_stream_unlock_irq(substream);
-
- if (!nonblock) {
- for (i = 0; i < num_drecs; i++) {
- d = &drec[i];
- runtime = d->substream->runtime;
- remove_wait_queue(&runtime->sleep, &d->wait);
- }
- if (drec != &drec_tmp)
- kfree(drec);
- }
+ up_read(&snd_pcm_link_rwsem);
snd_power_unlock(card);
return result;
@@ -3018,7 +2985,7 @@ static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
return 0;
}
-static struct vm_operations_struct snd_pcm_vm_ops_status =
+static const struct vm_operations_struct snd_pcm_vm_ops_status =
{
.fault = snd_pcm_mmap_status_fault,
};
@@ -3057,7 +3024,7 @@ static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
return 0;
}
-static struct vm_operations_struct snd_pcm_vm_ops_control =
+static const struct vm_operations_struct snd_pcm_vm_ops_control =
{
.fault = snd_pcm_mmap_control_fault,
};
@@ -3127,7 +3094,7 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
return 0;
}
-static struct vm_operations_struct snd_pcm_vm_ops_data =
+static const struct vm_operations_struct snd_pcm_vm_ops_data =
{
.open = snd_pcm_mmap_data_open,
.close = snd_pcm_mmap_data_close,
@@ -3151,7 +3118,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
* mmap the DMA buffer on I/O memory area
*/
#if SNDRV_PCM_INFO_MMAP_IOMEM
-static struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
+static const struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
{
.open = snd_pcm_mmap_data_open,
.close = snd_pcm_mmap_data_close,
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 6ba066c41d2..146ef00f94a 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -808,8 +808,6 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
unsigned int idx;
int err;
- if (snd_BUG_ON(!dummy))
- return -EINVAL;
spin_lock_init(&dummy->mixer_lock);
strcpy(card->mixername, "Dummy Mixer");
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 6e7d09ae0e8..7d722a025d0 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -29,6 +29,8 @@ extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
extern int use_internal_drums;
+static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
+ struct snd_midi_channel *chan);
/*
* The next table looks magical, but it certainly is not. Its values have
* been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
@@ -242,16 +244,20 @@ void snd_opl3_timer_func(unsigned long data)
int again = 0;
int i;
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
+ spin_lock_irqsave(&opl3->voice_lock, flags);
for (i = 0; i < opl3->max_voices; i++) {
struct snd_opl3_voice *vp = &opl3->voices[i];
if (vp->state > 0 && vp->note_off_check) {
if (vp->note_off == jiffies)
- snd_opl3_note_off(opl3, vp->note, 0, vp->chan);
+ snd_opl3_note_off_unsafe(opl3, vp->note, 0,
+ vp->chan);
else
again++;
}
}
+ spin_unlock_irqrestore(&opl3->voice_lock, flags);
+
+ spin_lock_irqsave(&opl3->sys_timer_lock, flags);
if (again) {
opl3->tlist.expires = jiffies + 1; /* invoke again */
add_timer(&opl3->tlist);
@@ -658,15 +664,14 @@ static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
/*
* Release a note in response to a midi note off.
*/
-void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
+static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
+ struct snd_midi_channel *chan)
{
struct snd_opl3 *opl3;
int voice;
struct snd_opl3_voice *vp;
- unsigned long flags;
-
opl3 = p;
#ifdef DEBUG_MIDI
@@ -674,12 +679,9 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan
chan->number, chan->midi_program, note);
#endif
- spin_lock_irqsave(&opl3->voice_lock, flags);
-
if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
if (chan->drum_channel && use_internal_drums) {
snd_opl3_drum_switch(opl3, note, vel, 0, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
return;
}
/* this loop will hopefully kill all extra voices, because
@@ -697,6 +699,16 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan
snd_opl3_kill_voice(opl3, voice);
}
}
+}
+
+void snd_opl3_note_off(void *p, int note, int vel,
+ struct snd_midi_channel *chan)
+{
+ struct snd_opl3 *opl3 = p;
+ unsigned long flags;
+
+ spin_lock_irqsave(&opl3->voice_lock, flags);
+ snd_opl3_note_off_unsafe(p, note, vel, chan);
spin_unlock_irqrestore(&opl3->voice_lock, flags);
}
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 84cc2658c05..e1145ac6e90 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -39,25 +39,20 @@ static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
/* write the port and returns the next expire time in ns;
* called at the trigger-start and in hrtimer callback
*/
-static unsigned long pcsp_timer_update(struct hrtimer *handle)
+static u64 pcsp_timer_update(struct snd_pcsp *chip)
{
unsigned char timer_cnt, val;
u64 ns;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
- struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
unsigned long flags;
if (chip->thalf) {
outb(chip->val61, 0x61);
chip->thalf = 0;
- if (!atomic_read(&chip->timer_active))
- return 0;
return chip->ns_rem;
}
- if (!atomic_read(&chip->timer_active))
- return 0;
substream = chip->playback_substream;
if (!substream)
return 0;
@@ -88,24 +83,17 @@ static unsigned long pcsp_timer_update(struct hrtimer *handle)
return ns;
}
-enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
+static void pcsp_pointer_update(struct snd_pcsp *chip)
{
- struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
struct snd_pcm_substream *substream;
- int periods_elapsed, pointer_update;
size_t period_bytes, buffer_bytes;
- unsigned long ns;
+ int periods_elapsed;
unsigned long flags;
- pointer_update = !chip->thalf;
- ns = pcsp_timer_update(handle);
- if (!ns)
- return HRTIMER_NORESTART;
-
/* update the playback position */
substream = chip->playback_substream;
if (!substream)
- return HRTIMER_NORESTART;
+ return;
period_bytes = snd_pcm_lib_period_bytes(substream);
buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
@@ -134,6 +122,26 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
if (periods_elapsed)
tasklet_schedule(&pcsp_pcm_tasklet);
+}
+
+enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
+{
+ struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
+ int pointer_update;
+ u64 ns;
+
+ if (!atomic_read(&chip->timer_active) || !chip->playback_substream)
+ return HRTIMER_NORESTART;
+
+ pointer_update = !chip->thalf;
+ ns = pcsp_timer_update(chip);
+ if (!ns) {
+ printk(KERN_WARNING "PCSP: unexpected stop\n");
+ return HRTIMER_NORESTART;
+ }
+
+ if (pointer_update)
+ pcsp_pointer_update(chip);
hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
@@ -142,8 +150,6 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
static int pcsp_start_playing(struct snd_pcsp *chip)
{
- unsigned long ns;
-
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: start_playing called\n");
#endif
@@ -159,11 +165,7 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
atomic_set(&chip->timer_active, 1);
chip->thalf = 0;
- ns = pcsp_timer_update(&pcsp_chip.timer);
- if (!ns)
- return -EIO;
-
- hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
+ hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL);
return 0;
}
@@ -232,21 +234,22 @@ static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
+ pcsp_sync_stop(chip);
+ chip->playback_ptr = 0;
+ chip->period_ptr = 0;
+ chip->fmt_size =
+ snd_pcm_format_physical_width(substream->runtime->format) >> 3;
+ chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: prepare called, "
- "size=%zi psize=%zi f=%zi f1=%i\n",
+ "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n",
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream) /
snd_pcm_lib_period_bytes(substream),
- substream->runtime->periods);
+ substream->runtime->periods,
+ chip->fmt_size);
#endif
- pcsp_sync_stop(chip);
- chip->playback_ptr = 0;
- chip->period_ptr = 0;
- chip->fmt_size =
- snd_pcm_format_physical_width(substream->runtime->format) >> 3;
- chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
return 0;
}
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c
index 199b0337714..903bc846763 100644
--- a/sound/drivers/pcsp/pcsp_mixer.c
+++ b/sound/drivers/pcsp/pcsp_mixer.c
@@ -72,7 +72,7 @@ static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
if (treble != chip->treble) {
chip->treble = treble;
#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: rate set to %i\n", PCSP_RATE());
+ printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
#endif
changed = 1;
}
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index c52691c2fc4..9a88cdfd952 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -915,7 +915,7 @@ static int __devinit hal2_probe(struct platform_device *pdev)
return 0;
}
-static int __exit hal2_remove(struct platform_device *pdev)
+static int __devexit hal2_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index e497525bc11..8691f4cf619 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -973,7 +973,7 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
return 0;
}
-static int __exit snd_sgio2audio_remove(struct platform_device *pdev)
+static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 1edab7b4ea8..3136c88eacd 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -110,9 +110,6 @@ static void start_adc(struct cs4297a_state *s);
// rather than 64k as some of the games work more responsively.
// log base 2( buff sz = 32k).
-//static unsigned long defaultorder = 3;
-//MODULE_PARM(defaultorder, "i");
-
//
// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
//
diff --git a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
index 107534477a2..8db6aefe15e 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -100,9 +100,6 @@ def_tmr_open(int dev, int mode)
curr_tempo = 60;
curr_timebase = 100;
opened = 1;
-
- ;
-
{
def_tmr.expires = (1) + jiffies;
add_timer(&def_tmr);
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index e924492df21..f47f9e226b0 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -624,6 +624,9 @@ snd_harmony_pcm_init(struct snd_harmony *h)
struct snd_pcm *pcm;
int err;
+ if (snd_BUG_ON(!h))
+ return -EINVAL;
+
harmony_disable_interrupts(h);
err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
@@ -865,11 +868,12 @@ snd_harmony_mixer_reset(struct snd_harmony *h)
static int __devinit
snd_harmony_mixer_init(struct snd_harmony *h)
{
- struct snd_card *card = h->card;
+ struct snd_card *card;
int idx, err;
if (snd_BUG_ON(!h))
return -EINVAL;
+ card = h->card;
strcpy(card->mixername, "Harmony Gain control interface");
for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index b458d208720..aaf4da68969 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -973,7 +973,7 @@ static void snd_ali_free_voice(struct snd_ali * codec,
void *private_data;
snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
- if (pvoice == NULL || !pvoice->use)
+ if (!pvoice->use)
return;
snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
spin_lock_irq(&codec->voice_alloc);
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 24585c6c6d0..4e2b925a94c 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -808,6 +808,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC),
/* Leadtek Winfast tv 2000xp delux */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
+ /* Pinnacle PCTV */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x11bd, 0x0012, GENERIC),
/* Voodoo TV 200 */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
/* Askey Computer Corp. MagicTView'99 */
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 6bfce99b42a..cb65bd0dd35 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1037,7 +1037,7 @@ static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
{
- return atc_daio_unmute(atc, state, LINEO4);
+ return atc_daio_unmute(atc, state, LINEO2);
}
static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
@@ -1047,7 +1047,7 @@ static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
{
- return atc_daio_unmute(atc, state, LINEO2);
+ return atc_daio_unmute(atc, state, LINEO4);
}
static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index da2065cd2c0..1305f7ca02c 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -950,7 +950,7 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
Control interface
******************************************************************************/
-#ifndef ECHOCARD_HAS_VMIXER
+#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
/******************* PCM output volume *******************/
static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
@@ -1003,6 +1003,19 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
return changed;
}
+#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
+/* On the Mia this one controls the line-out volume */
+static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
+ .name = "Line Playback Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ .info = snd_echo_output_gain_info,
+ .get = snd_echo_output_gain_get,
+ .put = snd_echo_output_gain_put,
+ .tlv = {.p = db_scale_output_gain},
+};
+#else
static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
.name = "PCM Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1012,9 +1025,10 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
.put = snd_echo_output_gain_put,
.tlv = {.p = db_scale_output_gain},
};
-
#endif
+#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
+
#ifdef ECHOCARD_HAS_INPUT_GAIN
@@ -2030,10 +2044,18 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
goto ctl_error;
-#else
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0)
+#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_echo_line_output_gain, chip));
+ if (err < 0)
goto ctl_error;
#endif
+#else /* ECHOCARD_HAS_VMIXER */
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
+ if (err < 0)
+ goto ctl_error;
+#endif /* ECHOCARD_HAS_VMIXER */
#ifdef ECHOCARD_HAS_INPUT_GAIN
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index f3b9b45c9c1..f05c8c097aa 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -29,6 +29,7 @@
#define ECHOCARD_HAS_ADAT FALSE
#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
#define ECHOCARD_HAS_MIDI
+#define ECHOCARD_HAS_LINE_OUT_GAIN
/* Pipe indexes */
#define PX_ANALOG_OUT 0 /* 8 */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 20a66f85f0a..c9ad182e1b4 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
* white-list for enable_msi
*/
static struct snd_pci_quirk msi_white_list[] __devinitdata = {
+ SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1),
SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
{}
};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 215e72a8711..2d603f6aba6 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -4032,6 +4032,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
}
/*
+ * HP Touchsmart
+ * port-A (0x11) - front hp-out
+ * port-B (0x14) - unused
+ * port-C (0x15) - unused
+ * port-D (0x12) - rear line out
+ * port-E (0x1c) - front mic-in
+ * port-F (0x16) - Internal speakers
+ * digital-mic (0x17) - Internal mic
+ */
+
+static struct hda_verb ad1984a_touchsmart_verbs[] = {
+ /* DACs; unmute as default */
+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+ /* Port-A (HP) mixer - route only from analog mixer */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* Port-A pin */
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ /* Port-A (HP) pin - always unmuted */
+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Port-E (int speaker) mixer - route only from analog mixer */
+ {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
+ /* Port-E pin */
+ {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ /* Port-F (int speaker) mixer - route only from analog mixer */
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* Port-F pin */
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Analog mixer; mute as default */
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ /* Analog Mix output amp */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* capture sources */
+ /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* unsolicited event for pin-sense */
+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
+ {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
+ /* allow to touch GPIO1 (for mute control) */
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
+ /* internal mic - dmic */
+ {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ /* set magic COEFs for dmic */
+ {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
+ {0x01, AC_VERB_SET_PROC_COEF, 0x08},
+ { } /* end */
+};
+
+static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
+/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Master Playback Switch",
+ .info = snd_hda_mixer_amp_switch_info,
+ .get = snd_hda_mixer_amp_switch_get,
+ .put = ad1884a_mobile_master_sw_put,
+ .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
+ },
+ HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
+ HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+/* switch to external mic if plugged */
+static void ad1984a_touchsmart_automic(struct hda_codec *codec)
+{
+ if (snd_hda_codec_read(codec, 0x1c, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
+ snd_hda_codec_write(codec, 0x0c, 0,
+ AC_VERB_SET_CONNECT_SEL, 0x4);
+ } else {
+ snd_hda_codec_write(codec, 0x0c, 0,
+ AC_VERB_SET_CONNECT_SEL, 0x5);
+ }
+}
+
+
+/* unsolicited event for HP jack sensing */
+static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case AD1884A_HP_EVENT:
+ ad1884a_hp_automute(codec);
+ break;
+ case AD1884A_MIC_EVENT:
+ ad1984a_touchsmart_automic(codec);
+ break;
+ }
+}
+
+/* initialize jack-sensing, too */
+static int ad1984a_touchsmart_init(struct hda_codec *codec)
+{
+ ad198x_init(codec);
+ ad1884a_hp_automute(codec);
+ ad1984a_touchsmart_automic(codec);
+ return 0;
+}
+
+
+/*
*/
enum {
@@ -4039,6 +4160,7 @@ enum {
AD1884A_LAPTOP,
AD1884A_MOBILE,
AD1884A_THINKPAD,
+ AD1984A_TOUCHSMART,
AD1884A_MODELS
};
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
[AD1884A_LAPTOP] = "laptop",
[AD1884A_MOBILE] = "mobile",
[AD1884A_THINKPAD] = "thinkpad",
+ [AD1984A_TOUCHSMART] = "touchsmart",
};
static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
+ SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
{}
};
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
codec->patch_ops.init = ad1984a_thinkpad_init;
break;
+ case AD1984A_TOUCHSMART:
+ spec->mixers[0] = ad1984a_touchsmart_mixers;
+ spec->init_verbs[0] = ad1984a_touchsmart_verbs;
+ spec->multiout.dig_out_nid = 0;
+ codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
+ codec->patch_ops.init = ad1984a_touchsmart_init;
+ /* set the upper-limit for mixer amp to 0dB for avoiding the
+ * possible damage by overloading
+ */
+ snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
+ break;
}
return 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 9d899eda44d..3fbbc8c01e7 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = {
};
static struct hda_input_mux cxt5045_capture_source_benq = {
- .num_items = 3,
+ .num_items = 5,
.items = {
{ "IntMic", 0x1 },
{ "ExtMic", 0x2 },
{ "LineIn", 0x3 },
+ { "CD", 0x4 },
+ { "Mixer", 0x0 },
}
};
@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
};
static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
+ HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
+
HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
+
{}
};
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index c8435c9a97f..9fb60276f5c 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,6 +29,9 @@
#include "hda_codec.h"
#include "hda_local.h"
+/* define below to restrict the supported rates and formats */
+/* #define LIMITED_RATE_FMT_SUPPORT */
+
struct nvhdmi_spec {
struct hda_multi_out multiout;
@@ -60,6 +63,22 @@ static struct hda_verb nvhdmi_basic_init[] = {
{} /* terminator */
};
+#ifdef LIMITED_RATE_FMT_SUPPORT
+/* support only the safe format and rate */
+#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
+#define SUPPORTED_MAXBPS 16
+#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+#else
+/* support all rates and formats */
+#define SUPPORTED_RATES \
+ (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
+ SNDRV_PCM_RATE_192000)
+#define SUPPORTED_MAXBPS 24
+#define SUPPORTED_FORMATS \
+ (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
+#endif
+
/*
* Controls
*/
@@ -258,9 +277,9 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = {
.channels_min = 2,
.channels_max = 8,
.nid = Nv_Master_Convert_nid,
- .rates = SNDRV_PCM_RATE_48000,
- .maxbps = 16,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SUPPORTED_RATES,
+ .maxbps = SUPPORTED_MAXBPS,
+ .formats = SUPPORTED_FORMATS,
.ops = {
.open = nvhdmi_dig_playback_pcm_open,
.close = nvhdmi_dig_playback_pcm_close_8ch,
@@ -273,9 +292,9 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
.channels_min = 2,
.channels_max = 2,
.nid = Nv_Master_Convert_nid,
- .rates = SNDRV_PCM_RATE_48000,
- .maxbps = 16,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SUPPORTED_RATES,
+ .maxbps = SUPPORTED_MAXBPS,
+ .formats = SUPPORTED_FORMATS,
.ops = {
.open = nvhdmi_dig_playback_pcm_open,
.close = nvhdmi_dig_playback_pcm_close_2ch,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 12960581956..c08ca660dab 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -275,7 +275,7 @@ struct alc_spec {
struct snd_kcontrol_new *cap_mixer; /* capture mixer */
unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
- const struct hda_verb *init_verbs[5]; /* initialization verbs
+ const struct hda_verb *init_verbs[10]; /* initialization verbs
* don't forget NULL
* termination!
*/
@@ -1332,15 +1332,20 @@ do_sku:
* when the external headphone out jack is plugged"
*/
if (!spec->autocfg.hp_pins[0]) {
+ hda_nid_t nid;
tmp = (ass >> 11) & 0x3; /* HP to chassis */
if (tmp == 0)
- spec->autocfg.hp_pins[0] = porta;
+ nid = porta;
else if (tmp == 1)
- spec->autocfg.hp_pins[0] = porte;
+ nid = porte;
else if (tmp == 2)
- spec->autocfg.hp_pins[0] = portd;
+ nid = portd;
else
return 1;
+ for (i = 0; i < spec->autocfg.line_outs; i++)
+ if (spec->autocfg.line_out_pins[i] == nid)
+ return 1;
+ spec->autocfg.hp_pins[0] = nid;
}
alc_init_auto_hp(codec);
@@ -1362,7 +1367,7 @@ static void alc_ssid_check(struct hda_codec *codec,
}
/*
- * Fix-up pin default configurations
+ * Fix-up pin default configurations and add default verbs
*/
struct alc_pincfg {
@@ -1370,9 +1375,14 @@ struct alc_pincfg {
u32 val;
};
-static void alc_fix_pincfg(struct hda_codec *codec,
+struct alc_fixup {
+ const struct alc_pincfg *pins;
+ const struct hda_verb *verbs;
+};
+
+static void alc_pick_fixup(struct hda_codec *codec,
const struct snd_pci_quirk *quirk,
- const struct alc_pincfg **pinfix)
+ const struct alc_fixup *fix)
{
const struct alc_pincfg *cfg;
@@ -1380,9 +1390,14 @@ static void alc_fix_pincfg(struct hda_codec *codec,
if (!quirk)
return;
- cfg = pinfix[quirk->value];
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+ fix += quirk->value;
+ cfg = fix->pins;
+ if (cfg) {
+ for (; cfg->nid; cfg++)
+ snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+ }
+ if (fix->verbs)
+ add_verb(codec->spec, fix->verbs);
}
/*
@@ -9593,11 +9608,13 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
{ }
};
-static const struct alc_pincfg *alc882_pin_fixes[] = {
- [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
+static const struct alc_fixup alc882_fixups[] = {
+ [PINFIX_ABIT_AW9D_MAX] = {
+ .pins = alc882_abit_aw9d_pinfix
+ },
};
-static struct snd_pci_quirk alc882_pinfix_tbl[] = {
+static struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
{}
};
@@ -9869,7 +9886,7 @@ static int patch_alc882(struct hda_codec *codec)
board_config = ALC882_AUTO;
}
- alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
+ alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
if (board_config == ALC882_AUTO) {
/* automatic parse from the BIOS config */
@@ -12660,7 +12677,7 @@ static struct alc_config_preset alc268_presets[] = {
.init_hook = alc268_toshiba_automute,
},
[ALC268_ACER] = {
- .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer,
+ .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
alc268_beep_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_acer_verbs },
@@ -12842,12 +12859,15 @@ static int patch_alc268(struct hda_codec *codec)
unsigned int wcap = get_wcaps(codec, 0x07);
int i;
+ spec->capsrc_nids = alc268_capsrc_nids;
/* get type */
wcap = get_wcaps_type(wcap);
if (spec->auto_mic ||
wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
spec->adc_nids = alc268_adc_nids_alt;
spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
+ if (spec->auto_mic)
+ fixup_automic_adc(codec);
if (spec->auto_mic || spec->input_mux->num_items == 1)
add_mixer(spec, alc268_capture_nosrc_mixer);
else
@@ -12857,7 +12877,6 @@ static int patch_alc268(struct hda_codec *codec)
spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
add_mixer(spec, alc268_capture_mixer);
}
- spec->capsrc_nids = alc268_capsrc_nids;
/* set default input source */
for (i = 0; i < spec->num_adc_nids; i++)
snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
@@ -14357,15 +14376,16 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
static void alc861_auto_init_hp_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- hda_nid_t pin;
- pin = spec->autocfg.hp_pins[0];
- if (pin)
- alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
+ if (spec->autocfg.hp_outs)
+ alc861_auto_set_output_and_unmute(codec,
+ spec->autocfg.hp_pins[0],
+ PIN_HP,
spec->multiout.hp_nid);
- pin = spec->autocfg.speaker_pins[0];
- if (pin)
- alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT,
+ if (spec->autocfg.speaker_outs)
+ alc861_auto_set_output_and_unmute(codec,
+ spec->autocfg.speaker_pins[0],
+ PIN_OUT,
spec->multiout.dac_nids[0]);
}
@@ -15158,7 +15178,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
- SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+ /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
@@ -15551,6 +15571,29 @@ static void alc861vd_auto_init(struct hda_codec *codec)
alc_inithook(codec);
}
+enum {
+ ALC660VD_FIX_ASUS_GPIO1
+};
+
+/* reset GPIO1 */
+static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+ { }
+};
+
+static const struct alc_fixup alc861vd_fixups[] = {
+ [ALC660VD_FIX_ASUS_GPIO1] = {
+ .verbs = alc660vd_fix_asus_gpio1_verbs,
+ },
+};
+
+static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
+ {}
+};
+
static int patch_alc861vd(struct hda_codec *codec)
{
struct alc_spec *spec;
@@ -15572,6 +15615,8 @@ static int patch_alc861vd(struct hda_codec *codec)
board_config = ALC861VD_AUTO;
}
+ alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
+
if (board_config == ALC861VD_AUTO) {
/* automatic parse from the BIOS config */
err = alc861vd_parse_auto_config(codec);
@@ -16852,6 +16897,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
ALC662_3ST_6ch_DIG),
@@ -17145,70 +17191,145 @@ static struct alc_config_preset alc662_presets[] = {
* BIOS auto configuration
*/
+/* convert from MIX nid to DAC */
+static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
+{
+ if (nid == 0x0f)
+ return 0x02;
+ else if (nid >= 0x0c && nid <= 0x0e)
+ return nid - 0x0c + 0x02;
+ else
+ return 0;
+}
+
+/* get MIX nid connected to the given pin targeted to DAC */
+static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
+ hda_nid_t dac)
+{
+ hda_nid_t mix[4];
+ int i, num;
+
+ num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
+ for (i = 0; i < num; i++) {
+ if (alc662_mix_to_dac(mix[i]) == dac)
+ return mix[i];
+ }
+ return 0;
+}
+
+/* look for an empty DAC slot */
+static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t srcs[5];
+ int i, j, num;
+
+ num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
+ if (num < 0)
+ return 0;
+ for (i = 0; i < num; i++) {
+ hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
+ if (!nid)
+ continue;
+ for (j = 0; j < spec->multiout.num_dacs; j++)
+ if (spec->multiout.dac_nids[j] == nid)
+ break;
+ if (j >= spec->multiout.num_dacs)
+ return nid;
+ }
+ return 0;
+}
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg)
+{
+ struct alc_spec *spec = codec->spec;
+ int i;
+ hda_nid_t dac;
+
+ spec->multiout.dac_nids = spec->private_dac_nids;
+ for (i = 0; i < cfg->line_outs; i++) {
+ dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
+ if (!dac)
+ continue;
+ spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
+ }
+ return 0;
+}
+
+static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
+ hda_nid_t nid, unsigned int chs)
+{
+ char name[32];
+ sprintf(name, "%s Playback Volume", pfx);
+ return add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
+}
+
+static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
+ hda_nid_t nid, unsigned int chs)
+{
+ char name[32];
+ sprintf(name, "%s Playback Switch", pfx);
+ return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
+}
+
+#define alc662_add_stereo_vol(spec, pfx, nid) \
+ alc662_add_vol_ctl(spec, pfx, nid, 3)
+#define alc662_add_stereo_sw(spec, pfx, nid) \
+ alc662_add_sw_ctl(spec, pfx, nid, 3)
+
/* add playback controls from the parsed DAC table */
-static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
+static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- char name[32];
+ struct alc_spec *spec = codec->spec;
static const char *chname[4] = {
"Front", "Surround", NULL /*CLFE*/, "Side"
};
- hda_nid_t nid;
+ hda_nid_t nid, mix;
int i, err;
for (i = 0; i < cfg->line_outs; i++) {
- if (!spec->multiout.dac_nids[i])
+ nid = spec->multiout.dac_nids[i];
+ if (!nid)
+ continue;
+ mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
+ if (!mix)
continue;
- nid = alc880_idx_to_dac(i);
if (i == 2) {
/* Center/LFE */
- err = add_control(spec, ALC_CTL_WIDGET_VOL,
- "Center Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0,
- HDA_OUTPUT));
+ err = alc662_add_vol_ctl(spec, "Center", nid, 1);
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_WIDGET_VOL,
- "LFE Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 2, 0,
- HDA_OUTPUT));
+ err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_WIDGET_MUTE,
- "Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
- HDA_INPUT));
+ err = alc662_add_sw_ctl(spec, "Center", mix, 1);
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_WIDGET_MUTE,
- "LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
- HDA_INPUT));
+ err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
if (err < 0)
return err;
} else {
const char *pfx;
if (cfg->line_outs == 1 &&
cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
- if (!cfg->hp_pins)
+ if (cfg->hp_outs)
pfx = "Speaker";
else
pfx = "PCM";
} else
pfx = chname[i];
- sprintf(name, "%s Playback Volume", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0,
- HDA_OUTPUT));
+ err = alc662_add_vol_ctl(spec, pfx, nid, 3);
if (err < 0)
return err;
if (cfg->line_outs == 1 &&
cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
pfx = "Speaker";
- sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
- 3, 0, HDA_INPUT));
+ err = alc662_add_sw_ctl(spec, pfx, mix, 3);
if (err < 0)
return err;
}
@@ -17217,54 +17338,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
}
/* add playback controls for speaker and HP outputs */
-static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+/* return DAC nid if any new DAC is assigned */
+static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
const char *pfx)
{
- hda_nid_t nid;
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t nid, mix;
int err;
- char name[32];
if (!pin)
return 0;
-
- if (pin == 0x17) {
- /* ALC663 has a mono output pin on 0x17 */
+ nid = alc662_look_for_dac(codec, pin);
+ if (!nid) {
+ char name[32];
+ /* the corresponding DAC is already occupied */
+ if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
+ return 0; /* no way */
+ /* create a switch only */
sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
- return err;
+ return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
}
- if (alc880_is_fixed_pin(pin)) {
- nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
- /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
- /* specify the DAC as the extra output */
- if (!spec->multiout.hp_nid)
- spec->multiout.hp_nid = nid;
- else
- spec->multiout.extra_out_nid[0] = nid;
- /* control HP volume/switch on the output mixer amp */
- nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
- sprintf(name, "%s Playback Volume", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
- if (err < 0)
- return err;
- } else if (alc880_is_multi_pin(pin)) {
- /* set manual connection */
- /* we have only a switch on HP-out PIN */
- sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- }
- return 0;
+ mix = alc662_dac_to_mix(codec, pin, nid);
+ if (!mix)
+ return 0;
+ err = alc662_add_vol_ctl(spec, pfx, nid, 3);
+ if (err < 0)
+ return err;
+ err = alc662_add_sw_ctl(spec, pfx, mix, 3);
+ if (err < 0)
+ return err;
+ return nid;
}
/* create playback/capture controls for input pins */
@@ -17273,30 +17378,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
hda_nid_t nid, int pin_type,
- int dac_idx)
+ hda_nid_t dac)
{
+ int i, num;
+ hda_nid_t srcs[4];
+
alc_set_pin_output(codec, nid, pin_type);
/* need the manual connection? */
- if (alc880_is_multi_pin(nid)) {
- struct alc_spec *spec = codec->spec;
- int idx = alc880_multi_pin_idx(nid);
- snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
- AC_VERB_SET_CONNECT_SEL,
- alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+ num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
+ if (num <= 1)
+ return;
+ for (i = 0; i < num; i++) {
+ if (alc662_mix_to_dac(srcs[i]) != dac)
+ continue;
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
+ return;
}
}
static void alc662_auto_init_multi_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
int i;
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
- int pin_type = get_pin_type(spec->autocfg.line_out_type);
if (nid)
alc662_auto_set_output_and_unmute(codec, nid, pin_type,
- i);
+ spec->multiout.dac_nids[i]);
}
}
@@ -17306,12 +17416,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
hda_nid_t pin;
pin = spec->autocfg.hp_pins[0];
- if (pin) /* connect to front */
- /* use dac 0 */
- alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+ if (pin)
+ alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
+ spec->multiout.hp_nid);
pin = spec->autocfg.speaker_pins[0];
if (pin)
- alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
+ alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
+ spec->multiout.extra_out_nid[0]);
}
#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
@@ -17349,21 +17460,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
- err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+ err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
if (err < 0)
return err;
- err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
if (err < 0)
return err;
- err = alc662_auto_create_extra_out(spec,
+ err = alc662_auto_create_extra_out(codec,
spec->autocfg.speaker_pins[0],
"Speaker");
if (err < 0)
return err;
- err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+ if (err)
+ spec->multiout.extra_out_nid[0] = err;
+ err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
"Headphone");
if (err < 0)
return err;
+ if (err)
+ spec->multiout.hp_nid = err;
err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
if (err < 0)
return err;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 826137ec300..66c0876bf73 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -158,6 +158,7 @@ enum {
STAC_D965_5ST_NO_FP,
STAC_DELL_3ST,
STAC_DELL_BIOS,
+ STAC_927X_VOLKNOB,
STAC_927X_MODELS
};
@@ -182,8 +183,8 @@ struct sigmatel_jack {
struct sigmatel_mic_route {
hda_nid_t pin;
- unsigned char mux_idx;
- unsigned char dmux_idx;
+ signed char mux_idx;
+ signed char dmux_idx;
};
struct sigmatel_spec {
@@ -907,6 +908,16 @@ static struct hda_verb d965_core_init[] = {
{}
};
+static struct hda_verb dell_3st_core_init[] = {
+ /* don't set delta bit */
+ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
+ /* unmute node 0x1b */
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+ /* select node 0x03 as DAC */
+ {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {}
+};
+
static struct hda_verb stac927x_core_init[] = {
/* set master volume and direct control */
{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -915,6 +926,14 @@ static struct hda_verb stac927x_core_init[] = {
{}
};
+static struct hda_verb stac927x_volknob_core_init[] = {
+ /* don't set delta bit */
+ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
+ /* enable analog pc beep path */
+ {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
+ {}
+};
+
static struct hda_verb stac9205_core_init[] = {
/* set master volume and direct control */
{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -1999,6 +2018,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
[STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
[STAC_DELL_3ST] = dell_3st_pin_configs,
[STAC_DELL_BIOS] = NULL,
+ [STAC_927X_VOLKNOB] = NULL,
};
static const char *stac927x_models[STAC_927X_MODELS] = {
@@ -2010,6 +2030,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
[STAC_D965_5ST_NO_FP] = "5stack-no-fp",
[STAC_DELL_3ST] = "dell-3stack",
[STAC_DELL_BIOS] = "dell-bios",
+ [STAC_927X_VOLKNOB] = "volknob",
};
static struct snd_pci_quirk stac927x_cfg_tbl[] = {
@@ -2045,6 +2066,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
"Intel D965", STAC_D965_5ST),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
"Intel D965", STAC_D965_5ST),
+ /* volume-knob fixes */
+ SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
{} /* terminator */
};
@@ -3469,18 +3492,26 @@ static int set_mic_route(struct hda_codec *codec,
break;
if (i <= AUTO_PIN_FRONT_MIC) {
/* analog pin */
- mic->dmux_idx = 0;
i = get_connection_index(codec, spec->mux_nids[0], pin);
if (i < 0)
return -1;
mic->mux_idx = i;
+ mic->dmux_idx = -1;
+ if (spec->dmux_nids)
+ mic->dmux_idx = get_connection_index(codec,
+ spec->dmux_nids[0],
+ spec->mux_nids[0]);
} else if (spec->dmux_nids) {
/* digital pin */
- mic->mux_idx = 0;
i = get_connection_index(codec, spec->dmux_nids[0], pin);
if (i < 0)
return -1;
mic->dmux_idx = i;
+ mic->mux_idx = -1;
+ if (spec->mux_nids)
+ mic->mux_idx = get_connection_index(codec,
+ spec->mux_nids[0],
+ spec->dmux_nids[0]);
}
return 0;
}
@@ -4557,11 +4588,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
mic = &spec->ext_mic;
else
mic = &spec->int_mic;
- if (mic->dmux_idx)
+ if (mic->dmux_idx >= 0)
snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
AC_VERB_SET_CONNECT_SEL,
mic->dmux_idx);
- else
+ if (mic->mux_idx >= 0)
snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
AC_VERB_SET_CONNECT_SEL,
mic->mux_idx);
@@ -5604,10 +5635,14 @@ static int patch_stac927x(struct hda_codec *codec)
spec->dmic_nids = stac927x_dmic_nids;
spec->num_dmics = STAC927X_NUM_DMICS;
- spec->init = d965_core_init;
+ spec->init = dell_3st_core_init;
spec->dmux_nids = stac927x_dmux_nids;
spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
break;
+ case STAC_927X_VOLKNOB:
+ spec->num_dmics = 0;
+ spec->init = stac927x_volknob_core_init;
+ break;
default:
spec->num_dmics = 0;
spec->init = stac927x_core_init;
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 37564300b50..6da21a2bcad 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -52,11 +52,13 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
/* only use basic functionality for now */
- ice->num_total_dacs = 2; /* only PSDOUT0 is connected */
+ /* VT1616 6ch codec connected to PSDOUT0 using packed mode */
+ ice->num_total_dacs = 6;
ice->num_total_adcs = 2;
- /* Chaintech AV-710 has another codecs, which need initialization */
- /* initialize WM8728 codec */
+ /* Chaintech AV-710 has another WM8728 codec connected to PSDOUT4
+ (shared with the SPDIF output). Mixer control for this codec
+ is not yet supported. */
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
wm_put(ice, wm_inits[i], wm_inits[i+1]);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index cecf1ffeeaa..d74033a2cfb 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2259,7 +2259,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
}
static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Multi Track Peak",
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = snd_ice1712_pro_peak_info,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index af6e0014862..10fc92c0557 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -648,7 +648,7 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
(inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
/* running? we cannot change the rate now... */
spin_unlock_irqrestore(&ice->reg_lock, flags);
- return -EBUSY;
+ return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
}
if (!force && is_pro_rate_locked(ice)) {
spin_unlock_irqrestore(&ice->reg_lock, flags);
@@ -1294,7 +1294,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(ice->pci),
- 64*1024, 64*1024);
+ 256*1024, 256*1024);
ice->pcm = pcm;
@@ -1408,7 +1408,7 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(ice->pci),
- 64*1024, 64*1024);
+ 256*1024, 256*1024);
ice->pcm_ds = pcm;
@@ -2110,7 +2110,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
}
static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Multi Track Peak",
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = snd_vt1724_pro_peak_info,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 171ada53520..754867ed478 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1954,6 +1954,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "Sony S1XP",
.type = AC97_TUNE_INV_EAPD
},
+ {
+ .subvendor = 0x104d,
+ .subdevice = 0x81c0,
+ .name = "Sony VAIO VGN-T350P", /*AD1981B*/
+ .type = AC97_TUNE_INV_EAPD
+ },
+ {
+ .subvendor = 0x104d,
+ .subdevice = 0x81c5,
+ .name = "Sony VAIO VGN-B1VP", /*AD1981B*/
+ .type = AC97_TUNE_INV_EAPD
+ },
{
.subvendor = 0x1043,
.subdevice = 0x80f3,
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index 012c010c8c8..51afc048961 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -86,7 +86,6 @@ struct lx6464es {
/* messaging */
spinlock_t msg_lock; /* message spinlock */
- atomic_t send_message_locked;
struct lx_rmh rmh;
/* configuration */
@@ -95,7 +94,6 @@ struct lx6464es {
uint hardware_running[2];
u32 board_sample_rate; /* sample rate read from
* board */
- u32 sample_rate; /* our sample rate */
u16 pcm_granularity; /* board blocksize */
/* dma */
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 5812780d6e8..3086b751da4 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -314,98 +314,6 @@ static inline void lx_message_dump(struct lx_rmh *rmh)
#define XILINX_POLL_NO_SLEEP 100
#define XILINX_POLL_ITERATIONS 150
-#if 0 /* not used now */
-static int lx_message_send(struct lx6464es *chip, struct lx_rmh *rmh)
-{
- u32 reg = ED_DSP_TIMED_OUT;
- int dwloop;
- int answer_received;
-
- if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) {
- snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg);
- return -EBUSY;
- }
-
- /* write command */
- lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len);
-
- snd_BUG_ON(atomic_read(&chip->send_message_locked) != 0);
- atomic_set(&chip->send_message_locked, 1);
-
- /* MicoBlaze gogogo */
- lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);
-
- /* wait for interrupt to answer */
- for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS; ++dwloop) {
- answer_received = atomic_read(&chip->send_message_locked);
- if (answer_received == 0)
- break;
- msleep(1);
- }
-
- if (answer_received == 0) {
- /* in Debug mode verify Reg_CSM_MR */
- snd_BUG_ON(!(lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR));
-
- /* command finished, read status */
- if (rmh->dsp_stat == 0)
- reg = lx_dsp_reg_read(chip, eReg_CRM1);
- else
- reg = 0;
- } else {
- int i;
- snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! "
- "Interrupts disabled?\n");
-
- /* attente bit Reg_CSM_MR */
- for (i = 0; i != XILINX_POLL_ITERATIONS; i++) {
- if ((lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR)) {
- if (rmh->dsp_stat == 0)
- reg = lx_dsp_reg_read(chip, eReg_CRM1);
- else
- reg = 0;
- goto polling_successful;
- }
-
- if (i > XILINX_POLL_NO_SLEEP)
- msleep(1);
- }
- snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! "
- "polling failed\n");
-
-polling_successful:
- atomic_set(&chip->send_message_locked, 0);
- }
-
- if ((reg & ERROR_VALUE) == 0) {
- /* read response */
- if (rmh->stat_len) {
- snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1));
-
- lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
- rmh->stat_len);
- }
- } else
- snd_printk(KERN_WARNING LXP "lx_message_send: error_value %x\n",
- reg);
-
- /* clear Reg_CSM_MR */
- lx_dsp_reg_write(chip, eReg_CSM, 0);
-
- switch (reg) {
- case ED_DSP_TIMED_OUT:
- snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
- return -ETIMEDOUT;
-
- case ED_DSP_CRASHED:
- snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
- return -EAGAIN;
- }
-
- lx_message_dump(rmh);
- return 0;
-}
-#endif /* not used now */
static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
{
@@ -423,7 +331,7 @@ static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
/* MicoBlaze gogogo */
lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);
- /* wait for interrupt to answer */
+ /* wait for device to answer */
for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) {
if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) {
if (rmh->dsp_stat == 0)
@@ -1175,10 +1083,6 @@ static int lx_interrupt_ack(struct lx6464es *chip, u32 *r_irqsrc,
*r_async_escmd = 1;
}
- if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
- /* xilinx command notification */
- atomic_set(&chip->send_message_locked, 0);
-
if (irq_async) {
/* snd_printd("interrupt: async event pending\n"); */
*r_async_pending = 1;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index acfa4760da4..8a332d2f615 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -386,6 +386,7 @@ struct via82xx {
struct snd_pcm *pcms[2];
struct snd_rawmidi *rmidi;
+ struct snd_kcontrol *dxs_controls[4];
struct snd_ac97_bus *ac97_bus;
struct snd_ac97 *ac97;
@@ -1216,9 +1217,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
/*
- * open callback for playback on via686 and via823x DSX
+ * open callback for playback on via686
*/
-static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
+static int snd_via686_playback_open(struct snd_pcm_substream *substream)
{
struct via82xx *chip = snd_pcm_substream_chip(substream);
struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
@@ -1230,6 +1231,32 @@ static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
}
/*
+ * open callback for playback on via823x DXS
+ */
+static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
+{
+ struct via82xx *chip = snd_pcm_substream_chip(substream);
+ struct viadev *viadev;
+ unsigned int stream;
+ int err;
+
+ viadev = &chip->devs[chip->playback_devno + substream->number];
+ if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+ return err;
+ stream = viadev->reg_offset / 0x10;
+ if (chip->dxs_controls[stream]) {
+ chip->playback_volume[stream][0] = 0;
+ chip->playback_volume[stream][1] = 0;
+ chip->dxs_controls[stream]->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO,
+ &chip->dxs_controls[stream]->id);
+ }
+ return 0;
+}
+
+/*
* open callback for playback on via823x multi-channel
*/
static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
@@ -1302,10 +1329,26 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
return 0;
}
+static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
+{
+ struct via82xx *chip = snd_pcm_substream_chip(substream);
+ struct viadev *viadev = substream->runtime->private_data;
+ unsigned int stream;
+
+ stream = viadev->reg_offset / 0x10;
+ if (chip->dxs_controls[stream]) {
+ chip->dxs_controls[stream]->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO,
+ &chip->dxs_controls[stream]->id);
+ }
+ return snd_via82xx_pcm_close(substream);
+}
+
/* via686 playback callbacks */
static struct snd_pcm_ops snd_via686_playback_ops = {
- .open = snd_via82xx_playback_open,
+ .open = snd_via686_playback_open,
.close = snd_via82xx_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
@@ -1331,8 +1374,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = {
/* via823x DSX playback callbacks */
static struct snd_pcm_ops snd_via8233_playback_ops = {
- .open = snd_via82xx_playback_open,
- .close = snd_via82xx_pcm_close,
+ .open = snd_via8233_playback_open,
+ .close = snd_via8233_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
.hw_free = snd_via82xx_hw_free,
@@ -1626,7 +1669,7 @@ static int snd_via8233_dxs_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+ unsigned int idx = kcontrol->id.subdevice;
ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
@@ -1646,7 +1689,7 @@ static int snd_via8233_dxs_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+ unsigned int idx = kcontrol->id.subdevice;
unsigned long port = chip->port + 0x10 * idx;
unsigned char val;
int i, change = 0;
@@ -1705,11 +1748,13 @@ static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata =
};
static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
- .name = "VIA DXS Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .count = 4,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .device = 0,
+ /* .subdevice set later */
+ .name = "PCM Playback Volume",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
@@ -1936,10 +1981,19 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
}
else /* Using DXS when PCM emulation is enabled is really weird */
{
- /* Standalone DXS controls */
- err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
- if (err < 0)
- return err;
+ for (i = 0; i < 4; ++i) {
+ struct snd_kcontrol *kctl;
+
+ kctl = snd_ctl_new1(
+ &snd_via8233_dxs_volume_control, chip);
+ if (!kctl)
+ return -ENOMEM;
+ kctl->id.subdevice = i;
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
+ return err;
+ chip->dxs_controls[i] = kctl;
+ }
}
}
/* select spdif data slot 10/11 */
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 835fa19ed46..d06f780bd7e 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
strlcpy(info.type, "keywest", I2C_NAME_SIZE);
info.addr = keywest_ctx->addr;
keywest_ctx->client = i2c_new_device(adapter, &info);
+ if (!keywest_ctx->client)
+ return -ENODEV;
+ /*
+ * We know the driver is already loaded, so the device should be
+ * already bound. If not it means binding failed, and then there
+ * is no point in keeping the device instantiated.
+ */
+ if (!keywest_ctx->client->driver) {
+ i2c_unregister_device(keywest_ctx->client);
+ keywest_ctx->client = NULL;
+ return -ENODEV;
+ }
/*
* Let i2c-core delete that device on driver removal.
@@ -86,7 +98,7 @@ static const struct i2c_device_id keywest_i2c_id[] = {
{ }
};
-struct i2c_driver keywest_driver = {
+static struct i2c_driver keywest_driver = {
.driver = {
.name = "PMac Keywest Audio",
},
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index ac927ffdc96..97f1a251e44 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -7,15 +7,6 @@ config SND_BF5XX_I2S
mode (supports single stereo In/Out).
You will also need to select the audio interfaces to support below.
-config SND_BF5XX_TDM
- tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
- depends on (BLACKFIN && SND_SOC)
- help
- Say Y or M if you want to add support for codecs attached to
- the Blackfin SPORT (synchronous serial ports) interface in TDM
- mode.
- You will also need to select the audio interfaces to support below.
-
config SND_BF5XX_SOC_SSM2602
tristate "SoC SSM2602 Audio support for BF52x ezkit"
depends on SND_BF5XX_I2S
@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE
Enter the GPIO used to control AD73311's SE pin. Acceptable
values are 0 to 7
+config SND_BF5XX_TDM
+ tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
+ depends on (BLACKFIN && SND_SOC)
+ help
+ Say Y or M if you want to add support for codecs attached to
+ the Blackfin SPORT (synchronous serial ports) interface in TDM
+ mode.
+ You will also need to select the audio interfaces to support below.
+
+config SND_BF5XX_SOC_AD1836
+ tristate "SoC AD1836 Audio support for BF5xx"
+ depends on SND_BF5XX_TDM
+ select SND_BF5XX_SOC_TDM
+ select SND_SOC_AD1836
+ help
+ Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
+
+config SND_BF5XX_SOC_AD1938
+ tristate "SoC AD1938 Audio support for Blackfin"
+ depends on SND_BF5XX_TDM
+ select SND_BF5XX_SOC_TDM
+ select SND_SOC_AD1938
+ help
+ Say Y if you want to add support for AD1938 codec on Blackfin.
+
config SND_BF5XX_AC97
tristate "SoC AC97 Audio for the ADI BF5xx chip"
depends on BLACKFIN
@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT
Say y if you want AC97 driver to support up to 5.1 channel audio.
this mode will consume much more memory for DMA.
+config SND_BF5XX_HAVE_COLD_RESET
+ bool "BOARD has COLD Reset GPIO"
+ depends on SND_BF5XX_AC97
+ default y if BFIN548_EZKIT
+ default n if !BFIN548_EZKIT
+
+config SND_BF5XX_RESET_GPIO_NUM
+ int "Set a GPIO for cold reset"
+ depends on SND_BF5XX_HAVE_COLD_RESET
+ range 0 159
+ default 19 if BFIN548_EZKIT
+ default 5 if BFIN537_STAMP
+ default 0
+ help
+ Set the correct GPIO for RESET the sound chip.
+
+config SND_BF5XX_SOC_AD1980
+ tristate "SoC AD1980/1 Audio support for BF5xx"
+ depends on SND_BF5XX_AC97
+ select SND_BF5XX_SOC_AC97
+ select SND_SOC_AD1980
+ help
+ Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
+
config SND_BF5XX_SOC_SPORT
tristate
@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97
select SND_SOC_AC97_BUS
select SND_BF5XX_SOC_SPORT
-config SND_BF5XX_SOC_AD1836
- tristate "SoC AD1836 Audio support for BF5xx"
- depends on SND_BF5XX_TDM
- select SND_BF5XX_SOC_TDM
- select SND_SOC_AD1836
- help
- Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD1980
- tristate "SoC AD1980/1 Audio support for BF5xx"
- depends on SND_BF5XX_AC97
- select SND_BF5XX_SOC_AC97
- select SND_SOC_AD1980
- help
- Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD1938
- tristate "SoC AD1938 Audio support for Blackfin"
- depends on SND_BF5XX_TDM
- select SND_BF5XX_SOC_TDM
- select SND_SOC_AD1938
- help
- Say Y if you want to add support for AD1938 codec on Blackfin.
-
config SND_BF5XX_SPORT_NUM
int "Set a SPORT for Sound chip"
depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM
default 0
help
Set the correct SPORT for sound chip.
-
-config SND_BF5XX_HAVE_COLD_RESET
- bool "BOARD has COLD Reset GPIO"
- depends on SND_BF5XX_AC97
- default y if BFIN548_EZKIT
- default n if !BFIN548_EZKIT
-
-config SND_BF5XX_RESET_GPIO_NUM
- int "Set a GPIO for cold reset"
- depends on SND_BF5XX_HAVE_COLD_RESET
- range 0 159
- default 19 if BFIN548_EZKIT
- default 5 if BFIN537_STAMP
- default 0
- help
- Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 2758b9017a7..e6932297873 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -277,7 +277,11 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
if (!dai->active)
return 0;
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+ ret = sport_set_multichannel(sport, 16, 0x3FF, 1);
+#else
ret = sport_set_multichannel(sport, 16, 0x1F, 1);
+#endif
if (ret) {
pr_err("SPORT is busy!\n");
return -EBUSY;
@@ -334,7 +338,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
goto sport_err;
}
/*SPORT works in TDM mode to simulate AC97 transfers*/
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+ ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
+#else
ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
+#endif
if (ret) {
pr_err("SPORT is busy!\n");
ret = -EBUSY;
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
index 3f2a911fe0c..a1f97dd809d 100644
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -1,5 +1,5 @@
/*
- * linux/sound/arm/bf5xx-ac97.h
+ * sound/soc/blackfin/bf5xx-ac97.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 876abade27e..084b68884ad 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both
- * ssm2602 using Port G and EMAC concurrently.
+ * codecs and EMAC using Port G concurrently.
*/
-#ifdef CONFIG_BF527_SPORT0_PORTF
-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
-#else
+#ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (0)
+#else
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
@@ -227,7 +227,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
return 0;
}
-static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
+static void bf5xx_i2s_remove(struct platform_device *pdev,
+ struct snd_soc_dai *dai)
{
pr_debug("%s enter\n", __func__);
peripheral_free_list(&sport_req[sport_num][0]);
@@ -236,36 +237,31 @@ static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
#ifdef CONFIG_PM
static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
{
- struct sport_device *sport =
- (struct sport_device *)dai->private_data;
pr_debug("%s : sport %d\n", __func__, dai->id);
- if (!dai->active)
- return 0;
+
if (dai->capture.active)
- sport_rx_stop(sport);
+ sport_rx_stop(sport_handle);
if (dai->playback.active)
- sport_tx_stop(sport);
+ sport_tx_stop(sport_handle);
return 0;
}
static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
{
int ret;
- struct sport_device *sport =
- (struct sport_device *)dai->private_data;
pr_debug("%s : sport %d\n", __func__, dai->id);
- if (!dai->active)
- return 0;
- ret = sport_config_rx(sport, RFSR | RCKFE, RSFSE|0x1f, 0, 0);
+ ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
+ bf5xx_i2s.rcr2, 0, 0);
if (ret) {
pr_err("SPORT is busy!\n");
return -EBUSY;
}
- ret = sport_config_tx(sport, TFSR | TCKFE, TSFSE|0x1f, 0, 0);
+ ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1,
+ bf5xx_i2s.tcr2, 0, 0);
if (ret) {
pr_err("SPORT is busy!\n");
return -EBUSY;
diff --git a/sound/soc/blackfin/bf5xx-i2s.h b/sound/soc/blackfin/bf5xx-i2s.h
index 7107d1a0b06..264ecdcba35 100644
--- a/sound/soc/blackfin/bf5xx-i2s.h
+++ b/sound/soc/blackfin/bf5xx-i2s.h
@@ -1,5 +1,5 @@
/*
- * linux/sound/arm/bf5xx-i2s.h
+ * sound/soc/blackfin/bf5xx-i2s.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
index 469ce7fab20..99051ff0954 100644
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -326,7 +326,7 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport)
int sport_tx_start(struct sport_device *sport)
{
- unsigned flags;
+ unsigned long flags;
pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
sport->tx_run, sport->rx_run);
if (sport->tx_run)
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 3096badf09a..ff546e91a22 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both
- * ssm2602 using Port G and EMAC concurrently.
+ * codecs and EMAC using Port G concurrently.
*/
-#ifdef CONFIG_BF527_SPORT0_PORTF
-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
-#else
+#ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (0)
+#else
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 01343dc984f..c48485f2c55 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -251,8 +251,7 @@ static int __devexit ad1836_spi_remove(struct spi_device *spi)
static struct spi_driver ad1836_spi_driver = {
.driver = {
- .name = "ad1836-spi",
- .bus = &spi_bus_type,
+ .name = "ad1836",
.owner = THIS_MODULE,
},
.probe = ad1836_spi_probe,
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 9a049a1995a..34b30efc3cb 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -456,7 +456,6 @@ static int __devexit ad1938_spi_remove(struct spi_device *spi)
static struct spi_driver ad1938_spi_driver = {
.driver = {
.name = "ad1938",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = ad1938_spi_probe,
@@ -515,6 +514,7 @@ static int ad1938_register(struct ad1938_priv *ad1938)
codec->num_dai = 1;
codec->write = ad1938_write_reg;
codec->read = ad1938_read_reg_cache;
+ codec->set_bias_level = ad1938_set_bias_level;
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 3ff0373dff8..593d5b9c9f0 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -579,7 +579,7 @@ static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
+ WM8350_LEFT_INPUT_VOLUME, 14, 1, 1),
};
/* Right Input Mixer */
@@ -589,7 +589,7 @@ static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
+ WM8350_RIGHT_INPUT_VOLUME, 14, 1, 1),
};
/* Left Mic Mixer */
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d80d414cfbb..5ad677ce80d 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -595,6 +595,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Mono Capture mixer-mux */
{"Capture Right Mixer", "Stereo", "Capture Right Mux"},
+ {"Capture Left Mixer", "Stereo", "Capture Left Mux"},
{"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
{"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
{"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index da97aae475a..1ef2454c520 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -790,7 +790,7 @@ static int wm8940_register(struct wm8940_priv *wm8940,
codec->reg_cache = &wm8940->reg_cache;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
- if (ret == 0) {
+ if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index c64e55aa63b..686e5aa9720 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1027,7 +1027,7 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
- wm9081->fs);
for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
cur_val = abs((wm9081->sysclk_rate /
- clk_sys_rates[i].ratio) - wm9081->fs);;
+ clk_sys_rates[i].ratio) - wm9081->fs);
if (cur_val < best_val) {
best = i;
best_val = cur_val;
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 12a6c549ee6..4ae70704802 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -97,22 +97,19 @@ enum {
DAVINCI_MCBSP_WORD_32,
};
-static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
- .name = "I2S PCM Stereo out",
-};
-
-static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
- .name = "I2S PCM Stereo in",
-};
-
struct davinci_mcbsp_dev {
+ /*
+ * dma_params must be first because rtd->dai->cpu_dai->private_data
+ * is cast to a pointer of an array of struct davinci_pcm_dma_params in
+ * davinci_pcm_open.
+ */
+ struct davinci_pcm_dma_params dma_params[2];
void __iomem *base;
#define MOD_DSP_A 0
#define MOD_DSP_B 1
int mode;
u32 pcr;
struct clk *clk;
- struct davinci_pcm_dma_params *dma_params[2];
};
static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
toggle_clock(dev, playback);
}
-static int davinci_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
- cpu_dai->dma_data = dev->dma_params[substream->stream];
- return 0;
-}
-
#define DEFAULT_BITPERSAMPLE 16
static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct davinci_pcm_dma_params *dma_params = dai->dma_data;
struct davinci_mcbsp_dev *dev = dai->private_data;
+ struct davinci_pcm_dma_params *dma_params =
+ &dev->dma_params[substream->stream];
struct snd_interval *i = NULL;
int mcbsp_word_length;
unsigned int rcr, xcr, srgr;
@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
- .startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare,
.trigger = davinci_i2s_trigger,
@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->base = (void __iomem *)IO_ADDRESS(mem->start);
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out;
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
+ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in;
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
+ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
/* first TX, then RX */
@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO;
goto err_free_mem;
}
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start;
+ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) {
@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO;
goto err_free_mem;
}
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start;
+ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev;
ret = snd_soc_register_dai(&davinci_i2s_dai);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index eca22d7829d..5d1f98a4c97 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
printk(KERN_ERR "GBLCTL write error\n");
}
-static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct davinci_audio_dev *dev = cpu_dai->private_data;
- cpu_dai->dma_data = dev->dma_params[substream->stream];
- return 0;
-}
-
static void mcasp_start_rx(struct davinci_audio_dev *dev)
{
mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (dev->txnumevt) /* enable FIFO */
+ mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ FIFO_ENABLE);
mcasp_start_tx(dev);
- else
+ } else {
+ if (dev->rxnumevt) /* enable FIFO */
+ mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ FIFO_ENABLE);
mcasp_start_rx(dev);
-
- /* enable FIFO */
- if (dev->txnumevt)
- mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
-
- if (dev->rxnumevt)
- mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ }
}
static void mcasp_stop_rx(struct davinci_audio_dev *dev)
@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (dev->txnumevt) /* disable FIFO */
+ mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ FIFO_ENABLE);
mcasp_stop_tx(dev);
- else
+ } else {
+ if (dev->rxnumevt) /* disable FIFO */
+ mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ FIFO_ENABLE);
mcasp_stop_rx(dev);
-
- /* disable FIFO */
- if (dev->txnumevt)
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
-
- if (dev->rxnumevt)
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ }
}
static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -512,34 +504,49 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
int channel_size)
{
u32 fmt = 0;
+ u32 mask, rotate;
switch (channel_size) {
case DAVINCI_AUDIO_WORD_8:
fmt = 0x03;
+ rotate = 6;
+ mask = 0x000000ff;
break;
case DAVINCI_AUDIO_WORD_12:
fmt = 0x05;
+ rotate = 5;
+ mask = 0x00000fff;
break;
case DAVINCI_AUDIO_WORD_16:
fmt = 0x07;
+ rotate = 4;
+ mask = 0x0000ffff;
break;
case DAVINCI_AUDIO_WORD_20:
fmt = 0x09;
+ rotate = 3;
+ mask = 0x000fffff;
break;
case DAVINCI_AUDIO_WORD_24:
fmt = 0x0B;
+ rotate = 2;
+ mask = 0x00ffffff;
break;
case DAVINCI_AUDIO_WORD_28:
fmt = 0x0D;
+ rotate = 1;
+ mask = 0x0fffffff;
break;
case DAVINCI_AUDIO_WORD_32:
fmt = 0x0F;
+ rotate = 0;
+ mask = 0xffffffff;
break;
default:
@@ -550,6 +557,13 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
RXSSZ(fmt), RXSSZ(0x0F));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
TXSSZ(fmt), TXSSZ(0x0F));
+ mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate),
+ TXROT(7));
+ mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate),
+ RXROT(7));
+ mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask);
+ mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask);
+
return 0;
}
@@ -638,7 +652,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
printk(KERN_ERR "playback tdm slot %d not supported\n",
dev->tdm_slots);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF);
mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
} else {
/* bit stream is MSB first with no delay */
@@ -655,7 +668,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
printk(KERN_ERR "capture tdm slot %d not supported\n",
dev->tdm_slots);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF);
mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
}
}
@@ -700,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
{
struct davinci_audio_dev *dev = cpu_dai->private_data;
struct davinci_pcm_dma_params *dma_params =
- dev->dma_params[substream->stream];
+ &dev->dma_params[substream->stream];
int word_length;
u8 numevt;
@@ -778,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
}
static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
- .startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params,
.set_fmt = davinci_mcasp_set_dai_fmt,
@@ -829,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
struct resource *mem, *ioarea, *res;
struct snd_platform_data *pdata;
struct davinci_audio_dev *dev;
- int count = 0;
int ret = 0;
dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
- dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
- GFP_KERNEL);
- if (!dma_data) {
- ret = -ENOMEM;
- goto err_release_dev;
- }
-
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
@@ -877,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev->txnumevt = pdata->txnumevt;
dev->rxnumevt = pdata->rxnumevt;
- dma_data[count].name = "I2S PCM Stereo out";
- dma_data[count].eventq_no = pdata->eventq_no;
- dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
+ dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
+ dma_data->eventq_no = pdata->eventq_no;
+ dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
io_v2p(dev->base));
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
/* first TX, then RX */
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -890,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region;
}
- dma_data[count].channel = res->start;
- count++;
- dma_data[count].name = "I2S PCM Stereo in";
- dma_data[count].eventq_no = pdata->eventq_no;
- dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
+ dma_data->channel = res->start;
+
+ dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
+ dma_data->eventq_no = pdata->eventq_no;
+ dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
io_v2p(dev->base));
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) {
@@ -904,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region;
}
- dma_data[count].channel = res->start;
+ dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
@@ -916,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
err_release_region:
release_mem_region(mem->start, (mem->end - mem->start) + 1);
err_release_data:
- kfree(dma_data);
-err_release_dev:
kfree(dev);
return ret;
@@ -926,7 +925,6 @@ err_release_dev:
static int davinci_mcasp_remove(struct platform_device *pdev)
{
struct snd_platform_data *pdata = pdev->dev.platform_data;
- struct davinci_pcm_dma_params *dma_data;
struct davinci_audio_dev *dev;
struct resource *mem;
@@ -939,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, (mem->end - mem->start) + 1);
- dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
- kfree(dma_data);
kfree(dev);
return 0;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 554354c1cc2..9d179cc88f7 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -39,10 +39,15 @@ enum {
};
struct davinci_audio_dev {
+ /*
+ * dma_params must be first because rtd->dai->cpu_dai->private_data
+ * is cast to a pointer of an array of struct davinci_pcm_dma_params in
+ * davinci_pcm_open.
+ */
+ struct davinci_pcm_dma_params dma_params[2];
void __iomem *base;
int sample_rate;
struct clk *clk;
- struct davinci_pcm_dma_params *dma_params[2];
unsigned int codec_fmt;
/* McASP specific data */
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 2f7da49ed34..c73a915f233 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
{
struct davinci_runtime_data *prtd = substream->runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
struct edmacc_param p_ram;
int ret;
- if (!dma_data)
- return -ENODEV;
-
- prtd->params = dma_data;
-
/* Request master DMA channel */
ret = edma_alloc_channel(prtd->params->channel,
davinci_pcm_dma_irq, substream,
@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd;
int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data;
+ struct davinci_pcm_dma_params *params = &pa[substream->stream];
+ if (!params)
+ return -ENODEV;
snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
/* ensure that buffer size is a multiple of period size */
@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
return -ENOMEM;
spin_lock_init(&prtd->lock);
+ prtd->params = params;
runtime->private_data = prtd;
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 63d96253c73..8746606efc8 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -17,7 +17,6 @@
struct davinci_pcm_dma_params {
- char *name; /* stream identifier */
int channel; /* sync dma channel ID */
unsigned short acnt;
dma_addr_t dma_addr; /* device physical address for DMA */
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
index 3806ff2c0cd..ccdefe60e75 100644
--- a/sound/soc/imx/mxc-ssi.c
+++ b/sound/soc/imx/mxc-ssi.c
@@ -397,14 +397,6 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
break;
}
- /* sync */
- if (!(fmt & SND_SOC_DAIFMT_ASYNC))
- scr |= SSI_SCR_SYN;
-
- /* tdm - only for stereo atm */
- if (fmt & SND_SOC_DAIFMT_TDM)
- scr |= SSI_SCR_NET;
-
if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
SSI1_STCR = stcr;
SSI1_SRCR = srcr;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 6375b4ea525..dcb3181bb34 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701
config SND_PXA2XX_SOC_IMOTE2
tristate "SoC Audio support for IMote 2"
- depends on SND_PXA2XX_SOC && MACH_INTELMOTE2
+ depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8940
help
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 5b9ed646478..d11a6d7e384 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -351,7 +351,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
do_div(tmp, freq_out);
val = tmp;
- val = (val << 16) | 64;;
+ val = (val << 16) | 64;
ssp_write_reg(ssp, SSACDD, val);
ssacd |= (0x6 << 4);
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
index 8e79a416db5..c215d32d632 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -67,7 +67,7 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
{
int ret = 0;
#ifdef ENFORCE_RATES
- struct snd_pcm_runtime *runtime = substream->runtime;;
+ struct snd_pcm_runtime *runtime = substream->runtime;
#endif
mutex_lock(&clk_lock);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f79711b9fa5..8de6f9dec4a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -524,7 +524,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
/* connected jack or spk ? */
if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
- widget->id == snd_soc_dapm_line)
+ (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
return 1;
}
@@ -573,7 +573,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
return 1;
/* connected jack ? */
- if (widget->id == snd_soc_dapm_mic || widget->id == snd_soc_dapm_line)
+ if (widget->id == snd_soc_dapm_mic ||
+ (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
return 1;
}
diff --git a/sound/sound_core.c b/sound/sound_core.c
index bb4b88e606b..49c99818659 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Core sound module");
MODULE_AUTHOR("Alan Cox");
MODULE_LICENSE("GPL");
-static char *sound_nodename(struct device *dev)
+static char *sound_devnode(struct device *dev, mode_t *mode)
{
if (MAJOR(dev->devt) == SOUND_MAJOR)
return NULL;
@@ -50,7 +50,7 @@ static int __init init_soundcore(void)
return PTR_ERR(sound_class);
}
- sound_class->nodename = sound_nodename;
+ sound_class->devnode = sound_devnode;
return 0;
}
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 121af0644fd..86b2c3b92df 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -62,10 +62,14 @@ static void
activate_substream(struct snd_usb_caiaqdev *dev,
struct snd_pcm_substream *sub)
{
+ spin_lock(&dev->spinlock);
+
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
dev->sub_playback[sub->number] = sub;
else
dev->sub_capture[sub->number] = sub;
+
+ spin_unlock(&dev->spinlock);
}
static void
@@ -269,16 +273,22 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
{
int index = sub->number;
struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+ snd_pcm_uframes_t ptr;
+
+ spin_lock(&dev->spinlock);
if (dev->input_panic || dev->output_panic)
- return SNDRV_PCM_POS_XRUN;
+ ptr = SNDRV_PCM_POS_XRUN;
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return bytes_to_frames(sub->runtime,
+ ptr = bytes_to_frames(sub->runtime,
dev->audio_out_buf_pos[index]);
else
- return bytes_to_frames(sub->runtime,
+ ptr = bytes_to_frames(sub->runtime,
dev->audio_in_buf_pos[index]);
+
+ spin_unlock(&dev->spinlock);
+ return ptr;
}
/* operators for both playback and capture */
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 83e6c1312d4..a3f02dd9744 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -35,7 +35,7 @@
#include "input.h"
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio, version 1.3.19");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, RigKontrol3},"
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index ab5a3ac2ac4..9efcfd08d74 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -898,6 +898,11 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
* build a feature control
*/
+static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
+{
+ return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
+}
+
static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
unsigned int ctl_mask, int control,
struct usb_audio_term *iterm, int unitid)
@@ -978,13 +983,13 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
*/
if (! mapped_name && ! (state->oterm.type >> 16)) {
if ((state->oterm.type & 0xff00) == 0x0100) {
- len = strlcat(kctl->id.name, " Capture", sizeof(kctl->id.name));
+ len = append_ctl_name(kctl, " Capture");
} else {
- len = strlcat(kctl->id.name + len, " Playback", sizeof(kctl->id.name));
+ len = append_ctl_name(kctl, " Playback");
}
}
- strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume",
- sizeof(kctl->id.name));
+ append_ctl_name(kctl, control == USB_FEATURE_MUTE ?
+ " Switch" : " Volume");
if (control == USB_FEATURE_VOLUME) {
kctl->tlv.c = mixer_vol_tlv;
kctl->vd[0].access |=
@@ -1143,7 +1148,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
if (! len)
len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
- strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name));
+ append_ctl_name(kctl, " Volume");
snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1400,8 +1405,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
if (! len)
strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
}
- strlcat(kctl->id.name, " ", sizeof(kctl->id.name));
- strlcat(kctl->id.name, valinfo->suffix, sizeof(kctl->id.name));
+ append_ctl_name(kctl, " ");
+ append_ctl_name(kctl, valinfo->suffix);
snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1610,9 +1615,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
if ((state->oterm.type & 0xff00) == 0x0100)
- strlcat(kctl->id.name, " Capture Source", sizeof(kctl->id.name));
+ append_ctl_name(kctl, " Capture Source");
else
- strlcat(kctl->id.name, " Playback Source", sizeof(kctl->id.name));
+ append_ctl_name(kctl, " Playback Source");
}
snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index b54e8ca360d..00cd54c236b 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -176,7 +176,7 @@ static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
}
-static struct vm_operations_struct usb_stream_hwdep_vm_ops = {
+static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
.open = usb_stream_hwdep_vm_open,
.fault = usb_stream_hwdep_vm_fault,
.close = usb_stream_hwdep_vm_close,
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index f3d8f71265d..52e04b2f35d 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -53,7 +53,7 @@ static int snd_us428ctls_vm_fault(struct vm_area_struct *area,
return 0;
}
-static struct vm_operations_struct us428ctls_vm_ops = {
+static const struct vm_operations_struct us428ctls_vm_ops = {
.fault = snd_us428ctls_vm_fault,
};
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 117946f2deb..4b2304c2e02 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -697,7 +697,7 @@ static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_area_struct *area,
}
-static struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
+static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
.open = snd_usX2Y_hwdep_pcm_vm_open,
.close = snd_usX2Y_hwdep_pcm_vm_close,
.fault = snd_usX2Y_hwdep_pcm_vm_fault,