diff options
Diffstat (limited to 'sound')
-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 |
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, | |||
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 | }; |