summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-27 10:10:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-27 10:10:51 -0700
commit09cefbb605ccb07c65f313253268a634e0dcd283 (patch)
treee7be04bdf5dca8c3e2205f44f06b8f09b99bb025 /sound
parentdc7acbb2518f250050179c8581a972df3b6a24f1 (diff)
parentcf73df1e2975ae8f88e573e5f593761339a65def (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (26 commits) ASoC: Fix power down for widgetless per-card DAPM context case ASoC: wm1250-ev1: Define "WM1250 Output" with SND_SOC_DAPM_OUTPUT ASoC: Remove duplicate linux/delay.h inclusion. ASoC: sam9g20_wm8731: use the proper SYSCKL value ASoC: wm8731: fix wm8731_check_osc() connected condition ALSA: hda - Reorganize controller quriks with bit flags ALSA: hda - Use snd_printd() in snd_hda_parse_pin_def_config() ALSA: core: remove unused variables. ALSA: HDA: Increase MAX_HDMI_PINS ALSA: PCM - Don't check DMA time-out too shortly MAINTAINERS: add FireWire audio maintainer ALSA: usb-audio: more control quirks for M-Audio FastTrack devices ALSA: usb-audio: add new quirk type QUIRK_AUDIO_STANDARD_MIXER ALSA: usb-audio: export snd_usb_feature_unit_ctl ALSA: usb-audio: rework add_control_to_empty() ALSA: usb-audio: move assignment of chip->ctrl_intf ALSA: hda - Use model=auto for Lenovo G555 ALSA: HDA: Unify HDMI hotplug handling. ALSA: hda - Force AD1988_6STACK_DIG for Asus M3N-HT Deluxe ASoC: core - remove superfluous new line. ...
Diffstat (limited to 'sound')
-rw-r--r--sound/core/control.c3
-rw-r--r--sound/core/init.c3
-rw-r--r--sound/core/oss/linear.c3
-rw-r--r--sound/core/pcm_lib.c17
-rw-r--r--sound/core/pcm_native.c21
-rw-r--r--sound/core/seq/seq_queue.c2
-rw-r--r--sound/pci/hda/hda_codec.c2
-rw-r--r--sound/pci/hda/hda_eld.c21
-rw-r--r--sound/pci/hda/hda_intel.c206
-rw-r--r--sound/pci/hda/patch_analog.c1
-rw-r--r--sound/pci/hda/patch_conexant.c42
-rw-r--r--sound/pci/hda/patch_hdmi.c123
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/codecs/wm1250-ev1.c2
-rw-r--r--sound/soc/codecs/wm8731.c2
-rw-r--r--sound/soc/codecs/wm8915.c1
-rw-r--r--sound/soc/pxa/raumfeld.c92
-rw-r--r--sound/soc/soc-core.c8
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/usb/card.c17
-rw-r--r--sound/usb/mixer.c32
-rw-r--r--sound/usb/mixer.h14
-rw-r--r--sound/usb/mixer_quirks.c70
-rw-r--r--sound/usb/quirks-table.h4
-rw-r--r--sound/usb/quirks.c18
-rw-r--r--sound/usb/usbaudio.h1
26 files changed, 425 insertions, 284 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 5d98194bcad5..f8c5be464510 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -704,13 +704,12 @@ static int snd_ctl_elem_list(struct snd_card *card,
struct snd_ctl_elem_list list;
struct snd_kcontrol *kctl;
struct snd_ctl_elem_id *dst, *id;
- unsigned int offset, space, first, jidx;
+ unsigned int offset, space, jidx;
if (copy_from_user(&list, _list, sizeof(list)))
return -EFAULT;
offset = list.offset;
space = list.space;
- first = 0;
/* try limit maximum space */
if (space > 16384)
return -ENOMEM;
diff --git a/sound/core/init.c b/sound/core/init.c
index 30ecad41403c..2c041bb36ab3 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -342,7 +342,6 @@ static const struct file_operations snd_shutdown_f_ops =
int snd_card_disconnect(struct snd_card *card)
{
struct snd_monitor_file *mfile;
- struct file *file;
int err;
if (!card)
@@ -366,8 +365,6 @@ int snd_card_disconnect(struct snd_card *card)
spin_lock(&card->files_lock);
list_for_each_entry(mfile, &card->files_list, list) {
- file = mfile->file;
-
/* it's critical part, use endless loop */
/* we have no room to fail */
mfile->disconnected_f_op = mfile->file->f_op;
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index 13b3f6f49fae..2045697f449d 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -90,11 +90,8 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
struct snd_pcm_plugin_channel *dst_channels,
snd_pcm_uframes_t frames)
{
- struct linear_priv *data;
-
if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
return -ENXIO;
- data = (struct linear_priv *)plugin->extra_data;
if (frames == 0)
return 0;
#ifdef CONFIG_SND_DEBUG
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index abfeff1611ce..f1341308beda 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1756,8 +1756,18 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
wait_queue_t wait;
int err = 0;
snd_pcm_uframes_t avail = 0;
- long tout;
-
+ long wait_time, tout;
+
+ if (runtime->no_period_wakeup)
+ wait_time = MAX_SCHEDULE_TIMEOUT;
+ else {
+ wait_time = 10;
+ if (runtime->rate) {
+ long t = runtime->period_size * 2 / runtime->rate;
+ wait_time = max(t, wait_time);
+ }
+ wait_time = msecs_to_jiffies(wait_time * 1000);
+ }
init_waitqueue_entry(&wait, current);
add_wait_queue(&runtime->tsleep, &wait);
for (;;) {
@@ -1765,9 +1775,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
err = -ERESTARTSYS;
break;
}
- set_current_state(TASK_INTERRUPTIBLE);
snd_pcm_stream_unlock_irq(substream);
- tout = schedule_timeout(msecs_to_jiffies(10000));
+ tout = schedule_timeout_interruptible(wait_time);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_SUSPENDED:
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 1a07750f3836..1c6be91dfb98 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1481,11 +1481,20 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
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);
+ if (runtime->no_period_wakeup)
+ tout = MAX_SCHEDULE_TIMEOUT;
+ else {
+ tout = 10;
+ if (runtime->rate) {
+ long t = runtime->period_size * 2 / runtime->rate;
+ tout = max(t, tout);
+ }
+ tout = msecs_to_jiffies(tout * 1000);
+ }
+ tout = schedule_timeout_interruptible(tout);
snd_power_lock(card);
down_read(&snd_pcm_link_rwsem);
snd_pcm_stream_lock_irq(substream);
@@ -1518,13 +1527,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
static int snd_pcm_drop(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
- struct snd_card *card;
int result = 0;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
- card = substream->pcm->card;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
@@ -2056,7 +2063,6 @@ static int snd_pcm_open_file(struct file *file,
{
struct snd_pcm_file *pcm_file;
struct snd_pcm_substream *substream;
- struct snd_pcm_str *str;
int err;
if (rpcm_file)
@@ -2073,7 +2079,6 @@ static int snd_pcm_open_file(struct file *file,
}
pcm_file->substream = substream;
if (substream->ref_count == 1) {
- str = substream->pstr;
substream->file = pcm_file;
substream->pcm_release = pcm_release_private;
}
@@ -3015,11 +3020,9 @@ static const struct vm_operations_struct snd_pcm_vm_ops_status =
static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
struct vm_area_struct *area)
{
- struct snd_pcm_runtime *runtime;
long size;
if (!(area->vm_flags & VM_READ))
return -EINVAL;
- runtime = substream->runtime;
size = area->vm_end - area->vm_start;
if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
return -EINVAL;
@@ -3054,11 +3057,9 @@ static const struct vm_operations_struct snd_pcm_vm_ops_control =
static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
struct vm_area_struct *area)
{
- struct snd_pcm_runtime *runtime;
long size;
if (!(area->vm_flags & VM_READ))
return -EINVAL;
- runtime = substream->runtime;
size = area->vm_end - area->vm_start;
if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)))
return -EINVAL;
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index e7a8e9e4edb2..f9077361c119 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -467,13 +467,11 @@ int snd_seq_queue_timer_open(int queueid)
int snd_seq_queue_timer_close(int queueid)
{
struct snd_seq_queue *queue;
- struct snd_seq_timer *tmr;
int result = 0;
queue = queueptr(queueid);
if (queue == NULL)
return -EINVAL;
- tmr = queue->timer;
snd_seq_timer_close(queue);
queuefree(queue);
return result;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8edd998509f7..45b4a8d70e08 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4719,7 +4719,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
snd_printd(" inputs:");
for (i = 0; i < cfg->num_inputs; i++) {
- snd_printdd(" %s=0x%x",
+ snd_printd(" %s=0x%x",
hda_get_autocfg_input_label(codec, cfg, i),
cfg->inputs[i].pin);
}
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 74b0560289c0..b05f7be9dc1b 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -312,23 +312,6 @@ out_fail:
return -EINVAL;
}
-static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
-{
- int eldv;
- int present;
-
- present = snd_hda_pin_sense(codec, nid);
- eldv = (present & AC_PINSENSE_ELDV);
- present = (present & AC_PINSENSE_PRESENCE);
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n",
- !!present, !!eldv);
-#endif
-
- return eldv && present;
-}
-
int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
{
return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
@@ -343,7 +326,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
int size;
unsigned char *buf;
- if (!hdmi_eld_valid(codec, nid))
+ if (!eld->eld_valid)
return -ENOENT;
size = snd_hdmi_get_eld_size(codec, nid);
@@ -477,6 +460,8 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry,
snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present);
snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid);
+ if (!e->eld_valid)
+ return;
snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
snd_iprintf(buffer, "connection_type\t\t%s\n",
eld_connection_type_names[e->conn_type]);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 43a036716d25..348705666f99 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -391,6 +391,7 @@ struct azx {
/* chip type specific */
int driver_type;
+ unsigned int driver_caps;
int playback_streams;
int playback_index_offset;
int capture_streams;
@@ -464,6 +465,34 @@ enum {
AZX_NUM_DRIVERS, /* keep this as last entry */
};
+/* driver quirks (capabilities) */
+/* bits 0-7 are used for indicating driver type */
+#define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */
+#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */
+#define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */
+#define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */
+#define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */
+#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */
+#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */
+#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
+#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
+#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
+#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
+#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
+
+/* quirks for ATI SB / AMD Hudson */
+#define AZX_DCAPS_PRESET_ATI_SB \
+ (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \
+ AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
+
+/* quirks for ATI/AMD HDMI */
+#define AZX_DCAPS_PRESET_ATI_HDMI \
+ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
+
+/* quirks for Nvidia */
+#define AZX_DCAPS_PRESET_NVIDIA \
+ (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI)
+
static char *driver_short_names[] __devinitdata = {
[AZX_DRIVER_ICH] = "HDA Intel",
[AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -566,7 +595,7 @@ static void azx_init_cmd_io(struct azx *chip)
/* reset the rirb hw write pointer */
azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
/* set N=1, get RIRB response interrupt for new entry */
- if (chip->driver_type == AZX_DRIVER_CTX)
+ if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
azx_writew(chip, RINTCNT, 0xc0);
else
azx_writew(chip, RINTCNT, 1);
@@ -1056,19 +1085,24 @@ static void azx_init_pci(struct azx *chip)
* codecs.
* The PCI register TCSEL is defined in the Intel manuals.
*/
- if (chip->driver_type != AZX_DRIVER_ATI &&
- chip->driver_type != AZX_DRIVER_ATIHDMI)
+ if (chip->driver_caps & AZX_DCAPS_NO_TCSEL) {
+ snd_printdd(SFX "Clearing TCSEL\n");
update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
+ }
- switch (chip->driver_type) {
- case AZX_DRIVER_ATI:
- /* For ATI SB450 azalia HD audio, we need to enable snoop */
+ /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
+ * we need to enable snoop.
+ */
+ if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
+ snd_printdd(SFX "Enabling ATI snoop\n");
update_pci_byte(chip->pci,
ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
- break;
- case AZX_DRIVER_NVIDIA:
- /* For NVIDIA HDA, enable snoop */
+ }
+
+ /* For NVIDIA HDA, enable snoop */
+ if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
+ snd_printdd(SFX "Enabling Nvidia snoop\n");
update_pci_byte(chip->pci,
NVIDIA_HDA_TRANSREG_ADDR,
0x0f, NVIDIA_HDA_ENABLE_COHBITS);
@@ -1078,9 +1112,10 @@ static void azx_init_pci(struct azx *chip)
update_pci_byte(chip->pci,
NVIDIA_HDA_OSTRM_COH,
0x01, NVIDIA_HDA_ENABLE_COHBIT);
- break;
- case AZX_DRIVER_SCH:
- case AZX_DRIVER_PCH:
+ }
+
+ /* Enable SCH/PCH snoop if needed */
+ if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) {
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1091,14 +1126,6 @@ static void azx_init_pci(struct azx *chip)
(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
? "Failed" : "OK");
}
- break;
- default:
- /* AMD Hudson needs the similar snoop, as it seems... */
- if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
- update_pci_byte(chip->pci,
- ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
- break;
}
}
@@ -1152,7 +1179,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
status = azx_readb(chip, RIRBSTS);
if (status & RIRB_INT_MASK) {
if (status & RIRB_INT_RESPONSE) {
- if (chip->driver_type == AZX_DRIVER_CTX)
+ if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)
udelay(80);
azx_update_rirb(chip);
}
@@ -1421,8 +1448,10 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
if (err < 0)
return err;
- if (chip->driver_type == AZX_DRIVER_NVIDIA)
+ if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
+ snd_printd(SFX "Enable delay in RIRB handling\n");
chip->bus->needs_damn_long_delay = 1;
+ }
codecs = 0;
max_slots = azx_max_codecs[chip->driver_type];
@@ -1457,9 +1486,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
* sequence like the pin-detection. It seems that forcing the synced
* access works around the stall. Grrr...
*/
- if (chip->pci->vendor == PCI_VENDOR_ID_AMD ||
- chip->pci->vendor == PCI_VENDOR_ID_ATI) {
- snd_printk(KERN_INFO SFX "Enable sync_write for AMD chipset\n");
+ if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
+ snd_printd(SFX "Enable sync_write for stable communication\n");
chip->bus->sync_write = 1;
chip->bus->allow_bus_reset = 1;
}
@@ -1720,7 +1748,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
stream_tag = azx_dev->stream_tag;
/* CA-IBG chips need the playback stream starting from 1 */
- if (chip->driver_type == AZX_DRIVER_CTX &&
+ if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
stream_tag > chip->capture_streams)
stream_tag -= chip->capture_streams;
return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
@@ -2365,20 +2393,14 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
}
/* Check VIA/ATI HD Audio Controller exist */
- switch (chip->driver_type) {
- case AZX_DRIVER_VIA:
- /* Use link position directly, avoid any transfer problem. */
+ if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
+ snd_printd(SFX "Using VIACOMBO position fix\n");
return POS_FIX_VIACOMBO;
- case AZX_DRIVER_ATI:
- /* ATI chipsets don't work well with position-buffer */
+ }
+ if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
+ snd_printd(SFX "Using LPIB position fix\n");
return POS_FIX_LPIB;
- case AZX_DRIVER_GENERIC:
- /* AMD chipsets also don't work with position-buffer */
- if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
- return POS_FIX_LPIB;
- break;
}
-
return POS_FIX_AUTO;
}
@@ -2460,8 +2482,8 @@ static void __devinit check_msi(struct azx *chip)
}
/* NVidia chipsets seem to cause troubles with MSI */
- if (chip->driver_type == AZX_DRIVER_NVIDIA) {
- printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n");
+ if (chip->driver_caps & AZX_DCAPS_NO_MSI) {
+ printk(KERN_INFO "hda_intel: Disabling MSI\n");
chip->msi = 0;
}
}
@@ -2471,7 +2493,7 @@ static void __devinit check_msi(struct azx *chip)
* constructor
*/
static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
- int dev, int driver_type,
+ int dev, unsigned int driver_caps,
struct azx **rchip)
{
struct azx *chip;
@@ -2499,7 +2521,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- chip->driver_type = driver_type;
+ chip->driver_caps = driver_caps;
+ chip->driver_type = driver_caps & 0xff;
check_msi(chip);
chip->dev_index = dev;
INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
@@ -2563,8 +2586,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
/* disable SB600 64bit support for safety */
- if ((chip->driver_type == AZX_DRIVER_ATI) ||
- (chip->driver_type == AZX_DRIVER_ATIHDMI)) {
+ if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
struct pci_dev *p_smbus;
p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
PCI_DEVICE_ID_ATI_SBX00_SMBUS,
@@ -2574,19 +2596,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
gcap &= ~ICH6_GCAP_64OK;
pci_dev_put(p_smbus);
}
- } else {
- /* FIXME: not sure whether this is really needed, but
- * Hudson isn't stable enough for allowing everything...
- * let's check later again.
- */
- if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
- gcap &= ~ICH6_GCAP_64OK;
}
- /* disable 64bit DMA address for Teradici */
- /* it does not work with device 6549:1200 subsys e4a2:040b */
- if (chip->driver_type == AZX_DRIVER_TERA)
+ /* disable 64bit DMA address on some devices */
+ if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
+ snd_printd(SFX "Disabling 64bit DMA\n");
gcap &= ~ICH6_GCAP_64OK;
+ }
/* allow 64bit DMA address if supported by H/W */
if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2788,38 +2804,62 @@ static void __devexit azx_remove(struct pci_dev *pci)
/* PCI IDs */
static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
/* CPT */
- { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
+ { PCI_DEVICE(0x8086, 0x1c20),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
/* PBG */
- { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH },
+ { PCI_DEVICE(0x8086, 0x1d20),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
/* Panther Point */
- { PCI_DEVICE(0x8086, 0x1e20), .driver_data = AZX_DRIVER_PCH },
+ { PCI_DEVICE(0x8086, 0x1e20),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
/* SCH */
- { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
+ { PCI_DEVICE(0x8086, 0x811b),
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
/* Generic Intel */
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff,
.driver_data = AZX_DRIVER_ICH },
- /* ATI SB 450/600 */
- { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI },
- { PCI_DEVICE(0x1002, 0x4383), .driver_data = AZX_DRIVER_ATI },
+ /* ATI SB 450/600/700/800/900 */
+ { PCI_DEVICE(0x1002, 0x437b),
+ .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
+ { PCI_DEVICE(0x1002, 0x4383),
+ .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
+ /* AMD Hudson */
+ { PCI_DEVICE(0x1022, 0x780d),
+ .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
/* ATI HDMI */
- { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa18), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa20), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa28), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa30), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa38), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa40), .driver_data = AZX_DRIVER_ATIHDMI },
- { PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI },
+ { PCI_DEVICE(0x1002, 0x793b),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x7919),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x960f),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x970f),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa00),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa08),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa10),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa18),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa20),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa28),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa30),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa38),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa40),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaa48),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
/* VIA VT8251/VT8237A */
- { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
+ { PCI_DEVICE(0x1106, 0x3288),
+ .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
/* SIS966 */
{ PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
/* ULI M5461 */
@@ -2828,9 +2868,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_NVIDIA },
+ .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA },
/* Teradici */
- { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
+ { PCI_DEVICE(0x6549, 0x1200),
+ .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
/* Creative X-Fi (CA0110-IBG) */
#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
/* the following entry conflicts with snd-ctxfi driver,
@@ -2840,10 +2881,13 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_CTX },
+ .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
+ AZX_DCAPS_RIRB_PRE_DELAY },
#else
/* this entry seems still valid -- i.e. without emu20kx chip */
- { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX },
+ { PCI_DEVICE(0x1102, 0x0009),
+ .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
+ AZX_DCAPS_RIRB_PRE_DELAY },
#endif
/* Vortex86MX */
{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
@@ -2853,11 +2897,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_GENERIC },
+ .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_GENERIC },
+ .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index f1b3875c57df..696ac2590307 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3159,6 +3159,7 @@ static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
+ SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
{}
};
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 4f37477d3c71..3e6b9a8539c2 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3098,7 +3098,9 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
+ SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
+ SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
{}
};
@@ -3433,7 +3435,9 @@ static void cx_auto_parse_output(struct hda_codec *codec)
break;
}
}
- if (spec->auto_mute && cfg->line_out_pins[0] &&
+ if (spec->auto_mute &&
+ cfg->line_out_pins[0] &&
+ cfg->line_out_type != AUTO_PIN_SPEAKER_OUT &&
cfg->line_out_pins[0] != cfg->hp_pins[0] &&
cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
for (i = 0; i < cfg->line_outs; i++) {
@@ -3481,25 +3485,32 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
- int on;
+ int on = 1;
- if (!spec->auto_mute)
- on = 0;
- else
- on = spec->hp_present | spec->line_present;
+ /* turn on HP EAPD when HP jacks are present */
+ if (spec->auto_mute)
+ on = spec->hp_present;
cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
- do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, !on);
+ /* mute speakers in auto-mode if HP or LO jacks are plugged */
+ if (spec->auto_mute)
+ on = !(spec->hp_present ||
+ (spec->detect_line && spec->line_present));
+ do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on);
/* toggle line-out mutes if needed, too */
/* if LO is a copy of either HP or Speaker, don't need to handle it */
if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
cfg->line_out_pins[0] == cfg->speaker_pins[0])
return;
- if (!spec->automute_lines || !spec->auto_mute)
- on = 0;
- else
- on = spec->hp_present;
- do_automute(codec, cfg->line_outs, cfg->line_out_pins, !on);
+ if (spec->auto_mute) {
+ /* mute LO in auto-mode when HP jack is present */
+ if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ||
+ spec->automute_lines)
+ on = !spec->hp_present;
+ else
+ on = 1;
+ }
+ do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
}
static void cx_auto_hp_automute(struct hda_codec *codec)
@@ -3696,13 +3707,14 @@ static int cx_auto_mux_enum_update(struct hda_codec *codec,
{
struct conexant_spec *spec = codec->spec;
hda_nid_t adc;
+ int changed = 1;
if (!imux->num_items)
return 0;
if (idx >= imux->num_items)
idx = imux->num_items - 1;
if (spec->cur_mux[0] == idx)
- return 0;
+ changed = 0;
adc = spec->imux_info[idx].adc;
select_input_connection(codec, spec->imux_info[idx].adc,
spec->imux_info[idx].pin);
@@ -3715,7 +3727,7 @@ static int cx_auto_mux_enum_update(struct hda_codec *codec,
spec->cur_adc_format);
}
spec->cur_mux[0] = idx;
- return 1;
+ return changed;
}
static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
@@ -3789,7 +3801,7 @@ static void cx_auto_check_auto_mic(struct hda_codec *codec)
int pset[INPUT_PIN_ATTR_NORMAL + 1];
int i;
- for (i = 0; i < INPUT_PIN_ATTR_NORMAL; i++)
+ for (i = 0; i < ARRAY_SIZE(pset); i++)
pset[i] = -1;
for (i = 0; i < spec->private_imux.num_items; i++) {
hda_nid_t pin = spec->imux_info[i].pin;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 322901873222..bd0ae697f9c4 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -48,8 +48,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
*
* The HDA correspondence of pipes/ports are converter/pin nodes.
*/
-#define MAX_HDMI_CVTS 3
-#define MAX_HDMI_PINS 3
+#define MAX_HDMI_CVTS 4
+#define MAX_HDMI_PINS 4
struct hdmi_spec {
int num_cvts;
@@ -78,10 +78,6 @@ struct hdmi_spec {
*/
struct hda_multi_out multiout;
const struct hda_pcm_stream *pcm_playback;
-