diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 13:10:51 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 13:10:51 -0400 |
| commit | 09cefbb605ccb07c65f313253268a634e0dcd283 (patch) | |
| tree | e7be04bdf5dca8c3e2205f44f06b8f09b99bb025 | |
| parent | dc7acbb2518f250050179c8581a972df3b6a24f1 (diff) | |
| parent | cf73df1e2975ae8f88e573e5f593761339a65def (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.
...
| -rw-r--r-- | MAINTAINERS | 7 | ||||
| -rw-r--r-- | sound/core/control.c | 3 | ||||
| -rw-r--r-- | sound/core/init.c | 3 | ||||
| -rw-r--r-- | sound/core/oss/linear.c | 3 | ||||
| -rw-r--r-- | sound/core/pcm_lib.c | 17 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 21 | ||||
| -rw-r--r-- | sound/core/seq/seq_queue.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_eld.c | 21 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 206 | ||||
| -rw-r--r-- | sound/pci/hda/patch_analog.c | 1 | ||||
| -rw-r--r-- | sound/pci/hda/patch_conexant.c | 42 | ||||
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 123 | ||||
| -rw-r--r-- | sound/soc/atmel/sam9g20_wm8731.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm1250-ev1.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8731.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8915.c | 1 | ||||
| -rw-r--r-- | sound/soc/pxa/raumfeld.c | 92 | ||||
| -rw-r--r-- | sound/soc/soc-core.c | 8 | ||||
| -rw-r--r-- | sound/soc/soc-dapm.c | 2 | ||||
| -rw-r--r-- | sound/usb/card.c | 17 | ||||
| -rw-r--r-- | sound/usb/mixer.c | 32 | ||||
| -rw-r--r-- | sound/usb/mixer.h | 14 | ||||
| -rw-r--r-- | sound/usb/mixer_quirks.c | 70 | ||||
| -rw-r--r-- | sound/usb/quirks-table.h | 4 | ||||
| -rw-r--r-- | sound/usb/quirks.c | 18 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 1 |
27 files changed, 432 insertions, 284 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c4fc1daddcb6..572b5b20ba48 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2584,6 +2584,13 @@ S: Maintained | |||
| 2584 | F: drivers/hwmon/f75375s.c | 2584 | F: drivers/hwmon/f75375s.c |
| 2585 | F: include/linux/f75375s.h | 2585 | F: include/linux/f75375s.h |
| 2586 | 2586 | ||
| 2587 | FIREWIRE AUDIO DRIVERS | ||
| 2588 | M: Clemens Ladisch <clemens@ladisch.de> | ||
| 2589 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | ||
| 2590 | T: git git://git.alsa-project.org/alsa-kernel.git | ||
| 2591 | S: Maintained | ||
| 2592 | F: sound/firewire/ | ||
| 2593 | |||
| 2587 | FIREWIRE SUBSYSTEM | 2594 | FIREWIRE SUBSYSTEM |
| 2588 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> | 2595 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> |
| 2589 | L: linux1394-devel@lists.sourceforge.net | 2596 | L: linux1394-devel@lists.sourceforge.net |
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, | |||
| 704 | struct snd_ctl_elem_list list; | 704 | struct snd_ctl_elem_list list; |
| 705 | struct snd_kcontrol *kctl; | 705 | struct snd_kcontrol *kctl; |
| 706 | struct snd_ctl_elem_id *dst, *id; | 706 | struct snd_ctl_elem_id *dst, *id; |
| 707 | unsigned int offset, space, first, jidx; | 707 | unsigned int offset, space, jidx; |
| 708 | 708 | ||
| 709 | if (copy_from_user(&list, _list, sizeof(list))) | 709 | if (copy_from_user(&list, _list, sizeof(list))) |
| 710 | return -EFAULT; | 710 | return -EFAULT; |
| 711 | offset = list.offset; | 711 | offset = list.offset; |
| 712 | space = list.space; | 712 | space = list.space; |
| 713 | first = 0; | ||
| 714 | /* try limit maximum space */ | 713 | /* try limit maximum space */ |
| 715 | if (space > 16384) | 714 | if (space > 16384) |
| 716 | return -ENOMEM; | 715 | 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 = | |||
| 342 | int snd_card_disconnect(struct snd_card *card) | 342 | int snd_card_disconnect(struct snd_card *card) |
| 343 | { | 343 | { |
| 344 | struct snd_monitor_file *mfile; | 344 | struct snd_monitor_file *mfile; |
| 345 | struct file *file; | ||
| 346 | int err; | 345 | int err; |
| 347 | 346 | ||
| 348 | if (!card) | 347 | if (!card) |
| @@ -366,8 +365,6 @@ int snd_card_disconnect(struct snd_card *card) | |||
| 366 | 365 | ||
| 367 | spin_lock(&card->files_lock); | 366 | spin_lock(&card->files_lock); |
| 368 | list_for_each_entry(mfile, &card->files_list, list) { | 367 | list_for_each_entry(mfile, &card->files_list, list) { |
| 369 | file = mfile->file; | ||
| 370 | |||
| 371 | /* it's critical part, use endless loop */ | 368 | /* it's critical part, use endless loop */ |
| 372 | /* we have no room to fail */ | 369 | /* we have no room to fail */ |
| 373 | mfile->disconnected_f_op = mfile->file->f_op; | 370 | 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, | |||
| 90 | struct snd_pcm_plugin_channel *dst_channels, | 90 | struct snd_pcm_plugin_channel *dst_channels, |
| 91 | snd_pcm_uframes_t frames) | 91 | snd_pcm_uframes_t frames) |
| 92 | { | 92 | { |
| 93 | struct linear_priv *data; | ||
| 94 | |||
| 95 | if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) | 93 | if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) |
| 96 | return -ENXIO; | 94 | return -ENXIO; |
| 97 | data = (struct linear_priv *)plugin->extra_data; | ||
| 98 | if (frames == 0) | 95 | if (frames == 0) |
| 99 | return 0; | 96 | return 0; |
| 100 | #ifdef CONFIG_SND_DEBUG | 97 | #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, | |||
| 1756 | wait_queue_t wait; | 1756 | wait_queue_t wait; |
| 1757 | int err = 0; | 1757 | int err = 0; |
| 1758 | snd_pcm_uframes_t avail = 0; | 1758 | snd_pcm_uframes_t avail = 0; |
| 1759 | long tout; | 1759 | long wait_time, tout; |
| 1760 | 1760 | ||
| 1761 | if (runtime->no_period_wakeup) | ||
| 1762 | wait_time = MAX_SCHEDULE_TIMEOUT; | ||
| 1763 | else { | ||
| 1764 | wait_time = 10; | ||
| 1765 | if (runtime->rate) { | ||
| 1766 | long t = runtime->period_size * 2 / runtime->rate; | ||
| 1767 | wait_time = max(t, wait_time); | ||
| 1768 | } | ||
| 1769 | wait_time = msecs_to_jiffies(wait_time * 1000); | ||
| 1770 | } | ||
| 1761 | init_waitqueue_entry(&wait, current); | 1771 | init_waitqueue_entry(&wait, current); |
| 1762 | add_wait_queue(&runtime->tsleep, &wait); | 1772 | add_wait_queue(&runtime->tsleep, &wait); |
| 1763 | for (;;) { | 1773 | for (;;) { |
| @@ -1765,9 +1775,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream, | |||
| 1765 | err = -ERESTARTSYS; | 1775 | err = -ERESTARTSYS; |
| 1766 | break; | 1776 | break; |
| 1767 | } | 1777 | } |
| 1768 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1769 | snd_pcm_stream_unlock_irq(substream); | 1778 | snd_pcm_stream_unlock_irq(substream); |
| 1770 | tout = schedule_timeout(msecs_to_jiffies(10000)); | 1779 | tout = schedule_timeout_interruptible(wait_time); |
| 1771 | snd_pcm_stream_lock_irq(substream); | 1780 | snd_pcm_stream_lock_irq(substream); |
| 1772 | switch (runtime->status->state) { | 1781 | switch (runtime->status->state) { |
| 1773 | case SNDRV_PCM_STATE_SUSPENDED: | 1782 | 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, | |||
| 1481 | break; /* all drained */ | 1481 | break; /* all drained */ |
| 1482 | init_waitqueue_entry(&wait, current); | 1482 | init_waitqueue_entry(&wait, current); |
| 1483 | add_wait_queue(&to_check->sleep, &wait); | 1483 | add_wait_queue(&to_check->sleep, &wait); |
| 1484 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1485 | snd_pcm_stream_unlock_irq(substream); | 1484 | snd_pcm_stream_unlock_irq(substream); |
| 1486 | up_read(&snd_pcm_link_rwsem); | 1485 | up_read(&snd_pcm_link_rwsem); |
| 1487 | snd_power_unlock(card); | 1486 | snd_power_unlock(card); |
| 1488 | tout = schedule_timeout(10 * HZ); | 1487 | if (runtime->no_period_wakeup) |
| 1488 | tout = MAX_SCHEDULE_TIMEOUT; | ||
| 1489 | else { | ||
| 1490 | tout = 10; | ||
| 1491 | if (runtime->rate) { | ||
| 1492 | long t = runtime->period_size * 2 / runtime->rate; | ||
| 1493 | tout = max(t, tout); | ||
| 1494 | } | ||
| 1495 | tout = msecs_to_jiffies(tout * 1000); | ||
| 1496 | } | ||
| 1497 | tout = schedule_timeout_interruptible(tout); | ||
| 1489 | snd_power_lock(card); | 1498 | snd_power_lock(card); |
| 1490 | down_read(&snd_pcm_link_rwsem); | 1499 | down_read(&snd_pcm_link_rwsem); |
| 1491 | snd_pcm_stream_lock_irq(substream); | 1500 | snd_pcm_stream_lock_irq(substream); |
| @@ -1518,13 +1527,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, | |||
| 1518 | static int snd_pcm_drop(struct snd_pcm_substream *substream) | 1527 | static int snd_pcm_drop(struct snd_pcm_substream *substream) |
| 1519 | { | 1528 | { |
| 1520 | struct snd_pcm_runtime *runtime; | 1529 | struct snd_pcm_runtime *runtime; |
| 1521 | struct snd_card *card; | ||
| 1522 | int result = 0; | 1530 | int result = 0; |
| 1523 | 1531 | ||
| 1524 | if (PCM_RUNTIME_CHECK(substream)) | 1532 | if (PCM_RUNTIME_CHECK(substream)) |
| 1525 | return -ENXIO; | 1533 | return -ENXIO; |
| 1526 | runtime = substream->runtime; | 1534 | runtime = substream->runtime; |
| 1527 | card = substream->pcm->card; | ||
| 1528 | 1535 | ||
| 1529 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN || | 1536 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN || |
| 1530 | runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED || | 1537 | runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED || |
| @@ -2056,7 +2063,6 @@ static int snd_pcm_open_file(struct file *file, | |||
| 2056 | { | 2063 | { |
| 2057 | struct snd_pcm_file *pcm_file; | 2064 | struct snd_pcm_file *pcm_file; |
| 2058 | struct snd_pcm_substream *substream; | 2065 | struct snd_pcm_substream *substream; |
| 2059 | struct snd_pcm_str *str; | ||
| 2060 | int err; | 2066 | int err; |
| 2061 | 2067 | ||
| 2062 | if (rpcm_file) | 2068 | if (rpcm_file) |
| @@ -2073,7 +2079,6 @@ static int snd_pcm_open_file(struct file *file, | |||
| 2073 | } | 2079 | } |
| 2074 | pcm_file->substream = substream; | 2080 | pcm_file->substream = substream; |
| 2075 | if (substream->ref_count == 1) { | 2081 | if (substream->ref_count == 1) { |
| 2076 | str = substream->pstr; | ||
| 2077 | substream->file = pcm_file; | 2082 | substream->file = pcm_file; |
| 2078 | substream->pcm_release = pcm_release_private; | 2083 | substream->pcm_release = pcm_release_private; |
| 2079 | } | 2084 | } |
| @@ -3015,11 +3020,9 @@ static const struct vm_operations_struct snd_pcm_vm_ops_status = | |||
| 3015 | static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, | 3020 | static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, |
| 3016 | struct vm_area_struct *area) | 3021 | struct vm_area_struct *area) |
| 3017 | { | 3022 | { |
| 3018 | struct snd_pcm_runtime *runtime; | ||
| 3019 | long size; | 3023 | long size; |
| 3020 | if (!(area->vm_flags & VM_READ)) | 3024 | if (!(area->vm_flags & VM_READ)) |
| 3021 | return -EINVAL; | 3025 | return -EINVAL; |
| 3022 | runtime = substream->runtime; | ||
| 3023 | size = area->vm_end - area->vm_start; | 3026 | size = area->vm_end - area->vm_start; |
| 3024 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) | 3027 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) |
| 3025 | return -EINVAL; | 3028 | return -EINVAL; |
| @@ -3054,11 +3057,9 @@ static const struct vm_operations_struct snd_pcm_vm_ops_control = | |||
| 3054 | static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, | 3057 | static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, |
| 3055 | struct vm_area_struct *area) | 3058 | struct vm_area_struct *area) |
| 3056 | { | 3059 | { |
| 3057 | struct snd_pcm_runtime *runtime; | ||
| 3058 | long size; | 3060 | long size; |
| 3059 | if (!(area->vm_flags & VM_READ)) | 3061 | if (!(area->vm_flags & VM_READ)) |
| 3060 | return -EINVAL; | 3062 | return -EINVAL; |
| 3061 | runtime = substream->runtime; | ||
| 3062 | size = area->vm_end - area->vm_start; | 3063 | size = area->vm_end - area->vm_start; |
| 3063 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) | 3064 | if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) |
| 3064 | return -EINVAL; | 3065 | 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) | |||
| 467 | int snd_seq_queue_timer_close(int queueid) | 467 | int snd_seq_queue_timer_close(int queueid) |
| 468 | { | 468 | { |
| 469 | struct snd_seq_queue *queue; | 469 | struct snd_seq_queue *queue; |
| 470 | struct snd_seq_timer *tmr; | ||
| 471 | int result = 0; | 470 | int result = 0; |
| 472 | 471 | ||
| 473 | queue = queueptr(queueid); | 472 | queue = queueptr(queueid); |
| 474 | if (queue == NULL) | 473 | if (queue == NULL) |
| 475 | return -EINVAL; | 474 | return -EINVAL; |
| 476 | tmr = queue->timer; | ||
| 477 | snd_seq_timer_close(queue); | 475 | snd_seq_timer_close(queue); |
| 478 | queuefree(queue); | 476 | queuefree(queue); |
| 479 | return result; | 477 | 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, | |||
| 4719 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | 4719 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); |
| 4720 | snd_printd(" inputs:"); | 4720 | snd_printd(" inputs:"); |
| 4721 | for (i = 0; i < cfg->num_inputs; i++) { | 4721 | for (i = 0; i < cfg->num_inputs; i++) { |
| 4722 | snd_printdd(" %s=0x%x", | 4722 | snd_printd(" %s=0x%x", |
| 4723 | hda_get_autocfg_input_label(codec, cfg, i), | 4723 | hda_get_autocfg_input_label(codec, cfg, i), |
| 4724 | cfg->inputs[i].pin); | 4724 | cfg->inputs[i].pin); |
| 4725 | } | 4725 | } |
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: | |||
| 312 | return -EINVAL; | 312 | return -EINVAL; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) | ||
| 316 | { | ||
| 317 | int eldv; | ||
| 318 | int present; | ||
| 319 | |||
| 320 | present = snd_hda_pin_sense(codec, nid); | ||
| 321 | eldv = (present & AC_PINSENSE_ELDV); | ||
| 322 | present = (present & AC_PINSENSE_PRESENCE); | ||
| 323 | |||
| 324 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
| 325 | printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n", | ||
| 326 | !!present, !!eldv); | ||
| 327 | #endif | ||
| 328 | |||
| 329 | return eldv && present; | ||
| 330 | } | ||
| 331 | |||
| 332 | int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) | 315 | int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) |
| 333 | { | 316 | { |
| 334 | return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, | 317 | 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, | |||
| 343 | int size; | 326 | int size; |
| 344 | unsigned char *buf; | 327 | unsigned char *buf; |
| 345 | 328 | ||
| 346 | if (!hdmi_eld_valid(codec, nid)) | 329 | if (!eld->eld_valid) |
| 347 | return -ENOENT; | 330 | return -ENOENT; |
| 348 | 331 | ||
| 349 | size = snd_hdmi_get_eld_size(codec, nid); | 332 | size = snd_hdmi_get_eld_size(codec, nid); |
| @@ -477,6 +460,8 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry, | |||
| 477 | 460 | ||
| 478 | snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present); | 461 | snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present); |
| 479 | snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid); | 462 | snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid); |
| 463 | if (!e->eld_valid) | ||
| 464 | return; | ||
| 480 | snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); | 465 | snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); |
| 481 | snd_iprintf(buffer, "connection_type\t\t%s\n", | 466 | snd_iprintf(buffer, "connection_type\t\t%s\n", |
| 482 | eld_connection_type_names[e->conn_type]); | 467 | 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 { | |||
| 391 | 391 | ||
| 392 | /* chip type specific */ | 392 | /* chip type specific */ |
| 393 | int driver_type; | 393 | int driver_type; |
| 394 | unsigned int driver_caps; | ||
| 394 | int playback_streams; | 395 | int playback_streams; |
| 395 | int playback_index_offset; | 396 | int playback_index_offset; |
| 396 | int capture_streams; | 397 | int capture_streams; |
| @@ -464,6 +465,34 @@ enum { | |||
| 464 | AZX_NUM_DRIVERS, /* keep this as last entry */ | 465 | AZX_NUM_DRIVERS, /* keep this as last entry */ |
| 465 | }; | 466 | }; |
| 466 | 467 | ||
| 468 | /* driver quirks (capabilities) */ | ||
| 469 | /* bits 0-7 are used for indicating driver type */ | ||
| 470 | #define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */ | ||
| 471 | #define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ | ||
| 472 | #define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */ | ||
| 473 | #define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */ | ||
| 474 | #define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */ | ||
| 475 | #define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ | ||
| 476 | #define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ | ||
| 477 | #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ | ||
| 478 | #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ | ||
| 479 | #define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ | ||
| 480 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ | ||
| 481 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | ||
| 482 | |||
| 483 | /* quirks for ATI SB / AMD Hudson */ | ||
| 484 | #define AZX_DCAPS_PRESET_ATI_SB \ | ||
| 485 | (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \ | ||
| 486 | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB) | ||
| 487 | |||
| 488 | /* quirks for ATI/AMD HDMI */ | ||
| 489 | #define AZX_DCAPS_PRESET_ATI_HDMI \ | ||
| 490 | (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB) | ||
| 491 | |||
| 492 | /* quirks for Nvidia */ | ||
| 493 | #define AZX_DCAPS_PRESET_NVIDIA \ | ||
| 494 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) | ||
| 495 | |||
| 467 | static char *driver_short_names[] __devinitdata = { | 496 | static char *driver_short_names[] __devinitdata = { |
| 468 | [AZX_DRIVER_ICH] = "HDA Intel", | 497 | [AZX_DRIVER_ICH] = "HDA Intel", |
| 469 | [AZX_DRIVER_PCH] = "HDA Intel PCH", | 498 | [AZX_DRIVER_PCH] = "HDA Intel PCH", |
| @@ -566,7 +595,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
| 566 | /* reset the rirb hw write pointer */ | 595 | /* reset the rirb hw write pointer */ |
| 567 | azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); | 596 | azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); |
| 568 | /* set N=1, get RIRB response interrupt for new entry */ | 597 | /* set N=1, get RIRB response interrupt for new entry */ |
| 569 | if (chip->driver_type == AZX_DRIVER_CTX) | 598 | if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) |
| 570 | azx_writew(chip, RINTCNT, 0xc0); | 599 | azx_writew(chip, RINTCNT, 0xc0); |
| 571 | else | 600 | else |
| 572 | azx_writew(chip, RINTCNT, 1); | 601 | azx_writew(chip, RINTCNT, 1); |
| @@ -1056,19 +1085,24 @@ static void azx_init_pci(struct azx *chip) | |||
| 1056 | * codecs. | 1085 | * codecs. |
| 1057 | * The PCI register TCSEL is defined in the Intel manuals. | 1086 | * The PCI register TCSEL is defined in the Intel manuals. |
| 1058 | */ | 1087 | */ |
| 1059 | if (chip->driver_type != AZX_DRIVER_ATI && | 1088 | if (chip->driver_caps & AZX_DCAPS_NO_TCSEL) { |
| 1060 | chip->driver_type != AZX_DRIVER_ATIHDMI) | 1089 | snd_printdd(SFX "Clearing TCSEL\n"); |
| 1061 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); | 1090 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); |
| 1091 | } | ||
| 1062 | 1092 | ||
| 1063 | switch (chip->driver_type) { | 1093 | /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, |
| 1064 | case AZX_DRIVER_ATI: | 1094 | * we need to enable snoop. |
| 1065 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ | 1095 | */ |
| 1096 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { | ||
| 1097 | snd_printdd(SFX "Enabling ATI snoop\n"); | ||
| 1066 | update_pci_byte(chip->pci, | 1098 | update_pci_byte(chip->pci, |
| 1067 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 1099 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, |
| 1068 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); | 1100 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); |
| 1069 | break; | 1101 | } |
| 1070 | case AZX_DRIVER_NVIDIA: | 1102 | |
| 1071 | /* For NVIDIA HDA, enable snoop */ | 1103 | /* For NVIDIA HDA, enable snoop */ |
| 1104 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { | ||
| 1105 | snd_printdd(SFX "Enabling Nvidia snoop\n"); | ||
| 1072 | update_pci_byte(chip->pci, | 1106 | update_pci_byte(chip->pci, |
| 1073 | NVIDIA_HDA_TRANSREG_ADDR, | 1107 | NVIDIA_HDA_TRANSREG_ADDR, |
| 1074 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); | 1108 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); |
| @@ -1078,9 +1112,10 @@ static void azx_init_pci(struct azx *chip) | |||
| 1078 | update_pci_byte(chip->pci, | 1112 | update_pci_byte(chip->pci, |
| 1079 | NVIDIA_HDA_OSTRM_COH, | 1113 | NVIDIA_HDA_OSTRM_COH, |
| 1080 | 0x01, NVIDIA_HDA_ENABLE_COHBIT); | 1114 | 0x01, NVIDIA_HDA_ENABLE_COHBIT); |
| 1081 | break; | 1115 | } |
| 1082 | case AZX_DRIVER_SCH: | 1116 | |
| 1083 | case AZX_DRIVER_PCH: | 1117 | /* Enable SCH/PCH snoop if needed */ |
| 1118 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { | ||
| 1084 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 1119 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
| 1085 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 1120 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { |
| 1086 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, | 1121 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, |
| @@ -1091,14 +1126,6 @@ static void azx_init_pci(struct azx *chip) | |||
| 1091 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | 1126 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) |
| 1092 | ? "Failed" : "OK"); | 1127 | ? "Failed" : "OK"); |
| 1093 | } | 1128 | } |
| 1094 | break; | ||
| 1095 | default: | ||
| 1096 | /* AMD Hudson needs the similar snoop, as it seems... */ | ||
| 1097 | if (chip->pci->vendor == PCI_VENDOR_ID_AMD) | ||
| 1098 | update_pci_byte(chip->pci, | ||
| 1099 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | ||
| 1100 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); | ||
| 1101 | break; | ||
| 1102 | } | 1129 | } |
| 1103 | } | 1130 | } |
| 1104 | 1131 | ||
| @@ -1152,7 +1179,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
| 1152 | status = azx_readb(chip, RIRBSTS); | 1179 | status = azx_readb(chip, RIRBSTS); |
| 1153 | if (status & RIRB_INT_MASK) { | 1180 | if (status & RIRB_INT_MASK) { |
| 1154 | if (status & RIRB_INT_RESPONSE) { | 1181 | if (status & RIRB_INT_RESPONSE) { |
| 1155 | if (chip->driver_type == AZX_DRIVER_CTX) | 1182 | if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) |
| 1156 | udelay(80); | 1183 | udelay(80); |
| 1157 | azx_update_rirb(chip); | 1184 | azx_update_rirb(chip); |
| 1158 | } | 1185 | } |
| @@ -1421,8 +1448,10 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
| 1421 | if (err < 0) | 1448 | if (err < 0) |
| 1422 | return err; | 1449 | return err; |
| 1423 | 1450 | ||
| 1424 | if (chip->driver_type == AZX_DRIVER_NVIDIA) | 1451 | if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { |
| 1452 | snd_printd(SFX "Enable delay in RIRB handling\n"); | ||
| 1425 | chip->bus->needs_damn_long_delay = 1; | 1453 | chip->bus->needs_damn_long_delay = 1; |
| 1454 | } | ||
| 1426 | 1455 | ||
| 1427 | codecs = 0; | 1456 | codecs = 0; |
| 1428 | max_slots = azx_max_codecs[chip->driver_type]; | 1457 | max_slots = azx_max_codecs[chip->driver_type]; |
| @@ -1457,9 +1486,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
| 1457 | * sequence like the pin-detection. It seems that forcing the synced | 1486 | * sequence like the pin-detection. It seems that forcing the synced |
| 1458 | * access works around the stall. Grrr... | 1487 | * access works around the stall. Grrr... |
| 1459 | */ | 1488 | */ |
| 1460 | if (chip->pci->vendor == PCI_VENDOR_ID_AMD || | 1489 | if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) { |
| 1461 | chip->pci->vendor == PCI_VENDOR_ID_ATI) { | 1490 | snd_printd(SFX "Enable sync_write for stable communication\n"); |
| 1462 | snd_printk(KERN_INFO SFX "Enable sync_write for AMD chipset\n"); | ||
| 1463 | chip->bus->sync_write = 1; | 1491 | chip->bus->sync_write = 1; |
| 1464 | chip->bus->allow_bus_reset = 1; | 1492 | chip->bus->allow_bus_reset = 1; |
| 1465 | } | 1493 | } |
| @@ -1720,7 +1748,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
| 1720 | 1748 | ||
| 1721 | stream_tag = azx_dev->stream_tag; | 1749 | stream_tag = azx_dev->stream_tag; |
| 1722 | /* CA-IBG chips need the playback stream starting from 1 */ | 1750 | /* CA-IBG chips need the playback stream starting from 1 */ |
| 1723 | if (chip->driver_type == AZX_DRIVER_CTX && | 1751 | if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) && |
| 1724 | stream_tag > chip->capture_streams) | 1752 | stream_tag > chip->capture_streams) |
| 1725 | stream_tag -= chip->capture_streams; | 1753 | stream_tag -= chip->capture_streams; |
| 1726 | return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag, | 1754 | 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) | |||
| 2365 | } | 2393 | } |
| 2366 | 2394 | ||
| 2367 | /* Check VIA/ATI HD Audio Controller exist */ | 2395 | /* Check VIA/ATI HD Audio Controller exist */ |
| 2368 | switch (chip->driver_type) { | 2396 | if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) { |
| 2369 | case AZX_DRIVER_VIA: | 2397 | snd_printd(SFX "Using VIACOMBO position fix\n"); |
| 2370 | /* Use link position directly, avoid any transfer problem. */ | ||
| 2371 | return POS_FIX_VIACOMBO; | 2398 | return POS_FIX_VIACOMBO; |
| 2372 | case AZX_DRIVER_ATI: | 2399 | } |
| 2373 | /* ATI chipsets don't work well with position-buffer */ | 2400 | if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) { |
| 2401 | snd_printd(SFX "Using LPIB position fix\n"); | ||
| 2374 | return POS_FIX_LPIB; | 2402 | return POS_FIX_LPIB; |
| 2375 | case AZX_DRIVER_GENERIC: | ||
| 2376 | /* AMD chipsets also don't work with position-buffer */ | ||
| 2377 | if (chip->pci->vendor == PCI_VENDOR_ID_AMD) | ||
| 2378 | return POS_FIX_LPIB; | ||
| 2379 | break; | ||
| 2380 | } | 2403 | } |
| 2381 | |||
| 2382 | return POS_FIX_AUTO; | 2404 | return POS_FIX_AUTO; |
| 2383 | } | 2405 | } |
| 2384 | 2406 | ||
| @@ -2460,8 +2482,8 @@ static void __devinit check_msi(struct azx *chip) | |||
| 2460 | } | 2482 | } |
| 2461 | 2483 | ||
| 2462 | /* NVidia chipsets seem to cause troubles with MSI */ | 2484 | /* NVidia chipsets seem to cause troubles with MSI */ |
| 2463 | if (chip->driver_type == AZX_DRIVER_NVIDIA) { | 2485 | if (chip->driver_caps & AZX_DCAPS_NO_MSI) { |
| 2464 | printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n"); | 2486 | printk(KERN_INFO "hda_intel: Disabling MSI\n"); |
| 2465 | chip->msi = 0; | 2487 | chip->msi = 0; |
| 2466 | } | 2488 | } |
| 2467 | } | 2489 | } |
| @@ -2471,7 +2493,7 @@ static void __devinit check_msi(struct azx *chip) | |||
| 2471 | * constructor | 2493 | * constructor |
| 2472 | */ | 2494 | */ |
| 2473 | static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | 2495 | static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, |
| 2474 | int dev, int driver_type, | 2496 | int dev, unsigned int driver_caps, |
| 2475 | struct azx **rchip) | 2497 | struct azx **rchip) |
| 2476 | { | 2498 | { |
| 2477 | struct azx *chip; | 2499 | struct azx *chip; |
| @@ -2499,7 +2521,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 2499 | chip->card = card; | 2521 | chip->card = card; |
| 2500 | chip->pci = pci; | 2522 | chip->pci = pci; |
| 2501 | chip->irq = -1; | 2523 | chip->irq = -1; |
| 2502 | chip->driver_type = driver_type; | 2524 | chip->driver_caps = driver_caps; |
| 2525 | chip->driver_type = driver_caps & 0xff; | ||
| 2503 | check_msi(chip); | 2526 | check_msi(chip); |
| 2504 | chip->dev_index = dev; | 2527 | chip->dev_index = dev; |
| 2505 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); | 2528 | 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, | |||
| 2563 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); | 2586 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); |
| 2564 | 2587 | ||
| 2565 | /* disable SB600 64bit support for safety */ | 2588 | /* disable SB600 64bit support for safety */ |
| 2566 | if ((chip->driver_type == AZX_DRIVER_ATI) || | 2589 | if (chip->pci->vendor == PCI_VENDOR_ID_ATI) { |
| 2567 | (chip->driver_type == AZX_DRIVER_ATIHDMI)) { | ||
| 2568 | struct pci_dev *p_smbus; | 2590 | struct pci_dev *p_smbus; |
| 2569 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, | 2591 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, |
| 2570 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, | 2592 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, |
| @@ -2574,19 +2596,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 2574 | gcap &= ~ICH6_GCAP_64OK; | 2596 | gcap &= ~ICH6_GCAP_64OK; |
| 2575 | pci_dev_put(p_smbus); | 2597 | pci_dev_put(p_smbus); |
| 2576 | } | 2598 | } |
| 2577 | } else { | ||
| 2578 | /* FIXME: not sure whether this is really needed, but | ||
| 2579 | * Hudson isn't stable enough for allowing everything... | ||
| 2580 | * let's check later again. | ||
| 2581 | */ | ||
| 2582 | if (chip->pci->vendor == PCI_VENDOR_ID_AMD) | ||
| 2583 | gcap &= ~ICH6_GCAP_64OK; | ||
| 2584 | } | 2599 | } |
| 2585 | 2600 | ||
| 2586 | /* disable 64bit DMA address for Teradici */ | 2601 | /* disable 64bit DMA address on some devices */ |
| 2587 | /* it does not work with device 6549:1200 subsys e4a2:040b */ | 2602 | if (chip->driver_caps & AZX_DCAPS_NO_64BIT) { |
| 2588 | if (chip->driver_type == AZX_DRIVER_TERA) | 2603 | snd_printd(SFX "Disabling 64bit DMA\n"); |
| 2589 | gcap &= ~ICH6_GCAP_64OK; | 2604 | gcap &= ~ICH6_GCAP_64OK; |
| 2605 | } | ||
| 2590 | 2606 | ||
| 2591 | /* allow 64bit DMA address if supported by H/W */ | 2607 | /* allow 64bit DMA address if supported by H/W */ |
| 2592 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2608 | 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) | |||
| 2788 | /* PCI IDs */ | 2804 | /* PCI IDs */ |
| 2789 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | 2805 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { |
| 2790 | /* CPT */ | 2806 | /* CPT */ |
| 2791 | { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, | 2807 | { PCI_DEVICE(0x8086, 0x1c20), |
| 2808 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | ||
| 2792 | /* PBG */ | 2809 | /* PBG */ |
| 2793 | { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, | 2810 | { PCI_DEVICE(0x8086, 0x1d20), |
| 2811 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | ||
| 2794 | /* Panther Point */ | 2812 | /* Panther Point */ |
| 2795 | { PCI_DEVICE(0x8086, 0x1e20), .driver_data = AZX_DRIVER_PCH }, | 2813 | { PCI_DEVICE(0x8086, 0x1e20), |
| 2814 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | ||
| 2796 | /* SCH */ | 2815 | /* SCH */ |
| 2797 | { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, | 2816 | { PCI_DEVICE(0x8086, 0x811b), |
| 2817 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, | ||
| 2798 | /* Generic Intel */ | 2818 | /* Generic Intel */ |
| 2799 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), | 2819 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), |
| 2800 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2820 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 2801 | .class_mask = 0xffffff, | 2821 | .class_mask = 0xffffff, |
| 2802 | .driver_data = AZX_DRIVER_ICH }, | 2822 | .driver_data = AZX_DRIVER_ICH }, |
| 2803 | /* ATI SB 450/600 */ | 2823 | /* ATI SB 450/600/700/800/900 */ |
| 2804 | { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI }, | 2824 | { PCI_DEVICE(0x1002, 0x437b), |
| 2805 | { PCI_DEVICE(0x1002, 0x4383), .driver_data = AZX_DRIVER_ATI }, | 2825 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, |
| 2826 | { PCI_DEVICE(0x1002, 0x4383), | ||
| 2827 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, | ||
| 2828 | /* AMD Hudson */ | ||
| 2829 | { PCI_DEVICE(0x1022, 0x780d), | ||
| 2830 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, | ||
| 2806 | /* ATI HDMI */ | 2831 | /* ATI HDMI */ |
| 2807 | { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI }, | 2832 | { PCI_DEVICE(0x1002, 0x793b), |
| 2808 | { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI }, | 2833 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2809 | { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI }, | 2834 | { PCI_DEVICE(0x1002, 0x7919), |
| 2810 | { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI }, | 2835 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2811 | { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI }, | 2836 | { PCI_DEVICE(0x1002, 0x960f), |
| 2812 | { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI }, | 2837 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2813 | { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI }, | 2838 | { PCI_DEVICE(0x1002, 0x970f), |
| 2814 | { PCI_DEVICE(0x1002, 0xaa18), .driver_data = AZX_DRIVER_ATIHDMI }, | 2839 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2815 | { PCI_DEVICE(0x1002, 0xaa20), .driver_data = AZX_DRIVER_ATIHDMI }, | 2840 | { PCI_DEVICE(0x1002, 0xaa00), |
| 2816 | { PCI_DEVICE(0x1002, 0xaa28), .driver_data = AZX_DRIVER_ATIHDMI }, | 2841 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2817 | { PCI_DEVICE(0x1002, 0xaa30), .driver_data = AZX_DRIVER_ATIHDMI }, | 2842 | { PCI_DEVICE(0x1002, 0xaa08), |
| 2818 | { PCI_DEVICE(0x1002, 0xaa38), .driver_data = AZX_DRIVER_ATIHDMI }, | 2843 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2819 | { PCI_DEVICE(0x1002, 0xaa40), .driver_data = AZX_DRIVER_ATIHDMI }, | 2844 | { PCI_DEVICE(0x1002, 0xaa10), |
| 2820 | { PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI }, | 2845 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2846 | { PCI_DEVICE(0x1002, 0xaa18), | ||
| 2847 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2848 | { PCI_DEVICE(0x1002, 0xaa20), | ||
| 2849 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2850 | { PCI_DEVICE(0x1002, 0xaa28), | ||
| 2851 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2852 | { PCI_DEVICE(0x1002, 0xaa30), | ||
| 2853 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2854 | { PCI_DEVICE(0x1002, 0xaa38), | ||
| 2855 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2856 | { PCI_DEVICE(0x1002, 0xaa40), | ||
| 2857 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2858 | { PCI_DEVICE(0x1002, 0xaa48), | ||
| 2859 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
| 2821 | /* VIA VT8251/VT8237A */ | 2860 | /* VIA VT8251/VT8237A */ |
| 2822 | { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA }, | 2861 | { PCI_DEVICE(0x1106, 0x3288), |
| 2862 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, | ||
| 2823 | /* SIS966 */ | 2863 | /* SIS966 */ |
| 2824 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, | 2864 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, |
| 2825 | /* ULI M5461 */ | 2865 | /* ULI M5461 */ |
| @@ -2828,9 +2868,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
| 2828 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), | 2868 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), |
| 2829 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2869 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 2830 | .class_mask = 0xffffff, | 2870 | .class_mask = 0xffffff, |
| 2831 | .driver_data = AZX_DRIVER_NVIDIA }, | 2871 | .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA }, |
| 2832 | /* Teradici */ | 2872 | /* Teradici */ |
| 2833 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | 2873 | { PCI_DEVICE(0x6549, 0x1200), |
| 2874 | .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, | ||
| 2834 | /* Creative X-Fi (CA0110-IBG) */ | 2875 | /* Creative X-Fi (CA0110-IBG) */ |
| 2835 | #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) | 2876 | #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) |
| 2836 | /* the following entry conflicts with snd-ctxfi driver, | 2877 | /* the following entry conflicts with snd-ctxfi driver, |
| @@ -2840,10 +2881,13 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
| 2840 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), | 2881 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), |
| 2841 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2882 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 2842 | .class_mask = 0xffffff, | 2883 | .class_mask = 0xffffff, |
| 2843 | .driver_data = AZX_DRIVER_CTX }, | 2884 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | |
| 2885 | AZX_DCAPS_RIRB_PRE_DELAY }, | ||
| 2844 | #else | 2886 | #else |
| 2845 | /* this entry seems still valid -- i.e. without emu20kx chip */ | 2887 | /* this entry seems still valid -- i.e. without emu20kx chip */ |
| 2846 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX }, | 2888 | { PCI_DEVICE(0x1102, 0x0009), |
| 2889 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | | ||
| 2890 | AZX_DCAPS_RIRB_PRE_DELAY }, | ||
| 2847 | #endif | 2891 | #endif |
| 2848 | /* Vortex86MX */ | 2892 | /* Vortex86MX */ |
| 2849 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | 2893 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, |
| @@ -2853,11 +2897,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
| 2853 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2897 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
| 2854 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2898 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 2855 | .class_mask = 0xffffff, | 2899 | .class_mask = 0xffffff, |
| 2856 | .driver_data = AZX_DRIVER_GENERIC }, | 2900 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2857 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), | 2901 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), |
| 2858 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2902 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 2859 | .class_mask = 0xffffff, | 2903 | .class_mask = 0xffffff, |
| 2860 | .driver_data = AZX_DRIVER_GENERIC }, | 2904 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, |
| 2861 | { 0, } | 2905 | { 0, } |
| 2862 | }; | 2906 | }; |
| 2863 | MODULE_DEVICE_TABLE(pci, azx_ids); | 2907 | 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[] = { | |||
| 3159 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), | 3159 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), |
| 3160 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), | 3160 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), |
| 3161 | SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), | 3161 | SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), |
| 3162 | SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG), | ||
| 3162 | SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), | 3163 | SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), |
| 3163 | {} | 3164 | {} |
| 3164 | }; | 3165 | }; |
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[] = { | |||
| 3098 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3098 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
| 3099 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), | 3099 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), |
| 3100 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), | 3100 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), |
| 3101 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), | ||
| 3101 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), | 3102 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), |
| 3103 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), | ||
| 3102 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ | 3104 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ |
| 3103 | {} | 3105 | {} |
| 3104 | }; | 3106 | }; |
| @@ -3433,7 +3435,9 @@ static void cx_auto_parse_output(struct hda_codec *codec) | |||
| 3433 | break; | 3435 | break; |
| 3434 | } | 3436 | } |
| 3435 | } | 3437 | } |
| 3436 | if (spec->auto_mute && cfg->line_out_pins[0] && | 3438 | if (spec->auto_mute && |
| 3439 | cfg->line_out_pins[0] && | ||
| 3440 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT && | ||
| 3437 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | 3441 | cfg->line_out_pins[0] != cfg->hp_pins[0] && |
| 3438 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | 3442 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { |
| 3439 | for (i = 0; i < cfg->line_outs; i++) { | 3443 | for (i = 0; i < cfg->line_outs; i++) { |
| @@ -3481,25 +3485,32 @@ static void cx_auto_update_speakers(struct hda_codec *codec) | |||
| 3481 | { | 3485 | { |
| 3482 | struct conexant_spec *spec = codec->spec; | 3486 | struct conexant_spec *spec = codec->spec; |
| 3483 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3487 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 3484 | int on; | 3488 | int on = 1; |
| 3485 | 3489 | ||
| 3486 | if (!spec->auto_mute) | 3490 | /* turn on HP EAPD when HP jacks are present */ |
| 3487 | on = 0; | 3491 | if (spec->auto_mute) |
| 3488 | else | 3492 | on = spec->hp_present; |
| 3489 | on = spec->hp_present | spec->line_present; | ||
| 3490 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); | 3493 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); |
| 3491 | do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, !on); | 3494 | /* mute speakers in auto-mode if HP or LO jacks are plugged */ |
| 3495 | if (spec->auto_mute) | ||
| 3496 | on = !(spec->hp_present || | ||
| 3497 | (spec->detect_line && spec->line_present)); | ||
| 3498 | do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on); | ||
| 3492 | 3499 | ||
| 3493 | /* toggle line-out mutes if needed, too */ | 3500 | /* toggle line-out mutes if needed, too */ |
| 3494 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | 3501 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ |
| 3495 | if (cfg->line_out_pins[0] == cfg->hp_pins[0] || | 3502 | if (cfg->line_out_pins[0] == cfg->hp_pins[0] || |
| 3496 | cfg->line_out_pins[0] == cfg->speaker_pins[0]) | 3503 | cfg->line_out_pins[0] == cfg->speaker_pins[0]) |
| 3497 | return; | 3504 | return; |
| 3498 | if (!spec->automute_lines || !spec->auto_mute) | 3505 | if (spec->auto_mute) { |
| 3499 | on = 0; | 3506 | /* mute LO in auto-mode when HP jack is present */ |
| 3500 | else | 3507 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT || |
| 3501 | on = spec->hp_present; | 3508 | spec->automute_lines) |
| 3502 | do_automute(codec, cfg->line_outs, cfg->line_out_pins, !on); | 3509 | on = !spec->hp_present; |
| 3510 | else | ||
| 3511 | on = 1; | ||
| 3512 | } | ||
| 3513 | do_automute(codec, cfg->line_outs, cfg->line_out_pins, on); | ||
| 3503 | } | 3514 | } |
| 3504 | 3515 | ||
| 3505 | static void cx_auto_hp_automute(struct hda_codec *codec) | 3516 | 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, | |||
| 3696 | { | 3707 | { |
| 3697 | struct conexant_spec *spec = codec->spec; | 3708 | struct conexant_spec *spec = codec->spec; |
| 3698 | hda_nid_t adc; | 3709 | hda_nid_t adc; |
| 3710 | int changed = 1; | ||
| 3699 | 3711 | ||
| 3700 | if (!imux->num_items) | 3712 | if (!imux->num_items) |
| 3701 | return 0; | 3713 | return 0; |
| 3702 | if (idx >= imux->num_items) | 3714 | if (idx >= imux->num_items) |
| 3703 | idx = imux->num_items - 1; | 3715 | idx = imux->num_items - 1; |
| 3704 | if (spec->cur_mux[0] == idx) | 3716 | if (spec->cur_mux[0] == idx) |
| 3705 | return 0; | 3717 | changed = 0; |
| 3706 | adc = spec->imux_info[idx].adc; | 3718 | adc = spec->imux_info[idx].adc; |
| 3707 | select_input_connection(codec, spec->imux_info[idx].adc, | 3719 | select_input_connection(codec, spec->imux_info[idx].adc, |
| 3708 | spec->imux_info[idx].pin); | 3720 | spec->imux_info[idx].pin); |
| @@ -3715,7 +3727,7 @@ static int cx_auto_mux_enum_update(struct hda_codec *codec, | |||
| 3715 | spec->cur_adc_format); | 3727 | spec->cur_adc_format); |
| 3716 | } | 3728 | } |
| 3717 | spec->cur_mux[0] = idx; | 3729 | spec->cur_mux[0] = idx; |
| 3718 | return 1; | 3730 | return changed; |
| 3719 | } | 3731 | } |
| 3720 | 3732 | ||
| 3721 | static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol, | 3733 | 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) | |||
| 3789 | int pset[INPUT_PIN_ATTR_NORMAL + 1]; | 3801 | int pset[INPUT_PIN_ATTR_NORMAL + 1]; |
| 3790 | int i; | 3802 | int i; |
| 3791 | 3803 | ||
| 3792 | for (i = 0; i < INPUT_PIN_ATTR_NORMAL; i++) | 3804 | for (i = 0; i < ARRAY_SIZE(pset); i++) |
| 3793 | pset[i] = -1; | 3805 | pset[i] = -1; |
| 3794 | for (i = 0; i < spec->private_imux.num_items; i++) { | 3806 | for (i = 0; i < spec->private_imux.num_items; i++) { |
| 3795 | hda_nid_t pin = spec->imux_info[i].pin; | 3807 | 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"); | |||
| 48 | * | 48 | * |
| 49 | * The HDA correspondence of pipes/ports are converter/pin nodes. | 49 | * The HDA correspondence of pipes/ports are converter/pin nodes. |
| 50 | */ | 50 | */ |
| 51 | #define MAX_HDMI_CVTS 3 | 51 | #define MAX_HDMI_CVTS 4 |
| 52 | #define MAX_HDMI_PINS 3 | 52 | #define MAX_HDMI_PINS 4 |
| 53 | 53 | ||
| 54 | struct hdmi_spec { | 54 | struct hdmi_spec { |
| 55 | int num_cvts; | 55 | int num_cvts; |
| @@ -78,10 +78,6 @@ struct hdmi_spec { | |||
| 78 | */ | 78 | */ |
| 79 | struct hda_multi_out multiout; | 79 | struct hda_multi_out multiout; |
| 80 | const struct hda_pcm_stream *pcm_playback; | 80 | const struct hda_pcm_stream *pcm_playback; |
| 81 | |||
| 82 | /* misc flags */ | ||
| 83 | /* PD bit indicates only the update, not the current state */ | ||
| 84 | unsigned int old_pin_detect:1; | ||
| 85 | }; | 81 | }; |
| 86 | 82 | ||
| 87 | 83 | ||
| @@ -300,13 +296,6 @@ static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) | |||
| 300 | return -EINVAL; | 296 | return -EINVAL; |
| 301 | } | 297 | } |
| 302 | 298 | ||
| 303 | static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid, | ||
| 304 | struct hdmi_eld *eld) | ||
| 305 | { | ||
| 306 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | ||
| 307 | snd_hdmi_show_eld(eld); | ||
| 308 | } | ||
| 309 | |||
| 310 | #ifdef BE_PARANOID | 299 | #ifdef BE_PARANOID |
| 311 | static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, | 300 | static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, |
| 312 | int *packet_index, int *byte_index) | 301 | int *packet_index, int *byte_index) |
| @@ -694,35 +683,20 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
| 694 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 683 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) |
| 695 | { | 684 | { |
| 696 | struct hdmi_spec *spec = codec->spec; | 685 | struct hdmi_spec *spec = codec->spec; |
| 697 | int tag = res >> AC_UNSOL_RES_TAG_SHIFT; | 686 | int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; |
| 698 | int pind = !!(res & AC_UNSOL_RES_PD); | 687 | int pd = !!(res & AC_UNSOL_RES_PD); |
| 699 | int eldv = !!(res & AC_UNSOL_RES_ELDV); | 688 | int eldv = !!(res & AC_UNSOL_RES_ELDV); |
| 700 | int index; | 689 | int index; |
| 701 | 690 | ||
| 702 | printk(KERN_INFO | 691 | printk(KERN_INFO |
| 703 | "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 692 | "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
| 704 | tag, pind, eldv); | 693 | pin_nid, pd, eldv); |
| 705 | 694 | ||
| 706 | index = hda_node_index(spec->pin, tag); | 695 | index = hda_node_index(spec->pin, pin_nid); |
| 707 | if (index < 0) | 696 | if (index < 0) |
| 708 | return; | 697 | return; |
| 709 | 698 | ||
| 710 | if (spec->old_pin_detect) { | 699 | hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); |
| 711 | if (pind) | ||
| 712 | hdmi_present_sense(codec, tag, &spec->sink_eld[index]); | ||
| 713 | pind = spec->sink_eld[index].monitor_present; | ||
| 714 | } | ||
| 715 | |||
| 716 | spec->sink_eld[index].monitor_present = pind; | ||
| 717 | spec->sink_eld[index].eld_valid = eldv; | ||
| 718 | |||
| 719 | if (pind && eldv) { | ||
| 720 | hdmi_get_show_eld(codec, spec->pin[index], | ||
| 721 | &spec->sink_eld[index]); | ||
| 722 | /* TODO: do real things about ELD */ | ||
| 723 | } | ||
| 724 | |||
| 725 | snd_hda_input_jack_report(codec, tag); | ||
| 726 | } | 700 | } |
| 727 | 701 | ||
| 728 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | 702 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) |
| @@ -903,13 +877,33 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) | |||
| 903 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | 877 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, |
| 904 | struct hdmi_eld *eld) | 878 | struct hdmi_eld *eld) |
| 905 | { | 879 | { |
| 880 | /* | ||
| 881 | * Always execute a GetPinSense verb here, even when called from | ||
| 882 | * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited | ||
| 883 | * response's PD bit is not the real PD value, but indicates that | ||
| 884 | * the real PD value changed. An older version of the HD-audio | ||
| 885 | * specification worked this way. Hence, we just ignore the data in | ||
| 886 | * the unsolicited response to avoid custom WARs. | ||
| 887 | */ | ||
| 906 | int present = snd_hda_pin_sense(codec, pin_nid); | 888 | int present = snd_hda_pin_sense(codec, pin_nid); |
| 907 | 889 | ||
| 890 | memset(eld, 0, sizeof(*eld)); | ||
| 891 | |||
| 908 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 892 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); |
| 909 | eld->eld_valid = !!(present & AC_PINSENSE_ELDV); | 893 | if (eld->monitor_present) |
| 894 | eld->eld_valid = !!(present & AC_PINSENSE_ELDV); | ||
| 895 | else | ||
| 896 | eld->eld_valid = 0; | ||
| 910 | 897 | ||
| 911 | if (present & AC_PINSENSE_ELDV) | 898 | printk(KERN_INFO |
| 912 | hdmi_get_show_eld(codec, pin_nid, eld); | 899 | "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
| 900 | pin_nid, eld->monitor_present, eld->eld_valid); | ||
| 901 | |||
| 902 | if (eld->eld_valid) | ||
| 903 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | ||
| 904 | snd_hdmi_show_eld(eld); | ||
| 905 | |||
| 906 | snd_hda_input_jack_report(codec, pin_nid); | ||
| 913 | } | 907 | } |
| 914 | 908 | ||
| 915 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | 909 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
| @@ -927,7 +921,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
| 927 | SND_JACK_VIDEOOUT, NULL); | 921 | SND_JACK_VIDEOOUT, NULL); |
| 928 | if (err < 0) | 922 | if (err < 0) |
| 929 | return err; | 923 | return err; |
| 930 | snd_hda_input_jack_report(codec, pin_nid); | ||
| 931 | 924 | ||
| 932 | hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); | 925 | hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); |
| 933 | 926 | ||
| @@ -1034,6 +1027,7 @@ static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { | |||
| 1034 | "HDMI 0", | 1027 | "HDMI 0", |
| 1035 | "HDMI 1", | 1028 | "HDMI 1", |
| 1036 | "HDMI 2", | 1029 | "HDMI 2", |
| 1030 | "HDMI 3", | ||
| 1037 | }; | 1031 | }; |
| 1038 | 1032 | ||
| 1039 | /* | 1033 | /* |
| @@ -1490,18 +1484,6 @@ static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { | |||
| 1490 | .free = generic_hdmi_free, | 1484 | .free = generic_hdmi_free, |
| 1491 | }; | 1485 | }; |
| 1492 | 1486 | ||
| 1493 | static int patch_nvhdmi_8ch_89(struct hda_codec *codec) | ||
| 1494 | { | ||
| 1495 | struct hdmi_spec *spec; | ||
| 1496 | int err = patch_generic_hdmi(codec); | ||
| 1497 | |||
| 1498 | if (err < 0) | ||
| 1499 | return err; | ||
| 1500 | spec = codec->spec; | ||
| 1501 | spec->old_pin_detect = 1; | ||
| 1502 | return 0; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | static int patch_nvhdmi_2ch(struct hda_codec *codec) | 1487 | static int patch_nvhdmi_2ch(struct hda_codec *codec) |
| 1506 | { | 1488 | { |
| 1507 | struct hdmi_spec *spec; | 1489 | struct hdmi_spec *spec; |
| @@ -1515,7 +1497,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) | |||
| 1515 | spec->multiout.num_dacs = 0; /* no analog */ | 1497 | spec->multiout.num_dacs = 0; /* no analog */ |
| 1516 | spec->multiout.max_channels = 2; | 1498 | spec->multiout.max_channels = 2; |
| 1517 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | 1499 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; |
| 1518 | spec->old_pin_detect = 1; | ||
| 1519 | spec->num_cvts = 1; | 1500 | spec->num_cvts = 1; |
| 1520 | spec->cvt[0] = nvhdmi_master_con_nid_7x; | 1501 | spec->cvt[0] = nvhdmi_master_con_nid_7x; |
| 1521 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; | 1502 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; |
| @@ -1658,28 +1639,28 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
| 1658 | { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, | 1639 | { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, |
| 1659 | { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, | 1640 | { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, |
| 1660 | { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, | 1641 | { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, |
| 1661 | { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1642 | { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_generic_hdmi }, |
| 1662 | { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1643 | { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_generic_hdmi }, |
| 1663 | { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 }, | 1644 | { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_generic_hdmi }, |
| 1664 | { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1645 | { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_generic_hdmi }, |
| 1665 | { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1646 | { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1666 | { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1647 | { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1667 | { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1648 | { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1668 | { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1649 | { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1669 | { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1650 | { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1670 | { .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1651 | { .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1671 | { .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1652 | { .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1672 | /* 17 is known to be absent */ | 1653 | /* 17 is known to be absent */ |
| 1673 | { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1654 | { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1674 | { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1655 | { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1675 | { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1656 | { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi }, |
| 1676 | { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1657 | { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi }, |
| 1677 | { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1658 | { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi }, |
| 1678 | { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1659 | { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1679 | { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1660 | { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1680 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1661 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1681 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1662 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1682 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1663 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, |
| 1683 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, | 1664 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
| 1684 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, | 1665 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
| 1685 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1666 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 28afbbf69ce0..95572d290c27 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
| @@ -146,7 +146,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
| 146 | "at91sam9g20ek_wm8731 " | 146 | "at91sam9g20ek_wm8731 " |
| 147 | ": at91sam9g20ek_wm8731_init() called\n"); | 147 | ": at91sam9g20ek_wm8731_init() called\n"); |
| 148 | 148 | ||
| 149 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, | 149 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_MCLK, |
| 150 | MCLK_RATE, SND_SOC_CLOCK_IN); | 150 | MCLK_RATE, SND_SOC_CLOCK_IN); |
| 151 | if (ret < 0) { | 151 | if (ret < 0) { |
| 152 | printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret); | 152 | printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret); |
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index 14d0716bf009..bcc208967917 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c | |||
| @@ -22,7 +22,7 @@ SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), | |||
| 22 | SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0), | 22 | SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0), |
| 23 | 23 | ||
| 24 | SND_SOC_DAPM_INPUT("WM1250 Input"), | 24 | SND_SOC_DAPM_INPUT("WM1250 Input"), |
| 25 | SND_SOC_DAPM_INPUT("WM1250 Output"), | 25 | SND_SOC_DAPM_OUTPUT("WM1250 Output"), |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = { | 28 | static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = { |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 6dec7cee2cb4..2dc964b55e4f 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
| @@ -198,7 +198,7 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source, | |||
| 198 | { | 198 | { |
| 199 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec); | 199 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec); |
| 200 | 200 | ||
| 201 | return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; | 201 | return wm8731->sysclk_type == WM8731_SYSCLK_XTAL; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static const struct snd_soc_dapm_route wm8731_intercon[] = { | 204 | static const struct snd_soc_dapm_route wm8731_intercon[] = { |
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c index ccc9bd832794..a0b1a7278284 100644 --- a/sound/soc/codecs/wm8915.c +++ b/sound/soc/codecs/wm8915.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/gcd.h> | 19 | #include <linux/gcd.h> |
| 20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
| 21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
| 24 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 25 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index 2afabaf59491..1a591f1ebfbd 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c | |||
| @@ -151,13 +151,13 @@ static struct snd_soc_ops raumfeld_cs4270_ops = { | |||
| 151 | .hw_params = raumfeld_cs4270_hw_params, | 151 | .hw_params = raumfeld_cs4270_hw_params, |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | static int raumfeld_line_suspend(struct snd_soc_card *card) | 154 | static int raumfeld_analog_suspend(struct snd_soc_card *card) |
| 155 | { | 155 | { |
| 156 | raumfeld_enable_audio(false); | 156 | raumfeld_enable_audio(false); |
| 157 | return 0; | 157 | return 0; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static int raumfeld_line_resume(struct snd_soc_card *card) | 160 | static int raumfeld_analog_resume(struct snd_soc_card *card) |
| 161 | { | 161 | { |
| 162 | raumfeld_enable_audio(true); | 162 | raumfeld_enable_audio(true); |
| 163 | return 0; | 163 | return 0; |
| @@ -225,32 +225,53 @@ static struct snd_soc_ops raumfeld_ak4104_ops = { | |||
| 225 | .hw_params = raumfeld_ak4104_hw_params, | 225 | .hw_params = raumfeld_ak4104_hw_params, |
| 226 | }; | 226 | }; |
| 227 | 227 | ||
| 228 | static struct snd_soc_dai_link raumfeld_dai[] = { | 228 | #define DAI_LINK_CS4270 \ |
| 229 | { \ | ||
| 230 | .name = "CS4270", \ | ||
| 231 | .stream_name = "CS4270", \ | ||
| 232 | .cpu_dai_name = "pxa-ssp-dai.0", \ | ||
| 233 | .platform_name = "pxa-pcm-audio", \ | ||
| 234 | .codec_dai_name = "cs4270-hifi", \ | ||
| 235 | .codec_name = "cs4270-codec.0-0048", \ | ||
| 236 | .ops = &raumfeld_cs4270_ops, \ | ||
| 237 | } | ||
| 238 | |||
| 239 | #define DAI_LINK_AK4104 \ | ||
| 240 | { \ | ||
| 241 | .name = "ak4104", \ | ||
| 242 | .stream_name = "Playback", \ | ||
| 243 | .cpu_dai_name = "pxa-ssp-dai.1", \ | ||
| 244 | .codec_dai_name = "ak4104-hifi", \ | ||
| 245 | .platform_name = "pxa-pcm-audio", \ | ||
| 246 | .ops = &raumfeld_ak4104_ops, \ | ||
| 247 | .codec_name = "spi0.0", \ | ||
| 248 | } | ||
| 249 | |||
| 250 | static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = | ||
| 229 | { | 251 | { |
| 230 | .name = "ak4104", | 252 | DAI_LINK_CS4270, |
| 231 | .stream_name = "Playback", | 253 | DAI_LINK_AK4104, |
| 232 | .cpu_dai_name = "pxa-ssp-dai.1", | 254 | }; |
| 233 | .codec_dai_name = "ak4104-hifi", | 255 | |
| 234 | .platform_name = "pxa-pcm-audio", | 256 | static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = |
| 235 | .ops = &raumfeld_ak4104_ops, | ||
| 236 | .codec_name = "ak4104-codec.0", | ||
| 237 | }, | ||
| 238 | { | 257 | { |
| 239 | .name = "CS4270", | 258 | DAI_LINK_CS4270, |
| 240 | .stream_name = "CS4270", | 259 | }; |
| 241 | .cpu_dai_name = "pxa-ssp-dai.0", | 260 | |
| 242 | .platform_name = "pxa-pcm-audio", | 261 | static struct snd_soc_card snd_soc_raumfeld_connector = { |
| 243 | .codec_dai_name = "cs4270-hifi", | 262 | .name = "Raumfeld Connector", |
| 244 | .codec_name = "cs4270-codec.0-0048", | 263 | .dai_link = snd_soc_raumfeld_connector_dai, |
| 245 | .ops = &raumfeld_cs4270_ops, | 264 | .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai), |
| 246 | },}; | 265 | .suspend_post = raumfeld_analog_suspend, |
| 247 | 266 | .resume_pre = raumfeld_analog_resume, | |
| 248 | static struct snd_soc_card snd_soc_raumfeld = { | 267 | }; |
| 249 | .name = "Raumfeld", | 268 | |
| 250 | .dai_link = raumfeld_dai, | 269 | static struct snd_soc_card snd_soc_raumfeld_speaker = { |
| 251 | .suspend_post = raumfeld_line_suspend, | 270 | .name = "Raumfeld Speaker", |
| 252 | .resume_pre = raumfeld_line_resume, | 271 | .dai_link = snd_soc_raumfeld_speaker_dai, |
| 253 | .num_links = ARRAY_SIZE(raumfeld_dai), | 272 | .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai), |
| 273 | .suspend_post = raumfeld_analog_suspend, | ||
| 274 | .resume_pre = raumfeld_analog_resume, | ||
| 254 | }; | 275 | }; |
| 255 | 276 | ||
| 256 | static struct platform_device *raumfeld_audio_device; | 277 | static struct platform_device *raumfeld_audio_device; |
| @@ -271,22 +292,25 @@ static int __init raumfeld_audio_init(void) | |||
| 271 | 292 | ||
| 272 | set_max9485_clk(MAX9485_MCLK_FREQ_122880); | 293 | set_max9485_clk(MAX9485_MCLK_FREQ_122880); |
| 273 | 294 | ||
| 274 | /* Register LINE and SPDIF */ | 295 | /* Register analog device */ |
| 275 | raumfeld_audio_device = platform_device_alloc("soc-audio", 0); | 296 | raumfeld_audio_device = platform_device_alloc("soc-audio", 0); |
| 276 | if (!raumfeld_audio_device) | 297 | if (!raumfeld_audio_device) |
| 277 | return -ENOMEM; | 298 | return -ENOMEM; |
| 278 | 299 | ||
| 279 | platform_set_drvdata(raumfeld_audio_device, | ||
| 280 | &snd_soc_raumfeld); | ||
| 281 | ret = platform_device_add(raumfeld_audio_device); | ||
| 282 | |||
| 283 | /* no S/PDIF on Speakers */ | ||
| 284 | if (machine_is_raumfeld_speaker()) | 300 | if (machine_is_raumfeld_speaker()) |
| 301 | platform_set_drvdata(raumfeld_audio_device, | ||
| 302 | &snd_soc_raumfeld_speaker); | ||
| 303 | |||
| 304 | if (machine_is_raumfeld_connector()) | ||
| 305 | platform_set_drvdata(raumfeld_audio_device, | ||
| 306 | &snd_soc_raumfeld_connector); | ||
| 307 | |||
| 308 | ret = platform_device_add(raumfeld_audio_device); | ||
| 309 | if (ret < 0) | ||
| 285 | return ret; | 310 | return ret; |
| 286 | 311 | ||
| 287 | raumfeld_enable_audio(true); | 312 | raumfeld_enable_audio(true); |
| 288 | 313 | return 0; | |
| 289 | return ret; | ||
| 290 | } | 314 | } |
| 291 | 315 | ||
| 292 | static void __exit raumfeld_audio_exit(void) | 316 | static void __exit raumfeld_audio_exit(void) |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bb7cd5812945..d75043ed7fc0 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -1306,10 +1306,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
| 1306 | /* no, then find CPU DAI from registered DAIs*/ | 1306 | /* no, then find CPU DAI from registered DAIs*/ |
| 1307 | list_for_each_entry(cpu_dai, &dai_list, list) { | 1307 | list_for_each_entry(cpu_dai, &dai_list, list) { |
| 1308 | if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) { | 1308 | if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) { |
| 1309 | |||
| 1310 | if (!try_module_get(cpu_dai->dev->driver->owner)) | ||
| 1311 | return -ENODEV; | ||
| 1312 | |||
| 1313 | rtd->cpu_dai = cpu_dai; | 1309 | rtd->cpu_dai = cpu_dai; |
| 1314 | goto find_codec; | 1310 | goto find_codec; |
| 1315 | } | 1311 | } |
| @@ -1622,11 +1618,15 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) | |||
| 1622 | 1618 | ||
| 1623 | /* probe the cpu_dai */ | 1619 | /* probe the cpu_dai */ |
| 1624 | if (!cpu_dai->probed) { | 1620 | if (!cpu_dai->probed) { |
| 1621 | if (!try_module_get(cpu_dai->dev->driver->owner)) | ||
| 1622 | return -ENODEV; | ||
| 1623 | |||
| 1625 | if (cpu_dai->driver->probe) { | 1624 | if (cpu_dai->driver->probe) { |
| 1626 | ret = cpu_dai->driver->probe(cpu_dai); | 1625 | ret = cpu_dai->driver->probe(cpu_dai); |
| 1627 | if (ret < 0) { | 1626 | if (ret < 0) { |
| 1628 | printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", | 1627 | printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", |
| 1629 | cpu_dai->name); | 1628 | cpu_dai->name); |
| 1629 | module_put(cpu_dai->dev->driver->owner); | ||
| 1630 | return ret; | 1630 | return ret; |
| 1631 | } | 1631 | } |
| 1632 | } | 1632 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 456617e63789..999bb08cdfb1 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -1110,7 +1110,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
| 1110 | trace_snd_soc_dapm_start(card); | 1110 | trace_snd_soc_dapm_start(card); |
| 1111 | 1111 | ||
| 1112 | list_for_each_entry(d, &card->dapm_list, list) | 1112 | list_for_each_entry(d, &card->dapm_list, list) |
| 1113 | if (d->n_widgets) | 1113 | if (d->n_widgets || d->codec == NULL) |
| 1114 | d->dev_power = 0; | 1114 | d->dev_power = 0; |
| 1115 | 1115 | ||
| 1116 | /* Check which widgets we need to power and store them in | 1116 | /* Check which widgets we need to power and store them in |
diff --git a/sound/usb/card.c b/sound/usb/card.c index a90662af2d6b..220c6167dd86 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | #include <linux/usb/audio.h> | 48 | #include <linux/usb/audio.h> |
| 49 | #include <linux/usb/audio-v2.h> | 49 | #include <linux/usb/audio-v2.h> |
| 50 | 50 | ||
| 51 | #include <sound/control.h> | ||
| 51 | #include <sound/core.h> | 52 | #include <sound/core.h> |
| 52 | #include <sound/info.h> | 53 | #include <sound/info.h> |
| 53 | #include <sound/pcm.h> | 54 | #include <sound/pcm.h> |
| @@ -492,14 +493,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
| 492 | } | 493 | } |
| 493 | } | 494 | } |
| 494 | 495 | ||
| 495 | chip->txfr_quirk = 0; | ||
| 496 | err = 1; /* continue */ | ||
| 497 | if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { | ||
| 498 | /* need some special handlings */ | ||
| 499 | if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0) | ||
| 500 | goto __error; | ||
| 501 | } | ||
| 502 | |||
| 503 | /* | 496 | /* |
| 504 | * For devices with more than one control interface, we assume the | 497 | * For devices with more than one control interface, we assume the |
| 505 | * first contains the audio controls. We might need a more specific | 498 | * first contains the audio controls. We might need a more specific |
| @@ -508,6 +501,14 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
| 508 | if (!chip->ctrl_intf) | 501 | if (!chip->ctrl_intf) |
| 509 | chip->ctrl_intf = alts; | 502 | chip->ctrl_intf = alts; |
| 510 | 503 | ||
| 504 | chip->txfr_quirk = 0; | ||
| 505 | err = 1; /* continue */ | ||
| 506 | if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { | ||
| 507 | /* need some special handlings */ | ||
| 508 | if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0) | ||
| 509 | goto __error; | ||
| 510 | } | ||
| 511 | |||
| 511 | if (err > 0) { | 512 | if (err > 0) { |
| 512 | /* create normal USB audio interfaces */ | 513 | /* create normal USB audio interfaces */ |
| 513 | if (snd_usb_create_streams(chip, ifnum) < 0 || | 514 | if (snd_usb_create_streams(chip, ifnum) < 0 || |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index eab06edcc9b7..c22fa76e363a 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -86,16 +86,6 @@ struct mixer_build { | |||
| 86 | const struct usbmix_selector_map *selector_map; | 86 | const struct usbmix_selector_map *selector_map; |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | enum { | ||
| 90 | USB_MIXER_BOOLEAN, | ||
| 91 | USB_MIXER_INV_BOOLEAN, | ||
| 92 | USB_MIXER_S8, | ||
| 93 | USB_MIXER_U8, | ||
| 94 | USB_MIXER_S16, | ||
| 95 | USB_MIXER_U16, | ||
| 96 | }; | ||
| 97 | |||
| 98 | |||
| 99 | /*E-mu 0202/0404/0204 eXtension Unit(XU) control*/ | 89 | /*E-mu 0202/0404/0204 eXtension Unit(XU) control*/ |
| 100 | enum { | 90 | enum { |
| 101 | USB_XU_CLOCK_RATE = 0xe301, | 91 | USB_XU_CLOCK_RATE = 0xe301, |
| @@ -535,20 +525,21 @@ static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_ou | |||
| 535 | * if failed, give up and free the control instance. | 525 | * if failed, give up and free the control instance. |
| 536 | */ | 526 | */ |
| 537 | 527 | ||
| 538 | static int add_control_to_empty(struct mixer_build *state, struct snd_kcontrol *kctl) | 528 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, |
| 529 | struct snd_kcontrol *kctl) | ||
| 539 | { | 530 | { |
| 540 | struct usb_mixer_elem_info *cval = kctl->private_data; | 531 | struct usb_mixer_elem_info *cval = kctl->private_data; |
| 541 | int err; | 532 | int err; |
| 542 | 533 | ||
| 543 | while (snd_ctl_find_id(state->chip->card, &kctl->id)) | 534 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) |
| 544 | kctl->id.index++; | 535 | kctl->id.index++; |
| 545 | if ((err = snd_ctl_add(state->chip->card, kctl)) < 0) { | 536 | if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) { |
| 546 | snd_printd(KERN_ERR "cannot add control (err = %d)\n", err); | 537 | snd_printd(KERN_ERR "cannot add control (err = %d)\n", err); |
| 547 | return err; | 538 | return err; |
| 548 | } | 539 | } |
| 549 | cval->elem_id = &kctl->id; | 540 | cval->elem_id = &kctl->id; |
| 550 | cval->next_id_elem = state->mixer->id_elems[cval->id]; | 541 | cval->next_id_elem = mixer->id_elems[cval->id]; |
| 551 | state->mixer->id_elems[cval->id] = cval; | 542 | mixer->id_elems[cval->id] = cval; |
| 552 | return 0; | 543 | return 0; |
| 553 | } | 544 | } |
| 554 | 545 | ||
| @@ -984,6 +975,9 @@ static struct snd_kcontrol_new usb_feature_unit_ctl_ro = { | |||
| 984 | .put = NULL, | 975 | .put = NULL, |
| 985 | }; | 976 | }; |
| 986 | 977 | ||
| 978 | /* This symbol is exported in order to allow the mixer quirks to | ||
| 979 | * hook up to the standard feature unit control mechanism */ | ||
| 980 | struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl; | ||
| 987 | 981 | ||
| 988 | /* | 982 | /* |
| 989 | * build a feature control | 983 | * build a feature control |
| @@ -1176,7 +1170,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
| 1176 | 1170 | ||
| 1177 | snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", | 1171 | snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", |
| 1178 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); | 1172 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); |
| 1179 | add_control_to_empty(state, kctl); | 1173 | snd_usb_mixer_add_control(state->mixer, kctl); |
| 1180 | } | 1174 | } |
| 1181 | 1175 | ||
| 1182 | 1176 | ||
| @@ -1340,7 +1334,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
| 1340 | 1334 | ||
| 1341 | snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", | 1335 | snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", |
| 1342 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); | 1336 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); |
| 1343 | add_control_to_empty(state, kctl); | 1337 | snd_usb_mixer_add_control(state->mixer, kctl); |
| 1344 | } | 1338 | } |
| 1345 | 1339 | ||
| 1346 | 1340 | ||
| @@ -1641,7 +1635,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
| 1641 | 1635 | ||
| 1642 | snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n", | 1636 | snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n", |
| 1643 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); | 1637 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); |
| 1644 | if ((err = add_control_to_empty(state, kctl)) < 0) | 1638 | if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) |
| 1645 | return err; | 1639 | return err; |
| 1646 | } | 1640 | } |
| 1647 | return 0; | 1641 | return 0; |
| @@ -1858,7 +1852,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
| 1858 | 1852 | ||
| 1859 | snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", | 1853 | snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", |
| 1860 | cval->id, kctl->id.name, desc->bNrInPins); | 1854 | cval->id, kctl->id.name, desc->bNrInPins); |
| 1861 | if ((err = add_control_to_empty(state, kctl)) < 0) | 1855 | if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) |
| 1862 | return err; | 1856 | return err; |
| 1863 | 1857 | ||
| 1864 | return 0; | 1858 | return 0; |
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index b4a2c8165e4b..ae1a14dcfe82 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
| @@ -24,7 +24,16 @@ struct usb_mixer_interface { | |||
| 24 | u8 xonar_u1_status; | 24 | u8 xonar_u1_status; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | #define MAX_CHANNELS 10 /* max logical channels */ | 27 | #define MAX_CHANNELS 16 /* max logical channels */ |
| 28 | |||
| 29 | enum { | ||
| 30 | USB_MIXER_BOOLEAN, | ||
| 31 | USB_MIXER_INV_BOOLEAN, | ||
| 32 | USB_MIXER_S8, | ||
| 33 | USB_MIXER_U8, | ||
| 34 | USB_MIXER_S16, | ||
| 35 | USB_MIXER_U16, | ||
| 36 | }; | ||
| 28 | 37 | ||
| 29 | struct usb_mixer_elem_info { | 38 | struct usb_mixer_elem_info { |
| 30 | struct usb_mixer_interface *mixer; | 39 | struct usb_mixer_interface *mixer; |
| @@ -55,4 +64,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
| 55 | void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer); | 64 | void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer); |
| 56 | int snd_usb_mixer_activate(struct usb_mixer_interface *mixer); | 65 | int snd_usb_mixer_activate(struct usb_mixer_interface *mixer); |
| 57 | 66 | ||
| 67 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | ||
| 68 | struct snd_kcontrol *kctl); | ||
| 69 | |||
| 58 | #endif /* __USBMIXER_H */ | 70 | #endif /* __USBMIXER_H */ |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 9146cffa6ede..3d0f4873112b 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
| @@ -40,6 +40,8 @@ | |||
| 40 | #include "mixer_quirks.h" | 40 | #include "mixer_quirks.h" |
| 41 | #include "helper.h" | 41 | #include "helper.h" |
| 42 | 42 | ||
| 43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; | ||
| 44 | |||
| 43 | /* | 45 | /* |
| 44 | * Sound Blaster remote control configuration | 46 | * Sound Blaster remote control configuration |
| 45 | * | 47 | * |
| @@ -492,6 +494,69 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, | |||
| 492 | return err; | 494 | return err; |
| 493 | } | 495 | } |
| 494 | 496 | ||
| 497 | /* M-Audio FastTrack Ultra quirks */ | ||
| 498 | |||
| 499 | /* private_free callback */ | ||
| 500 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | ||
| 501 | { | ||
| 502 | kfree(kctl->private_data); | ||
| 503 | kctl->private_data = NULL; | ||
| 504 | } | ||
| 505 | |||
| 506 | static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer, | ||
| 507 | int in, int out, const char *name) | ||
| 508 | { | ||
| 509 | struct usb_mixer_elem_info *cval; | ||
| 510 | struct snd_kcontrol *kctl; | ||
| 511 | |||
| 512 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | ||
| 513 | if (!cval) | ||
| 514 | return -ENOMEM; | ||
| 515 | |||
| 516 | cval->id = 5; | ||
| 517 | cval->mixer = mixer; | ||
| 518 | cval->val_type = USB_MIXER_S16; | ||
| 519 | cval->channels = 1; | ||
| 520 | cval->control = out + 1; | ||
| 521 | cval->cmask = 1 << in; | ||
| 522 | |||
| 523 | kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval); | ||
| 524 | if (!kctl) { | ||
| 525 | kfree(cval); | ||
| 526 | return -ENOMEM; | ||
| 527 | } | ||
| 528 | |||
| 529 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); | ||
| 530 | kctl->private_free = usb_mixer_elem_free; | ||
| 531 | return snd_usb_mixer_add_control(mixer, kctl); | ||
| 532 | } | ||
| 533 | |||
| 534 | static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer) | ||
| 535 | { | ||
| 536 | char name[64]; | ||
| 537 | int in, out, err; | ||
| 538 | |||
| 539 | for (out = 0; out < 8; out++) { | ||
| 540 | for (in = 0; in < 8; in++) { | ||
| 541 | snprintf(name, sizeof(name), | ||
| 542 | "AIn%d - Out%d Capture Volume", in + 1, out + 1); | ||
| 543 | err = snd_maudio_ftu_create_ctl(mixer, in, out, name); | ||
| 544 | if (err < 0) | ||
| 545 | return err; | ||
| 546 | } | ||
| 547 | |||
| 548 | for (in = 8; in < 16; in++) { | ||
| 549 | snprintf(name, sizeof(name), | ||
| 550 | "DIn%d - Out%d Playback Volume", in - 7, out + 1); | ||
| 551 | err = snd_maudio_ftu_create_ctl(mixer, in, out, name); | ||
| 552 | if (err < 0) | ||
| 553 | return err; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | |||
| 557 | return 0; | ||
| 558 | } | ||
| 559 | |||
| 495 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | 560 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
| 496 | unsigned char samplerate_id) | 561 | unsigned char samplerate_id) |
| 497 | { | 562 | { |
| @@ -533,6 +598,11 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
| 533 | snd_audigy2nx_proc_read); | 598 | snd_audigy2nx_proc_read); |
| 534 | break; | 599 | break; |
| 535 | 600 | ||
| 601 | case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ | ||
| 602 | case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ | ||
| 603 | err = snd_maudio_ftu_create_mixer(mixer); | ||
| 604 | break; | ||
| 605 | |||
| 536 | case USB_ID(0x0b05, 0x1739): | 606 | case USB_ID(0x0b05, 0x1739): |
| 537 | case USB_ID(0x0b05, 0x1743): | 607 | case USB_ID(0x0b05, 0x1743): |
| 538 | err = snd_xonar_u1_controls_create(mixer); | 608 | err = snd_xonar_u1_controls_create(mixer); |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 78792a8900c3..0b2ae8e1c02d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
| @@ -1988,7 +1988,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 1988 | .data = & (const struct snd_usb_audio_quirk[]) { | 1988 | .data = & (const struct snd_usb_audio_quirk[]) { |
| 1989 | { | 1989 | { |
| 1990 | .ifnum = 0, | 1990 | .ifnum = 0, |
| 1991 | .type = QUIRK_IGNORE_INTERFACE | 1991 | .type = QUIRK_AUDIO_STANDARD_MIXER, |
| 1992 | }, | 1992 | }, |
| 1993 | { | 1993 | { |
| 1994 | .ifnum = 1, | 1994 | .ifnum = 1, |
| @@ -2055,7 +2055,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 2055 | .data = & (const struct snd_usb_audio_quirk[]) { | 2055 | .data = & (const struct snd_usb_audio_quirk[]) { |
| 2056 | { | 2056 | { |
| 2057 | .ifnum = 0, | 2057 | .ifnum = 0, |
| 2058 | .type = QUIRK_IGNORE_INTERFACE | 2058 | .type = QUIRK_AUDIO_STANDARD_MIXER, |
| 2059 | }, | 2059 | }, |
| 2060 | { | 2060 | { |
| 2061 | .ifnum = 1, | 2061 | .ifnum = 1, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index bd13d7257240..2e969cbb393b 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
| 20 | #include <linux/usb/audio.h> | 20 | #include <linux/usb/audio.h> |
| 21 | 21 | ||
| 22 | #include <sound/control.h> | ||
| 22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
| 23 | #include <sound/info.h> | 24 | #include <sound/info.h> |
| 24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
| @@ -263,6 +264,20 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
| 263 | } | 264 | } |
| 264 | 265 | ||
| 265 | /* | 266 | /* |
| 267 | * Create a standard mixer for the specified interface. | ||
| 268 | */ | ||
| 269 | static int create_standard_mixer_quirk(struct snd_usb_audio *chip, | ||
| 270 | struct usb_interface *iface, | ||
| 271 | struct usb_driver *driver, | ||
| 272 | const struct snd_usb_audio_quirk *quirk) | ||
| 273 | { | ||
| 274 | if (quirk->ifnum < 0) | ||
| 275 | return 0; | ||
| 276 | |||
| 277 | return snd_usb_create_mixer(chip, quirk->ifnum, 0); | ||
| 278 | } | ||
| 279 | |||
| 280 | /* | ||
| 266 | * audio-interface quirks | 281 | * audio-interface quirks |
| 267 | * | 282 | * |
| 268 | * returns zero if no standard audio/MIDI parsing is needed. | 283 | * returns zero if no standard audio/MIDI parsing is needed. |
| @@ -294,7 +309,8 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
| 294 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 309 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
| 295 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 310 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
| 296 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 311 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
| 297 | [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk | 312 | [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk, |
| 313 | [QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk, | ||
| 298 | }; | 314 | }; |
| 299 | 315 | ||
| 300 | if (quirk->type < QUIRK_TYPE_COUNT) { | 316 | if (quirk->type < QUIRK_TYPE_COUNT) { |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 32f2a97f2f14..1e79986b5777 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -84,6 +84,7 @@ enum quirk_type { | |||
| 84 | QUIRK_AUDIO_FIXED_ENDPOINT, | 84 | QUIRK_AUDIO_FIXED_ENDPOINT, |
| 85 | QUIRK_AUDIO_EDIROL_UAXX, | 85 | QUIRK_AUDIO_EDIROL_UAXX, |
| 86 | QUIRK_AUDIO_ALIGN_TRANSFER, | 86 | QUIRK_AUDIO_ALIGN_TRANSFER, |
| 87 | QUIRK_AUDIO_STANDARD_MIXER, | ||
| 87 | 88 | ||
| 88 | QUIRK_TYPE_COUNT | 89 | QUIRK_TYPE_COUNT |
| 89 | }; | 90 | }; |
