diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/oss/pcm_oss.c | 12 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 5 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_clientmgr.c | 3 | ||||
-rw-r--r-- | sound/core/seq/seq_clientmgr.h | 1 | ||||
-rw-r--r-- | sound/core/seq/seq_queue.c | 4 | ||||
-rw-r--r-- | sound/core/seq/seq_timer.c | 13 | ||||
-rw-r--r-- | sound/core/seq/seq_timer.h | 2 | ||||
-rw-r--r-- | sound/drivers/dummy.c | 2 | ||||
-rw-r--r-- | sound/isa/gus/gus_dma.c | 5 | ||||
-rw-r--r-- | sound/mips/hal2.c | 2 | ||||
-rw-r--r-- | sound/mips/sgio2audio.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/Kconfig | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 132 | ||||
-rw-r--r-- | sound/pci/ice1712/prodigy_hifi.c | 131 | ||||
-rw-r--r-- | sound/pci/korg1212/korg1212.c | 1 | ||||
-rw-r--r-- | sound/sound_core.c | 42 | ||||
-rw-r--r-- | sound/usb/card.c | 21 | ||||
-rw-r--r-- | sound/usb/mixer.c | 8 | ||||
-rw-r--r-- | sound/usb/mixer_quirks.c | 82 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 48 |
22 files changed, 410 insertions, 110 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index c2db7e905f7d..e8b19876c420 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -186,7 +186,7 @@ static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params, | |||
186 | { | 186 | { |
187 | int changed; | 187 | int changed; |
188 | changed = snd_mask_refine(hw_param_mask(params, var), val); | 188 | changed = snd_mask_refine(hw_param_mask(params, var), val); |
189 | if (changed) { | 189 | if (changed > 0) { |
190 | params->cmask |= 1 << var; | 190 | params->cmask |= 1 << var; |
191 | params->rmask |= 1 << var; | 191 | params->rmask |= 1 << var; |
192 | } | 192 | } |
@@ -233,7 +233,7 @@ static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, | |||
233 | val, open); | 233 | val, open); |
234 | else | 234 | else |
235 | return -EINVAL; | 235 | return -EINVAL; |
236 | if (changed) { | 236 | if (changed > 0) { |
237 | params->cmask |= 1 << var; | 237 | params->cmask |= 1 << var; |
238 | params->rmask |= 1 << var; | 238 | params->rmask |= 1 << var; |
239 | } | 239 | } |
@@ -294,7 +294,7 @@ static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params, | |||
294 | val, open); | 294 | val, open); |
295 | else | 295 | else |
296 | return -EINVAL; | 296 | return -EINVAL; |
297 | if (changed) { | 297 | if (changed > 0) { |
298 | params->cmask |= 1 << var; | 298 | params->cmask |= 1 << var; |
299 | params->rmask |= 1 << var; | 299 | params->rmask |= 1 << var; |
300 | } | 300 | } |
@@ -499,7 +499,7 @@ static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, | |||
499 | } | 499 | } |
500 | } else | 500 | } else |
501 | return -EINVAL; | 501 | return -EINVAL; |
502 | if (changed) { | 502 | if (changed > 0) { |
503 | params->cmask |= 1 << var; | 503 | params->cmask |= 1 << var; |
504 | params->rmask |= 1 << var; | 504 | params->rmask |= 1 << var; |
505 | } | 505 | } |
@@ -539,7 +539,7 @@ static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, | |||
539 | { | 539 | { |
540 | int changed; | 540 | int changed; |
541 | changed = snd_interval_setinteger(hw_param_interval(params, var)); | 541 | changed = snd_interval_setinteger(hw_param_interval(params, var)); |
542 | if (changed) { | 542 | if (changed > 0) { |
543 | params->cmask |= 1 << var; | 543 | params->cmask |= 1 << var; |
544 | params->rmask |= 1 << var; | 544 | params->rmask |= 1 << var; |
545 | } | 545 | } |
@@ -842,7 +842,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, | |||
842 | if (!(mutex_trylock(&runtime->oss.params_lock))) | 842 | if (!(mutex_trylock(&runtime->oss.params_lock))) |
843 | return -EAGAIN; | 843 | return -EAGAIN; |
844 | } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) | 844 | } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) |
845 | return -EINTR; | 845 | return -ERESTARTSYS; |
846 | sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); | 846 | sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); |
847 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 847 | params = kmalloc(sizeof(*params), GFP_KERNEL); |
848 | sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); | 848 | sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index db7894bb028c..a83152e7d387 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -560,7 +560,6 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, | |||
560 | { | 560 | { |
561 | u_int64_t n = (u_int64_t) a * b; | 561 | u_int64_t n = (u_int64_t) a * b; |
562 | if (c == 0) { | 562 | if (c == 0) { |
563 | snd_BUG_ON(!n); | ||
564 | *r = 0; | 563 | *r = 0; |
565 | return UINT_MAX; | 564 | return UINT_MAX; |
566 | } | 565 | } |
@@ -1603,7 +1602,7 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | |||
1603 | changed = snd_interval_refine_first(hw_param_interval(params, var)); | 1602 | changed = snd_interval_refine_first(hw_param_interval(params, var)); |
1604 | else | 1603 | else |
1605 | return -EINVAL; | 1604 | return -EINVAL; |
1606 | if (changed) { | 1605 | if (changed > 0) { |
1607 | params->cmask |= 1 << var; | 1606 | params->cmask |= 1 << var; |
1608 | params->rmask |= 1 << var; | 1607 | params->rmask |= 1 << var; |
1609 | } | 1608 | } |
@@ -1649,7 +1648,7 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | |||
1649 | changed = snd_interval_refine_last(hw_param_interval(params, var)); | 1648 | changed = snd_interval_refine_last(hw_param_interval(params, var)); |
1650 | else | 1649 | else |
1651 | return -EINVAL; | 1650 | return -EINVAL; |
1652 | if (changed) { | 1651 | if (changed > 0) { |
1653 | params->cmask |= 1 << var; | 1652 | params->cmask |= 1 << var; |
1654 | params->rmask |= 1 << var; | 1653 | params->rmask |= 1 << var; |
1655 | } | 1654 | } |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index f08772568c17..484a18d96371 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -3446,7 +3446,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); | |||
3446 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | 3446 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, |
3447 | struct vm_area_struct *area) | 3447 | struct vm_area_struct *area) |
3448 | { | 3448 | { |
3449 | struct snd_pcm_runtime *runtime = substream->runtime;; | 3449 | struct snd_pcm_runtime *runtime = substream->runtime; |
3450 | 3450 | ||
3451 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | 3451 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); |
3452 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); | 3452 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 6e22eea72654..d01913404581 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -221,6 +221,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) | |||
221 | rwlock_init(&client->ports_lock); | 221 | rwlock_init(&client->ports_lock); |
222 | mutex_init(&client->ports_mutex); | 222 | mutex_init(&client->ports_mutex); |
223 | INIT_LIST_HEAD(&client->ports_list_head); | 223 | INIT_LIST_HEAD(&client->ports_list_head); |
224 | mutex_init(&client->ioctl_mutex); | ||
224 | 225 | ||
225 | /* find free slot in the client table */ | 226 | /* find free slot in the client table */ |
226 | spin_lock_irqsave(&clients_lock, flags); | 227 | spin_lock_irqsave(&clients_lock, flags); |
@@ -2130,7 +2131,9 @@ static long snd_seq_ioctl(struct file *file, unsigned int cmd, | |||
2130 | return -EFAULT; | 2131 | return -EFAULT; |
2131 | } | 2132 | } |
2132 | 2133 | ||
2134 | mutex_lock(&client->ioctl_mutex); | ||
2133 | err = handler->func(client, &buf); | 2135 | err = handler->func(client, &buf); |
2136 | mutex_unlock(&client->ioctl_mutex); | ||
2134 | if (err >= 0) { | 2137 | if (err >= 0) { |
2135 | /* Some commands includes a bug in 'dir' field. */ | 2138 | /* Some commands includes a bug in 'dir' field. */ |
2136 | if (handler->cmd == SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT || | 2139 | if (handler->cmd == SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT || |
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index c6614254ef8a..0611e1e0ed5b 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h | |||
@@ -61,6 +61,7 @@ struct snd_seq_client { | |||
61 | struct list_head ports_list_head; | 61 | struct list_head ports_list_head; |
62 | rwlock_t ports_lock; | 62 | rwlock_t ports_lock; |
63 | struct mutex ports_mutex; | 63 | struct mutex ports_mutex; |
64 | struct mutex ioctl_mutex; | ||
64 | int convert32; /* convert 32->64bit */ | 65 | int convert32; /* convert 32->64bit */ |
65 | 66 | ||
66 | /* output pool */ | 67 | /* output pool */ |
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 79e0c5604ef8..0428e9061b47 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c | |||
@@ -497,9 +497,7 @@ int snd_seq_queue_timer_set_tempo(int queueid, int client, | |||
497 | return -EPERM; | 497 | return -EPERM; |
498 | } | 498 | } |
499 | 499 | ||
500 | result = snd_seq_timer_set_tempo(q->timer, info->tempo); | 500 | result = snd_seq_timer_set_tempo_ppq(q->timer, info->tempo, info->ppq); |
501 | if (result >= 0) | ||
502 | result = snd_seq_timer_set_ppq(q->timer, info->ppq); | ||
503 | if (result >= 0 && info->skew_base > 0) | 501 | if (result >= 0 && info->skew_base > 0) |
504 | result = snd_seq_timer_set_skew(q->timer, info->skew_value, | 502 | result = snd_seq_timer_set_skew(q->timer, info->skew_value, |
505 | info->skew_base); | 503 | info->skew_base); |
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index b80985fbc334..23167578231f 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c | |||
@@ -191,14 +191,15 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo) | |||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* set current ppq */ | 194 | /* set current tempo and ppq in a shot */ |
195 | int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) | 195 | int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq) |
196 | { | 196 | { |
197 | int changed; | ||
197 | unsigned long flags; | 198 | unsigned long flags; |
198 | 199 | ||
199 | if (snd_BUG_ON(!tmr)) | 200 | if (snd_BUG_ON(!tmr)) |
200 | return -EINVAL; | 201 | return -EINVAL; |
201 | if (ppq <= 0) | 202 | if (tempo <= 0 || ppq <= 0) |
202 | return -EINVAL; | 203 | return -EINVAL; |
203 | spin_lock_irqsave(&tmr->lock, flags); | 204 | spin_lock_irqsave(&tmr->lock, flags); |
204 | if (tmr->running && (ppq != tmr->ppq)) { | 205 | if (tmr->running && (ppq != tmr->ppq)) { |
@@ -208,9 +209,11 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) | |||
208 | pr_debug("ALSA: seq: cannot change ppq of a running timer\n"); | 209 | pr_debug("ALSA: seq: cannot change ppq of a running timer\n"); |
209 | return -EBUSY; | 210 | return -EBUSY; |
210 | } | 211 | } |
211 | 212 | changed = (tempo != tmr->tempo) || (ppq != tmr->ppq); | |
213 | tmr->tempo = tempo; | ||
212 | tmr->ppq = ppq; | 214 | tmr->ppq = ppq; |
213 | snd_seq_timer_set_tick_resolution(tmr); | 215 | if (changed) |
216 | snd_seq_timer_set_tick_resolution(tmr); | ||
214 | spin_unlock_irqrestore(&tmr->lock, flags); | 217 | spin_unlock_irqrestore(&tmr->lock, flags); |
215 | return 0; | 218 | return 0; |
216 | } | 219 | } |
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h index 9506b661fe5b..62f390671096 100644 --- a/sound/core/seq/seq_timer.h +++ b/sound/core/seq/seq_timer.h | |||
@@ -131,7 +131,7 @@ int snd_seq_timer_stop(struct snd_seq_timer *tmr); | |||
131 | int snd_seq_timer_start(struct snd_seq_timer *tmr); | 131 | int snd_seq_timer_start(struct snd_seq_timer *tmr); |
132 | int snd_seq_timer_continue(struct snd_seq_timer *tmr); | 132 | int snd_seq_timer_continue(struct snd_seq_timer *tmr); |
133 | int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo); | 133 | int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo); |
134 | int snd_seq_timer_set_ppq(struct snd_seq_timer *tmr, int ppq); | 134 | int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq); |
135 | int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position); | 135 | int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position); |
136 | int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position); | 136 | int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position); |
137 | int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base); | 137 | int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base); |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 7b2b1f766b00..69db45bc0197 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -830,7 +830,7 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
830 | static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol, | 830 | static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol, |
831 | struct snd_ctl_elem_info *info) | 831 | struct snd_ctl_elem_info *info) |
832 | { | 832 | { |
833 | const char *const names[] = { "None", "CD Player" }; | 833 | static const char *const names[] = { "None", "CD Player" }; |
834 | 834 | ||
835 | return snd_ctl_enum_info(info, 1, 2, names); | 835 | return snd_ctl_enum_info(info, 1, 2, names); |
836 | } | 836 | } |
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index 36c27c832360..7f95f452f106 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c | |||
@@ -201,10 +201,9 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus, | |||
201 | struct snd_gf1_dma_block *block; | 201 | struct snd_gf1_dma_block *block; |
202 | 202 | ||
203 | block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL); | 203 | block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL); |
204 | if (block == NULL) { | 204 | if (!block) |
205 | snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n"); | ||
206 | return -ENOMEM; | 205 | return -ENOMEM; |
207 | } | 206 | |
208 | *block = *__block; | 207 | *block = *__block; |
209 | block->next = NULL; | 208 | block->next = NULL; |
210 | 209 | ||
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 37d378a26a50..c8904e732aaa 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c | |||
@@ -814,7 +814,7 @@ static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip) | |||
814 | struct hpc3_regs *hpc3 = hpc3c0; | 814 | struct hpc3_regs *hpc3 = hpc3c0; |
815 | int err; | 815 | int err; |
816 | 816 | ||
817 | hal2 = kzalloc(sizeof(struct snd_hal2), GFP_KERNEL); | 817 | hal2 = kzalloc(sizeof(*hal2), GFP_KERNEL); |
818 | if (!hal2) | 818 | if (!hal2) |
819 | return -ENOMEM; | 819 | return -ENOMEM; |
820 | 820 | ||
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 71c942162c25..9fb68b35de5a 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c | |||
@@ -840,7 +840,7 @@ static int snd_sgio2audio_create(struct snd_card *card, | |||
840 | if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) | 840 | if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) |
841 | return -ENOENT; | 841 | return -ENOENT; |
842 | 842 | ||
843 | chip = kzalloc(sizeof(struct snd_sgio2audio), GFP_KERNEL); | 843 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
844 | if (chip == NULL) | 844 | if (chip == NULL) |
845 | return -ENOMEM; | 845 | return -ENOMEM; |
846 | 846 | ||
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 7f3b5ed81995..f7a492c382d9 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -88,7 +88,6 @@ config SND_HDA_PATCH_LOADER | |||
88 | config SND_HDA_CODEC_REALTEK | 88 | config SND_HDA_CODEC_REALTEK |
89 | tristate "Build Realtek HD-audio codec support" | 89 | tristate "Build Realtek HD-audio codec support" |
90 | select SND_HDA_GENERIC | 90 | select SND_HDA_GENERIC |
91 | select INPUT | ||
92 | help | 91 | help |
93 | Say Y or M here to include Realtek HD-audio codec support in | 92 | Say Y or M here to include Realtek HD-audio codec support in |
94 | snd-hda-intel driver, such as ALC880. | 93 | snd-hda-intel driver, such as ALC880. |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 80bbadc83721..d6e079f4ec09 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -408,6 +408,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { | |||
408 | /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ | 408 | /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ |
409 | 409 | ||
410 | /* codec SSID */ | 410 | /* codec SSID */ |
411 | SND_PCI_QUIRK(0x106b, 0x0600, "iMac 14,1", CS420X_IMAC27_122), | ||
411 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), | 412 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), |
412 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), | 413 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), |
413 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), | 414 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8fd2d9c62c96..0004e282a837 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -3166,6 +3166,93 @@ static void alc256_shutup(struct hda_codec *codec) | |||
3166 | snd_hda_shutup_pins(codec); | 3166 | snd_hda_shutup_pins(codec); |
3167 | } | 3167 | } |
3168 | 3168 | ||
3169 | static void alc225_init(struct hda_codec *codec) | ||
3170 | { | ||
3171 | struct alc_spec *spec = codec->spec; | ||
3172 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3173 | bool hp1_pin_sense, hp2_pin_sense; | ||
3174 | |||
3175 | if (!hp_pin) | ||
3176 | return; | ||
3177 | |||
3178 | msleep(30); | ||
3179 | |||
3180 | hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
3181 | hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); | ||
3182 | |||
3183 | if (hp1_pin_sense || hp2_pin_sense) | ||
3184 | msleep(2); | ||
3185 | |||
3186 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ | ||
3187 | |||
3188 | if (hp1_pin_sense) | ||
3189 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3190 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3191 | if (hp2_pin_sense) | ||
3192 | snd_hda_codec_write(codec, 0x16, 0, | ||
3193 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3194 | |||
3195 | if (hp1_pin_sense || hp2_pin_sense) | ||
3196 | msleep(85); | ||
3197 | |||
3198 | if (hp1_pin_sense) | ||
3199 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3200 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3201 | if (hp2_pin_sense) | ||
3202 | snd_hda_codec_write(codec, 0x16, 0, | ||
3203 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3204 | |||
3205 | if (hp1_pin_sense || hp2_pin_sense) | ||
3206 | msleep(100); | ||
3207 | |||
3208 | alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); | ||
3209 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ | ||
3210 | } | ||
3211 | |||
3212 | static void alc225_shutup(struct hda_codec *codec) | ||
3213 | { | ||
3214 | struct alc_spec *spec = codec->spec; | ||
3215 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3216 | bool hp1_pin_sense, hp2_pin_sense; | ||
3217 | |||
3218 | if (!hp_pin) { | ||
3219 | alc269_shutup(codec); | ||
3220 | return; | ||
3221 | } | ||
3222 | |||
3223 | /* 3k pull low control for Headset jack. */ | ||
3224 | alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); | ||
3225 | |||
3226 | hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
3227 | hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); | ||
3228 | |||
3229 | if (hp1_pin_sense || hp2_pin_sense) | ||
3230 | msleep(2); | ||
3231 | |||
3232 | if (hp1_pin_sense) | ||
3233 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3234 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3235 | if (hp2_pin_sense) | ||
3236 | snd_hda_codec_write(codec, 0x16, 0, | ||
3237 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3238 | |||
3239 | if (hp1_pin_sense || hp2_pin_sense) | ||
3240 | msleep(85); | ||
3241 | |||
3242 | if (hp1_pin_sense) | ||
3243 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3244 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
3245 | if (hp2_pin_sense) | ||
3246 | snd_hda_codec_write(codec, 0x16, 0, | ||
3247 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
3248 | |||
3249 | if (hp1_pin_sense || hp2_pin_sense) | ||
3250 | msleep(100); | ||
3251 | |||
3252 | alc_auto_setup_eapd(codec, false); | ||
3253 | snd_hda_shutup_pins(codec); | ||
3254 | } | ||
3255 | |||
3169 | static void alc_default_init(struct hda_codec *codec) | 3256 | static void alc_default_init(struct hda_codec *codec) |
3170 | { | 3257 | { |
3171 | struct alc_spec *spec = codec->spec; | 3258 | struct alc_spec *spec = codec->spec; |
@@ -3723,6 +3810,7 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, | |||
3723 | } | 3810 | } |
3724 | } | 3811 | } |
3725 | 3812 | ||
3813 | #if IS_REACHABLE(INPUT) | ||
3726 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, | 3814 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, |
3727 | struct hda_jack_callback *event) | 3815 | struct hda_jack_callback *event) |
3728 | { | 3816 | { |
@@ -3855,6 +3943,10 @@ static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec, | |||
3855 | spec->kb_dev = NULL; | 3943 | spec->kb_dev = NULL; |
3856 | } | 3944 | } |
3857 | } | 3945 | } |
3946 | #else /* INPUT */ | ||
3947 | #define alc280_fixup_hp_gpio2_mic_hotkey NULL | ||
3948 | #define alc233_fixup_lenovo_line2_mic_hotkey NULL | ||
3949 | #endif /* INPUT */ | ||
3858 | 3950 | ||
3859 | static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, | 3951 | static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, |
3860 | const struct hda_fixup *fix, int action) | 3952 | const struct hda_fixup *fix, int action) |
@@ -3994,8 +4086,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) | |||
3994 | case 0x10ec0668: | 4086 | case 0x10ec0668: |
3995 | alc_process_coef_fw(codec, coef0668); | 4087 | alc_process_coef_fw(codec, coef0668); |
3996 | break; | 4088 | break; |
4089 | case 0x10ec0215: | ||
3997 | case 0x10ec0225: | 4090 | case 0x10ec0225: |
4091 | case 0x10ec0285: | ||
3998 | case 0x10ec0295: | 4092 | case 0x10ec0295: |
4093 | case 0x10ec0289: | ||
3999 | case 0x10ec0299: | 4094 | case 0x10ec0299: |
4000 | alc_process_coef_fw(codec, coef0225); | 4095 | alc_process_coef_fw(codec, coef0225); |
4001 | break; | 4096 | break; |
@@ -4117,8 +4212,11 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
4117 | alc_process_coef_fw(codec, coef0688); | 4212 | alc_process_coef_fw(codec, coef0688); |
4118 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 4213 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
4119 | break; | 4214 | break; |
4215 | case 0x10ec0215: | ||
4120 | case 0x10ec0225: | 4216 | case 0x10ec0225: |
4217 | case 0x10ec0285: | ||
4121 | case 0x10ec0295: | 4218 | case 0x10ec0295: |
4219 | case 0x10ec0289: | ||
4122 | case 0x10ec0299: | 4220 | case 0x10ec0299: |
4123 | alc_process_coef_fw(codec, alc225_pre_hsmode); | 4221 | alc_process_coef_fw(codec, alc225_pre_hsmode); |
4124 | alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); | 4222 | alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); |
@@ -4189,8 +4287,11 @@ static void alc_headset_mode_default(struct hda_codec *codec) | |||
4189 | }; | 4287 | }; |
4190 | 4288 | ||
4191 | switch (codec->core.vendor_id) { | 4289 | switch (codec->core.vendor_id) { |
4290 | case 0x10ec0215: | ||
4192 | case 0x10ec0225: | 4291 | case 0x10ec0225: |
4292 | case 0x10ec0285: | ||
4193 | case 0x10ec0295: | 4293 | case 0x10ec0295: |
4294 | case 0x10ec0289: | ||
4194 | case 0x10ec0299: | 4295 | case 0x10ec0299: |
4195 | alc_process_coef_fw(codec, alc225_pre_hsmode); | 4296 | alc_process_coef_fw(codec, alc225_pre_hsmode); |
4196 | alc_process_coef_fw(codec, coef0225); | 4297 | alc_process_coef_fw(codec, coef0225); |
@@ -4332,8 +4433,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) | |||
4332 | case 0x10ec0668: | 4433 | case 0x10ec0668: |
4333 | alc_process_coef_fw(codec, coef0688); | 4434 | alc_process_coef_fw(codec, coef0688); |
4334 | break; | 4435 | break; |
4436 | case 0x10ec0215: | ||
4335 | case 0x10ec0225: | 4437 | case 0x10ec0225: |
4438 | case 0x10ec0285: | ||
4336 | case 0x10ec0295: | 4439 | case 0x10ec0295: |
4440 | case 0x10ec0289: | ||
4337 | case 0x10ec0299: | 4441 | case 0x10ec0299: |
4338 | val = alc_read_coef_idx(codec, 0x45); | 4442 | val = alc_read_coef_idx(codec, 0x45); |
4339 | if (val & (1 << 9)) | 4443 | if (val & (1 << 9)) |
@@ -4436,8 +4540,11 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) | |||
4436 | case 0x10ec0668: | 4540 | case 0x10ec0668: |
4437 | alc_process_coef_fw(codec, coef0688); | 4541 | alc_process_coef_fw(codec, coef0688); |
4438 | break; | 4542 | break; |
4543 | case 0x10ec0215: | ||
4439 | case 0x10ec0225: | 4544 | case 0x10ec0225: |
4545 | case 0x10ec0285: | ||
4440 | case 0x10ec0295: | 4546 | case 0x10ec0295: |
4547 | case 0x10ec0289: | ||
4441 | case 0x10ec0299: | 4548 | case 0x10ec0299: |
4442 | alc_process_coef_fw(codec, coef0225); | 4549 | alc_process_coef_fw(codec, coef0225); |
4443 | break; | 4550 | break; |
@@ -4566,9 +4673,18 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
4566 | val = alc_read_coef_idx(codec, 0xbe); | 4673 | val = alc_read_coef_idx(codec, 0xbe); |
4567 | is_ctia = (val & 0x1c02) == 0x1c02; | 4674 | is_ctia = (val & 0x1c02) == 0x1c02; |
4568 | break; | 4675 | break; |
4676 | case 0x10ec0215: | ||
4569 | case 0x10ec0225: | 4677 | case 0x10ec0225: |
4678 | case 0x10ec0285: | ||
4570 | case 0x10ec0295: | 4679 | case 0x10ec0295: |
4680 | case 0x10ec0289: | ||
4571 | case 0x10ec0299: | 4681 | case 0x10ec0299: |
4682 | snd_hda_codec_write(codec, 0x21, 0, | ||
4683 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
4684 | msleep(80); | ||
4685 | snd_hda_codec_write(codec, 0x21, 0, | ||
4686 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
4687 | |||
4572 | alc_process_coef_fw(codec, alc225_pre_hsmode); | 4688 | alc_process_coef_fw(codec, alc225_pre_hsmode); |
4573 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); | 4689 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); |
4574 | val = alc_read_coef_idx(codec, 0x45); | 4690 | val = alc_read_coef_idx(codec, 0x45); |
@@ -4588,6 +4704,12 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
4588 | alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); | 4704 | alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); |
4589 | alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); | 4705 | alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); |
4590 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); | 4706 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); |
4707 | |||
4708 | snd_hda_codec_write(codec, 0x21, 0, | ||
4709 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
4710 | msleep(80); | ||
4711 | snd_hda_codec_write(codec, 0x21, 0, | ||
4712 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | ||
4591 | break; | 4713 | break; |
4592 | case 0x10ec0867: | 4714 | case 0x10ec0867: |
4593 | is_ctia = true; | 4715 | is_ctia = true; |
@@ -6196,6 +6318,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6196 | SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), | 6318 | SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), |
6197 | SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), | 6319 | SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), |
6198 | SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), | 6320 | SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), |
6321 | SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), | ||
6199 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 6322 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
6200 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 6323 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
6201 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 6324 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
@@ -6919,16 +7042,17 @@ static int patch_alc269(struct hda_codec *codec) | |||
6919 | case 0x10ec0285: | 7042 | case 0x10ec0285: |
6920 | case 0x10ec0289: | 7043 | case 0x10ec0289: |
6921 | spec->codec_variant = ALC269_TYPE_ALC215; | 7044 | spec->codec_variant = ALC269_TYPE_ALC215; |
7045 | spec->shutup = alc225_shutup; | ||
7046 | spec->init_hook = alc225_init; | ||
6922 | spec->gen.mixer_nid = 0; | 7047 | spec->gen.mixer_nid = 0; |
6923 | break; | 7048 | break; |
6924 | case 0x10ec0225: | 7049 | case 0x10ec0225: |
6925 | case 0x10ec0295: | 7050 | case 0x10ec0295: |
6926 | spec->codec_variant = ALC269_TYPE_ALC225; | ||
6927 | spec->gen.mixer_nid = 0; /* no loopback on ALC225 ALC295 */ | ||
6928 | break; | ||
6929 | case 0x10ec0299: | 7051 | case 0x10ec0299: |
6930 | spec->codec_variant = ALC269_TYPE_ALC225; | 7052 | spec->codec_variant = ALC269_TYPE_ALC225; |
6931 | spec->gen.mixer_nid = 0; /* no loopback on ALC299 */ | 7053 | spec->shutup = alc225_shutup; |
7054 | spec->init_hook = alc225_init; | ||
7055 | spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */ | ||
6932 | break; | 7056 | break; |
6933 | case 0x10ec0234: | 7057 | case 0x10ec0234: |
6934 | case 0x10ec0274: | 7058 | case 0x10ec0274: |
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 2697402b5195..8dabd4d0211d 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c | |||
@@ -965,13 +965,32 @@ static int prodigy_hd2_add_controls(struct snd_ice1712 *ice) | |||
965 | return 0; | 965 | return 0; |
966 | } | 966 | } |
967 | 967 | ||
968 | static void wm8766_init(struct snd_ice1712 *ice) | ||
969 | { | ||
970 | static unsigned short wm8766_inits[] = { | ||
971 | WM8766_RESET, 0x0000, | ||
972 | WM8766_DAC_CTRL, 0x0120, | ||
973 | WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ | ||
974 | WM8766_DAC_CTRL2, 0x0001, | ||
975 | WM8766_DAC_CTRL3, 0x0080, | ||
976 | WM8766_LDA1, 0x0100, | ||
977 | WM8766_LDA2, 0x0100, | ||
978 | WM8766_LDA3, 0x0100, | ||
979 | WM8766_RDA1, 0x0100, | ||
980 | WM8766_RDA2, 0x0100, | ||
981 | WM8766_RDA3, 0x0100, | ||
982 | WM8766_MUTE1, 0x0000, | ||
983 | WM8766_MUTE2, 0x0000, | ||
984 | }; | ||
985 | unsigned int i; | ||
968 | 986 | ||
969 | /* | 987 | for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) |
970 | * initialize the chip | 988 | wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i + 1]); |
971 | */ | 989 | } |
972 | static int prodigy_hifi_init(struct snd_ice1712 *ice) | 990 | |
991 | static void wm8776_init(struct snd_ice1712 *ice) | ||
973 | { | 992 | { |
974 | static unsigned short wm_inits[] = { | 993 | static unsigned short wm8776_inits[] = { |
975 | /* These come first to reduce init pop noise */ | 994 | /* These come first to reduce init pop noise */ |
976 | WM_ADC_MUX, 0x0003, /* ADC mute */ | 995 | WM_ADC_MUX, 0x0003, /* ADC mute */ |
977 | /* 0x00c0 replaced by 0x0003 */ | 996 | /* 0x00c0 replaced by 0x0003 */ |
@@ -982,7 +1001,76 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) | |||
982 | WM_POWERDOWN, 0x0008, /* All power-up except HP */ | 1001 | WM_POWERDOWN, 0x0008, /* All power-up except HP */ |
983 | WM_RESET, 0x0000, /* reset */ | 1002 | WM_RESET, 0x0000, /* reset */ |
984 | }; | 1003 | }; |
985 | static unsigned short wm_inits2[] = { | 1004 | unsigned int i; |
1005 | |||
1006 | for (i = 0; i < ARRAY_SIZE(wm8776_inits); i += 2) | ||
1007 | wm_put(ice, wm8776_inits[i], wm8776_inits[i + 1]); | ||
1008 | } | ||
1009 | |||
1010 | #ifdef CONFIG_PM_SLEEP | ||
1011 | static int prodigy_hifi_resume(struct snd_ice1712 *ice) | ||
1012 | { | ||
1013 | static unsigned short wm8776_reinit_registers[] = { | ||
1014 | WM_MASTER_CTRL, | ||
1015 | WM_DAC_INT, | ||
1016 | WM_ADC_INT, | ||
1017 | WM_OUT_MUX, | ||
1018 | WM_HP_ATTEN_L, | ||
1019 | WM_HP_ATTEN_R, | ||
1020 | WM_PHASE_SWAP, | ||
1021 | WM_DAC_CTRL2, | ||
1022 | WM_ADC_ATTEN_L, | ||
1023 | WM_ADC_ATTEN_R, | ||
1024 | WM_ALC_CTRL1, | ||
1025 | WM_ALC_CTRL2, | ||
1026 | WM_ALC_CTRL3, | ||
1027 | WM_NOISE_GATE, | ||
1028 | WM_ADC_MUX, | ||
1029 | /* no DAC attenuation here */ | ||
1030 | }; | ||
1031 | struct prodigy_hifi_spec *spec = ice->spec; | ||
1032 | int i, ch; | ||
1033 | |||
1034 | mutex_lock(&ice->gpio_mutex); | ||
1035 | |||
1036 | /* reinitialize WM8776 and re-apply old register values */ | ||
1037 | wm8776_init(ice); | ||
1038 | schedule_timeout_uninterruptible(1); | ||
1039 | for (i = 0; i < ARRAY_SIZE(wm8776_reinit_registers); i++) | ||
1040 | wm_put(ice, wm8776_reinit_registers[i], | ||
1041 | wm_get(ice, wm8776_reinit_registers[i])); | ||
1042 | |||
1043 | /* reinitialize WM8766 and re-apply volumes for all DACs */ | ||
1044 | wm8766_init(ice); | ||
1045 | for (ch = 0; ch < 2; ch++) { | ||
1046 | wm_set_vol(ice, WM_DAC_ATTEN_L + ch, | ||
1047 | spec->vol[2 + ch], spec->master[ch]); | ||
1048 | |||
1049 | wm8766_set_vol(ice, WM8766_LDA1 + ch, | ||
1050 | spec->vol[0 + ch], spec->master[ch]); | ||
1051 | |||
1052 | wm8766_set_vol(ice, WM8766_LDA2 + ch, | ||
1053 | spec->vol[4 + ch], spec->master[ch]); | ||
1054 | |||
1055 | wm8766_set_vol(ice, WM8766_LDA3 + ch, | ||
1056 | spec->vol[6 + ch], spec->master[ch]); | ||
1057 | } | ||
1058 | |||
1059 | /* unmute WM8776 DAC */ | ||
1060 | wm_put(ice, WM_DAC_MUTE, 0x00); | ||
1061 | wm_put(ice, WM_DAC_CTRL1, 0x90); | ||
1062 | |||
1063 | mutex_unlock(&ice->gpio_mutex); | ||
1064 | return 0; | ||
1065 | } | ||
1066 | #endif | ||
1067 | |||
1068 | /* | ||
1069 | * initialize the chip | ||
1070 | */ | ||
1071 | static int prodigy_hifi_init(struct snd_ice1712 *ice) | ||
1072 | { | ||
1073 | static unsigned short wm8776_defaults[] = { | ||
986 | WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ | 1074 | WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ |
987 | WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ | 1075 | WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ |
988 | WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ | 1076 | WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ |
@@ -1010,22 +1098,6 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) | |||
1010 | WM_DAC_MUTE, 0x0000, /* DAC unmute */ | 1098 | WM_DAC_MUTE, 0x0000, /* DAC unmute */ |
1011 | WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ | 1099 | WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ |
1012 | }; | 1100 | }; |
1013 | static unsigned short wm8766_inits[] = { | ||
1014 | WM8766_RESET, 0x0000, | ||
1015 | WM8766_DAC_CTRL, 0x0120, | ||
1016 | WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ | ||
1017 | WM8766_DAC_CTRL2, 0x0001, | ||
1018 | WM8766_DAC_CTRL3, 0x0080, | ||
1019 | WM8766_LDA1, 0x0100, | ||
1020 | WM8766_LDA2, 0x0100, | ||
1021 | WM8766_LDA3, 0x0100, | ||
1022 | WM8766_RDA1, 0x0100, | ||
1023 | WM8766_RDA2, 0x0100, | ||
1024 | WM8766_RDA3, 0x0100, | ||
1025 | WM8766_MUTE1, 0x0000, | ||
1026 | WM8766_MUTE2, 0x0000, | ||
1027 | }; | ||
1028 | |||
1029 | struct prodigy_hifi_spec *spec; | 1101 | struct prodigy_hifi_spec *spec; |
1030 | unsigned int i; | 1102 | unsigned int i; |
1031 | 1103 | ||
@@ -1052,16 +1124,17 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) | |||
1052 | ice->spec = spec; | 1124 | ice->spec = spec; |
1053 | 1125 | ||
1054 | /* initialize WM8776 codec */ | 1126 | /* initialize WM8776 codec */ |
1055 | for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) | 1127 | wm8776_init(ice); |
1056 | wm_put(ice, wm_inits[i], wm_inits[i+1]); | ||
1057 | schedule_timeout_uninterruptible(1); | 1128 | schedule_timeout_uninterruptible(1); |
1058 | for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2) | 1129 | for (i = 0; i < ARRAY_SIZE(wm8776_defaults); i += 2) |
1059 | wm_put(ice, wm_inits2[i], wm_inits2[i+1]); | 1130 | wm_put(ice, wm8776_defaults[i], wm8776_defaults[i + 1]); |
1060 | 1131 | ||
1061 | /* initialize WM8766 codec */ | 1132 | wm8766_init(ice); |
1062 | for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) | ||
1063 | wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]); | ||
1064 | 1133 | ||
1134 | #ifdef CONFIG_PM_SLEEP | ||
1135 | ice->pm_resume = &prodigy_hifi_resume; | ||
1136 | ice->pm_suspend_enabled = 1; | ||
1137 | #endif | ||
1065 | 1138 | ||
1066 | return 0; | 1139 | return 0; |
1067 | } | 1140 | } |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index c7b007164c99..4206ba44d8bb 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -2348,7 +2348,6 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci, | |||
2348 | 2348 | ||
2349 | err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); | 2349 | err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); |
2350 | if (err < 0) { | 2350 | if (err < 0) { |
2351 | release_firmware(dsp_code); | ||
2352 | snd_printk(KERN_ERR "firmware not available\n"); | 2351 | snd_printk(KERN_ERR "firmware not available\n"); |
2353 | snd_korg1212_free(korg1212); | 2352 | snd_korg1212_free(korg1212); |
2354 | return err; | 2353 | return err; |
diff --git a/sound/sound_core.c b/sound/sound_core.c index 99b73c675743..b4efb22db561 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c | |||
@@ -119,13 +119,6 @@ struct sound_unit | |||
119 | char name[32]; | 119 | char name[32]; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | #ifdef CONFIG_SOUND_MSNDCLAS | ||
123 | extern int msnd_classic_init(void); | ||
124 | #endif | ||
125 | #ifdef CONFIG_SOUND_MSNDPIN | ||
126 | extern int msnd_pinnacle_init(void); | ||
127 | #endif | ||
128 | |||
129 | /* | 122 | /* |
130 | * By default, OSS sound_core claims full legacy minor range (0-255) | 123 | * By default, OSS sound_core claims full legacy minor range (0-255) |
131 | * of SOUND_MAJOR to trap open attempts to any sound minor and | 124 | * of SOUND_MAJOR to trap open attempts to any sound minor and |
@@ -452,26 +445,6 @@ int register_sound_mixer(const struct file_operations *fops, int dev) | |||
452 | 445 | ||
453 | EXPORT_SYMBOL(register_sound_mixer); | 446 | EXPORT_SYMBOL(register_sound_mixer); |
454 | 447 | ||
455 | /** | ||
456 | * register_sound_midi - register a midi device | ||
457 | * @fops: File operations for the driver | ||
458 | * @dev: Unit number to allocate | ||
459 | * | ||
460 | * Allocate a midi device. Unit is the number of the midi device requested. | ||
461 | * Pass -1 to request the next free midi unit. | ||
462 | * | ||
463 | * Return: On success, the allocated number is returned. On failure, | ||
464 | * a negative error code is returned. | ||
465 | */ | ||
466 | |||
467 | int register_sound_midi(const struct file_operations *fops, int dev) | ||
468 | { | ||
469 | return sound_insert_unit(&chains[2], fops, dev, 2, 130, | ||
470 | "midi", S_IRUSR | S_IWUSR, NULL); | ||
471 | } | ||
472 | |||
473 | EXPORT_SYMBOL(register_sound_midi); | ||
474 | |||
475 | /* | 448 | /* |
476 | * DSP's are registered as a triple. Register only one and cheat | 449 | * DSP's are registered as a triple. Register only one and cheat |
477 | * in open - see below. | 450 | * in open - see below. |
@@ -533,21 +506,6 @@ void unregister_sound_mixer(int unit) | |||
533 | EXPORT_SYMBOL(unregister_sound_mixer); | 506 | EXPORT_SYMBOL(unregister_sound_mixer); |
534 | 507 | ||
535 | /** | 508 | /** |
536 | * unregister_sound_midi - unregister a midi device | ||
537 | * @unit: unit number to allocate | ||
538 | * | ||
539 | * Release a sound device that was allocated with register_sound_midi(). | ||
540 | * The unit passed is the return value from the register function. | ||
541 | */ | ||
542 | |||
543 | void unregister_sound_midi(int unit) | ||
544 | { | ||
545 | sound_remove_unit(&chains[2], unit); | ||
546 | } | ||
547 | |||
548 | EXPORT_SYMBOL(unregister_sound_midi); | ||
549 | |||
550 | /** | ||
551 | * unregister_sound_dsp - unregister a DSP device | 509 | * unregister_sound_dsp - unregister a DSP device |
552 | * @unit: unit number to allocate | 510 | * @unit: unit number to allocate |
553 | * | 511 | * |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 23d1d23aefec..8018d56cfecc 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -585,15 +585,24 @@ static int usb_audio_probe(struct usb_interface *intf, | |||
585 | * now look for an empty slot and create a new card instance | 585 | * now look for an empty slot and create a new card instance |
586 | */ | 586 | */ |
587 | for (i = 0; i < SNDRV_CARDS; i++) | 587 | for (i = 0; i < SNDRV_CARDS; i++) |
588 | if (enable[i] && ! usb_chip[i] && | 588 | if (!usb_chip[i] && |
589 | (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && | 589 | (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && |
590 | (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { | 590 | (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { |
591 | err = snd_usb_audio_create(intf, dev, i, quirk, | 591 | if (enable[i]) { |
592 | id, &chip); | 592 | err = snd_usb_audio_create(intf, dev, i, quirk, |
593 | if (err < 0) | 593 | id, &chip); |
594 | if (err < 0) | ||
595 | goto __error; | ||
596 | chip->pm_intf = intf; | ||
597 | break; | ||
598 | } else if (vid[i] != -1 || pid[i] != -1) { | ||
599 | dev_info(&dev->dev, | ||
600 | "device (%04x:%04x) is disabled\n", | ||
601 | USB_ID_VENDOR(id), | ||
602 | USB_ID_PRODUCT(id)); | ||
603 | err = -ENOENT; | ||
594 | goto __error; | 604 | goto __error; |
595 | chip->pm_intf = intf; | 605 | } |
596 | break; | ||
597 | } | 606 | } |
598 | if (!chip) { | 607 | if (!chip) { |
599 | dev_err(&dev->dev, "no available usb audio device\n"); | 608 | dev_err(&dev->dev, "no available usb audio device\n"); |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 2b4ceda36291..9afb8ab524c7 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -656,10 +656,14 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
656 | unsigned char *name, int maxlen, int term_only) | 656 | unsigned char *name, int maxlen, int term_only) |
657 | { | 657 | { |
658 | struct iterm_name_combo *names; | 658 | struct iterm_name_combo *names; |
659 | int len; | ||
659 | 660 | ||
660 | if (iterm->name) | 661 | if (iterm->name) { |
661 | return snd_usb_copy_string_desc(state, iterm->name, | 662 | len = snd_usb_copy_string_desc(state, iterm->name, |
662 | name, maxlen); | 663 | name, maxlen); |
664 | if (len) | ||
665 | return len; | ||
666 | } | ||
663 | 667 | ||
664 | /* virtual type - not a real terminal */ | 668 | /* virtual type - not a real terminal */ |
665 | if (iterm->type >> 16) { | 669 | if (iterm->type >> 16) { |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e1e7ce9ab217..e6359d341878 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/hid.h> | ||
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
@@ -1721,6 +1722,83 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer) | |||
1721 | return 0; | 1722 | return 0; |
1722 | } | 1723 | } |
1723 | 1724 | ||
1725 | /* Creative Sound Blaster E1 */ | ||
1726 | |||
1727 | static int snd_soundblaster_e1_switch_get(struct snd_kcontrol *kcontrol, | ||
1728 | struct snd_ctl_elem_value *ucontrol) | ||
1729 | { | ||
1730 | ucontrol->value.integer.value[0] = kcontrol->private_value; | ||
1731 | return 0; | ||
1732 | } | ||
1733 | |||
1734 | static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer, | ||
1735 | unsigned char state) | ||
1736 | { | ||
1737 | struct snd_usb_audio *chip = mixer->chip; | ||
1738 | int err; | ||
1739 | unsigned char buff[2]; | ||
1740 | |||
1741 | buff[0] = 0x02; | ||
1742 | buff[1] = state ? 0x02 : 0x00; | ||
1743 | |||
1744 | err = snd_usb_lock_shutdown(chip); | ||
1745 | if (err < 0) | ||
1746 | return err; | ||
1747 | err = snd_usb_ctl_msg(chip->dev, | ||
1748 | usb_sndctrlpipe(chip->dev, 0), HID_REQ_SET_REPORT, | ||
1749 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
1750 | 0x0202, 3, buff, 2); | ||
1751 | snd_usb_unlock_shutdown(chip); | ||
1752 | return err; | ||
1753 | } | ||
1754 | |||
1755 | static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol, | ||
1756 | struct snd_ctl_elem_value *ucontrol) | ||
1757 | { | ||
1758 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); | ||
1759 | unsigned char value = !!ucontrol->value.integer.value[0]; | ||
1760 | int err; | ||
1761 | |||
1762 | if (kcontrol->private_value == value) | ||
1763 | return 0; | ||
1764 | kcontrol->private_value = value; | ||
1765 | err = snd_soundblaster_e1_switch_update(list->mixer, value); | ||
1766 | return err < 0 ? err : 1; | ||
1767 | } | ||
1768 | |||
1769 | static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list) | ||
1770 | { | ||
1771 | return snd_soundblaster_e1_switch_update(list->mixer, | ||
1772 | list->kctl->private_value); | ||
1773 | } | ||
1774 | |||
1775 | static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol, | ||
1776 | struct snd_ctl_elem_info *uinfo) | ||
1777 | { | ||
1778 | static const char *const texts[2] = { | ||
1779 | "Mic", "Aux" | ||
1780 | }; | ||
1781 | |||
1782 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); | ||
1783 | } | ||
1784 | |||
1785 | static struct snd_kcontrol_new snd_soundblaster_e1_input_switch = { | ||
1786 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1787 | .name = "Input Source", | ||
1788 | .info = snd_soundblaster_e1_switch_info, | ||
1789 | .get = snd_soundblaster_e1_switch_get, | ||
1790 | .put = snd_soundblaster_e1_switch_put, | ||
1791 | .private_value = 0, | ||
1792 | }; | ||
1793 | |||
1794 | static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) | ||
1795 | { | ||
1796 | return add_single_ctl_with_resume(mixer, 0, | ||
1797 | snd_soundblaster_e1_switch_resume, | ||
1798 | &snd_soundblaster_e1_input_switch, | ||
1799 | NULL); | ||
1800 | } | ||
1801 | |||
1724 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | 1802 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
1725 | { | 1803 | { |
1726 | int err = 0; | 1804 | int err = 0; |
@@ -1802,6 +1880,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1802 | case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */ | 1880 | case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */ |
1803 | err = snd_scarlett_controls_create(mixer); | 1881 | err = snd_scarlett_controls_create(mixer); |
1804 | break; | 1882 | break; |
1883 | |||
1884 | case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ | ||
1885 | err = snd_soundblaster_e1_switch_create(mixer); | ||
1886 | break; | ||
1805 | } | 1887 | } |
1806 | 1888 | ||
1807 | return err; | 1889 | return err; |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 8a59d4782a0f..50252046b01d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -3277,4 +3277,52 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), | |||
3277 | } | 3277 | } |
3278 | }, | 3278 | }, |
3279 | 3279 | ||
3280 | { | ||
3281 | /* | ||
3282 | * Nura's first gen headphones use Cambridge Silicon Radio's vendor | ||
3283 | * ID, but it looks like the product ID actually is only for Nura. | ||
3284 | * The capture interface does not work at all (even on Windows), | ||
3285 | * and only the 48 kHz sample rate works for the playback interface. | ||
3286 | */ | ||
3287 | USB_DEVICE(0x0a12, 0x1243), | ||
3288 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
3289 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3290 | .type = QUIRK_COMPOSITE, | ||
3291 | .data = (const struct snd_usb_audio_quirk[]) { | ||
3292 | { | ||
3293 | .ifnum = 0, | ||
3294 | .type = QUIRK_AUDIO_STANDARD_MIXER, | ||
3295 | }, | ||
3296 | /* Capture */ | ||
3297 | { | ||
3298 | .ifnum = 1, | ||
3299 | .type = QUIRK_IGNORE_INTERFACE, | ||
3300 | }, | ||
3301 | /* Playback */ | ||
3302 | { | ||
3303 | .ifnum = 2, | ||
3304 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
3305 | .data = &(const struct audioformat) { | ||
3306 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
3307 | .channels = 2, | ||
3308 | .iface = 2, | ||
3309 | .altsetting = 1, | ||
3310 | .altset_idx = 1, | ||
3311 | .attributes = UAC_EP_CS_ATTR_FILL_MAX | | ||
3312 | UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
3313 | .endpoint = 0x03, | ||
3314 | .ep_attr = USB_ENDPOINT_XFER_ISOC, | ||
3315 | .rates = SNDRV_PCM_RATE_48000, | ||
3316 | .rate_min = 48000, | ||
3317 | .rate_max = 48000, | ||
3318 | .nr_rates = 1, | ||
3319 | .rate_table = (unsigned int[]) { | ||
3320 | 48000 | ||
3321 | } | ||
3322 | } | ||
3323 | }, | ||
3324 | } | ||
3325 | } | ||
3326 | }, | ||
3327 | |||
3280 | #undef USB_DEVICE_VENDOR_SPEC | 3328 | #undef USB_DEVICE_VENDOR_SPEC |